<groupId>org.opendaylight.groupbasedpolicy</groupId>
<artifactId>neutron-ovsdb</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.groupbasedpolicy</groupId>
- <artifactId>ui-backend</artifactId>
- </dependency>
<dependency>
<groupId>org.opendaylight.groupbasedpolicy</groupId>
<artifactId>groupbasedpolicy-ui-bundle</artifactId>
</dependency>
- <dependency>
- <groupId>org.opendaylight.groupbasedpolicy</groupId>
- <artifactId>groupbasedpolicy-old-ui-bundle</artifactId>
- </dependency>
<dependency>
<groupId>org.opendaylight.groupbasedpolicy</groupId>
<artifactId>sxp-mapper</artifactId>
<type>xml</type>
<classifier>config</classifier>
</dependency>
- <dependency>
- <groupId>org.opendaylight.groupbasedpolicy</groupId>
- <artifactId>ui-backend</artifactId>
- <type>xml</type>
- <classifier>config</classifier>
- </dependency>
<dependency>
<groupId>org.opendaylight.groupbasedpolicy</groupId>
<artifactId>sxp-mapper</artifactId>
<repository>mvn:org.opendaylight.neutron/features-neutron/{{VERSION}}/xml/features</repository>
<!-- Repos needed by ofoverlay for SFC -->
<repository>mvn:org.opendaylight.sfc/features-sfc/{{VERSION}}/xml/features</repository>
- <!-- Repos needed by the UI Backend -->
- <repository>mvn:org.opendaylight.netconf/features-restconf/{{VERSION}}/xml/features</repository>
<!-- Repos needed by the UI -->
<repository>mvn:org.opendaylight.dlux/features-dlux/{{VERSION}}/xml/features</repository>
<!-- Repos needed by IOvisor Renderer -->
<configfile finalname="${config.configfile.directory}/15-neutron-vpp-mapper.xml">mvn:org.opendaylight.groupbasedpolicy/neutron-vpp-mapper/{{VERSION}}/xml/config</configfile>
</feature>
- <!--
- The UI Backend
- -->
- <feature name='odl-groupbasedpolicy-uibackend' version='${project.version}' description='OpenDaylight :: groupbasedpolicy :: UI Backend provides APIs for UI '>
- <feature version="${project.version}">odl-groupbasedpolicy-base</feature>
- <feature version="${restconf.version}">odl-restconf</feature>
- <bundle>mvn:org.opendaylight.groupbasedpolicy/ui-backend/{{VERSION}}</bundle>
- <configfile finalname="${config.configfile.directory}/15-ui-backend.xml">mvn:org.opendaylight.groupbasedpolicy/ui-backend/{{VERSION}}/xml/config</configfile>
- </feature>
-
<!--
UI
-->
<feature name='odl-groupbasedpolicy-ui' version='${project.version}' description='OpenDaylight :: groupbasedpolicy :: DLUX UI '>
<feature version="${dlux.version}">odl-dlux-core</feature>
- <feature version="${dlux.version}">odl-dlux-yangvisualizer</feature>
- <feature version="${project.version}">odl-groupbasedpolicy-uibackend</feature>
<bundle>mvn:org.opendaylight.groupbasedpolicy/groupbasedpolicy-ui-bundle/{{VERSION}}</bundle>
- <bundle>mvn:org.opendaylight.groupbasedpolicy/groupbasedpolicy-old-ui-bundle/{{VERSION}}</bundle>
</feature>
<!--
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.groupbasedpolicy</groupId>
- <artifactId>groupbasedpolicy-old-ui</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>groupbasedpolicy-old-ui-bundle</artifactId>
- <name>groupbasedpolicy-old-ui-bundle</name>
- <packaging>bundle</packaging>
-
- <properties>
- <dlux.version>0.4.0-SNAPSHOT</dlux.version>
- </properties>
-
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.dlux</groupId>
- <artifactId>loader</artifactId>
- <version>${dlux.version}</version>
- </dependency>
- <dependency>
- <groupId>org.opendaylight.groupbasedpolicy</groupId>
- <artifactId>groupbasedpolicy-old-ui-module</artifactId>
- <version>${project.version}</version>
- </dependency>
- </dependencies>
- <build>
- <resources>
- <resource>
- <directory>target/generated-resources</directory>
- </resource>
- <resource>
- <directory>src/main/resources</directory>
- </resource>
- </resources>
- <plugins>
- <plugin>
- <groupId>org.apache.maven.plugins</groupId>
- <artifactId>maven-dependency-plugin</artifactId>
- <version>2.6</version>
- <executions>
- <!--loader Resources-->
- <execution>
- <id>unpack-loader-resources</id>
- <goals>
- <goal>unpack-dependencies</goal>
- </goals>
- <phase>generate-resources</phase>
- <configuration>
- <outputDirectory>${project.build.directory}/generated-resources</outputDirectory>
- <groupId>org.opendaylight.dlux</groupId>
- <includeArtifactIds>groupbasedpolicy-old-ui-module</includeArtifactIds>
- <excludes>META-INF\/**</excludes>
- <excludeTransitive>true</excludeTransitive>
- <ignorePermissions>false</ignorePermissions>
- </configuration>
- </execution>
- </executions>
- </plugin>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Import-Package>org.osgi.service.http,
- org.osgi.framework;version="1.0.0",
- org.opendaylight.dlux.loader,
- org.slf4j
- </Import-Package>
- <Export-Package></Export-Package>
- </instructions>
- </configuration>
- </plugin>
- </plugins>
- </build>
- <scm>
- <connection>scm:git:ssh://git.opendaylight.org:29418/dlux.git</connection>
- <developerConnection>scm:git:ssh://git.opendaylight.org:29418/dlux.git</developerConnection>
- <tag>HEAD</tag>
- <url>https://wiki.opendaylight.org/view/OpenDaylight_dlux:Main</url>
- </scm>
-</project>
+++ /dev/null
-<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0">
- <reference id="httpService" availability="mandatory" activation="eager" interface="org.osgi.service.http.HttpService"/>
- <reference id="loader" availability="mandatory" activation="eager" interface="org.opendaylight.dlux.loader.DluxModuleLoader"/>
- <bean id="bundle" init-method="initialize" destroy-method="clean" class="org.opendaylight.dlux.loader.DluxModule">
- <property name="httpService" ref="httpService"/>
- <property name="loader" ref="loader"/>
- <property name="moduleName" value="gbpOld"/>
- <property name="url" value="/src/app/gbp-old"/>
- <property name="directory" value="/gbp-old"/>
- <property name="requireJs" value="app/gbp-old/gbp.module"/>
- <property name="angularJs" value="app.gbpOld"/>
- <property name="cssDependencies">
- <list>
- <value>src/app/gbp-old/gbp.css</value>
- <value>src/app/gbp-old/js/joint.css</value>
- </list>
- </property>
- </bean>
-</blueprint>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (c) 2014 Inocybe Technologies, and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
- <parent>
- <groupId>org.opendaylight.groupbasedpolicy</groupId>
- <artifactId>groupbasedpolicy-old-ui</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- </parent>
-
- <artifactId>groupbasedpolicy-old-ui-module</artifactId>
- <name>${project.artifactId}</name>
- <description>GBP Old UI Module Resources</description>
- <packaging>jar</packaging>
-
-</project>
+++ /dev/null
-var modules = ['app/gbp-old/gbp.module',
- 'app/gbp-old/gbp.services'
- ];
-
-
-define(modules, function(gbpOld) {
-
- gbpOld.register.controller('gbpCtrl', ['$scope', '$rootScope', 'GBPTenantServices','DesignGbpFactory', 'GBPConstants',
- function ($scope, $rootScope, GBPTenantServices, DesignGbpFactory, GBPConstants) {
- $rootScope['section_logo'] = 'logo_gbp';
- $scope.view_path = 'src/app/gbp-old/views/';
-
- $scope.mainView = {
- main: true,
- 'policy-renderer': false,
- governance: false
- };
-
- $scope.policyRendererView = {
- slider : true,
- basic : true,
- policy: false,
- tenants : false,
- l2l3 : false,
- epg : false,
- contracts : false,
- docs : false,
- groupMenu: false,
- classifiers: false,
- actions: false,
- registerEndpoint : false,
- registerL3PrefixEndpoint : false
- };
-
- $scope.subMenuView = {
- governance : false,
- policy : false,
- policySub : false,
- renderers : false,
- endpoints : false
- };
-
- $scope.breadcrumbs = {'l1' : null,
- 'l2' : null,
- 'l3' : null};
-
- $scope.wizards = {
- accessModelWizard: false,
- actionReferenceWizard: false
- };
-
- $scope.setBreadcrumb = function(level, label, visible){
- $scope.breadcrumbs[level] = visible ? label : null;
- if(level === 'l1'){
- $scope.breadcrumbs.l2 = null;
- $scope.breadcrumbs.l3 = null;
- }
- if(level === 'l2'){
- $scope.breadcrumbs.l3 = null;
- }
- };
-
- $scope.setViewExpand = function(menu, expand, show){
- $scope[menu][expand] = show ? true : !$scope[menu][expand];
- for ( var property in $scope[menu] ) {
- $scope[menu][property] = expand !== property ? false : $scope[menu][expand];
- }
-
- };
-
- $scope.toggleExpandedMM = function(expand, show, broadcast){
- $scope.setViewExpand('mainView',expand, show);
-
- if ( broadcast ) {
- $scope.$broadcast(broadcast);
- }
- };
-
- $scope.sliceLabel = function(label){
- return label.length > GBPConstants.numbers.displayLabelLength ? label.slice(0,GBPConstants.numbers.displayLabelLength)+'...' : label;
- };
-
- $scope.getDisplayLabel = function(obj, labelArray, dontSlice){
- var ret = '';
-
- if((typeof labelArray) === 'string'){
- ret = obj[labelArray];
- } else if (angular.isFunction(labelArray)) {
- ret = labelArray(obj);
- } else {
- labelArray.some(function(labelParam) {
- if(angular.isFunction(labelParam)) {
- ret = labelParam(obj);
- } else if(obj.hasOwnProperty(labelParam)) {
- ret = obj[labelParam];
- }
- return ret;
- });
- }
-
- return dontSlice ? ret : $scope.sliceLabel(ret);
- };
-
- // TENANTS
- $scope.tenantList = [];
- $scope.selectedTenant = null;
- $scope.tenantDisplayLabel = ['name' , 'id'];
-
- $scope.loadTenants = function() {
- GBPTenantServices.load(
- function(tenants) {
- $scope.tenantList = tenants;
- console.log('$scope.tenantList', $scope.tenantList);
- },
- function(){
- //TODO error
- });
-
- DesignGbpFactory.setMainClass();
- };
-
- $scope.setTenant = function(selectedTenant) {
- $scope.selectedTenant = selectedTenant;
- $scope.$broadcast('GBP_TENANT_RELOAD', $scope.selectedTenant);
- };
-
- $scope.loadTenants();
-
- $scope.$on('GBP_GLOBAL_TENANT_RELOAD',function(){
- $scope.loadTenants();
- });
-
- $scope.sendReloadEventFromRoot = function(eventName, val) {
- $scope.$broadcast(eventName, val);
- };
-
-
- // TODO: rework, use $scope.setViewContent or something
- $scope.showWizard = function(wizardName, broadcast, broadcastedData, path) {
- $scope.wizards[wizardName] = true;
-
- if ( broadcast ) {
- $scope.sendReloadEventFromRoot(broadcast, {data: broadcastedData, path: path});
- }
- };
-
- $scope.closeWizard = function(wizardName) {
- $scope.wizards[wizardName] = false;
- };
-
- $scope.updateList = function(list, object, key) {
- var elementPos = list.map(function(x) {return x[key]; }).indexOf(object[key]);
-
- if(elementPos < 0) {
- list.push(object);
- }
- else {
- list[elementPos] = object;
- }
- };
-
- }]);
-
- gbpOld.register.controller('governanceCtrl', ['$rootScope','$scope',
- function ($rootScope, $scope) {
- $scope.menuTpl = 'main-menu';
- $scope.menuBox = null;
- $scope.contentTpl = 'main';
- // $scope.selectedTenant = null;
- $scope.rendererList = [];
- var broadcastObj = {};
-
- $scope.rendererList.push({'name' : 'of_overlay', 'id' : 0});
-
- $scope.toggleExpanded = function(expand, menu, tplType){
- var type = tplType ? tplType : 'contentTpl';
- $scope.menuBox = null;
-
- $scope[type] = expand;
-
- if ( menu && menu === false ) {
- $scope.menuTpl = !menu ? null : menu;
- }
- };
-
-
-
- $scope.setViewContent = function(tplName, data, broadcast, tplType) {
-
- if ( $scope[tplType] === tplName ) {
- $scope.$broadcast(broadcast, data, true);
- } else {
-
- broadcastObj[tplType] = {};
- broadcastObj[tplType].name = broadcast;
- broadcastObj[tplType].data = data;
-
- $scope.toggleExpanded(tplName, null, tplType);
- $scope.$apply();
-
- }
- };
-
- $scope.broadcastCalling = function(tplType){
- $scope.$broadcast(broadcastObj[tplType].name, broadcastObj[tplType].data);
- };
-
- $scope.checkBroadcastCalling = function(tplName){
- var objClickAction = {
- 'epg-detail': function(){
- $scope.broadcastCalling('contentTpl');
- },
- 'subject-detail': function(){
- $scope.broadcastCalling('contentTpl');
- }
- };
-
- if ( angular.isFunction(objClickAction[tplName]) ) {
- objClickAction[tplName]();
- }
-
- };
-
-
- $scope.$on('GOV_INIT', function(){
- $scope.menuTpl = 'main-menu';
- $scope.contentTpl = 'main';
- // $scope.$emit('GBP_GLOBAL_TENANT_RELOAD');
- $scope.menuBox = null;
- });
-
- $scope.$on('GBP_TENANT_RELOAD', function(e, obj){
- $scope.selectedTenant = obj;
- });
-
-
- }]);
-
- gbpOld.register.controller('boxStaticCtrl',['$scope',
- function($scope){
-
- $scope.selectedObj = null;
-
- $scope.getLabel = function(id, type){
- var objAction = {
- providerItems: function(){
- var name = $scope.selectedObj[type][id].attributes.objData['name'];
- return name ? name + ' : ' + id : id;
- },
- consumerItems: function(){
- var name = $scope.selectedObj[type][id].attributes.objData['name'];
- return name ? name + ' : ' + id : id;
- }
- };
-
- if ( angular.isFunction(objAction[type]) ) {
- return objAction[type]();
- }
- };
-
- $scope.$on('SET_SEL_STA_OBJ', function(obj, data, apply){
- $scope.selectedObj = data;
-
- if ( apply ) {
- $scope.$apply();
- }
-
- });
-
- }]);
-
- gbpOld.register.controller('graphCtrl', ['$scope', function($scope){
- var paper = null,
- paperScale = 1;
-
- $scope.init = function(paperInstance){
- paper = paperInstance;
- $scope.loadMouseScrollEvent();
- };
-
-
- $scope.zoom = function(out){
- paperScale = out ? paperScale - 0.1 : paperScale >= 1 ? 1 : paperScale + 0.1;
- paper.scale(paperScale, paperScale);
- };
-
-
-
- $scope.loadMouseScrollEvent = function(){
- /*mouse wheel event for zooming*/
- var graph = document.getElementById('graph'),
- MouseWheelHandler = function(e){
- var mouseEvent = window.event || e; // old IE support
- var delta = Math.max(-1, Math.min(1, (mouseEvent.wheelDelta || -mouseEvent.detail)));
- $scope.zoom(delta === 1 ? false : true);
- };
-
- if (graph.addEventListener) {
- // IE9, Chrome, Safari, Opera
- graph.addEventListener("mousewheel", MouseWheelHandler, false);
- // Firefox
- graph.addEventListener("DOMMouseScroll", MouseWheelHandler, false);
- }
- // IE 6/7/8
- else {graph.attachEvent("onmousewheel", MouseWheelHandler);}
- /*mouse wheel event for zooming - end*/
- };
-
- }]);
-
- gbpOld.register.controller('expressedPolicyCtrl', ['$scope', 'JointGraphFactory', 'JointGraphOffsetFactory', 'GBPConstants',
- function ($scope, JointGraphFactory, JointGraphOffsetFactory, GBPConstants) {
- var paper = JointGraphFactory.createGraph(),
- epgItems = [],
- contractItems = [],
- linkItems = [];
-
- var objClickAction = {
- epg: function(data){
- $scope.setViewContent('epg-content-static',data, 'SET_SEL_STA_OBJ', 'menuBox');
- },
- contract: function(data){
- $scope.setViewContent('contract-content-static',data, 'SET_SEL_STA_OBJ', 'menuBox');
- }
- };
-
- paper.on('cell:pointerdown', function(cell) {
- if ( angular.isFunction(objClickAction[cell.model.attributes.objType]) ) {
- objClickAction[cell.model.attributes.objType](cell.model.attributes.objData);
- }
- });
-
- var createEpgLinks = function(epg, epgItem, contracts) {
- var providers = epg['provider-named-selector'] && epg['provider-named-selector'].length>0 ? epg['provider-named-selector'] : [];
- var consumers = epg['consumer-named-selector'] && epg['consumer-named-selector'].length>0 ? epg['consumer-named-selector'] : [];
- var consumerLinkItems = [];
- var providerLinkItems = [];
-
- consumers.forEach(function(c) {
- c.contract.forEach(function(con) {
- consumerLinkItems.push(JointGraphFactory.createLink(contracts[con].id, epgItem.id, 'green'));
- });
- });
-
- providers.forEach(function(p) {
- p.contract.forEach(function(con) {
- providerLinkItems.push(JointGraphFactory.createLink(epgItem.id, contracts[con].id, 'blue'));
- });
- });
-
- JointGraphFactory.addItemList(paper.model, providerLinkItems);
- JointGraphFactory.addItemList(paper.model, consumerLinkItems);
-
- };
-
- var loadData = function() {
- if($scope.selectedTenant) {
- var offsetObj = {
- ow: 100,
- oh: 100,
- w: 100,
- h: 100
- },
- marginObj = {
- w: 50,
- h: 80
- },
- offsetHobj = {
- contract: 0,
- epg: 0
- },
- itemsArray = {
- contract: [],
- epg: []
- };
-
- JointGraphFactory.reloadGraph(paper.model);
-
- if ( $scope.selectedTenant && $scope.selectedTenant.contract ) {
-
- $scope.selectedTenant.contract.forEach(function(c, i) {
- var label = c.description ? $scope.sliceLabel(c.description) : c.id,
- width = JointGraphFactory.getLabelLength(label.length);
- item = JointGraphFactory.createElement(label, offsetObj.w, offsetObj.h, width, null, GBPConstants.objType.contract, c, 'Click to see contract info', GBPConstants.colors.graph['subject'], 'Contract');
-
- itemsArray.contract.push(item);
-
- JointGraphOffsetFactory.updateOffsets(JointGraphOffsetFactory.createWHObj(width), offsetObj, marginObj, JointGraphOffsetFactory.createWHObj(paper.options.width, paper.options.height), paper);
- JointGraphFactory.addItem(paper.model, item);
- contractItems[c.id] = item;
- });
-
- offsetHobj.contract = offsetObj.h;
-
- }
-
- if ( $scope.selectedTenant && $scope.selectedTenant['endpoint-group'] ) {
-
- JointGraphOffsetFactory.resetOffsets(offsetObj, offsetObj.ow, offsetObj.h > 400 ? offsetObj.h : 400);
- $scope.selectedTenant['endpoint-group'].forEach(function(e, i) {
- var label = e.name || e.id,
- width = JointGraphFactory.getLabelLength(label.length);
- item = JointGraphFactory.createElement(label, offsetObj.w, offsetObj.h, width, null, GBPConstants.objType.epg, e, 'Click to see epg info', GBPConstants.colors.graph['pns'], 'EP group');
-
- itemsArray.epg.push(item);
-
- JointGraphOffsetFactory.updateOffsets(JointGraphOffsetFactory.createWHObj(width), offsetObj, marginObj, JointGraphOffsetFactory.createWHObj(paper.options.width, paper.options.height), paper);
- JointGraphFactory.addItem(paper.model, item);
- epgItems[e.id] = item;
-
- createEpgLinks(e, item, contractItems);
- });
-
- }
-
- offsetHobj.epg = JointGraphOffsetFactory.getCurrentOffset(itemsArray.contract, 'y');
- JointGraphOffsetFactory.checkObjsHoffsets(itemsArray.epg ,offsetHobj.epg, paper);
- }
-
- };
-
- $scope.getPaperObj = function(){
- return paper;
- };
-
- $scope.$on('GBP_TENANT_RELOAD',function(){
- if ($scope.selectedTenant) {
- loadData();
- }
- else {
- JointGraphFactory.reloadGraph(paper.model);
- }
- });
-
- loadData();
- }]);
-
- gbpOld.register.controller('deliveredPolicyCtrl', ['$scope', 'GPBServices', 'JointGraphFactory', 'GBPGovernanceServices', 'JointGraphOffsetFactory', 'GBPConstants',
- function ($scope, GPBServices, JointGraphFactory, GBPGovernanceServices, JointGraphOffsetFactory, GBPConstants) {
- var paper = JointGraphFactory.createGraph(),
- providerItems = {},
- consumerItems = {},
- subjectItems = {};
-
- var getEpList = function() {
- var providerEpKeys = Object.keys(providerItems),
- consumerEpKeys = Object.keys(consumerItems),
- epList = providerEpKeys.map(function (k) {
- return providerItems[k].attributes.objData;
- });
-
- consumerEpKeys.forEach(function(k) {
- if(providerEpKeys.indexOf(k) === -1) {
- epList.push(consumerItems[k].attributes.objData);
- }
- });
-
- return epList;
- };
-
- var getSubjList = function() {
- return Object.keys(subjectItems).map(function (k) {
- return subjectItems[k].attributes.objData;
- });
- };
-
- var objClickAction = {
- subject: function(data){
- data.providerItems = providerItems;
- data.consumerItems = consumerItems;
- $scope.setViewContent('subject-content-static',data, 'SET_SEL_STA_OBJ', 'menuBox');
- },
- consumer: function(data) {
- $scope.setViewContent('epg-content-static', data, 'SET_SEL_STA_OBJ', 'menuBox');
- },
- provider: function(data) {
- $scope.setViewContent('epg-content-static', data, 'SET_SEL_STA_OBJ', 'menuBox');
- }
- };
-
- var objDblClickAction = {
- consumer: function(data){
- $scope.setBreadcrumb('l3', 'Endpoint group detail', true);
- $scope.setViewContent('epg-detail', { ep: data, epList: getEpList() }, 'SET_SELECTED_EPG','contentTpl');
- },
- provider: function(data){
- $scope.setBreadcrumb('l3', 'Endpoint group detail', true);
- $scope.setViewContent('epg-detail', { ep: data, epList: getEpList() }, 'SET_SELECTED_EPG','contentTpl');
- },
- subject: function(data) {
- var obj = { subject: data,
- subjList: Object.keys(subjectItems).map(function (k) {
- return subjectItems[k].attributes.objData;
- }),
- providerItems: providerItems,
- consumerItems: consumerItems
- };
- $scope.setBreadcrumb('l3', 'Subject detail', true);
- $scope.setViewContent('subject-detail', obj, 'SET_SELECTED_SUBJECT','contentTpl');
- }
- };
-
- paper.on('cell:pointerdown', function(cell) {
- if ( angular.isFunction(objClickAction[cell.model.attributes.objType]) ) {
- objClickAction[cell.model.attributes.objType](cell.model.attributes.objData);
- }
- });
-
- paper.on('cell:pointerdblclick', function(cell) {
- objDblClickAction[cell.model.attributes.objType](cell.model.attributes.objData);
- });
-
- var createSubjectLinks = function(subject, subjectItem, providerItems, consumerItems) {
- var providerLinkItems = subject.providers.map(function(p) {
- return JointGraphFactory.createLink(providerItems[p].id, subjectItem.id, 'green');
- });
- consumerLinkItems = subject.consumers.map(function(c) {
- return JointGraphFactory.createLink(subjectItem.id, consumerItems[c].id, 'blue');
- });
-
- JointGraphFactory.addItemList(paper.model, providerLinkItems);
- JointGraphFactory.addItemList(paper.model, consumerLinkItems);
- };
-
- var loadData = function() {
- if($scope.selectedTenant) {
- providerItems = {};
- consumerItems = {};
- subjectItems = {};
-
- var classifierInstances = $scope.selectedTenant['subject-feature-instances'] &&
- $scope.selectedTenant['subject-feature-instances']['classifier-instance'] &&
- $scope.selectedTenant['subject-feature-instances']['classifier-instance'].length > 0 ? $scope.selectedTenant['subject-feature-instances']['classifier-instance'] : [];
-
- var offsetObj = {
- ow: 100,
- oh: 100,
- w: 100,
- h: 100
- },
- marginObj = {
- w: 50,
- h: 80
- },
- offsetHobj = {
- pEpg: 0,
- cEpg: 0,
- subject: 0
- },
- itemsArray = {
- pEpg: [],
- cEpg: [],
- subject: []
- };
-
- JointGraphFactory.reloadGraph(paper.model);
-
- GBPGovernanceServices.getEPGsAndSubjects($scope.selectedTenant.id, classifierInstances, function(data){
- data.providers.forEach(function(p, i) {
- var relatedObj = GPBServices.getPropFromListByProp($scope.selectedTenant['endpoint-group'], 'id', p.id),
- label = relatedObj.name || p.id,
- width = JointGraphFactory.getLabelLength(label.length);
-
- relatedObj.rules = p.rules;
- var item = JointGraphFactory.createElement(label, offsetObj.w, offsetObj.h, width, null, GBPConstants.objType.provider, relatedObj, 'Click to see epg info, doubleclick to see Endpoint group detail', GBPConstants.colors.graph['pns'], 'Provider EPG');
-
- itemsArray.pEpg.push(item);
-
- JointGraphOffsetFactory.updateOffsets(JointGraphOffsetFactory.createWHObj(width), offsetObj, marginObj, JointGraphOffsetFactory.createWHObj(paper.options.width, paper.options.height), paper);
- JointGraphFactory.addItem(paper.model, item);
- providerItems[p.id] = item;
- });
-
- offsetHobj.pEpg = offsetObj.h;
-
- JointGraphOffsetFactory.resetOffsets(offsetObj, offsetObj.ow, 500);
- data.consumers.forEach(function(c, i) {
- var relatedObj = GPBServices.getPropFromListByProp($scope.selectedTenant['endpoint-group'], 'id', c.id),
- label = relatedObj.name || c.id,
- width = JointGraphFactory.getLabelLength(label.length);
-
- relatedObj.rules = c.rules;
- var item = JointGraphFactory.createElement(label, offsetObj.w, offsetObj.h, width, null, GBPConstants.objType.consumer, relatedObj, 'Click to see epg info, doubleclick to see Endpoint group detail', GBPConstants.colors.graph['cns'], 'Consumer EPG');
-
- itemsArray.cEpg.push(item);
-
- JointGraphOffsetFactory.updateOffsets(JointGraphOffsetFactory.createWHObj(width), offsetObj, marginObj, JointGraphOffsetFactory.createWHObj(paper.options.width, paper.options.height), paper);
- JointGraphFactory.addItem(paper.model, item);
- consumerItems[c.id] = item;
- });
-
- JointGraphOffsetFactory.resetOffsets(offsetObj, offsetObj.ow, offsetHobj.pEpg > 300 ? offsetHobj.pEpg : 300);
- data.subjects.forEach(function(s, i) {
- var label = s.name,
- width = JointGraphFactory.getLabelLength(label.length),
- item = JointGraphFactory.createElement(label, offsetObj.w, offsetObj.h, width, null, GBPConstants.objType.subject, s, 'Click to see subject info, doubleclick to see Subject detail', GBPConstants.colors.graph['subject'], 'Subject');
-
- itemsArray.subject.push(item);
-
- JointGraphOffsetFactory.updateOffsets(JointGraphOffsetFactory.createWHObj(width), offsetObj, marginObj, JointGraphOffsetFactory.createWHObj(paper.options.width, paper.options.height), paper);
- JointGraphFactory.addItem(paper.model, item);
- subjectItems[s.name] = item;
- createSubjectLinks(s, item, providerItems, consumerItems);
- });
-
- offsetHobj.pEpg = JointGraphOffsetFactory.getCurrentOffset(itemsArray.pEpg, 'y');
- JointGraphOffsetFactory.checkObjsHoffsets(itemsArray.subject ,offsetHobj.pEpg, paper);
- offsetHobj.subject = JointGraphOffsetFactory.getCurrentOffset(itemsArray.subject, 'y');
- JointGraphOffsetFactory.checkObjsHoffsets(itemsArray.cEpg ,offsetHobj.subject, paper);
-
- }, function(){});
-
- }
-
-
- // paper.scaleContentToFit();
- // paper.fitToContent();
- };
-
- $scope.getPaperObj = function(){
- return paper;
- };
-
-
- $scope.$on('GBP_TENANT_RELOAD',function(){
- if ($scope.selectedTenant) {
- loadData();
- }
- else {
- JointGraphFactory.reloadGraph(paper.model);
- }
- });
-
- loadData();
- }]);
-
- gbpOld.register.controller('subjectDetailCtrl', ['$scope', 'GPBServices', 'JointGraphFactory', 'GBPGovernanceServices', 'JointGraphOffsetFactory', 'GBPConstants',
- function ($scope, GPBServices, JointGraphFactory, GBPGovernanceServices, JointGraphOffsetFactory, GBPConstants) {
- $scope.selectedSubject = null;
- $scope.subjectList = [];
-
- var paper = JointGraphFactory.createGraph(),
- subjectItem = null,
- ruleItems = {},
- subjectItems = {};
-
- var createSubjectLinks = function(subjectItem, ruleItem) {
- var linkItem = JointGraphFactory.createLink(subjectItem.id, ruleItem.id, 'blue');
- JointGraphFactory.addItem(paper.model, linkItem);
- };
-
- paper.on('cell:pointerdown', function(cell) {
- var objClickAction = {
- subject: function(data){
- $scope.setViewContent('subject-content-static',data, 'SET_SEL_STA_OBJ', 'menuBox');
- },
- rule: function(data){
- $scope.setViewContent('rule-content-static',data, 'SET_SEL_STA_OBJ', 'menuBox');
- }
- };
-
- // console.log('cell.model.attributes.objType', cell.model.attributes.objType, cell.model.attributes.objData);
- if ( angular.isFunction(objClickAction[cell.model.attributes.objType]) ) {
- objClickAction[cell.model.attributes.objType](cell.model.attributes.objData);
- }
- });
-
- var loadData = function() {
- if($scope.selectedSubject) {
- subjectItem = null;
- ruleItems = {};
-
- var offsetObj = {
- ow: 100,
- oh: 100,
- w: 100,
- h: 100
- },
- marginObj = {
- w: 50,
- h: 80
- };
-
- JointGraphFactory.reloadGraph(paper.model);
-
- var label = $scope.selectedSubject.name || $scope.selectedSubject.id,
- width = JointGraphFactory.getLabelLength(label.length);
- subjectItem = JointGraphFactory.createElement(label, offsetObj.w, offsetObj.h, width, null, GBPConstants.objType.subject, $scope.selectedSubject, 'Click to see subject info', GBPConstants.colors.graph['subject'], 'Subject');
-
- JointGraphFactory.addItem(paper.model, subjectItem);
-
- JointGraphOffsetFactory.resetOffsets(offsetObj, offsetObj.ow, 300);
- $scope.selectedSubject.rules.forEach(function(r, i) {
- var label = r.name,
- width = JointGraphFactory.getLabelLength(label.length);
- item = JointGraphFactory.createElement(label, offsetObj.w, offsetObj.h, width, null, GBPConstants.objType.rule, r, 'Click to see rule info', GBPConstants.colors.graph['cns'], 'Rule');
-
- JointGraphOffsetFactory.updateOffsets(JointGraphOffsetFactory.createWHObj(width), offsetObj, marginObj, JointGraphOffsetFactory.createWHObj(paper.options.width), paper);
- JointGraphFactory.addItem(paper.model, item);
- ruleItems[r.name] = item;
-
- createSubjectLinks(subjectItem, item);
- });
- }
- };
-
- $scope.getPaperObj = function(){
- return paper;
- };
-
- $scope.$on('SET_SELECTED_SUBJECT', function(event, data){
- $scope.selectedSubject = data.subject;
- $scope.subjectList = data.subjList;
- loadData();
- });
-
- $scope.setSubject = function(subject) {
- $scope.selectedSubject = subject;
- loadData();
- };
-
- loadData();
- }]);
-
- gbpOld.register.controller('epgDetailCtrl', ['$scope', 'JointGraphFactory', 'TopologyDataLoaders', 'GBPEpgServices', 'JointGraphOffsetFactory', 'GBPConstants',
- function ($scope, JointGraphFactory, TopologyDataLoaders, GBPEpgServices, JointGraphOffsetFactory, GBPConstants) {
- var paper = JointGraphFactory.createGraph(),
- epgItem = {},
- epItems = {};
-
- $scope.epgDisplayLabel = ['name', 'id'];
- $scope.epgList = [];
- $scope.selectedEpg = null;
-
- $scope.$on('SET_SELECTED_EPG', function(event, epg){
- $scope.selectedEpg = epg.ep;
- $scope.epgList = epg.epList;
- loadData();
- });
-
- $scope.setEpg = function(epg){
- selectedEpg = epg;
- loadData();
- };
-
- paper.on('cell:pointerdown', function(cell) {
- var objClickAction = {
- ep: function(data){
- $scope.setViewContent('ep-content-static',data, 'SET_SEL_STA_OBJ', 'menuBox');
- },
- epg: function(data){
- $scope.setViewContent('epg-content-static',data, 'SET_SEL_STA_OBJ', 'menuBox');
- },
- };
-
- if ( angular.isFunction(objClickAction[cell.model.attributes.objType]) ) {
- objClickAction[cell.model.attributes.objType](cell.model.attributes.objData);
- }
- });
-
- var loadData = function() {
- if($scope.selectedTenant && $scope.selectedEpg) {
- epgItem = {};
- epItems = {};
- links = [];
-
- JointGraphFactory.reloadGraph(paper.model);
-
- TopologyDataLoaders.getEndpointsFromEndpointGroup($scope.selectedTenant.id, $scope.selectedEpg.id, function(data){
- var offsetObj = {
- ow: 100,
- oh: 100,
- w: 100,
- h: 100
- },
- marginObj = {
- w: 50,
- h: 80
- };
-
- var label = $scope.selectedEpg.name || $scope.selectedEpg.id,
- width = JointGraphFactory.getLabelLength(label.length);
- epgItem = JointGraphFactory.createElement(label, offsetObj.w, offsetObj.h, width, null, 'epg', $scope.selectedEpg, 'Click to see epg info', GBPConstants.colors.graph['subject'], 'EPG');
-
- JointGraphOffsetFactory.updateOffsets(JointGraphOffsetFactory.createWHObj(width), offsetObj, marginObj, JointGraphOffsetFactory.createWHObj(paper.options.width), paper);
- JointGraphFactory.addItem(paper.model, epgItem);
-
- JointGraphOffsetFactory.resetOffsets(offsetObj, offsetObj.ow, 500);
- if(data && data.output && data.output['ui-endpoint'] && data.output['ui-endpoint'].length){
- data.output['ui-endpoint'].forEach(function(ep, i){
- var label = ep['mac-address'] + ':' + ep['l2-context'],
- width = JointGraphFactory.getLabelLength(label.length);
- item = JointGraphFactory.createElement(label, offsetObj.w, offsetObj.h, width, null, 'ep', ep, 'Click to see ep info', GBPConstants.colors.graph['pns'], 'Endpoint');
-
- JointGraphOffsetFactory.updateOffsets(JointGraphOffsetFactory.createWHObj(width), offsetObj, marginObj, JointGraphOffsetFactory.createWHObj(paper.options.width), paper);
- JointGraphFactory.addItem(paper.model, item);
- epItems[label] = item;
- links.push(JointGraphFactory.createLink(item.id, epgItem.id, 'green'));
- });
-
- JointGraphFactory.addItemList(paper.model, links);
- }
- }, function(){});
- }
- };
-
- $scope.getPaperObj = function(){
- return paper;
- };
-
- // init();
- }]);
-
- gbpOld.register.controller('policyRendererCtrl', ['$scope', '$http', '$timeout', 'PGNServices', 'TopoServices', 'GBPTenantServices', 'GBPConstants', 'JointGraphFactory','GBPJointGraphBuilder',
- function ($scope, $http, $timeout, PGNServices, TopoServices, GBPTenantServices, GBPConstants, JointGraphFactory, GBPJointGraphBuilder) {
-
- $scope.topologyData = { nodes: [], links: [] };
- $scope.topologyType = null;
- $scope.topologyArgs = {};
- $scope.legend = {};
- $scope.showLegend = false;
-
- var paper = JointGraphFactory.createGraph();
-
- var reloadShowLegend = function() {
- $scope.showLegend = !$.isEmptyObject($scope.legend);
- };
-
- $scope.settingsSigma = {
- defaultLabelColor: '#fff',
- doubleClickEnabled: false,
- labelThreshold: 8
- };
-
- $scope.settingsAtlas = {
- adjustSizes: true,
- gravity: 0.2
- };
-
- $scope.viewTopo = {
- box: false,
- button: false
- };
-
- paper.on('cell:pointerdown', function(cellView, evt) {
- if (cellView.model.isLink() && cellView.model.attributes.objData) {
- $scope.$broadcast('SET_LINK_DATA', cellView.model.attributes.objData);
- }
- });
-
- $scope.mandatoryProperties = [];
- $scope.loadTopology = function(type, args) {
- if ($scope.selectedTenant) {
- $scope.topologyType = type;
- $scope.topologyArgs = args;
- GBPJointGraphBuilder.loadTopology(args, paper, type);
- }
- };
- $scope.toggleExpanded = function(expand, show) {
- $scope.setViewExpand('policyRendererView',expand, show, 'l2');
-
- if($scope.policyRendererView[expand] && $scope.selectedTenant) {
- $scope.topologyArgs.tenantId = $scope.selectedTenant.id;
-
- if((expand === 'epg' || expand === 'contracts' || expand === 'classifiers' || expand === 'actions' || expand === 'renderers') && ($scope.topologyType !== GBPConstants.strings.config)) {
- $scope.loadTopology(GBPConstants.strings.config, $scope.topologyArgs);
- } else if((expand === 'l2l3' || expand === 'registerEndpoint' || expand === 'registerL3PrefixEndpoint') && ($scope.topologyType !== GBPConstants.strings.l2l3)) {
- $scope.loadTopology(GBPConstants.strings.l2l3, $scope.topologyArgs);
- }
- }
- };
-
- $scope.reloadTopo = function() {
- if($scope.selectedTenant) {
- $scope.topologyArgs.tenantId = $scope.selectedTenant.id;
- GBPJointGraphBuilder.loadTopology($scope.topologyArgs, paper, $scope.topologyType);
- }
- };
-
- $scope.getDisplayLabelsFromCtrl = function(eventName, val) {
- $scope.$broadcast(eventName, val);
- };
-
- $scope.validateMandatory = function(newObj, mandatoryProps){
- var ret = true,
- notFilledProps = [];
-
- mandatoryProps.forEach(function(el){
- if(newObj[el] === '' || newObj[el] === null || newObj[el] === undefined){
- notFilledProps.push(el);
- ret = false;
- }
- });
-
- return {'status' : ret, 'notFilledProps' : notFilledProps};
- };
-
- $scope.validate = function(value, errors){
- errors.int32 = !(parseInt(value) >= -2147483648 && parseInt(value) <= 2147483647);
- };
-
-
-
- $scope.validateForm = function(form) {
- return form.$valid;
- };
-
- $scope.$on('GBP_TENANT_RELOAD', function(e, obj){
- $scope.selectedTenant = obj;
- });
-
- }]);
-
- gbpOld.register.controller('linkDataCtrl',['$scope', function($scope){
- $scope.showTable = false;
-
- $scope.show = function(){
- $scope.showTable = true;
- };
-
- $scope.close = function(){
- $scope.showTable = false;
- };
-
- $scope.$on('SET_LINK_DATA', function(e, obj){
- $scope.linkData = obj;
- $scope.show();
- $scope.$apply();
- });
- }]);
-
- gbpOld.register.controller('crudCtrl',['$scope', function($scope){
- $scope.selectedObj = null;
- $scope.label = '';
- $scope.q = {};
-
- $scope.add = function() {
- $scope.selectedObj = null;
- $scope.showForm();
- };
-
- $scope.modify = function() {
- $scope.$emit('PGN_EDIT_ELEM');
- };
-
- $scope.init = function(label) {
- $scope.label = label;
- };
-
-
- $scope.$on('EV_SET_SEL_CLASS', function(event, selObj){
- $scope.selectedObj = selObj;
- });
- }]);
-
- gbpOld.register.controller('contractCtrl', ['$scope','GBPContractServices', '$filter', function($scope, GBPContractServices, $filter){
- $scope.list = [];
- $scope.selectedContract = null;
- $scope.newContractObj = GBPContractServices.createObj();
- $scope.displayLabel = ['description','id'];
- $scope.crudLabel = 'Contract list';
-
- $scope.internalView = {
- contract: false,
- edit: "view"
- };
-
- var path = null,
- mandatoryProperties = [],
- clear = function(){
- $scope.list = [];
- $scope.internalView = {
- contract: false,
- edit: "view"
- };
- $scope.selectedContract = null;
- $scope.newContractObj = GBPContractServices.createObj();
- };
-
- $scope.init = function() {
- if ( $scope.selectedTenant ) {
- $scope.selectedContract = null;
- path = GBPContractServices.createPathObj($scope.selectedTenant.id);
-
- GBPContractServices.load(path, function(data){
- $scope.list = data;
- // $scope.$broadcast('GBP_CONTRACT_RELOAD');
- $scope.sendReloadEventFromRoot('GBP_CONTRACT_RELOAD');
- }, function(){
-
- });
- }else{
- clear();
- }
- };
-
- $scope.save = function(){
- var resp = $scope.validateMandatory($scope.newContractObj, mandatoryProperties);
- if(resp.status){
- path = GBPContractServices.createPathObj($scope.selectedTenant.id, $scope.newContractObj.id);
- GBPContractServices.send(path, $scope.newContractObj, function(data){
- $scope.init();
- $scope.internalView.contract = false;
- $scope.reloadNewObj();
- $scope.internalView.edit = "view";
- }, function(){
- //TODO: error cbk
- });
- }else{
- alert($filter('translate')('GBP_MANDATORY_NOT_FILLED')+': '+resp.notFilledProps.join(', '));
- }
- };
-
- $scope.delete = function() {
- if ( $scope.selectedContract ) {
- path = GBPContractServices.createPathObj($scope.selectedTenant.id, $scope.selectedContract.id);
- GBPContractServices.delete(path, function(data){
- $scope.init();
- $scope.selectedContract = null;
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.reloadNewObj = function() {
- $scope.newContractObj = GBPContractServices.createObj();
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedContract = selectedObj;
- $scope.internalView.edit = $scope.internalView.edit == "edit" ? $scope.internalView.edit : "view";
- if(selectedObj){
- $scope.internalView.contract = true;
- }else {
- $scope.internalView.contract = false;
- $scope.internalView.edit = "view";
- }
-
- if($scope.internalView.contract) {
- angular.copy(selectedObj, $scope.newContractObj);
- }
- $scope.sendReloadEventFromRoot('GBP_CONTRACT_RELOAD');
- };
-
- $scope.showForm = function() {
- $scope.reloadNewObj();
- $scope.internalView.contract = true;
- $scope.selectedContract = null;
- $scope.internalView.edit = "add";
- };
-
- $scope.close = function(){
- $scope.internalView.contract = false;
- $scope.internalView.edit = "view";
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if(!event.defaultPrevented) {
- if ( $scope.selectedContract ) {
- $scope.internalView.contract = true;
- $scope.internalView.edit = "edit";
- angular.copy($scope.selectedContract, $scope.newContractObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('GBP_TENANT_RELOAD',function(event){
- $scope.init();
- });
-
- $scope.$on('GBP_CONTRACTS_LABEL', function(event, obj){
- obj.labels = $scope.displayLabel;
- });
- }]);
-
- gbpOld.register.controller('clauseCtrl', ['$scope','GBPClauseServices', 'GBPSubjectServices',
- function($scope, GBPClauseServices, GBPSubjectServices){
- $scope.list = [];
- $scope.selectedClause = null;
- $scope.newClauseObj = GBPClauseServices.createObj();
- $scope.internalView = {
- clause: false,
- edit: "view"
- };
- $scope.displayLabel = 'name';
- $scope.crudLabel = 'Clause list';
-
- $scope.subjects = {'options' : [], 'labels' : null};
- $scope.getDisplayLabelsFromCtrl('GBP_SUBJECTS_LABEL', $scope.subjects);
-
- var path = null,
-
- clear = function(){
- $scope.list = [];
- $scope.selectedClause = null;
- $scope.newClauseObj = GBPClauseServices.createObj();
- $scope.internalView = {
- clause: false,
- edit: "view"
- };
- };
-
- //move to separate ctrl \/
- $scope.addNewElem = function(templateObj) {
- if($scope.newClauseObj && $scope.newClauseObj['subject-refs']) {
- var objToPush = templateObj || "";
- $scope.newClauseObj['subject-refs'].push(objToPush);
- }
- };
-
- $scope.deleteElemAt = function(index) {
- if($scope.newClauseObj && $scope.newClauseObj['subject-refs']) {
- $scope.newClauseObj['subject-refs'].splice(index, 1);
- }
- };
-
- $scope.updateAt = function(index, value) {
- if($scope.newClauseObj && $scope.newClauseObj['subject-refs'] && $scope.newClauseObj['subject-refs'].length >= index) {
- $scope.newClauseObj['subject-refs'][index] = value;
- }
- };
- //move to separate ctrl /\
-
- var loadSubjects = function() {
- $scope.getDisplayLabelsFromCtrl('GBP_SUBJECTS_LABEL', $scope.subjects);
-
- GBPSubjectServices.load(path, function(data){
- $scope.subjects.options = data;
- }, function(){
- //TODO: error cbk
- });
- };
-
- $scope.init = function() {
- if ( $scope.selectedContract ) {
- path = GBPClauseServices.createPathObj($scope.selectedTenant.id, $scope.selectedContract.id);
-
- GBPClauseServices.load(path, function(data){
- $scope.list = data;
- }, function(){
- //TODO: error cbk
- });
- }else{
- clear();
- }
- };
-
- $scope.save = function(){
- if($scope.validateForm($scope.clauseForm)){
- path = GBPClauseServices.createPathObj($scope.selectedTenant.id, $scope.selectedContract.id, $scope.newClauseObj.name);
- GBPClauseServices.send(path, $scope.newClauseObj, function(data){
- $scope.init();
- $scope.internalView.clause = false;
- $scope.reloadNewObj();
- $scope.internalView.clause = "view";
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.delete = function() {
- if ( $scope.selectedClause ) {
- path = GBPClauseServices.createPathObj($scope.selectedTenant.id, $scope.selectedContract.id, $scope.selectedClause.name);
- GBPClauseServices.delete(path, function(data){
- $scope.init();
- $scope.selectedClause = null;
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.reloadNewObj = function() {
- $scope.newClauseObj = GBPClauseServices.createObj();
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedClause = selectedObj;
- $scope.internalView.edit = $scope.internalView.edit == "edit" ? $scope.internalView.edit : "view";
- if(selectedObj){
- $scope.internalView.clause = true;
- }else {
- $scope.internalView.clause = false;
- $scope.internalView.edit = "view";
- }
-
- if($scope.internalView.clause) {
- angular.copy(selectedObj, $scope.newClauseObj);
- }
- };
-
- $scope.showForm = function() {
- $scope.reloadNewObj();
- $scope.internalView.clause = true;
- $scope.internalView.edit = "add";
- $scope.selectedClause = null;
- };
-
- $scope.close = function(){
- $scope.internalView.clause = false;
- $scope.internalView.edit = "view";
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedClause ) {
- $scope.internalView.clause = true;
- $scope.internalView.edit = "edit";
- angular.copy($scope.selectedClause, $scope.newClauseObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('GBP_CONTRACT_RELOAD',function(){
- $scope.internalView.clause = false;
- $scope.init();
- });
-
- $scope.$on('GBP_SUBJECT_RELOAD',function(){
- loadSubjects();
- });
- }]);
-
- gbpOld.register.controller('subjectCtrl', ['$scope','GBPSubjectServices', '$filter', function($scope, GBPSubjectServices, $filter){
- $scope.list = [];
- $scope.selectedSubject = null;
- $scope.newSubjectObj = GBPSubjectServices.createObj();
- $scope.displayLabel = 'name';
- $scope.internalView = {
- subject : false,
- edit : "view"
- };
- $scope.crudLabel = 'Subject list';
- $scope.errors = {};
-
- var path = null,
- mandatoryProperties = ['order'],
-
- clear = function(){
- $scope.list = [];
- $scope.selectedSubject = null;
- $scope.newSubjectObj = GBPSubjectServices.createObj();
- $scope.internalView = {
- subject : false,
- edit : "view"
- };
- };
-
- $scope.init = function() {
- if ( $scope.selectedContract ) {
- $scope.selectedSubject = null;
- path = GBPSubjectServices.createPathObj($scope.selectedTenant.id, $scope.selectedContract.id);
-
- GBPSubjectServices.load(path, function(data){
- $scope.list = data;
- $scope.sendReloadEventFromRoot('GBP_SUBJECT_RELOAD');
- }, function(){
- //TODO: error cbk
- });
- }else{
- clear();
- }
- };
-
- $scope.save = function(){
- if($scope.validateForm($scope.subjectForm)){
- path = GBPSubjectServices.createPathObj($scope.selectedTenant.id, $scope.selectedContract.id, $scope.newSubjectObj.name);
- GBPSubjectServices.send(path, $scope.newSubjectObj, function(data){
- $scope.init();
- $scope.internalView.subject = false;
- $scope.reloadNewObj();
- $scope.internalView.edit = "view";
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.delete = function() {
- if ( $scope.selectedSubject ) {
- path = GBPSubjectServices.createPathObj($scope.selectedTenant.id, $scope.selectedContract.id, $scope.selectedSubject.name);
- GBPSubjectServices.delete(path, function(data){
- $scope.init();
- $scope.selectedSubject = null;
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.reloadNewObj = function() {
- $scope.newSubjectObj = GBPSubjectServices.createObj();
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedSubject = selectedObj;
- $scope.internalView.edit = $scope.internalView.edit == "edit" ? $scope.internalView.edit : "view";
- if(selectedObj){
- $scope.internalView.subject = true;
- }else {
- $scope.internalView.subject = false;
- $scope.internalView.edit = "view";
- }
-
- if($scope.internalView.subject) {
- angular.copy(selectedObj, $scope.newSubjectObj);
- }
- $scope.sendReloadEventFromRoot('GBP_SUBJECT_RELOAD');
- };
-
- $scope.showForm = function() {
- $scope.reloadNewObj();
- $scope.internalView.subject = true;
- $scope.internalView.edit = "add";
- $scope.selectedSubject = null;
- };
-
- $scope.close = function(){
- $scope.internalView.subject = false;
- $scope.internalView.edit = "view";
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedSubject ) {
- $scope.internalView.subject = true;
- $scope.internalView.edit = "edit";
- angular.copy($scope.selectedSubject, $scope.newSubjectObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('GBP_CONTRACT_RELOAD',function(){
- $scope.internalView.subject = false;
- $scope.init();
- });
-
- $scope.$on('GBP_SUBJECTS_LABEL', function(event, obj){
- obj.labels = $scope.displayLabel;
- });
- }]);
-
- gbpOld.register.controller('ruleCtrl', ['$scope','GBPRuleServices', '$filter', function($scope, GBPRuleServices, $filter){
- $scope.list = [];
- $scope.selectedRule = null;
- $scope.newRuleObj = GBPRuleServices.createObj();
- $scope.displayLabel = 'name';
- $scope.internalView = {
- rule : false,
- edit : "view"
- };
- $scope.crudLabel = 'Rule list';
- $scope.errors = {};
-
- var path = null,
- mandatoryProperties = ['order'],
-
- clear = function(){
- $scope.list = [];
- $scope.selectedRule = null;
- $scope.newRuleObj = GBPRuleServices.createObj();
- $scope.internalView = {
- rule : false,
- edit : "view"
- };
- };
-
- $scope.init = function() {
- if ( $scope.selectedSubject ) {
- $scope.selectedRule = null;
- path = GBPRuleServices.createPathObj($scope.selectedTenant.id, $scope.selectedContract.id, $scope.selectedSubject.name);
-
- GBPRuleServices.load(path, function(data){
- $scope.list = data;
- }, function(){
- //TODO: error cbk
- });
- }else{
- clear();
- }
- };
-
- $scope.save = function(){
- if($scope.validateForm($scope.rulesForm)){
- path = GBPRuleServices.createPathObj($scope.selectedTenant.id, $scope.selectedContract.id, $scope.selectedSubject.name, $scope.newRuleObj.name);
- GBPRuleServices.send(path, $scope.newRuleObj, function(data){
- $scope.init();
- $scope.internalView.rule = false;
- $scope.reloadNewObj();
- $scope.internalView.edit = "view";
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.delete = function() {
- if ( $scope.selectedRule ) {
- path = GBPRuleServices.createPathObj($scope.selectedTenant.id, $scope.selectedContract.id, $scope.selectedSubject.name, $scope.selectedRule.name);
- GBPRuleServices.delete(path, function(data){
- $scope.init();
- $scope.selectedRule = null;
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.reloadNewObj = function() {
- $scope.newRuleObj = GBPRuleServices.createObj();
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedRule = selectedObj;
- $scope.internalView.edit = $scope.internalView.edit == "edit" ? $scope.internalView.edit : "view";
- if(selectedObj){
- $scope.internalView.rule = true;
- }else {
- $scope.internalView.rule = false;
- $scope.internalView.edit = "view";
- }
-
- if($scope.internalView.rule) {
- angular.copy(selectedObj, $scope.newRuleObj);
- }
- $scope.$broadcast('GBP_RULE_RELOAD');
- };
-
- $scope.showForm = function() {
- $scope.reloadNewObj();
- $scope.internalView.rule = true;
- $scope.internalView.edit = "add";
- $scope.selectedRule = null;
- };
-
- $scope.close = function(){
- $scope.internalView.rule = false;
- $scope.internalView.edit = "view";
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedRule ) {
- $scope.internalView.rule = true;
- $scope.internalView.edit = "edit";
- angular.copy($scope.selectedRule, $scope.newRuleObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('GBP_SUBJECT_RELOAD',function(){
- $scope.init();
- });
- }]);
-
- gbpOld.register.controller('actionRefCtrl', ['$scope','GBPActionRefsServices', 'GBPActionInstanceServices', '$filter', function($scope, GBPActionRefsServices, GBPActionInstanceServices, $filter){
- $scope.list = [];
- $scope.selectedActionRef = null;
- $scope.newActionRefObj = GBPActionRefsServices.createObj();
- $scope.displayLabel = 'name';
- $scope.internalView = {
- actionRef : false,
- edit : "view"
- };
- $scope.crudLabel = 'Action ref list';
- $scope.errors = {};
-
- $scope.actionInstanceNames = {'options' : [], 'labels' : $scope.displayLabel};
-
- var path = null,
- mandatoryProperties = ['order'],
-
- actionInstanceNamesLoad = function() {
- var actionInstancePath = GBPActionInstanceServices.createPathObj($scope.selectedTenant.id);
- GBPActionInstanceServices.load(actionInstancePath, function(data){
- $scope.actionInstanceNames.options = data;
- },function(){
- //TODO: error cbk
- });
- },
-
- clear = function(){
- $scope.list = [];
- $scope.selectedActionRef = null;
- $scope.newActionRefObj = GBPActionRefsServices.createObj();
- $scope.internalView = {
- actionRef : false,
- edit : "view"
- };
- };
-
- $scope.init = function() {
- if ( $scope.selectedRule ) {
- $scope.selectedActionRef = null;
- path = GBPActionRefsServices.createPathObj($scope.selectedTenant.id, $scope.selectedContract.id, $scope.selectedSubject.name, $scope.selectedRule.name);
-
- GBPActionRefsServices.load(path, function(data){
- $scope.list = data;
- }, function(){
- //TODO: error cbk
- });
-
- actionInstanceNamesLoad();
- }else{
- clear();
- }
- };
-
- $scope.save = function(){
- if($scope.validateForm($scope.actionRefForm)){
- path = GBPActionRefsServices.createPathObj($scope.selectedTenant.id, $scope.selectedContract.id, $scope.selectedSubject.name, $scope.selectedRule.name, $scope.newActionRefObj.name);
- GBPActionRefsServices.send(path, $scope.newActionRefObj, function(data){
- $scope.init();
- $scope.internalView.actionRef = false;
- $scope.reloadNewObj();
- $scope.internalView.edit = "view";
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.delete = function() {
- if ( $scope.selectedActionRef ) {
- path = GBPActionRefsServices.createPathObj($scope.selectedTenant.id, $scope.selectedContract.id, $scope.selectedSubject.name, $scope.selectedRule.name, $scope.selectedActionRef.name);
- GBPActionRefsServices.delete(path, function(data){
- $scope.init();
- $scope.selectedActionRef = null;
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.reloadNewObj = function() {
- $scope.newActionRefObj = GBPActionRefsServices.createObj();
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedActionRef = selectedObj;
- $scope.internalView.edit = $scope.internalView.edit == "edit" ? $scope.internalView.edit : "view";
- if(selectedObj){
- $scope.internalView.actionRef = true;
- }else {
- $scope.internalView.actionRef = false;
- $scope.internalView.edit = "view";
- }
-
- if($scope.internalView.actionRef) {
- angular.copy(selectedObj, $scope.newActionRefObj);
- }
- };
-
- $scope.showForm = function() {
- $scope.reloadNewObj();
- $scope.internalView.actionRef = true;
- $scope.internalView.edit = "add";
- $scope.selectedActionRef = null;
- };
-
- $scope.close = function(){
- $scope.internalView.actionRef = false;
- $scope.internalView.edit = "view";
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedActionRef ) {
- $scope.internalView.actionRef = true;
- $scope.internalView.edit = "edit";
- angular.copy($scope.selectedActionRef, $scope.newActionRefObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('GBP_RULE_RELOAD',function(){
- $scope.internalView.actionRef = false;
- $scope.init();
- });
-
- $scope.$on('GBP_ACTION_INSTANCE_RELOAD',function(){
- actionInstanceNamesLoad();
- });
- }]);
-
- gbpOld.register.controller('classifierRefCtrl', ['$scope','GBPClassifierRefsServices', 'GBPClassifierInstanceServices', '$filter', function($scope, GBPClassifierRefsServices, GBPClassifierInstanceServices, $filter){
- $scope.list = [];
- $scope.selectedClassifierRef = null;
- $scope.newClassifierRefObj = GBPClassifierRefsServices.createObj();
- $scope.displayLabel = 'name';
- $scope.internalView = {
- classifierRef : false,
- edit : "view"
- };
-
- $scope.instanceNames = {'options' : [], 'labels' : $scope.displayLabel};
-
- $scope.formDirections = ['in', 'out', 'bidirectional'];
- $scope.formConnectionTracking = ['normal', 'reflexive'];
-
- $scope.crudLabel = 'Classifier ref list';
-
- var path = null,
-
- instanceNamesLoad = function() {
- var classifierInstancePath = GBPClassifierInstanceServices.createPathObj($scope.selectedTenant.id);
- GBPClassifierInstanceServices.load(classifierInstancePath, function(data){
- $scope.instanceNames.options = data;
- },function(){
- //TODO: error cbk
- });
- },
-
- clear = function(){
- $scope.list = [];
- $scope.selectedClassifierRef = null;
- $scope.newClassifierRefObj = GBPClassifierRefsServices.createObj();
- $scope.internalView = {
- classifierRef : false,
- edit : "view"
- };
- };
-
- $scope.init = function() {
- if ( $scope.selectedRule ) {
- $scope.selectedClassifierRef = null;
- path = GBPClassifierRefsServices.createPathObj($scope.selectedTenant.id, $scope.selectedContract.id, $scope.selectedSubject.name, $scope.selectedRule.name);
-
-
-
- GBPClassifierRefsServices.load(path, function(data){
- $scope.list = data;
- }, function(){
- //TODO: error cbk
- });
-
- instanceNamesLoad();
- }else{
- clear();
- }
- };
-
- $scope.save = function(){
- if($scope.validateForm($scope.classifierRefForm)){
- path = GBPClassifierRefsServices.createPathObj($scope.selectedTenant.id, $scope.selectedContract.id, $scope.selectedSubject.name, $scope.selectedRule.name, $scope.newClassifierRefObj.name);
- GBPClassifierRefsServices.send(path, $scope.newClassifierRefObj, function(data){
- $scope.init();
- $scope.internalView.classifierRef = false;
- $scope.reloadNewObj();
- $scope.internalView.edit = "view";
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.delete = function() {
- if ( $scope.selectedClassifierRef ) {
- path = GBPClassifierRefsServices.createPathObj($scope.selectedTenant.id, $scope.selectedContract.id, $scope.selectedSubject.name, $scope.selectedRule.name, $scope.selectedClassifierRef.name);
- GBPClassifierRefsServices.delete(path, function(data){
- $scope.init();
- $scope.selectedClassifierRef = null;
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.reloadNewObj = function() {
- $scope.newClassifierRefObj = GBPClassifierRefsServices.createObj();
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedClassifierRef = selectedObj;
- $scope.internalView.edit = $scope.internalView.edit == "edit" ? $scope.internalView.edit : "view";
- if(selectedObj){
- $scope.internalView.classifierRef = true;
- }else {
- $scope.internalView.classifierRef = false;
- $scope.internalView.edit = "view";
- }
-
- if($scope.internalView.classifierRef) {
- angular.copy(selectedObj, $scope.newClassifierRefObj);
- }
- };
-
- $scope.showForm = function() {
- $scope.reloadNewObj();
- $scope.internalView.classifierRef = true;
- $scope.internalView.edit = "add";
- $scope.selectedClassifierRef = null;
- };
-
- $scope.close = function(){
- $scope.internalView.classifierRef = false;
- $scope.internalView.edit = "view";
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedClassifierRef ) {
- $scope.internalView.classifierRef = true;
- $scope.internalView.edit = "edit";
- angular.copy($scope.selectedClassifierRef, $scope.newClassifierRefObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('GBP_RULE_RELOAD',function(){
- $scope.internalView.classifierRef = false;
- $scope.init();
- });
-
- $scope.$on('GBP_CLASSIFIER_INSTANCE_RELOAD',function(){
- instanceNamesLoad();
- });
- }]);
-
- gbpOld.register.controller('tenantCtrl', ['$scope', 'GBPTenantServices', '$filter', function($scope, GBPTenantServices, $filter){
- $scope.list = [];
- $scope.selectedTenantObj = null;
- $scope.newTenantObj = GBPTenantServices.createObj();
- $scope.displayLabel = ['name' , 'id'];
- $scope.crudLabel = 'Tenants list';
-
- $scope.view = {
- tenant: false,
- edit: "view"
- };
-
- $scope.init = function() {
- GBPTenantServices.load(
- function(data) {
- $scope.list = data;
- $scope.newTenantObj = GBPTenantServices.createObj();
- $scope.selectedTenantObj = null;
- },
- function(){
- //TODO error
- });
- };
-
- $scope.save = function(){
- if($scope.validateForm($scope.tenantForm)){
- path = GBPTenantServices.createPathObj($scope.newTenantObj.id);
- GBPTenantServices.send(path, $scope.newTenantObj, function(data){
- $scope.init();
- $scope.view.tenant = false;
- $scope.view.edit = "view";
- $scope.$emit('GBP_GLOBAL_TENANT_RELOAD');
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.delete = function() {
- if($scope.selectedTenantObj) {
- path = GBPTenantServices.createPathObj($scope.selectedTenantObj.id);
-
- GBPTenantServices.delete(path, function(data){
- $scope.init();
- $scope.view.tenant = false;
- $scope.$emit('GBP_GLOBAL_TENANT_RELOAD');
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedTenantObj = selectedObj;
-
- $scope.view.edit = $scope.view.edit == "edit" ? $scope.view.edit : "view";
- if(selectedObj){
- $scope.view.tenant = true;
- }
- else {
- $scope.view.tenant = false;
- $scope.view.edit = "view";
- }
-
- if ($scope.view.tenant) {
- angular.copy(selectedObj, $scope.newTenantObj);
- }
- };
-
- $scope.showForm = function() {
- $scope.newTenantObj = GBPTenantServices.createObj();
- $scope.selectedTenantObj = null;
- $scope.view.tenant = true;
- $scope.view.edit = "add";
- };
-
- $scope.close = function(){
- $scope.view.tenant = false;
- $scope.view.edit = "view";
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedTenantObj ) {
- $scope.view.tenant = true;
- $scope.view.edit = "edit";
- angular.copy($scope.selectedTenantObj, $scope.newTenantObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('GBP_GLOBAL_TENANT_RELOAD',function(){
- $scope.init();
- });
- }]);
-
- gbpOld.register.controller('epgCtrl',['$scope', 'GBPEpgServices', 'GBPContractServices', '$filter',
- function($scope, GBPEpgServices, GBPContractServices, $filter){
- $scope.selectedEpg = null;
- $scope.newEpgObj = GBPEpgServices.createObj();
- $scope.displayLabel = ['name', 'id'];
- $scope.crudLabel = 'Group list';
-
- $scope.igpOpts = ['allow', 'require-contract'];
-
- $scope.contracts = {'options' : [], 'labels' : null};
- $scope.getDisplayLabelsFromCtrl('GBP_CONTRACTS_LABEL', $scope.contracts);
-
- $scope.list = [];
-
- $scope.internalView = {
- epg: false,
- edit: "view"
- };
-
- var loadContracts = function() {
- GBPContractServices.load(path, function(data){
- $scope.contracts.options = data;
- }, function(){
- //TODO: error cbk
- });
- },
-
- mandatoryProperties = ['name'],
-
- clear = function(){
- $scope.list = [];
- $scope.selectedEpg = null;
- $scope.newEpgObj = GBPEpgServices.createObj();
- $scope.internalView = {
- epg: false,
- edit: "view"
- };
- };
-
- $scope.init = function() {
- if ($scope.selectedTenant) {
- path = GBPEpgServices.createPathObj($scope.selectedTenant.id);
-
- GBPEpgServices.load(path, function(data){
- $scope.list = data;
- // $scope.$broadcast('GBP_EPG_RELOAD');
- $scope.sendReloadEventFromRoot('GBP_EPG_RELOAD');
- }, function(){
- //TODO: error cbk
- });
-
- loadContracts();
- }else{
- clear();
- }
- };
-
- $scope.save = function(){
- if($scope.validateForm($scope.epgForm)){
- path = GBPEpgServices.createPathObj($scope.selectedTenant.id, $scope.newEpgObj.id);
- GBPEpgServices.send(path, $scope.newEpgObj, function(data){
- $scope.init();
- $scope.internalView.epg = false;
- $scope.reloadNewObj();
- $scope.internalView.edit = "view";
- $scope.reloadTopo();
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.delete = function() {
- if($scope.selectedTenant && $scope.selectedEpg) {
- path = GBPEpgServices.createPathObj($scope.selectedTenant.id, $scope.selectedEpg.id);
- GBPEpgServices.delete(path, function(data){
- $scope.init();
- $scope.internalView.epg = false;
- $scope.reloadTopo();
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.showForm = function() {
- $scope.internalView.epg = true;
- $scope.reloadNewObj();
- $scope.selectedEpg = null;
- $scope.internalView.edit = "add";
- };
-
- $scope.reloadNewObj = function() {
- $scope.newEpgObj = GBPEpgServices.createObj();
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedEpg = selectedObj;
- $scope.internalView.edit = $scope.internalView.edit == "edit" ? $scope.internalView.edit : "view";
- if(selectedObj){
- $scope.internalView.epg = true;
- }else {
- $scope.internalView.epg = false;
- $scope.internalView.edit = "view";
- }
-
- if($scope.internalView.epg) {
- angular.copy(selectedObj, $scope.newEpgObj);
- }
- $scope.sendReloadEventFromRoot('GBP_EPG_RELOAD');
- };
-
- $scope.close = function(){
- $scope.internalView.epg = false;
- $scope.internalView.edit = "view";
- };
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedEpg ) {
- $scope.internalView.epg = true;
- $scope.internalView.edit = "edit";
- angular.copy($scope.selectedEpg, $scope.newEpgObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('GBP_TENANT_RELOAD',function(){
- $scope.init();
- });
-
- $scope.$on('GBP_CONTRACT_RELOAD',function(){
- loadContracts();
- });
-
- $scope.$on('GBP_EPG_LABEL', function(event, obj){
- obj.labels = $scope.displayLabel;
- });
- }]);
-
- gbpOld.register.controller('cnsCtrl',['$scope', 'GBPConNamedSelServices', function($scope, GBPConNamedSelServices){
- $scope.list = [];
- $scope.selectedCNS = null;
- $scope.newCNSObj = GBPConNamedSelServices.createObj();
- $scope.internalView = {
- cns: false,
- edit: "view"
- };
- $scope.displayLabel = 'name';
- $scope.crudLabel = 'Consumer named selectors list';
-
- var clear = function(){
- $scope.list = [];
- $scope.selectedCNS = null;
- $scope.newCNSObj = GBPConNamedSelServices.createObj();
- $scope.internalView = {
- cns: false,
- edit: "view"
- };
- };
-
- //move to separate ctrl \/
- $scope.addNewElem = function(templateObj) {
- if($scope.newCNSObj && $scope.newCNSObj.contract) {
- var objToPush = templateObj || "";
- $scope.newCNSObj.contract.push(objToPush);
- }
- };
-
- $scope.deleteElemAt = function(index) {
- if($scope.newCNSObj && $scope.newCNSObj.contract) {
- $scope.newCNSObj.contract.splice(index, 1);
- }
- };
-
- $scope.updateAt = function(index, value) {
- if($scope.newCNSObj && $scope.newCNSObj.contract && $scope.newCNSObj.contract.length >= index) {
- $scope.newCNSObj.contract[index] = value;
- }
- };
- //move to separate ctrl /\
-
- $scope.init = function() {
- if ($scope.selectedTenant && $scope.selectedEpg) {
- path = GBPConNamedSelServices.createPathObj($scope.selectedTenant.id, $scope.selectedEpg.id);
-
- GBPConNamedSelServices.load(path, function(data){
- $scope.list = data;
- }, function(){
- //TODO: error cbk
- });
- }else{
- clear();
- }
- };
-
- $scope.save = function(){
- if($scope.validateForm($scope.cnsForm)){
- path = GBPConNamedSelServices.createPathObj($scope.selectedTenant.id, $scope.selectedEpg.id, $scope.newCNSObj.name);
- GBPConNamedSelServices.send(path, $scope.newCNSObj, function(data){
- $scope.init();
- $scope.internalView.cns = false;
- $scope.internalView.cns = "view";
- $scope.reloadNewObj();
- $scope.reloadTopo();
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.delete = function() {
- if($scope.selectedTenant && $scope.selectedEpg && $scope.selectedCNS) {
- path = GBPConNamedSelServices.createPathObj($scope.selectedTenant.id, $scope.selectedEpg.id, $scope.selectedCNS.name);
- GBPConNamedSelServices.delete(path, function(data){
- $scope.init();
- $scope.reloadTopo();
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.showForm = function() {
- $scope.reloadNewObj();
- $scope.selectedCNS = null;
- $scope.internalView.cns = true;
- $scope.internalView.edit = "add";
- };
-
- $scope.reloadNewObj = function() {
- $scope.newCNSObj = GBPConNamedSelServices.createObj();
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedCNS = selectedObj;
- $scope.internalView.edit = $scope.internalView.edit == "edit" ? $scope.internalView.edit : "view";
- if(selectedObj){
- $scope.internalView.cns = true;
- }else {
- $scope.internalView.cns = false;
- $scope.internalView.edit = "view";
- }
-
- if($scope.internalView.cns) {
- angular.copy(selectedObj, $scope.newCNSObj);
- }
- };
-
- $scope.close = function(){
- $scope.internalView.cns = false;
- $scope.internalView.edit = "view";
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedEpg ) {
- $scope.internalView.cns = true;
- $scope.internalView.edit = "add";
- angular.copy($scope.selectedCNS, $scope.newCNSObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('GBP_EPG_RELOAD',function(){
- $scope.init();
- });
- }]);
-
- gbpOld.register.controller('pnsCtrl',['$scope', 'GBPProNamedSelServices', function($scope, GBPProNamedSelServices){
- $scope.list = [];
- $scope.selectedPNS = null;
- $scope.newPNSObj = GBPProNamedSelServices.createObj();
- $scope.displayLabel = 'name';
- $scope.crudLabel = 'Provider named selectors list';
- $scope.internalView = {
- pns: false,
- edit: "view"
- };
-
- var clear = function(){
- $scope.list = [];
- $scope.selectedPNS = null;
- $scope.newPNSObj = GBPProNamedSelServices.createObj();
- $scope.internalView = {
- pns: false,
- edit: "view"
- };
- };
-
- //move to separate ctrl \/
- $scope.addNewElem = function(templateObj) {
- if($scope.newPNSObj && $scope.newPNSObj.contract) {
- var objToPush = templateObj || "";
- $scope.newPNSObj.contract.push(objToPush);
- }
- };
-
- $scope.deleteElemAt = function(index) {
- if($scope.newPNSObj && $scope.newPNSObj.contract) {
- $scope.newPNSObj.contract.splice(index, 1);
- }
- };
-
- $scope.updateAt = function(index, value) {
- if($scope.newPNSObj && $scope.newPNSObj.contract && $scope.newPNSObj.contract.length >= index) {
- $scope.newPNSObj.contract[index] = value;
- }
- };
- //move to separate ctrl /\
-
- $scope.init = function() {
- if ($scope.selectedTenant && $scope.selectedEpg) {
- path = GBPProNamedSelServices.createPathObj($scope.selectedTenant.id, $scope.selectedEpg.id);
-
- GBPProNamedSelServices.load(path, function(data){
- $scope.list = data;
- }, function(){
- //TODO: error cbk
- });
- }else{
- clear();
- }
- };
-
- $scope.save = function(){
- if($scope.validateForm($scope.pnsForm)){
- path = GBPProNamedSelServices.createPathObj($scope.selectedTenant.id, $scope.selectedEpg.id, $scope.newPNSObj.name);
- GBPProNamedSelServices.send(path, $scope.newPNSObj, function(data){
- $scope.init();
- $scope.internalView.pns = false;
- $scope.reloadNewObj();
- $scope.internalView.cns = "view";
- $scope.reloadTopo();
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.delete = function() {
- if($scope.selectedTenant && $scope.selectedEpg && $scope.selectedPNS) {
- path = GBPProNamedSelServices.createPathObj($scope.selectedTenant.id, $scope.selectedEpg.id, $scope.selectedPNS.name);
- GBPProNamedSelServices.delete(path, function(data){
- $scope.init();
- $scope.reloadTopo();
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.showForm = function() {
- $scope.reloadNewObj();
- $scope.internalView.pns = true;
- $scope.internalView.edit = "add";
- $scope.selectedPNS = null;
- };
-
- $scope.reloadNewObj = function() {
- $scope.newPNSObj = GBPProNamedSelServices.createObj();
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedPNS = selectedObj;
- $scope.internalView.edit = $scope.internalView.edit == "edit" ? $scope.internalView.edit : "view";
- if(selectedObj){
- $scope.internalView.pns = true;
- }else {
- $scope.internalView.pns = false;
- $scope.internalView.edit = "view";
- }
-
- if($scope.internalView.pns) {
- angular.copy(selectedObj, $scope.newPNSObj);
- }
- };
-
- $scope.close = function(){
- $scope.internalView.pns = false;
- $scope.internalView.edit = "view";
- };
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedEpg ) {
- $scope.internalView.pns = true;
- $scope.internalView.edit = "edit";
- angular.copy($scope.selectedPNS, $scope.newPNSObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('GBP_EPG_RELOAD',function(){
- $scope.init();
- });
- }]);
-
- gbpOld.register.controller('l2FloodCtrl', ['$scope', 'GBPL2FloodDomainServices', 'GBPL2BridgeDomainServices', '$filter', function($scope, GBPL2FloodDomainServices, GBPL2BridgeDomainServices, $filter){
- $scope.list = [];
- $scope.selectedL2Flood = null;
- $scope.newL2FloodObj = GBPL2FloodDomainServices.createObj();
- $scope.displayLabel = ['name', 'id'];
- $scope.crudLabel = 'L2 Flood Domain list';
-
- $scope.l2bridge = {'options' : [], 'labels' : null};
- $scope.getDisplayLabelsFromCtrl('GBP_L2BRIDGE_LABEL', $scope.l2bridge);
-
- $scope.view = {
- l2flood: false,
- edit: "view"
- };
-
- var path = null,
-
- loadL2BridgeList = function() {
- GBPL2BridgeDomainServices.load(GBPL2BridgeDomainServices.createPathObj($scope.selectedTenant.id), function(data){
- $scope.l2bridge.options = data;
- }, function(){
-
- });
- },
-
- clear = function(){
- $scope.list = [];
- $scope.selectedL2Flood = null;
- $scope.newL2FloodObj = GBPL2FloodDomainServices.createObj();
- $scope.view = {
- l2flood: false,
- edit: "view"
- };
- };
-
- $scope.init = function() {
- if ( $scope.selectedTenant ) {
- path = GBPL2FloodDomainServices.createPathObj($scope.selectedTenant.id);
-
- GBPL2FloodDomainServices.load(path, function(data){
- $scope.list = data;
- // clear objects
- $scope.newL2FloodObj = GBPL2FloodDomainServices.createObj();
- $scope.selectedL2Flood = null;
- }, function(){
-
- });
-
- loadL2BridgeList();
- }else{
- clear();
- }
- };
-
- $scope.save = function(){
- if($scope.validateForm($scope.l2FloodForm)){
- path = GBPL2FloodDomainServices.createPathObj($scope.selectedTenant.id, $scope.newL2FloodObj.id);
- GBPL2FloodDomainServices.send(path, $scope.newL2FloodObj, function(data){
- $scope.init();
- $scope.view.l2flood = false;
- $scope.view.edit = "view";
- $scope.sendReloadEventFromRoot('GBP_L2FLOOD_RELOAD');
-
- $scope.reloadTopo();
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.delete = function() {
- if($scope.selectedTenant && $scope.selectedL2Flood) {
- path = GBPL2FloodDomainServices.createPathObj($scope.selectedTenant.id, $scope.selectedL2Flood.id);
- GBPL2FloodDomainServices.delete(path, function(data){
- $scope.init();
- $scope.view.l2flood = false;
- $scope.view.edit = "view";
- $scope.sendReloadEventFromRoot('GBP_L2FLOOD_RELOAD');
-
- $scope.reloadTopo();
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedL2Flood = selectedObj;
-
- $scope.view.edit = $scope.view.edit == "edit" ? $scope.view.edit : "view";
- if(selectedObj){
- $scope.view.l2flood = true;
- }
- else {
- $scope.view.l2flood = false;
- $scope.view.edit = "view";
- }
-
- if ($scope.view.l2flood) {
- angular.copy(selectedObj, $scope.newL2FloodObj);
- }
-
- $scope.sendReloadEventFromRoot('GBP_L2FLOOD_RELOAD');
- };
-
- $scope.showForm = function() {
- $scope.newL2FloodObj = GBPL2FloodDomainServices.createObj();
- $scope.selectedL2Flood = null;
- $scope.view.l2flood = true;
- $scope.view.edit = "add";
- };
-
- $scope.close = function(){
- $scope.view.l2flood = false;
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedL2Flood ) {
- $scope.view.l2flood = true;
- $scope.view.edit = "edit";
- angular.copy($scope.selectedL2Flood, $scope.newL2FloodObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('GBP_TENANT_RELOAD',function(){
- $scope.init();
- });
-
- $scope.$on('GBP_L2BRIDGE_RELOAD',function(){
- loadL2BridgeList();
- });
-
- $scope.$on('GBP_L2FLOOD_LABEL', function(event, obj){
- obj.labels = $scope.displayLabel;
- });
- }]);
-
- gbpOld.register.controller('l2BridgeCtrl', ['$scope', 'GBPL2BridgeDomainServices', 'GBPL3ContextServices', '$filter', function($scope, GBPL2BridgeDomainServices, GBPL3ContextServices, $filter){
- $scope.list = [];
- $scope.selectedL2Bridge = null;
- $scope.newL2BridgeObj = GBPL2BridgeDomainServices.createObj();
- $scope.displayLabel = ['name', 'id'];
- $scope.crudLabel = 'L2 Bridge Domain list';
-
- $scope.l3context = {'options' : [], 'labels' : null};
- $scope.getDisplayLabelsFromCtrl('GBP_L3CONTEXT_LABEL', $scope.l3context);
-
- $scope.view = {
- l2bridge: false,
- edit: "view"
- };
-
- var path = null,
-
- loadL3ContextList = function() {
- GBPL3ContextServices.load(GBPL3ContextServices.createPathObj($scope.selectedTenant.id), function(data){
- $scope.l3context.options = data;
- //$scope.$broadcast('GBP_L2BRIDGE_RELOAD');
- }, function(){
-
- });
- },
-
- clear = function(){
- $scope.list = [];
- $scope.selectedL2Bridge = null;
- $scope.newL2BridgeObj = GBPL2BridgeDomainServices.createObj();
- $scope.view = {
- l2bridge: false,
- edit: "view"
- };
- };
-
- $scope.init = function() {
- if ( $scope.selectedTenant ) {
- path = GBPL2BridgeDomainServices.createPathObj($scope.selectedTenant.id);
-
- GBPL2BridgeDomainServices.load(path, function(data){
- $scope.list = data;
- $scope.newL2BridgeObj = GBPL2BridgeDomainServices.createObj();
- $scope.selectedL2Bridge = null;
- // $scope.$broadcast('GBP_L2BRIDGE_RELOAD');
- }, function(){
-
- });
-
- loadL3ContextList();
- }else{
- clear();
- }
- };
-
-
-
- $scope.save = function(){
- if($scope.validateForm($scope.l2BridgeForm)){
- path = GBPL2BridgeDomainServices.createPathObj($scope.selectedTenant.id, $scope.newL2BridgeObj.id);
- GBPL2BridgeDomainServices.send(path, $scope.newL2BridgeObj, function(data){
- $scope.init();
- $scope.view.l2bridge = false;
- $scope.view.edit = "view";
- $scope.sendReloadEventFromRoot('GBP_L2BRIDGE_RELOAD');
-
- $scope.reloadTopo();
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.delete = function() {
- if($scope.selectedTenant && $scope.selectedL2Bridge) {
- path = GBPL2BridgeDomainServices.createPathObj($scope.selectedTenant.id, $scope.selectedL2Bridge.id);
- GBPL2BridgeDomainServices.delete(path, function(data){
- $scope.init();
- $scope.view.l2bridge = false;
- $scope.view.edit = "view";
- $scope.sendReloadEventFromRoot('GBP_L2BRIDGE_RELOAD');
-
- $scope.reloadTopo();
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedL2Bridge = selectedObj;
-
- $scope.view.edit = $scope.view.edit == "edit" ? $scope.view.edit : "view";
- if(selectedObj){
- $scope.view.l2bridge = true;
- }
- else {
- $scope.view.l2bridge = false;
- $scope.view.edit = "view";
- }
-
- if ($scope.view.l2bridge) {
- angular.copy(selectedObj, $scope.newL2BridgeObj);
- }
-
- $scope.sendReloadEventFromRoot('GBP_L2BRIDGE_RELOAD');
- };
-
- $scope.showForm = function() {
- $scope.newL2BridgeObj = GBPL2BridgeDomainServices.createObj();
- $scope.selectedL2Bridge = null;
- $scope.view.l2bridge = true;
- $scope.view.edit = "add";
- };
-
- $scope.close = function(){
- $scope.view.l2bridge = false;
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedL2Bridge ) {
- $scope.view.l2bridge = true;
- $scope.view.edit = "edit";
- angular.copy($scope.selectedL2Bridge, $scope.newL2BridgeObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('GBP_TENANT_RELOAD',function(){
- $scope.init();
- });
-
- $scope.$on('GBP_L3CONTEXT_RELOAD',function(){
- loadL3ContextList();
- });
-
- $scope.$on('GBP_L2BRIDGE_LABEL', function(event, obj){
- obj.labels = $scope.displayLabel;
- });
- }]);
-
- gbpOld.register.controller('l3ContextCtrl', ['$scope', 'GBPL3ContextServices', '$filter', function($scope, GBPL3ContextServices, $filter){ //GBPContractServices
- $scope.list = [];
- $scope.selectedL3Context = null;
- $scope.newL3ContextObj = GBPL3ContextServices.createObj();
- $scope.displayLabel = ['name', 'id'];
- $scope.crudLabel = 'L3 Context list';
-
- $scope.view = {
- l3context: false,
- edit: "view"
- };
-
- var path = null,
-
- clear = function(){
- $scope.list = [];
- $scope.view = {
- l3context: false,
- edit: "view"
- };
- $scope.selectedL3Context = null;
- $scope.newL3ContextObj = GBPL3ContextServices.createObj();
- };
-
- $scope.init = function() {
- if ( $scope.selectedTenant ) {
- path = GBPL3ContextServices.createPathObj($scope.selectedTenant.id);
-
- GBPL3ContextServices.load(path, function(data){
- $scope.list = data;
- $scope.newL3ContextObj = GBPL3ContextServices.createObj();
- $scope.selectedL3Context = null;
- }, function(){
-
- });
- }else{
- clear();
- }
- };
-
- $scope.save = function(){
- if($scope.validateForm($scope.l3ContextForm)){
- path = GBPL3ContextServices.createPathObj($scope.selectedTenant.id, $scope.newL3ContextObj.id);
- GBPL3ContextServices.send(path, $scope.newL3ContextObj, function(data){
- $scope.init();
- $scope.view.l3context = false;
- $scope.view.edit = "view";
- $scope.sendReloadEventFromRoot('GBP_L3CONTEXT_RELOAD');
-
- $scope.reloadTopo();
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.delete = function() {
- if($scope.selectedTenant && $scope.selectedL3Context) {
- path = GBPL3ContextServices.createPathObj($scope.selectedTenant.id, $scope.selectedL3Context.id);
- GBPL3ContextServices.delete(path, function(data){
- $scope.init();
- $scope.view.l3context = false;
- $scope.view.edit = "view";
- $scope.sendReloadEventFromRoot('GBP_L3CONTEXT_RELOAD');
-
- $scope.reloadTopo();
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedL3Context = selectedObj;
-
- $scope.view.edit = $scope.view.edit == "edit" ? $scope.view.edit : "view";
- if(selectedObj){
- $scope.view.l3context = true;
- }
- else {
- $scope.view.l3context = false;
- $scope.view.edit = "view";
- }
-
- if($scope.view.l3context) {
- angular.copy(selectedObj, $scope.newL3ContextObj);
- }
-
- $scope.sendReloadEventFromRoot('GBP_L3CONTEXT_RELOAD');
- };
-
- $scope.showForm = function() {
- $scope.newL3ContextObj = GBPL3ContextServices.createObj();
- $scope.selectedL3Context = null;
- $scope.view.l3context = true;
- $scope.view.edit = "add";
- };
-
- $scope.close = function(){
- $scope.view.l3context = false;
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedL3Context ) {
- $scope.view.l3context = true;
- $scope.view.edit = "edit";
- angular.copy($scope.selectedL3Context, $scope.newL3ContextObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('GBP_TENANT_RELOAD',function(){
- $scope.init();
- });
-
- $scope.$on('GBP_L3CONTEXT_LABEL', function(event, obj){
- obj.labels = $scope.displayLabel;
- });
- }]);
-
- gbpOld.register.controller('subnetCtrl', ['$scope', 'GBPSubnetServices', 'GBPL2FloodDomainServices', 'GBPL2BridgeDomainServices', 'GBPL3ContextServices', '$filter', function($scope, GBPSubnetServices, GBPL2FloodDomainServices, GBPL2BridgeDomainServices, GBPL3ContextServices, $filter){
- $scope.list = [];
- $scope.selectedSubnet = null;
- $scope.newSubnetObj = GBPSubnetServices.createObj();
- $scope.displayLabel = ['name', 'id'];
- $scope.crudLabel = 'Subnet list';
-
- $scope.l2L3List = {'options' : [], 'labels' : null};
- $scope.getDisplayLabelsFromCtrl('GBP_L2FLOOD_LABEL', $scope.l2L3List);
-
- $scope.view = {
- subnet: false,
- edit: "view"
- };
-
-
- var path = null,
-
- loadL2L3List = function() {
- $scope.l2L3List.options = [];
-
- GBPL3ContextServices.load(GBPL3ContextServices.createPathObj($scope.selectedTenant.id), function(l3ContextData){
- $scope.l2L3List.options = $scope.l2L3List.options.concat(l3ContextData);
- }, function(){
-
- });
-
- GBPL2FloodDomainServices.load(GBPL2FloodDomainServices.createPathObj($scope.selectedTenant.id), function(l2FloodData){
- $scope.l2L3List.options = $scope.l2L3List.options.concat(l2FloodData);
- }, function(){
-
- });
-
- GBPL2BridgeDomainServices.load(GBPL2BridgeDomainServices.createPathObj($scope.selectedTenant.id), function(l2BridgeData){
- $scope.l2L3List.options = $scope.l2L3List.options.concat(l2BridgeData);
- }, function(){
-
- });
- },
-
- clear = function(){
- $scope.list = [];
- $scope.view = {
- subnet: false,
- edit: "view"
- };
- $scope.selectedSubnet = null;
- $scope.newSubnetObj = GBPSubnetServices.createObj();
- };
-
- $scope.init = function() {
- if ( $scope.selectedTenant ) {
- path = GBPSubnetServices.createPathObj($scope.selectedTenant.id);
-
- GBPSubnetServices.load(path, function(data){
- $scope.list = data;
- $scope.newSubnetObj = GBPSubnetServices.createObj();
- $scope.selectedSubnet = null;
-
- $scope.view.subnet = false;
- $scope.view.edit = "view";
- //$scope.sendReloadEventFromRoot('GBP_L2BRIDGE_RELOAD');
- }, function(){
-
- });
-
- loadL2L3List();
- }else{
- clear();
- }
- };
-
- $scope.save = function(){
- if($scope.validateForm($scope.subnetForm)){
- path = GBPSubnetServices.createPathObj($scope.selectedTenant.id, $scope.newSubnetObj.id);
- GBPSubnetServices.send(path, $scope.newSubnetObj, function(data){
- $scope.init();
- $scope.view.subnet = false;
- $scope.view.edit = "view";
-
- $scope.reloadTopo();
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.delete = function() {
- if($scope.selectedTenant && $scope.selectedSubnet) {
- path = GBPSubnetServices.createPathObj($scope.selectedTenant.id, $scope.selectedSubnet.id);
- GBPSubnetServices.delete(path, function(data){
- $scope.init();
- $scope.view.subnet = false;
- $scope.view.edit = "view";
-
- $scope.reloadTopo();
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedSubnet = selectedObj;
-
- $scope.view.edit = $scope.view.edit == "edit" ? $scope.view.edit : "view";
- if(selectedObj){
- $scope.view.subnet = true;
- }
- else {
- $scope.view.subnet = false;
- $scope.view.edit = "view";
- }
-
- if($scope.view.subnet) {
- angular.copy(selectedObj, $scope.newSubnetObj);
- }
-
- $scope.sendReloadEventFromRoot('GBP_SUBNET_RELOAD');
- };
-
- $scope.showForm = function() {
- $scope.newSubnetObj = GBPSubnetServices.createObj();
- $scope.selectedSubnet = null;
- $scope.view.subnet = true;
- $scope.view.edit = "add";
- };
-
- $scope.close = function(){
- $scope.view.subnet = false;
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedSubnet ) {
- $scope.view.subnet = true;
- $scope.view.edit = "edit";
- angular.copy($scope.selectedSubnet, $scope.newSubnetObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('GBP_TENANT_RELOAD',function(){
- $scope.init();
- });
-
- $scope.$on('GBP_GATEWAY_RELOAD',function(){
- $scope.init();
- });
-
- $scope.$on('GBP_L3CONTEXT_RELOAD',function(){
- loadL2L3List();
- });
-
- $scope.$on('GBP_L2BRIDGE_RELOAD',function(){
- loadL2L3List();
- });
-
- $scope.$on('GBP_L2FLOOD_RELOAD',function(){
- loadL2L3List();
- });
-
- $scope.$on('GBP_PREFIX_RELOAD',function(){
- $scope.init();
- });
- }]);
-
- gbpOld.register.controller('gatewayCtrl', ['$scope', 'GBPGatewayServices', function($scope, GBPGatewayServices){
- $scope.list = [];
- $scope.gatewayView = false;
- $scope.selectedGateway = null;
- $scope.newGatewayObj = GBPGatewayServices.createObj();
- $scope.displayLabel = 'gateway';
- $scope.crudLabel = 'Gateway list';
- $scope.internalView = {
- gateway: false,
- edit: "view"
- };
-
- var path = null,
-
- clear = function(){
- $scope.list = [];
- $scope.gatewayView = false;
- $scope.selectedGateway = null;
- $scope.newGatewayObj = GBPGatewayServices.createObj();
- };
-
- $scope.init = function() {
- if ( $scope.selectedTenant && $scope.selectedSubnet ) {
- path = GBPGatewayServices.createPathObj($scope.selectedTenant.id, $scope.selectedSubnet.id);
-
- GBPGatewayServices.load(path, function(data){
- $scope.list = data;
- $scope.newGatewayObj = GBPGatewayServices.createObj();
- $scope.internalView.gateway = false;
- $scope.selectedGateway = null;
- }, function(){
-
- });
- }else{
- clear();
- }
- };
-
- $scope.save = function(){
- if($scope.validateForm($scope.gatewayForm)){
- path = GBPGatewayServices.createPathObj($scope.selectedTenant.id, $scope.selectedSubnet.id, $scope.newGatewayObj.gateway);
- GBPGatewayServices.send(path, $scope.newGatewayObj, function(data){
- $scope.init();
- $scope.internalView.gateway = false;
- $scope.internalView.edit = "view";
- $scope.sendReloadEventFromRoot('GBP_GATEWAY_RELOAD');
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.delete = function() {
- if($scope.selectedTenant && $scope.selectedSubnet && $scope.selectedGateway) {
- path = GBPGatewayServices.createPathObj($scope.selectedTenant.id, $scope.selectedSubnet.id, $scope.selectedGateway.gateway);
- GBPGatewayServices.delete(path, function(data){
- $scope.init();
- $scope.internalView.gateway = false;
- $scope.sendReloadEventFromRoot('GBP_GATEWAY_RELOAD');
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedGateway = selectedObj;
- angular.copy(selectedObj, $scope.newGatewayObj);
- $scope.internalView.edit = $scope.internalView.edit == "edit" ? $scope.internalView.edit : "view";
- if(selectedObj){
- $scope.internalView.gateway = true;
- }else {
- $scope.internalView.gateway = false;
- $scope.internalView.edit = "view";
- }
-
- $scope.sendReloadEventFromRoot('GBP_GATEWAY_SET');
- };
-
- $scope.showForm = function() {
- $scope.newGatewayObj = GBPGatewayServices.createObj();
- $scope.internalView.gateway = true;
- $scope.internalView.edit = "add";
- $scope.selectedGateway = null;
- };
-
- $scope.close = function(){
- $scope.internalView.gateway = false;
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedGateway ) {
- $scope.internalView.gateway = true;
- $scope.internalView.edit = "edit";
- angular.copy($scope.selectedGateway, $scope.newGatewayObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('GBP_SUBNET_RELOAD',function(){
- $scope.init();
- });
-
- $scope.$on('GBP_PREFIX_RELOAD',function(){
- $scope.init();
- });
- }]);
-
- gbpOld.register.controller('prefixCtrl', ['$scope', 'GBPPrefixServices', function($scope, GBPPrefixServices){
- $scope.list = [];
- $scope.selectedPrefix = null;
- $scope.newPrefixObj = GBPPrefixServices.createObj();
- $scope.displayLabel = 'prefix';
- $scope.crudLabel = 'Prefix list';
- $scope.internalView = {
- prefix: false,
- edit: "view"
- };
-
- var path = null,
-
- clear = function(){
- $scope.list = [];
- $scope.selectedPrefix = null;
- $scope.newPrefixObj = GBPPrefixServices.createObj();
- $scope.internalView = {
- prefix: false,
- edit: "view"
- };
- };
-
- $scope.init = function() {
- if ( $scope.selectedTenant && $scope.selectedSubnet && $scope.selectedGateway) {
- path = GBPPrefixServices.createPathObj($scope.selectedTenant.id, $scope.selectedSubnet.id, $scope.selectedGateway.gateway);
-
- GBPPrefixServices.load(path, function(data){
- $scope.list = data;
- $scope.newPrefixObj = GBPPrefixServices.createObj();
- $scope.internalView.prefix = false;
- $scope.selectedPrefix = null;
- }, function(){
-
- });
- }else{
- clear();
- }
- };
-
- $scope.save = function(){
- if($scope.validateForm($scope.prefixForm)){
- path = GBPPrefixServices.createPathObj($scope.selectedTenant.id, $scope.selectedSubnet.id, $scope.selectedGateway.gateway, $scope.newPrefixObj.prefix);
- GBPPrefixServices.send(path, $scope.newPrefixObj, function(data){
- $scope.init();
- $scope.internalView.prefix = false;
- $scope.internalView.edit = "view";
- $scope.sendReloadEventFromRoot('GBP_PREFIX_RELOAD');
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.delete = function() {
- path = GBPPrefixServices.createPathObj($scope.selectedTenant.id, $scope.selectedSubnet.id, $scope.selectedGateway.gateway, $scope.selectedPrefix.prefix);
- GBPPrefixServices.delete(path, function(data){
- $scope.init();
- $scope.internalView.prefix = false;
- $scope.sendReloadEventFromRoot('GBP_PREFIX_RELOAD');
- }, function(){
- //TODO: error cbk
- });
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedPrefix = selectedObj;
- $scope.internalView.edit = $scope.internalView.edit == "edit" ? $scope.internalView.edit : "view";
- if(selectedObj){
- $scope.internalView.prefix = true;
- }else {
- $scope.internalView.prefix = false;
- $scope.internalView.edit = "view";
- }
-
- angular.copy(selectedObj, $scope.newPrefixObj);
- };
-
- $scope.showForm = function() {
- $scope.newPrefixObj = GBPPrefixServices.createObj();
- $scope.internalView.prefix = true;
- $scope.internalView.edit = "add";
- $scope.selectedPrefix = null;
- };
-
- $scope.close = function(){
- $scope.internalView.prefix = false;
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedPrefix ) {
- $scope.internalView.prefix = true;
- $scope.internalView.edit = "edit";
- angular.copy($scope.selectedPrefix, $scope.newPrefixObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('GBP_GATEWAY_SET',function(){
- $scope.init();
- });
- }]);
-
- gbpOld.register.controller('renderersCtrl', ['$scope', 'GPBServices', function($scope, GPBServices){ //GBPContractServices
- $scope.classifierDefinitions = {'options' : [], 'labels' : null};
- $scope.actionDefinitions = {'options' : [], 'labels' : null};
-
- //reload on event?
-
- var loadDefinitions = function() {
- GPBServices.getDefinitions(function(classifierDefs, actionDefs) {
- $scope.classifierDefinitions.options = classifierDefs;
- $scope.getDisplayLabelsFromCtrl('GBP_CLASSIFIERS_LABEL', $scope.classifierDefinitions);
-
- $scope.actionDefinitions.options = actionDefs;
- $scope.getDisplayLabelsFromCtrl('GBP_ACTIONS_LABEL', $scope.actionDefinitions);
- });
- };
-
- loadDefinitions();
- }]);
-
- gbpOld.register.controller('paramCtrl', ['$scope', 'GPBServices', function($scope, GPBServices){
- $scope.value = null;
-
- $scope.init = function(param, paramValues) {
- $scope.parameter = param;
-
- if(paramValues) {
- paramValues.forEach(function(p) {
- if($scope.parameter.name === p.name) {
- $scope.value = GPBServices.getInstanceParamValue(p);
- }
- });
- }
- };
-
- $scope.$on('GBP_SAVE_PARAM', function(event){
- if($scope.value !== '' && $scope.value !== null) {
- $scope.addParam($scope.parameter.name, $scope.parameter.type, $scope.value);
- }
- });
-
- $scope.$on('GBP_SET_PARAM_VALUE', function(event, name, intVal, strVal) {
- //console.info($scope.parameter, ' got GBP_SET_PARAM_VALUE', name, intVal, strVal, event);
-
- });
-
- $scope.$on('GBP_RESET_PARAM', function(event){
- $scope.value = null;
- });
- }]);
-
- gbpOld.register.controller('classifiersCtrl', ['$scope', 'GBPClassifierInstanceServices', 'GPBServices', '$filter',
- function($scope, GBPClassifierInstanceServices, GPBServices, $filter){
- $scope.list = [];
- $scope.classifiersView = false;
- $scope.displayLabel = 'name';
- $scope.selectedClassifier = null;
- $scope.crudLabel = 'Classifiers';
- $scope.newClassifierObj = GBPClassifierInstanceServices.createObj();
- $scope.edit = "view";
-
- var mandatoryProperties = ['name'],
-
- clear = function(){
- $scope.list = [];
- $scope.classifiersView = false;
- $scope.selectedClassifier = null;
- $scope.newClassifierObj = GBPClassifierInstanceServices.createObj();
- $scope.edit = "view";
- };
-
- $scope.getDefinitionObjParams = function(id){
- return GPBServices.getDefinitionObjParams($scope.classifierDefinitions.options, id);
- };
-
- $scope.reloadDefs = function(){
- $scope.defs = angular.copy($scope.getDefinitionObjParams($scope.newClassifierObj['classifier-definition-id']));
- };
-
- $scope.addParam = function(name, type, value) {
- $scope.newClassifierObj['parameter-value'].push(GPBServices.createParamObj(name, type, value));
- };
-
- var saveParams = function() {
- $scope.newClassifierObj['parameter-value'] = [];
- $scope.$broadcast('GBP_SAVE_PARAM');
- };
-
-
- $scope.init = function() {
- if ( $scope.selectedTenant ) {
- path = GBPClassifierInstanceServices.createPathObj($scope.selectedTenant.id);
- GBPClassifierInstanceServices.load(path, function(data){
- $scope.list = data;
- $scope.reloadDefs();
- }, function(){
- //TODO: error cbk
- });
- }else{
- clear();
- }
- };
-
- $scope.save = function(){
- if($scope.validateForm($scope.classifierForm)){
- path = GBPClassifierInstanceServices.createPathObj($scope.selectedTenant.id, $scope.newClassifierObj.name);
- saveParams();
- GBPClassifierInstanceServices.send(path, $scope.newClassifierObj, function(data){
- $scope.init();
- $scope.classifiersView = false;
- $scope.edit = "view";
- $scope.sendReloadEventFromRoot('GBP_CLASSIFIER_INSTANCE_RELOAD');
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.showForm = function() {
- $scope.newClassifierObj = GBPClassifierInstanceServices.createObj();
- $scope.selectedClassifier = null;
- $scope.classifiersView = true;
- $scope.edit = "add";
- $scope.reloadDefs();
- };
-
- $scope.reload = function(selectedObj){
- $scope.selectedClassifier = selectedObj;
- $scope.sendReloadEventFromRoot('GBP_CLASSIFIER_INSTANCE_RELOAD');
-
- $scope.edit = $scope.edit == "edit" ? $scope.edit : "view";
- if(selectedObj){
- $scope.classifiersView = true;
- }
- else {
- $scope.classifiersView = false;
- $scope.edit = "view";
- }
-
- if($scope.classifiersView) {
- angular.copy(selectedObj, $scope.newClassifierObj);
- }
-
- $scope.reloadDefs();
- };
-
- $scope.close = function(){
- $scope.classifiersView = false;
- $scope.edit = "view";
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedClassifier ) {
- $scope.classifiersView = true;
- angular.copy($scope.selectedClassifier, $scope.newClassifierObj);
- $scope.edit = "edit";
- $scope.reloadDefs();
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.delete = function(){
- path = GBPClassifierInstanceServices.createPathObj($scope.selectedTenant.id, $scope.selectedClassifier.name);
- GBPClassifierInstanceServices.delete(path, function(data){
- $scope.init();
- $scope.classifiersView = false;
- $scope.sendReloadEventFromRoot('GBP_CLASSIFIER_INSTANCE_RELOAD');
- }, function(){
- //TODO: error cbk
- });
- };
-
- $scope.$on('GBP_TENANT_RELOAD',function(){
- $scope.init();
- });
-
- $scope.$on('GBP_CLASSIFIERS_LABEL', function(event, obj){
- obj.labels = $scope.displayLabel;
- });
- }]);
-
- gbpOld.register.controller('actionsCtrl', ['$scope', 'GBPActionInstanceServices', 'GPBServices', '$filter',
- function($scope, GBPActionInstanceServices, GPBServices, $filter){
- $scope.list = [];
- $scope.actionsView = false;
- $scope.displayLabel = 'name';
- $scope.selectedAction = null;
- $scope.crudLabel = 'Actions';
- $scope.newActionObj = GBPActionInstanceServices.createObj();
- $scope.edit = "view";
-
- var mandatoryProperties = ['name'],
-
- clear = function(){
- $scope.list = [];
- $scope.actionsView = false;
- $scope.selectedAction = null;
- $scope.newActionObj = GBPActionInstanceServices.createObj();
- $scope.edit = "view";
- };
-
- $scope.getDefinitionObjParams = function(id){
- return GPBServices.getDefinitionObjParams($scope.actionDefinitions.options, id);
- };
-
- $scope.reloadDefs = function(){
- $scope.defs = angular.copy($scope.getDefinitionObjParams($scope.newActionObj['action-definition-id']));
- };
-
- $scope.addParam = function(name, type, value) {
- $scope.newActionObj['parameter-value'].push(GPBServices.createParamObj(name, type, value));
- };
-
- var saveParams = function() {
- $scope.newActionObj['parameter-value'] = [];
- $scope.$broadcast('GBP_SAVE_PARAM');
- };
-
-
- $scope.init = function() {
- if ( $scope.selectedTenant ) {
- path = GBPActionInstanceServices.createPathObj($scope.selectedTenant.id);
- GBPActionInstanceServices.load(path, function(data){
- $scope.list = data;
- $scope.reloadDefs();
- }, function(){
- //TODO: error cbk
- });
- }else{
- clear();
- }
- };
-
- $scope.save = function(){
- if($scope.validateForm($scope.actionsForm)){
- path = GBPActionInstanceServices.createPathObj($scope.selectedTenant.id, $scope.newActionObj.name);
- saveParams();
-
- GBPActionInstanceServices.send(path, $scope.newActionObj, function(data){
- $scope.init();
- $scope.actionsView = false;
- $scope.edit = "view";
- $scope.sendReloadEventFromRoot('GBP_ACTION_INSTANCE_RELOAD');
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.showForm = function() {
- $scope.newActionObj = GBPActionInstanceServices.createObj();
- $scope.selectedAction = null;
- $scope.actionsView = true;
- $scope.edit = "add";
- $scope.reloadDefs();
- };
-
- $scope.reload = function(selectedObj){
- $scope.selectedAction = selectedObj;
- $scope.sendReloadEventFromRoot('GBP_ACTION_INSTANCE_RELOAD');
-
- $scope.edit = $scope.edit == "edit" ? $scope.edit : "view";
- if(selectedObj){
- $scope.actionsView = true;
- }
- else {
- $scope.actionsView = false;
- $scope.edit = "view";
- }
-
- if($scope.actionsView) {
- angular.copy(selectedObj, $scope.newActionObj);
- }
-
- $scope.reloadDefs();
- };
-
- $scope.close = function(){
- $scope.actionsView = false;
- $scope.edit = "view";
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedAction ) {
- $scope.actionsView = true;
- angular.copy($scope.selectedAction, $scope.newActionObj);
- $scope.edit = "edit";
- $scope.reloadDefs();
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.delete = function(){
- path = GBPActionInstanceServices.createPathObj($scope.selectedTenant.id, $scope.selectedAction.name);
- GBPActionInstanceServices.delete(path, function(data){
- $scope.init();
- $scope.actionsView = false;
- $scope.sendReloadEventFromRoot('GBP_ACTION_INSTANCE_RELOAD');
- }, function(){
- //TODO: error cbk
- });
- };
-
- $scope.$on('GBP_TENANT_RELOAD',function(){
- $scope.init();
- });
-
- $scope.$on('GBP_ACTIONS_LABEL', function(event, obj){
- obj.labels = $scope.displayLabel;
- });
- }]);
-
- gbpOld.register.controller('endpointCtrl', ['$scope', 'GBPEndpointServices', 'GPBServices', 'GBPL2FloodDomainServices', 'GBPL2BridgeDomainServices', 'GBPL3ContextServices', 'GBPEpgServices', '$filter', 'GBPSubnetServices',
- function($scope, GBPEndpointServices, GPBServices, GBPL2FloodDomainServices, GBPL2BridgeDomainServices, GBPL3ContextServices, GBPEpgServices, $filter, GBPSubnetServices){
- $scope.list = [];
- $scope.selectedEndpoint = null;
- $scope.newEndpointObj = GBPEndpointServices.createObj($scope.selectedTenant ? $scope.selectedTenant.id : null);
- $scope.displayLabel = function(obj) {
- return obj['mac-address'] + ':' + obj['l2-context'];
- };
- $scope.crudLabel = 'Endpoint list';
-
- $scope.l2context = {'options' : [], 'labels' : null};
- $scope.getDisplayLabelsFromCtrl('GBP_L2FLOOD_LABEL', $scope.l2context);
-
- $scope.l3context = {'options' : [], 'labels' : null};
- $scope.getDisplayLabelsFromCtrl('GBP_L3CONTEXT_LABEL', $scope.l3context);
-
- $scope.subnet = {'options' : [], 'labels' : null};
- $scope.getDisplayLabelsFromCtrl('GBP_SUBNET_LABEL', $scope.subnet);
-
- $scope.epg = {'options' : [], 'labels' : null};
- $scope.getDisplayLabelsFromCtrl('GBP_EPG_LABEL', $scope.epg);
-
- $scope.networkContainment = {'options' : [], 'labels' : null};
- $scope.getDisplayLabelsFromCtrl('GBP_L2FLOOD_LABEL', $scope.networkContainment);
-
- $scope.view = {
- endpoint: false,
- edit: "view"
- };
-
- var path = null,
- mandatoryProperties = [],
-
- loadEpgOptions = function() {
- $scope.epg.options = [];
-
- path = GBPEpgServices.createPathObj($scope.selectedTenant.id);
- GBPEpgServices.load(path, function(data){
- $scope.epg.options = data;
- }, function(){
- //TODO: error cbk
- });
- },
-
- loadL2ContextOptions = function() {
- removeL2ContextOptions($scope.networkContainment.options, $scope.l2context.options);
- $scope.l2context.options = [];
-
- path = GBPL2FloodDomainServices.createPathObj($scope.selectedTenant.id);
-
- GBPL2FloodDomainServices.load(path, function(data){
- $scope.l2context.options = $scope.l2context.options.concat(data);
- $scope.networkContainment.options = $scope.networkContainment.options.concat(data);
- }, function(){
-
- });
-
- path = GBPL2BridgeDomainServices.createPathObj($scope.selectedTenant.id);
- GBPL2BridgeDomainServices.load(path, function(data){
- $scope.l2context.options = $scope.l2context.options.concat(data);
- $scope.networkContainment.options = $scope.networkContainment.options.concat(data);
- }, function(){
-
- });
- },
-
- loadL3ContextOptions = function(){
- removeL2ContextOptions($scope.networkContainment.options, $scope.l3context.options);
- $scope.l3context.options = [];
-
- GBPL3ContextServices.load(GBPL3ContextServices.createPathObj($scope.selectedTenant.id), function(data){
- $scope.l3context.options = data;
- $scope.networkContainment.options = $scope.networkContainment.options.concat(data);
- }, function(){
-
- });
- },
-
- loadSubnetOptions = function(){
- $scope.subnet.options = [];
-
- GBPSubnetServices.load(GBPSubnetServices.createPathObj($scope.selectedTenant.id), function(data){
- $scope.subnet.options = data;
- $scope.networkContainment.options = $scope.networkContainment.options.concat(data);
- }, function(){
-
- });
- },
-
- loadNetworkCotnaninemnt = function(){
- $scope.networkContainment.options = [];
-
- loadL2ContextOptions();
- loadL3ContextOptions();
- loadSubnetOptions();
- },
-
- clear = function(){
- $scope.list = [];
- $scope.selectedEndpoint = null;
- $scope.newEndpointObj = GBPEndpointServices.createObj($scope.selectedTenant ? $scope.selectedTenant.id : null);
- $scope.view = {
- endpoint: false,
- edit: "view"
- };
- },
- removeL2ContextOptions = function(arr1, arr2) {
- arr1 = arr1.filter( function( el ) {
- return arr2.indexOf( el ) < 0;
- });
- };
-
- $scope.init = function() {
- if ($scope.selectedTenant) {
-
- GBPEndpointServices.load(path, function(data){
- $scope.list = data;
- }, function(){
- //TODO: error cbk
- });
-
- loadEpgOptions();
- /*loadL2ContextOptions();
- loadL3ContextOptions();
- loadSubnetOptions();*/
- loadNetworkCotnaninemnt();
- }else{
- clear();
- }
- };
-
- $scope.addNewL3address = function() {
- if($scope.newEndpointObj) {
- if(!$scope.newEndpointObj['l3-address']){
- $scope.newEndpointObj['l3-address'] = [];
- }
- var objToPush = {'l3-context' : '', 'ip-address' : ''};
- $scope.newEndpointObj['l3-address'].push(objToPush);
- }
- };
-
- $scope.deleteNewL3address = function(index){
- if($scope.newEndpointObj) {
- $scope.newEndpointObj['l3-address'].splice(index, 1);
- }
- };
-
- $scope.addNewLeafListEl = function(prop) {
- if($scope.newEndpointObj) {
- if(!$scope.newEndpointObj[prop]){
- $scope.newEndpointObj[prop] = [];
- }
- var objToPush = "";
- $scope.newEndpointObj[prop].push(objToPush);
- }
- };
-
- $scope.updateLeafListEl = function(index, value, prop) {
- if($scope.newEndpointObj && $scope.newEndpointObj[prop] && $scope.newEndpointObj[prop].length >= index) {
- $scope.newEndpointObj[prop][index] = value;
- }
- };
-
- $scope.deleteNewLeafListEl = function(index, prop){
- if($scope.newEndpointObj) {
- $scope.newEndpointObj[prop].splice(index, 1);
- }
- };
-
- $scope.save = function(){
- if($scope.validateForm($scope.endpointForm)){
- GBPEndpointServices.send(path, $scope.newEndpointObj, function(data){
- $scope.init();
- $scope.view.endpoint = false;
- $scope.reloadNewObj();
- $scope.view.edit = "view";
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.delete = function() {
- if($scope.selectedTenant && $scope.selectedEndpoint) {
- GBPEndpointServices.delete(path, $scope.selectedEndpoint, function(data){
- $scope.init();
- $scope.view.endpoint = false;
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.showForm = function() {
- $scope.view.endpoint = true;
- $scope.reloadNewObj();
- $scope.selectedEndpoint = null;
-
- $scope.view.edit = "add";
- };
-
- $scope.reloadNewObj = function() {
- $scope.newEndpointObj = GBPEndpointServices.createObj($scope.selectedTenant ? $scope.selectedTenant.id : null);
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedEndpoint = selectedObj;
- $scope.view.edit = $scope.view.edit == "edit" ? $scope.view.edit : "view";
- if(selectedObj){
- $scope.view.endpoint = true;
- }
- else {
- $scope.view.endpoint = false;
- $scope.view.edit = "view";
- }
-
- if($scope.view.endpoint) {
- angular.copy(selectedObj, $scope.newEndpointObj);
- }
- };
-
- $scope.close = function(){
- $scope.view.endpoint = false;
- $scope.view.edit = "view";
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedEndpoint ) {
- $scope.view.endpoint = true;
- $scope.view.edit = "edit";
- angular.copy($scope.selectedEndpoint, $scope.newEndpointObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('GBP_TENANT_RELOAD',function(){
- $scope.init();
- });
-
- $scope.$on('GBP_EPG_RELOAD',function(){
- loadEpgOptions();
- });
-
- $scope.$on('GBP_L2BRIDGE_RELOAD',function(){
- //loadL2ContextOptions();
- loadNetworkCotnaninemnt();
- });
-
- $scope.$on('GBP_L2FLOOD_RELOAD',function(){
- //loadL2ContextOptions();
- loadNetworkCotnaninemnt();
- });
-
- $scope.$on('GBP_L3CONTEXT_RELOAD',function(){
- //loadL3ContextOptions();
- loadNetworkCotnaninemnt();
- });
-
- $scope.$on('GBP_SUBNET_RELOAD',function(){
- //loadSubnetOptions();
- loadNetworkCotnaninemnt();
- });
- }]);
-
- gbpOld.register.controller('l3EndpointCtrl', ['$scope', 'GBPEndpointL3Services', 'GPBServices', 'GBPEpgServices', 'GBPL3ContextServices', 'GBPL2FloodDomainServices', 'GBPL2BridgeDomainServices', '$filter',
- function($scope, GBPEndpointL3Services, GPBServices, GBPEpgServices, GBPL3ContextServices, GBPL2FloodDomainServices, GBPL2BridgeDomainServices, $filter){
- $scope.list = [];
- $scope.selectedEndpoint = null;
- $scope.newEndpointObj = GBPEndpointL3Services.createObj($scope.selectedTenant ? $scope.selectedTenant.id : null);
- $scope.displayLabel = function(obj) {
- return obj['ip-prefix'] + ':' + obj['l3-context'];
- };
- $scope.crudLabel = 'L3 Prefix endpoint list';
-
- $scope.l2context = {'options' : [], 'labels' : null};
- $scope.getDisplayLabelsFromCtrl('GBP_L2FLOOD_LABEL', $scope.l2context);
-
- $scope.l3context = {'options' : [], 'labels' : null};
- $scope.getDisplayLabelsFromCtrl('GBP_L3CONTEXT_LABEL', $scope.l3context);
-
- $scope.epg = {'options' : [], 'labels' : null};
- $scope.getDisplayLabelsFromCtrl('GBP_EPG_LABEL', $scope.epg);
-
- $scope.view = {
- endpoint: false,
- edit: "view"
- };
-
- var path = null,
- mandatoryProperties = [],
-
- loadEpgOptions = function() {
- $scope.epg.options = [];
-
- path = GBPEpgServices.createPathObj($scope.selectedTenant.id);
- GBPEpgServices.load(path, function(data){
- $scope.epg.options = data;
- }, function(){
- //TODO: error cbk
- });
- },
-
- loadL2ContextOptions = function() {
- $scope.l2context.options = [];
-
- path = GBPL2FloodDomainServices.createPathObj($scope.selectedTenant.id);
-
- GBPL2FloodDomainServices.load(path, function(data){
- $scope.l2context.options = $scope.l2context.options.concat(data);
- }, function(){
-
- });
-
- path = GBPL2BridgeDomainServices.createPathObj($scope.selectedTenant.id);
- GBPL2BridgeDomainServices.load(path, function(data){
- $scope.l2context.options = $scope.l2context.options.concat(data);
- }, function(){
-
- });
- },
-
- loadL3ContextOptions = function(){
- $scope.l3context.options = [];
-
- GBPL3ContextServices.load(GBPL3ContextServices.createPathObj($scope.selectedTenant.id), function(data){
- $scope.l3context.options = data;
- }, function(){
-
- });
- },
-
- clear = function(){
- $scope.list = [];
- $scope.selectedEndpoint = null;
- $scope.newEndpointObj = GBPEndpointL3Services.createObj($scope.selectedTenant ? $scope.selectedTenant.id : null);
- $scope.view = {
- endpoint: false,
- edit: "view"
- };
- };
-
- $scope.init = function() {
- if ($scope.selectedTenant) {
-
- GBPEndpointL3Services.load(path, function(data){
- $scope.list = data;
- }, function(){
- //TODO: error cbk
- });
-
- loadEpgOptions();
- loadL2ContextOptions();
- loadL3ContextOptions();
- }else{
- clear();
- }
- };
-
- $scope.addNewL2gateways = function() {
- if($scope.newEndpointObj) {
- if(!$scope.newEndpointObj['endpoint-l2-gateways']){
- $scope.newEndpointObj['endpoint-l2-gateways'] = [];
- }
- var objToPush = {'l2-context' : '', 'mac-address' : ''};
- $scope.newEndpointObj['endpoint-l2-gateways'].push(objToPush);
- }
- };
-
- $scope.deleteNewL2gateways = function(index){
- if($scope.newEndpointObj) {
- $scope.newEndpointObj['endpoint-l2-gateways'].splice(index, 1);
- }
- };
-
- $scope.addNewL3gateways = function() {
- if($scope.newEndpointObj) {
- if(!$scope.newEndpointObj['endpoint-l3-gateways']){
- $scope.newEndpointObj['endpoint-l3-gateways'] = [];
- }
- var objToPush = {'l3-context' : '', 'ip-address' : ''};
- $scope.newEndpointObj['endpoint-l3-gateways'].push(objToPush);
- }
- };
-
- $scope.deleteNewL3gateways = function(index){
- if($scope.newEndpointObj) {
- $scope.newEndpointObj['endpoint-l3-gateways'].splice(index, 1);
- }
- };
-
- $scope.addNewLeafListEl = function(prop) {
- if($scope.newEndpointObj) {
- if(!$scope.newEndpointObj[prop]){
- $scope.newEndpointObj[prop] = [];
- }
- var objToPush = "";
- $scope.newEndpointObj[prop].push(objToPush);
- }
- };
-
- $scope.updateLeafListEl = function(index, value, prop) {
- if($scope.newEndpointObj && $scope.newEndpointObj[prop] && $scope.newEndpointObj[prop].length >= index) {
- $scope.newEndpointObj[prop][index] = value;
- }
- };
-
- $scope.deleteNewLeafListEl = function(index, prop){
- if($scope.newEndpointObj) {
- $scope.newEndpointObj[prop].splice(index, 1);
- }
- };
-
- $scope.save = function(){
- if($scope.validateForm($scope.l3EndpointForm)){
- GBPEndpointL3Services.send(path, $scope.newEndpointObj, function(data){
- $scope.init();
- $scope.view.endpoint = false;
- $scope.reloadNewObj();
- $scope.view.edit = "view";
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.delete = function() {
- if($scope.selectedTenant && $scope.selectedEndpoint) {
- GBPEndpointL3Services.delete(path, $scope.selectedEndpoint, function(data){
- $scope.init();
- }, function(){
- //TODO: error cbk
- });
- }
- };
-
- $scope.showForm = function() {
- $scope.view.endpoint = true;
- $scope.reloadNewObj();
- $scope.selectedEndpoint = null;
- $scope.view.edit = "add";
- };
-
- $scope.reloadNewObj = function() {
- $scope.newEndpointObj = GBPEndpointL3Services.createObj($scope.selectedTenant ? $scope.selectedTenant.id : null);
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedEndpoint = selectedObj;
- angular.copy(selectedObj, $scope.newEndpointObj);
- $scope.view.edit = $scope.view.edit == "edit" ? $scope.view.edit : "view";
- if(selectedObj){
- $scope.view.endpoint = true;
- }
- else {
- $scope.view.endpoint = false;
- $scope.view.edit = "view";
- }
- };
-
- $scope.close = function(){
- $scope.view.endpoint = false;
- $scope.view.edit = "view";
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedEndpoint ) {
- $scope.view.endpoint = true;
- $scope.view.edit = "edit";
- angular.copy($scope.selectedEndpoint, $scope.newEndpointObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('GBP_TENANT_RELOAD',function(){
- $scope.init();
- });
-
- $scope.$on('GBP_EPG_RELOAD',function(){
- loadEpgOptions();
- });
-
- $scope.$on('GBP_L2BRIDGE_RELOAD',function(){
- loadL2ContextOptions();
- });
-
- $scope.$on('GBP_L2FLOOD_RELOAD',function(){
- loadL2ContextOptions();
- });
-
- $scope.$on('GBP_L3CONTEXT_RELOAD',function(){
- loadL3ContextOptions();
- });
- }]);
-
- gbpOld.register.controller('accessModelWizardCtrl', ['$scope', '$filter', 'GBPTenantServices', 'GBPEpgServices', 'GBPContractServices', 'GPBServices', function($scope, $filter, GBPTenantServices, GBPEpgServices, GBPContractServices, GPBServices){
- $scope.wizardPage = null;
-
- $scope.selectedTenant = null;
- $scope.tenant = null;
- //$scope.epgList = [];
- $scope.newContractObj = null;
-
- $scope.init = function() {
- $scope.setPage('tenants');
- };
-
- $scope.setPage = function(pageName, object) {
- $scope.wizardPage = pageName;
-
- switch(pageName) {
- case 'contracts':
- if(object) {
- $scope.tenant = object;
- }
-
- break;
-
- case 'summary':
- $scope.tenant['endpoint-group'] = $scope.tenant['endpoint-group'] ? $scope.tenant['endpoint-group'] : [];
-
- if(object) {
- object.forEach(function(o) {
- $scope.tenant['endpoint-group'].push(GPBServices.stripNullValues(o));
- });
- }
-
- break;
-
- case 'epgs':
- $scope.tenant['contract'] = $scope.tenant['contract'] ? $scope.tenant['contract'] : [];
-
- if(object) {
- object.forEach(function(o) {
- $scope.tenant['contract'].push(GPBServices.stripNullValues(o));
- });
- }
-
- break;
- }
- };
-
- $scope.submit = function(object) {
- $scope.tenant['endpoint-group'] = $scope.tenant['endpoint-group'] ? $scope.tenant['endpoint-group'] : [];
-
- if(object) {
- object.forEach(function(o) {
- $scope.tenant['endpoint-group'].push(GPBServices.stripNullValues(o));
- });
- }
-
-
- path = GBPTenantServices.createPathObj($scope.tenant.id);
- GBPTenantServices.send(path, $scope.tenant, function(data){
- $scope.wizards.accessModelWizard = false;
- $scope.sendReloadEventFromRoot('GBP_GLOBAL_TENANT_RELOAD');
- $scope.reloadTopo();
- }, function(){
- //TODO: error cbk
- });
- };
-
- // $scope.updateList = function(list, object, key) {
- // var elementPos = list.map(function(x) {return x[key]; }).indexOf(object[key]);
-
- // if(elementPos < 0) {
- // list.push(object);
- // }
- // else {
- // list[elementPos] = object;
- // }
- // };
- }]);
-
- gbpOld.register.controller('wizardTenantCtrl', ['$scope', '$filter', 'GBPTenantServices', function($scope, $filter, GBPTenantServices){
- // $scope.tenantList = [];
- $scope.newTenantObj = GBPTenantServices.createObj();
- $scope.displayLabel = ['name' , 'id'];
-
- $scope.view = {
- tenantEdit: false
- };
-
- // $scope.init = function() {
- // $scope.getTenants();
- // };
-
- // $scope.getTenants = function() {
- // GBPTenantServices.load(
- // function(data) {
- // $scope.tenantList = data;
- // $scope.newTenantObj = GBPTenantServices.createObj();
- // },
- // function(){
- // //TODO error
- // }
- // );
- // };
-
- $scope.reloadTenants = function(selectedObject) {
- if(!selectedObject) {
- selectedObject = GBPTenantServices.createObj();
- $scope.view.tenantEdit = false;
- }
- else {
- $scope.view.tenantEdit = true;
- }
-
- $scope.selectedTenant = selectedObject;
- $scope.newTenantObj = selectedObject;
- };
-
- $scope.getNewTenantObject = function() {
- return GBPTenantServices.createObj();
- };
- }]);
-
- gbpOld.register.controller('wizardEpgCtrl', ['$scope', '$filter', 'GBPEpgServices', function($scope, $filter, GBPEpgServices){
- $scope.list = [];
- $scope.newEpgObj = GBPEpgServices.createObj();
- $scope.selectedEpg = null;
- $scope.epgFormView = true;
-
- $scope.displayLabel = ['name', 'id'];
- $scope.crudLabel = 'Group list';
-
- $scope.igpOpts = ['allow', 'require-contract'];
-
- $scope.init = function() {
-
- };
-
- $scope.showForm = function() {
- $scope.epgFormView = true;
- $scope.newEpgObj = GBPEpgServices.createObj();
- };
-
- $scope.save = function() {
- $scope.updateList($scope.list, $scope.newEpgObj, "id");
- $scope.reload($scope.newEpgObj);
- $scope.$broadcast('EV_SET_SEL_CLASS', $scope.newEpgObj);
- };
-
- $scope.delete = function() {
- if($scope.selectedEpg) {
- var index = $scope.list.indexOf($scope.selectedEpg);
- $scope.list.splice(index, 1);
- $scope.epgFormView = false;
- }
- //$scope.newEpgObj = GBPEpgServices.createObj();
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedEpg = selectedObj;
- $scope.newEpgObj = selectedObj;
- $scope.epgFormView = true;
- $scope.$broadcast('WIZARD_EPG_RELOAD');
- };
-
- $scope.close = function() {
- $scope.epgFormView = false;
- $scope.newEpgObj = GBPEpgServices.createObj();
- $scope.selectedEpg = null;
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedEpg ) {
- $scope.epgFormView = true;
- angular.copy($scope.selectedEpg, $scope.newEpgObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on("WIZARD_CNS_RELOAD", function(event, args){
- //$scope.selectedEpg['consumer-named-selector'] = args;
- $scope.newEpgObj['consumer-named-selector'] = args;
- $scope.updateList($scope.list, $scope.newEpgObj, "id");
- });
-
- $scope.$on("WIZARD_PNS_RELOAD", function(event, args){
- //$scope.selectedEpg['provider-named-selector'] = args;
- $scope.newEpgObj['provider-named-selector'] = args;
- $scope.updateList($scope.list, $scope.newEpgObj, "id");
- });
- }]);
-
- gbpOld.register.controller('wizardContractCtrl', ['$scope', '$filter', 'GBPContractServices', function($scope, $filter, GBPContractServices){
- $scope.list = [];
- $scope.newContractObj = GBPContractServices.createObj();
- $scope.selectedContract = null;
-
- $scope.displayLabel = ['description', 'id'];
- $scope.crudLabel = 'Contract list';
-
- $scope.contractFormView = true;
-
- $scope.init = function() {
-
- };
-
- $scope.showForm = function() {
- $scope.contractFormView = true;
- $scope.newContractObj = GBPContractServices.createObj();
- };
-
- $scope.save = function() {
- $scope.updateList($scope.list, $scope.newContractObj, "id");
- $scope.reload($scope.newContractObj);
- $scope.$broadcast('EV_SET_SEL_CLASS', $scope.newContractObj);
- };
-
- $scope.delete = function() {
- if($scope.selectedContract) {
- var index = $scope.list.indexOf($scope.selectedContract);
- $scope.list.splice(index, 1);
- $scope.contractFormView = false;
- $scope.newContractObj = GBPContractServices.createObj();
- $scope.selectedContract = null;
- }
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedContract = selectedObj;
- $scope.newContractObj = selectedObj;
- $scope.contractFormView = true;
- };
-
- $scope.close = function() {
- $scope.contractFormView = false;
- //$scope.newContractObj = GBPContractServices.createObj();
- //$scope.selectedContract = null;
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedContract ) {
- $scope.contractFormView = true;
- angular.copy($scope.selectedContract, $scope.newContractObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on("WIZARD_SUBJECT_RELOAD", function(event, args){
- //$scope.selectedEpg['consumer-named-selector'] = args;
- $scope.newContractObj['subject'] = args;
- $scope.updateList($scope.list, $scope.newContractObj, "id");
- });
-
- $scope.$on("WIZARD_CLAUSE_RELOAD", function(event, args){
- //$scope.selectedEpg['consumer-named-selector'] = args;
- $scope.newContractObj['clause'] = args;
- $scope.updateList($scope.list, $scope.newContractObj, "id");
- });
- }]);
-
- gbpOld.register.controller('wizardCnsCtrl',['$scope', 'GBPConNamedSelServices', function($scope, GBPConNamedSelServices){
- $scope.list = [];
- $scope.selectedCNS = null;
- $scope.newCNSObj = GBPConNamedSelServices.createObj();
- $scope.internalView = {
- cns: false,
- edit: "view"
- };
- $scope.displayLabel = 'name';
- $scope.crudLabel = 'Consumer named selectors list';
-
- $scope.contractList = {'options' : [], 'labels' : null};
- $scope.getDisplayLabelsFromCtrl('GBP_CONTRACTS_LABEL', $scope.contractList);
-
- var clear = function(){
- $scope.list = [];
- $scope.selectedCNS = null;
- $scope.newCNSObj = GBPConNamedSelServices.createObj();
- $scope.internalView = {
- cns: false,
- edit: "add"
- };
- };
-
- //move to separate ctrl \/
- $scope.addNewElem = function(templateObj) {
- if($scope.newCNSObj && $scope.newCNSObj.contract) {
- var objToPush = templateObj || "";
- $scope.newCNSObj.contract.push(objToPush);
- }
- };
-
- $scope.deleteElemAt = function(index) {
- if($scope.newCNSObj && $scope.newCNSObj.contract) {
- $scope.newCNSObj.contract.splice(index, 1);
- }
- };
-
- $scope.updateAt = function(index, value) {
- if($scope.newCNSObj && $scope.newCNSObj.contract && $scope.newCNSObj.contract.length >= index) {
- $scope.newCNSObj.contract[index] = value;
- }
- };
- //move to separate ctrl /\
-
- $scope.init = function() {
- clear();
-
- if($scope.tenant && $scope.tenant['contract'].length>0) {
- $scope.contractList.options = $scope.tenant['contract'];
- }
-
- if($scope.selectedEpg && $scope.selectedEpg['consumer-named-selector']) {
- $scope.list = $scope.selectedEpg['consumer-named-selector'];
- }
- };
-
- $scope.save = function(){
- $scope.updateList($scope.list, $scope.newCNSObj, "name");
- $scope.reload($scope.newCNSObj);
- $scope.$emit('WIZARD_CNS_RELOAD', $scope.list);
- $scope.$broadcast('EV_SET_SEL_CLASS', $scope.newCNSObj);
- };
-
- $scope.delete = function() {
- if($scope.selectedCNS) {
- var index = $scope.list.indexOf($scope.selectedCNS);
- $scope.list.splice(index, 1);
- $scope.internalView = {
- cns: false,
- edit: "add"
- };
- $scope.$emit('WIZARD_CNS_RELOAD', $scope.list);
- }
- };
-
- $scope.showForm = function() {
- $scope.reloadNewObj();
- $scope.selectedCNS = null;
- $scope.internalView.cns = true;
- $scope.internalView.edit = "add";
- };
-
- $scope.reloadNewObj = function() {
- $scope.newCNSObj = GBPConNamedSelServices.createObj();
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedCNS = selectedObj;
- $scope.newCNSObj = selectedObj;
- $scope.internalView.cns = true;
- };
-
- $scope.close = function(){
- $scope.internalView.cns = false;
- //$scope.internalView.edit = "view";
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedEpg ) {
- $scope.internalView.cns = true;
- $scope.internalView.edit = "add";
- angular.copy($scope.selectedCNS, $scope.newCNSObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('WIZARD_EPG_RELOAD',function(){
- $scope.init();
- });
- }]);
-
- gbpOld.register.controller('wizardPnsCtrl',['$scope', 'GBPProNamedSelServices', function($scope, GBPProNamedSelServices){
- $scope.list = [];
- $scope.selectedPNS = null;
- $scope.newPNSObj = GBPProNamedSelServices.createObj();
- $scope.displayLabel = 'name';
- $scope.crudLabel = 'Provider named selectors list';
- $scope.internalView = {
- pns: false,
- edit: "view"
- };
-
- $scope.contractList = {'options' : [], 'labels' : null};
- $scope.getDisplayLabelsFromCtrl('GBP_CONTRACTS_LABEL', $scope.contractList);
-
- var clear = function(){
- $scope.list = [];
- $scope.selectedPNS = null;
- $scope.newPNSObj = GBPProNamedSelServices.createObj();
- $scope.internalView = {
- pns: false,
- edit: "view"
- };
- };
-
- //move to separate ctrl \/
- $scope.addNewElem = function(templateObj) {
- if($scope.newPNSObj && $scope.newPNSObj.contract) {
- var objToPush = templateObj || "";
- $scope.newPNSObj.contract.push(objToPush);
- }
- };
-
- $scope.deleteElemAt = function(index) {
- if($scope.newPNSObj && $scope.newPNSObj.contract) {
- $scope.newPNSObj.contract.splice(index, 1);
- }
- };
-
- $scope.updateAt = function(index, value) {
- if($scope.newPNSObj && $scope.newPNSObj.contract && $scope.newPNSObj.contract.length >= index) {
- $scope.newPNSObj.contract[index] = value;
- }
- };
- //move to separate ctrl /\
-
- $scope.init = function() {
- clear();
-
- if($scope.tenant && $scope.tenant['contract'].length>0) {
- $scope.contractList.options = $scope.tenant['contract'];
- }
-
- if($scope.selectedEpg && $scope.selectedEpg['provider-named-selector']) {
- $scope.list = $scope.selectedEpg['provider-named-selector'];
- }
- };
-
- $scope.save = function(){
- $scope.updateList($scope.list, $scope.newPNSObj, "name");
- $scope.reload($scope.newPNSObj);
- $scope.$emit('WIZARD_PNS_RELOAD', $scope.list);
- $scope.$broadcast('EV_SET_SEL_CLASS', $scope.newPNSObj);
- };
-
- $scope.delete = function() {
- if($scope.selectedPNS) {
- var index = $scope.list.indexOf($scope.selectedPNS);
- $scope.list.splice(index, 1);
- $scope.internalView = {
- pns: false,
- edit: "add"
- };
- $scope.$emit('WIZARD_PNS_RELOAD', $scope.list);
- }
- };
-
- $scope.showForm = function() {
- $scope.reloadNewObj();
- $scope.selectedPNS = null;
- $scope.internalView.pns = true;
- $scope.internalView.edit = "add";
- };
-
- $scope.reloadNewObj = function() {
- $scope.newPNSObj = GBPProNamedSelServices.createObj();
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedPNS = selectedObj;
- $scope.newPNSObj = selectedObj;
- $scope.internalView.pns = true;
- };
-
- $scope.close = function(){
- $scope.internalView.pns = false;
- $scope.internalView.edit = "view";
- };
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedEpg ) {
- $scope.internalView.pns = true;
- $scope.internalView.edit = "edit";
- angular.copy($scope.selectedPNS, $scope.newPNSObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('WIZARD_EPG_RELOAD',function(){
- $scope.init();
- });
- }]);
-
- gbpOld.register.controller('wizardSubjectCtrl', ['$scope','GBPSubjectServices', '$filter', function($scope, GBPSubjectServices, $filter){
- $scope.list = [];
- $scope.selectedSubject = null;
- $scope.newSubjectObj = GBPSubjectServices.createObj();
- $scope.displayLabel = 'name';
- $scope.internalView = {
- subject : false,
- edit : "view"
- };
- $scope.crudLabel = 'Subject list';
- $scope.errors = {};
-
-
- var path = null,
- mandatoryProperties = ['order'],
-
- clear = function(){
- $scope.list = [];
- $scope.selectedSubject = null;
- $scope.newSubjectObj = GBPSubjectServices.createObj();
- $scope.internalView = {
- subject : false,
- edit : "view"
- };
- };
-
- $scope.init = function() {
-
- };
-
- $scope.save = function(){
- $scope.updateList($scope.list, $scope.newSubjectObj, "name");
- $scope.reload($scope.newSubjectObj);
- $scope.$emit('WIZARD_SUBJECT_RELOAD', $scope.list);
- $scope.$broadcast('EV_SET_SEL_CLASS', $scope.newSubjectObj);
- };
-
- $scope.delete = function() {
- if($scope.selectedSubject) {
- var index = $scope.list.indexOf($scope.selectedSubject);
- $scope.list.splice(index, 1);
- $scope.internalView = {
- subject: false,
- edit: "add"
- };
- $scope.reloadNewObj();
- $scope.$emit('WIZARD_SUBJECT_RELOAD', $scope.list);
- }
- };
-
- $scope.reloadNewObj = function() {
- $scope.newSubjectObj = GBPSubjectServices.createObj();
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedSubject = selectedObj;
- $scope.newSubjectObj = selectedObj;
- $scope.internalView.subject = true;
- };
-
- $scope.showForm = function() {
- $scope.reloadNewObj();
- $scope.internalView.subject = true;
- $scope.internalView.edit = "add";
- $scope.selectedSubject = null;
- };
-
- $scope.close = function(){
- $scope.internalView.subject = false;
- $scope.internalView.edit = "view";
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedSubject ) {
- $scope.internalView.subject = true;
- $scope.internalView.edit = "edit";
- angular.copy($scope.selectedSubject, $scope.newSubjectObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('GBP_CONTRACT_RELOAD',function(){
- $scope.init();
- });
-
- $scope.$on('GBP_SUBJECTS_LABEL', function(event, obj){
- obj.labels = $scope.displayLabel;
- });
-
- $scope.$on("WIZARD_RULE_RELOAD", function(event, args){
- //$scope.selectedEpg['consumer-named-selector'] = args;
- $scope.newSubjectObj['rule'] = args;
- $scope.updateList($scope.list, $scope.newSubjectObj, "id");
- $scope.$emit('WIZARD_SUBJECT_RELOAD', $scope.list);
- });
- }]);
-
- gbpOld.register.controller('wizardRuleCtrl', ['$scope','GBPRuleServices', '$filter', function($scope, GBPRuleServices, $filter){
- $scope.list = [];
- $scope.selectedRule = null;
- $scope.newRuleObj = GBPRuleServices.createObj();
- $scope.displayLabel = 'name';
- $scope.internalView = {
- rule : false,
- edit : "view"
- };
- $scope.crudLabel = 'Rule list';
- $scope.errors = {};
-
- var path = null,
- mandatoryProperties = ['order'],
-
- clear = function(){
- $scope.list = [];
- $scope.selectedRule = null;
- $scope.newRuleObj = GBPRuleServices.createObj();
- $scope.internalView = {
- rule : false,
- edit : "view"
- };
- };
-
- $scope.init = function() {
-
- };
-
- $scope.save = function(){
- $scope.updateList($scope.list, $scope.newRuleObj, "name");
- $scope.reload($scope.newRuleObj);
- $scope.$emit('WIZARD_RULE_RELOAD', $scope.list);
- $scope.$broadcast('EV_SET_SEL_CLASS', $scope.newRuleObj);
- };
-
- $scope.delete = function() {
- if($scope.selectedRule) {
- var index = $scope.list.indexOf($scope.selectedRule);
- $scope.list.splice(index, 1);
- $scope.internalView = {
- rule: false,
- edit: "add"
- };
- $scope.reloadNewObj();
- $scope.$emit('WIZARD_RULE_RELOAD', $scope.list);
- }
- };
-
- $scope.reloadNewObj = function() {
- $scope.newRuleObj = GBPRuleServices.createObj();
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedRule = selectedObj;
- $scope.newRuleObj = selectedObj;
- $scope.internalView.rule = true;
- $scope.$broadcast('WIZARD_RULE_RELOAD');
- };
-
- $scope.showForm = function() {
- $scope.reloadNewObj();
- $scope.internalView.rule = true;
- $scope.internalView.edit = "add";
- $scope.selectedRule = null;
- };
-
- $scope.close = function(){
- $scope.internalView.rule = false;
- $scope.internalView.edit = "view";
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedRule ) {
- $scope.internalView.rule = true;
- $scope.internalView.edit = "edit";
- angular.copy($scope.selectedRule, $scope.newRuleObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('GBP_SUBJECT_RELOAD',function(){
- $scope.init();
- });
-
- $scope.$on("WIZARD_CLASREF_RELOAD", function(event, args){
- $scope.newRuleObj['classifier-ref'] = args;
- $scope.updateList($scope.list, $scope.newRuleObj, "name");
- $scope.$emit('WIZARD_RULE_RELOAD', $scope.list);
- });
-
- $scope.$on("WIZARD_ACTIONREF_RELOAD", function(event, args){
- $scope.newRuleObj['action-ref'] = args;
- $scope.updateList($scope.list, $scope.newRuleObj, "name");
- $scope.$emit('WIZARD_RULE_RELOAD', $scope.list);
- });
- }]);
-
- gbpOld.register.controller('wizardClauseCtrl', ['$scope','GBPClauseServices', 'GBPSubjectServices',
- function($scope, GBPClauseServices, GBPSubjectServices){
- $scope.list = [];
- $scope.selectedClause = null;
- $scope.newClauseObj = GBPClauseServices.createObj();
- $scope.internalView = {
- clause: false,
- edit: "view"
- };
- $scope.displayLabel = 'name';
- $scope.crudLabel = 'Clause list';
-
- $scope.subjects = {'options' : [], 'labels' : null};
- $scope.getDisplayLabelsFromCtrl('GBP_SUBJECTS_LABEL', $scope.subjects);
-
- var path = null,
-
- clear = function(){
- $scope.list = [];
- $scope.selectedClause = null;
- $scope.newClauseObj = GBPClauseServices.createObj();
- $scope.internalView = {
- clause: false,
- edit: "view"
- };
- };
-
- //move to separate ctrl \/
- $scope.addNewElem = function(templateObj) {
- if($scope.newClauseObj && $scope.newClauseObj['subject-refs']) {
- $scope.init();
- var objToPush = templateObj || "";
- $scope.newClauseObj['subject-refs'].push(objToPush);
- }
- };
-
- $scope.deleteElemAt = function(index) {
- if($scope.newClauseObj && $scope.newClauseObj['subject-refs']) {
- $scope.newClauseObj['subject-refs'].splice(index, 1);
- }
- };
-
- $scope.updateAt = function(index, value) {
- if($scope.newClauseObj && $scope.newClauseObj['subject-refs'] && $scope.newClauseObj['subject-refs'].length >= index) {
- $scope.newClauseObj['subject-refs'][index] = value;
- }
- };
- //move to separate ctrl /\
-
- $scope.init = function() {
- if($scope.selectedContract && $scope.selectedContract['subject'].length>0) {
- $scope.subjects.options = $scope.selectedContract['subject'];
- }
- };
-
- $scope.save = function(){
- $scope.updateList($scope.list, $scope.newClauseObj, "name");
- $scope.reload($scope.newClauseObj);
- $scope.$emit('WIZARD_CLAUSE_RELOAD', $scope.list);
- $scope.$broadcast('EV_SET_SEL_CLASS', $scope.newClauseObj);
- };
-
- $scope.delete = function() {
- if($scope.selectedClause) {
- var index = $scope.list.indexOf($scope.selectedClause);
- $scope.list.splice(index, 1);
- $scope.internalView = {
- clause: false,
- edit: "add"
- };
- $scope.$emit('WIZARD_CLAUSE_RELOAD', $scope.list);
- }
- };
-
- $scope.reloadNewObj = function() {
- $scope.newClauseObj = GBPClauseServices.createObj();
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedClause = selectedObj;
- $scope.newClauseObj = selectedObj;
- $scope.internalView.clause = true;
- };
-
- $scope.showForm = function() {
- $scope.reloadNewObj();
- $scope.internalView.clause = true;
- $scope.internalView.edit = "add";
- $scope.selectedClause = null;
- };
-
- $scope.close = function(){
- $scope.internalView.clause = false;
- $scope.internalView.edit = "view";
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedClause ) {
- $scope.internalView.clause = true;
- $scope.internalView.edit = "edit";
- angular.copy($scope.selectedClause, $scope.newClauseObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('WIZARD_SUBJECT_RELOAD',function(){
- $scope.init();
- });
- }]);
-
- gbpOld.register.controller('wizardActionRefCtrl', ['$scope','GBPActionRefsServices', 'GBPActionInstanceServices', '$filter', function($scope, GBPActionRefsServices, GBPActionInstanceServices, $filter){
- $scope.list = [];
- $scope.selectedActionRef = null;
- $scope.newActionRefObj = GBPActionRefsServices.createObj();
- $scope.displayLabel = 'name';
- $scope.internalView = {
- actionRef : false,
- edit : "view"
- };
- $scope.crudLabel = 'Action ref list';
-
- $scope.actionInstanceNames = {'options' : [], 'labels' : $scope.displayLabel};
-
- var path = null,
- mandatoryProperties = ['order'],
-
- actionInstanceNamesLoad = function() {
- if($scope.tenant) {
- var actionInstancePath = GBPActionInstanceServices.createPathObj($scope.tenant.id);
- GBPActionInstanceServices.load(actionInstancePath, function(data){
- $scope.actionInstanceNames.options = data;
- },function(){
- //TODO: error cbk
- });
- }
- },
-
- clear = function(){
- $scope.list = [];
- $scope.selectedActionRef = null;
- $scope.newActionRefObj = GBPActionRefsServices.createObj();
- $scope.internalView = {
- actionRef : false,
- edit : "view"
- };
- };
-
- $scope.init = function() {
- actionInstanceNamesLoad();
- };
-
- $scope.save = function(){
- $scope.updateList($scope.list, $scope.newActionRefObj, "name");
- $scope.reload($scope.newActionRefObj);
- $scope.$emit('WIZARD_ACTIONREF_RELOAD', $scope.list);
- $scope.$broadcast('EV_SET_SEL_CLASS', $scope.newActionRefObj);
- };
-
- $scope.delete = function() {
- if($scope.selectedActionRef) {
- var index = $scope.list.indexOf($scope.selectedActionRef);
- $scope.list.splice(index, 1);
- $scope.internalView = {
- actionRef: false,
- edit: "add"
- };
- $scope.$emit('WIZARD_ACTIONREF_RELOAD', $scope.list);
- }
- };
-
- $scope.reloadNewObj = function() {
- $scope.newActionRefObj = GBPActionRefsServices.createObj();
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedActionRef = selectedObj;
- $scope.newActionRefObj = selectedObj;
- $scope.internalView.actionRef = true;
- };
-
- $scope.showForm = function() {
- $scope.reloadNewObj();
- $scope.internalView.actionRef = true;
- $scope.internalView.edit = "add";
- $scope.selectedActionRef = null;
- };
-
- $scope.close = function(){
- $scope.internalView.actionRef = false;
- $scope.internalView.edit = "view";
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedActionRef ) {
- $scope.internalView.actionRef = true;
- $scope.internalView.edit = "edit";
- angular.copy($scope.selectedActionRef, $scope.newActionRefObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('WIZARD_RULE_RELOAD',function(){
- $scope.init();
- });
- }]);
-
- gbpOld.register.controller('wizardClassifierRefCtrl', ['$scope','GBPClassifierRefsServices', 'GBPClassifierInstanceServices', '$filter', function($scope, GBPClassifierRefsServices, GBPClassifierInstanceServices, $filter){
- $scope.list = [];
- $scope.selectedClassifierRef = null;
- $scope.newClassifierRefObj = GBPClassifierRefsServices.createObj();
- $scope.displayLabel = 'name';
- $scope.internalView = {
- classifierRef : false,
- edit : "view"
- };
-
- $scope.instanceNames = {'options' : [], 'labels' : $scope.displayLabel};
-
- $scope.formDirections = ['in', 'out', 'bidirectional'];
- $scope.formConnectionTracking = ['normal', 'reflexive'];
-
- $scope.crudLabel = 'Classifier ref list';
-
- var path = null,
-
- instanceNamesLoad = function() {
- if($scope.tenant) {
- var classifierInstancePath = GBPClassifierInstanceServices.createPathObj($scope.tenant.id);
- GBPClassifierInstanceServices.load(classifierInstancePath, function(data){
- $scope.instanceNames.options = data;
- },function(){
- //TODO: error cbk
- });
- }
- },
-
- clear = function(){
- $scope.list = [];
- $scope.selectedClassifierRef = null;
- $scope.newClassifierRefObj = GBPClassifierRefsServices.createObj();
- $scope.internalView = {
- classifierRef : false,
- edit : "view"
- };
- };
-
- $scope.init = function() {
- instanceNamesLoad();
- };
-
- $scope.save = function(){
- $scope.updateList($scope.list, $scope.newClassifierRefObj, "name");
- $scope.reload($scope.newClassifierRefObj);
- $scope.$emit('WIZARD_CLASREF_RELOAD', $scope.list);
- $scope.$broadcast('EV_SET_SEL_CLASS', $scope.newClassifierRefObj);
- };
-
- $scope.delete = function() {
- if($scope.selectedClassifierRef) {
- var index = $scope.list.indexOf($scope.selectedClassifierRef);
- $scope.list.splice(index, 1);
- $scope.internalView = {
- classifierRef: false,
- edit: "add"
- };
- $scope.$emit('WIZARD_CLASREF_RELOAD', $scope.list);
- }
- };
-
- $scope.reloadNewObj = function() {
- $scope.newClassifierRefObj = GBPClassifierRefsServices.createObj();
- };
-
- $scope.reload = function(selectedObj) {
- $scope.selectedClassifierRef = selectedObj;
- $scope.newClassifierRefObj = selectedObj;
- $scope.internalView.classifierRef = true;
- };
-
- $scope.showForm = function() {
- $scope.reloadNewObj();
- $scope.internalView.classifierRef = true;
- $scope.internalView.edit = "add";
- $scope.selectedClassifierRef = null;
- };
-
- $scope.close = function(){
- $scope.internalView.classifierRef = false;
- $scope.internalView.edit = "view";
- };
-
- $scope.$on('PGN_EDIT_ELEM', function(event){
- if (!event.defaultPrevented) {
- if ( $scope.selectedClassifierRef ) {
- $scope.internalView.classifierRef = true;
- $scope.internalView.edit = "edit";
- angular.copy($scope.selectedClassifierRef, $scope.newClassifierRefObj);
- }
- event.defaultPrevented = true;
- }
- });
-
- $scope.$on('WIZARD_RULE_RELOAD',function(){
- $scope.init();
- });
- }]);
-
- gbpOld.register.controller('rendererStateCtrl', ['$scope', 'GPBServices', function($scope, GPBServices){
- $scope.data = {'subject-feature-definitions' : {}};
- $scope.view_path = 'src/app/gbp-old/views/governance';
-
- var init = function(){
- GPBServices.getDefinitions(function(classifiersDefs, actionsDefs){
- $scope.data['subject-feature-definitions']['classifier-definition'] = classifiersDefs;
- $scope.data['subject-feature-definitions']['action-definition'] = actionsDefs;
- }, function(){
- //error
- });
- };
-
- init();
- }]);
-
- gbpOld.register.controller('layerCtrl', ['$scope', function($scope){
-
- var moveOffset = 1;
- $scope.currentDisplayIndex = 1;
- $scope.displayOffsets = [-1, 0, 1];
- $scope.expanded = true;
-
- $scope.init = function(key, value){
- $scope.data = value;
- if($scope.checkData(value, 'Array')){
- $scope.setActData($scope.data[$scope.data.length - 1]);
- }
- };
-
- $scope.toggleExpanded = function(){
- $scope.expanded = !$scope.expanded;
- };
-
- $scope.shiftDisplayNext = function() {
- $scope.currentDisplayIndex = Math.min($scope.currentDisplayIndex + moveOffset, $scope.data.length - 2);
- };
-
- $scope.shiftDisplayPrev = function() {
- $scope.currentDisplayIndex = Math.max($scope.currentDisplayIndex - moveOffset, 1);
- };
-
- $scope.showPrevButton = function() {
- return $scope.currentDisplayIndex > 1;
- };
-
- $scope.showNextButton = function() {
- return $scope.data && $scope.currentDisplayIndex < $scope.data.length - 2;
- };
-
- $scope.setActData = function(data) {
- $scope.actSelected = data;
- };
-
- $scope.checkData = function(data, type){
- var result = {'Array' : data instanceof Array,
- 'Object' : data instanceof Object};
-
- return result[type];
- };
- }]);
-
- gbpOld.register.controller('actionReferenceWizardCtrl', ['$scope', '$filter', 'GBPRuleServices', 'GBPActionInstanceServices', function($scope, $filter, GBPRuleServices, GBPActionInstanceServices){
- $scope.wizardPage = null;
- $scope.path = {};
- $scope.rule = {};
-
- $scope.actionInstanceNames = {'options' : [], 'labels' : "name"};
-
- var actionInstanceNamesLoad = function() {
- var actionInstancePath = GBPActionInstanceServices.createPathObj($scope.selectedTenant.id);
- GBPActionInstanceServices.load(actionInstancePath, function(data){
- $scope.actionInstanceNames.options = data;
- },function(){
- //TODO: error cbk
- });
- };
-
- $scope.init = function() {
- $scope.setPage('reference');
- };
-
- $scope.setPage = function(pageName, object) {
- $scope.wizardPage = pageName;
- };
-
- $scope.submit = function() {
- //if($scope.validateForm($scope.actionsForm)){
- $scope.actionInstanceNames.options.forEach(function(i) {
- path = GBPActionInstanceServices.createPathObj($scope.path.tenantId, i.name);
- //saveParams();
-
- GBPActionInstanceServices.send(path, i, function(data){
- $scope.sendReloadEventFromRoot('GBP_ACTION_INSTANCE_RELOAD');
- }, function(){
- //TODO: error cbk
- });
- });
-
- //}
-
- //if($scope.validateForm($scope.rulesForm)){
- path = GBPRuleServices.createPathObj($scope.path.tenantId, $scope.path.contractId, $scope.path.subjectId, $scope.path.ruleId);
- GBPRuleServices.send(path, $scope.rule, function(data){
-
- $scope.wizards.actionReferenceWizard = false;
-
- //$scope.sendReloadEventFromRoot('GBP_TENANT_RELOAD');
- }, function(){
- //TODO: error cbk
- });
- //}
- //$scope.
- };
-
- $scope.$on('ACTION_RULE_WIZARD_LOAD', function(event, data){
- $scope.rule = angular.copy(data.data);
- $scope.path = data.path;
- });
-
- $scope.$on('WIZARD_ACTIONREF_ADD', function(event, data){
- if(!$scope.rule['action-ref']) {
- $scope.rule['action-ref'] = [];
- }
- $scope.updateList($scope.rule['action-ref'], data, "name");
- });
-
- $scope.$on('WIZARD_ACTIONREF_DELETE', function(event, data){
- $scope.rule['action-ref'].splice(data, 1);
- });
-
- $scope.$on('WIZARD_ACTIONINSTANCE_ADD', function(event, data){
- $scope.updateList($scope.actionInstanceNames.options, data, "name");
-
- $scope.setPage('reference');
- });
-
- $scope.$on('GBP_TENANT_RELOAD',function(){
- actionInstanceNamesLoad();
- });
-
- }]);
-
- gbpOld.register.controller('actionsRefListCtrl', ['$scope', '$filter', function($scope, $filter){
-
- $scope.actionReferenceForm = false;
-
- $scope.showForm = function(object) {
- $scope.actionReferenceForm = true;
- $scope.newActionRefObj = object || null;
- };
-
- $scope.closeForm = function() {
- $scope.actionReferenceForm = false;
- };
-
- $scope.save = function(){
- $scope.$emit('WIZARD_ACTIONREF_ADD', $scope.newActionRefObj);
- $scope.resetObject();
- };
-
- $scope.deleteElemAt = function(index) {
- $scope.$emit('WIZARD_ACTIONREF_DELETE', index);
- $scope.resetObject();
- };
-
- $scope.resetObject = function() {
- $scope.newActionRefObj = null;
- };
-
-
-
- }]);
-
- gbpOld.register.controller('actionInstanceWizardCtrl', ['$scope', '$filter', 'GPBServices', 'GBPActionInstanceServices', function($scope, $filter, GPBServices, GBPActionInstanceServices){
- $scope.actionDefinitions = {'options' : [], 'labels' : "name"};
- $scope.newActionObj = GBPActionInstanceServices.createObj();
-
- var loadDefinitions = function() {
- GPBServices.getDefinitions(function(classifierDefs, actionDefs) {
- $scope.actionDefinitions.options = actionDefs;
- //$scope.getDisplayLabelsFromCtrl('GBP_ACTIONS_LABEL', $scope.actionDefinitions);
- });
- };
-
- $scope.reloadDefs = function(){
- $scope.defs = angular.copy($scope.getDefinitionObjParams($scope.newActionObj['action-definition-id']));
-
- //TODO: rework
- if($scope.defs.length && $scope.defs[0].name === 'sfc-chain-name') {
- GPBServices.getServiceFunctionChains(function(data) {
- $scope.serviceFunctionChains = data;
- });
- }
- };
-
- $scope.getDefinitionObjParams = function(id){
- return GPBServices.getDefinitionObjParams($scope.actionDefinitions.options, id);
- };
-
- $scope.save = function(){
- $scope.newActionObj['parameter-value'] = [];
- $scope.$broadcast('GBP_SAVE_PARAM');
- $scope.$emit('WIZARD_ACTIONINSTANCE_ADD', $scope.newActionObj);
- $scope.resetObject();
- };
-
- $scope.resetObject = function() {
- $scope.newActionObj = GBPActionInstanceServices.createObj();
- };
-
- $scope.saveParam = function() {
-
- };
-
- $scope.addParam = function(name, type, value) {
- $scope.newActionObj['parameter-value'].push(GPBServices.createParamObj(name, type, value));
- };
-
- loadDefinitions();
-
- }]);
-
-});
-
-
+++ /dev/null
-.pl0 {
- padding-left: 0 !important;
-}
-.pr0 {
- padding-right: 0 !important;
-}
-.mt10 {
- margin-top: 10px;
-}
-.mt20 {
- margin-top: 20px;
-}
-.mt30 {
- margin-top: 30px;
-}
-.mt40 {
- margin-top: 40px;
-}
-.mb50 {
- margin-bottom: 50px;
-}
-.mb0 {
- margin-bottom: 0px !important;
-}
-.ml10 {
- margin-left: 10px !important;
-}
-.ml20 {
- margin-left: 20px !important;
-}
-.ml30 {
- margin-left: 30px !important;
-}
-.maxHeight500 {
- max-height: 500px;
- overflow-y: scroll;
-}
-.gbpGlobalWrapper {
- background: #f5f5f5;
- margin-bottom: 0!important;
- min-height: 100%;
- padding-bottom: 60px;
-}
-.gbpGlobalWrapper span,
-.gbpGlobalWrapper label {
- color: #393939;
-}
-.gbpGlobalWrapper h2 {
- color: #666;
-}
-.gbpGlobalWrapper .form-control,
-.gbpGlobalWrapper .main input[type="text"] {
- background: #fff;
- color: #858585;
-}
-.gbpGlobalWrapper .form-control[disabled],
-.gbpGlobalWrapper .main input[type="text"][disabled] {
- background: #eeeeee;
-}
-.gbpGlobalWrapper .form-control.narrow-input-left {
- width: 45%;
- float: left;
-}
-.gbpGlobalWrapper .form-control.narrow-input-right {
- width: 45%;
- float: right;
-}
-.gbpGlobalWrapper .row-param {
- margin-bottom: 15px;
- float: left;
-}
-.gbpGlobalWrapper .param-label {
- width: 100%;
- float: left;
-}
-.gbpGlobalWrapper .ep-filter {
- margin-bottom: 20px;
-}
-.gbpGlobalWrapper .ep-filter DIV {
- width: 48%;
-}
-.gbpGlobalWrapper .float-left {
- float: left;
-}
-.gbpGlobalWrapper .float-right {
- float: right;
-}
-.gbpGlobalWrapper .full-width {
- width: 100%;
-}
-.gbpGlobalWrapper .full-width .btn {
- width: 50px;
-}
-.gbpGlobalWrapper .full-width label {
- margin-top: 10px;
-}
-.gbpWrapper .btn-primary {
- color: #ffffff;
- background-color: #428bca;
- border-color: #357ebd;
- font-weight: normal;
-}
-.gbpWrapper .btn-primary:hover {
- background-color: #1BAAFD;
- border-color: #1BAAFD;
-}
-.gbpWrapper .btn-primary.bottom-buttons {
- bottom: 0;
- position: absolute;
- margin-bottom: 0 !important;
- background-color: #FF7300;
- border-color: #FF7300;
- width: 45%;
-}
-.gbpWrapper .btn-primary.bottom-buttons.back {
- right: 0;
- margin-right: 15px;
-}
-.gbpWrapper .btn-primary.bottom-buttons.home {
- left: 0;
- margin-left: 15px;
-}
-.gbpWrapper .btn-primary.bottom-buttons:hover {
- background-color: #FF8f33;
- border-color: #FF8f33;
-}
-.gbpWrapper .btn-primary.bottom-buttons.full-width {
- width: calc(100% - 30px);
- left: 0;
- margin-left: 15px;
-}
-.gbpWrapper .btn-primary.bottom-buttons.wizard-button {
- bottom: 40px;
-}
-.gbpWrapper .btn-primary.btn-big {
- padding: 20px;
- font-size: 1.5em;
- white-space: normal;
-}
-.gbpWrapper .noPadding {
- padding: 0!important;
-}
-.gbpWrapper .basicLabel {
- padding: 0;
- font-weight: normal;
-}
-.gbpWrapper .rowWrapper {
- margin-bottom: 5px;
-}
-.gbpWrapper .inline-block {
- display: inline-block;
-}
-.gbpWrapper #graph {
- overflow: auto;
- width: 100%;
- height: 100%;
-}
-.gbpWrapper .graphWrapper {
- position: relative;
-}
-.gbpWrapper .graphWrapper .controlPanelButtons {
- position: absolute;
- top: 50px;
- right: 0px;
-}
-.gbpWrapper .graphWrapper .controlPanelButtons .line {
- margin: 5px 0;
-}
-.gbpWrapper .graphWrapper .btn {
- min-width: 22px;
- line-height: 22px;
- text-align: center;
- padding: 0!important;
-}
-.gbpWrapper .simpleBox {
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
- -ms-border-radius: 5px;
- -o-border-radius: 5px;
- border-radius: 5px;
- border: 1px solid #e5e5e5;
- background: #fff;
- padding: 20px;
-}
-.gbpWrapper .simpleBox h2 {
- margin-top: 0;
-}
-.gbpWrapper .sectionTitle {
- padding: 20px;
-}
-.gbpWrapper .sectionTitle label {
- font-size: 25px;
-}
-.gbpWrapper .legendBox {
- position: absolute;
- top: 50px;
- right: 50px;
- z-index: 10;
-}
-.gbpWrapper .legendBox ul {
- padding: 0;
- list-style: none;
-}
-.gbpWrapper .legendBox ul .item {
- padding-top: 5px;
- margin-bottom: 10px;
-}
-.gbpWrapper .legendBox ul .line {
- display: -moz-inline-stack;
- display: inline-block;
- vertical-align: top;
- zoom: 1;
- *display: inline;
- margin: 9px 5px 0 0;
- width: 50px;
-}
-.gbpWrapper .legendBox ul .line.blue {
- border-top: 2px solid blue;
-}
-.gbpWrapper .legendBox ul .line.green {
- border-top: 2px solid green;
-}
-.gbpWrapper .mainNavigationWrapper {
- padding-bottom: 50px;
- overflow-x: scroll;
-}
-.gbpWrapper .mainNavigation {
- padding-top: 5%;
- min-width: 1450px;
-}
-.gbpWrapper .mainNavigation .topButtonsWrapper,
-.gbpWrapper .mainNavigation .bottomButtonsWrapper {
- text-align: center;
- width: 400px;
- margin: 0 auto 15px;
- padding: 0 0 20px;
- border-bottom: 5px solid #393939;
-}
-.gbpWrapper .mainNavigation .bottomButtonsWrapper {
- border-bottom: 0;
- border-top: 5px solid #393939;
- padding: 20px 0 0;
- margin: 15px auto 0;
-}
-.gbpWrapper .mainNavigation .middleButtonsWrapper {
- text-align: center;
-}
-.gbpWrapper .mainNavigation .middleButtonsWrapper .buttonWrapper {
- margin-top: 25px;
-}
-.gbpWrapper .mainNavigation .middleButtonsWrapper .iconWrapper {
- display: -moz-inline-stack;
- display: inline-block;
- vertical-align: top;
- zoom: 1;
- *display: inline;
- padding-top: 10px;
-}
-.gbpWrapper .mainNavigation .middleBox {
- display: -moz-inline-stack;
- display: inline-block;
- vertical-align: top;
- zoom: 1;
- *display: inline;
- width: 500px;
- height: 150px;
- border-left: 5px solid #393939;
- border-right: 5px solid #393939;
-}
-.gbpWrapper .mainNavigation .middleBox .infinityIcon {
- background: transparent url('../../src/app/gbp/images/infinity-loop.tpl.html') no-repeat center center;
- width: 128px;
- height: 128px;
- margin: 11px auto 0;
- cursor: pointer;
-}
-.gbpWrapper .mainNavigation .buttonWrapper {
- text-align: center;
- display: -moz-inline-stack;
- display: inline-block;
- vertical-align: top;
- zoom: 1;
- *display: inline;
-}
-.gbpWrapper .mainNavigation .buttonWrapper .btn-primary {
- font-size: 2em;
- padding: 25px 0;
- width: 350px;
- display: -moz-inline-stack;
- display: inline-block;
- vertical-align: top;
- zoom: 1;
- *display: inline;
-}
-.gbpWrapper .mainNavigation .buttonWrapper .icon-large:before {
- font-size: 5em;
-}
-.gbpWrapper aside.col-md-3 {
- min-height: 800px;
-}
-.gbpWrapper aside.col-md-3 .inWrapper {
- height: 100%;
-}
-.gbpWrapper .panelWrapper {
- padding: 20px 0 50px;
- height: calc(100% - 109px);
-}
-.gbpWrapper .panelWrapper.no-padd-top {
- padding-top: 0px;
-}
-.gbpWrapper .panelWrapper button.btn {
- margin-bottom: 5px;
-}
-.gbpWrapper .panelWrapper button.btn-list {
- margin-top: 25px;
-}
-.gbpWrapper .panelWrapper button.btn-default:hover {
- background-color: #e6e6e6 !important;
-}
-.gbpWrapper .panelWrapper button.btn-default:focus {
- background-color: #fff;
-}
-.gbpWrapper .panelWrapper button.activated,
-.gbpWrapper .panelWrapper button.activated:focus {
- background-color: #e6e6e6 !important;
-}
-.gbpWrapper .breadcrumbs {
- padding: 10px 0px;
- font-weight: bold;
- border: 0;
- line-height: initial;
-}
-.gbpWrapper section.sigmaWrapper div.legend {
- margin-bottom: 25px;
-}
-.gbpWrapper section.sigmaWrapper div.legend span,
-.gbpWrapper section.sigmaWrapper div.legend .text {
- color: #fff;
-}
-.gbpWrapper section.sigmaWrapper div.legend ul {
- padding: 0;
- margin: 0;
- list-style: none;
-}
-.gbpWrapper section.sigmaWrapper div.legend li {
- margin-bottom: 5px;
-}
-.gbpWrapper section.sigmaWrapper div.legend li .textHidden {
- display: none;
-}
-.gbpWrapper section.sigmaWrapper div.legend li .text {
- margin-left: 10px;
- line-height: 18px;
-}
-.gbpWrapper section.sigmaWrapper div.legend li .showChckbx {
- position: relative;
- top: 2px;
- left: 5px;
-}
-.gbpWrapper section.sigmaWrapper div.legend li .itemWrapper:hover .text {
- display: block !important;
-}
-.gbpWrapper section.sigmaWrapper div.legend div.color {
- /*margin-right: 15px;*/
- width: 18px;
- height: 18px;
- -webkit-border-radius: 9px;
- border-radius: 9px;
- cursor: pointer;
-}
-.gbpWrapper #graph-container {
- padding: 0;
- height: 800px;
-}
-.gbpWrapper .selectWrapper {
- padding-left: 0;
-}
-.gbpWrapper .selectWrapper.col-md-12 {
- padding: 0;
- margin-bottom: 5px;
-}
-.gbpWrapper .inputWrapper.leftInput {
- padding-left: 0;
-}
-.gbpWrapper .inputWrapper.rightInput {
- padding-right: 0;
-}
-.gbpWrapper .separator {
- padding-bottom: 10px;
- margin-top: 15px;
- height: 1px;
- padding-left: 0px;
- padding-right: 15px;
-}
-.gbpWrapper .inner-separator {
- border-bottom: 1px solid #858585;
- width: 100%;
- float: left;
-}
-.gbpWrapper .btn-group {
- padding: 0;
-}
-.gbpWrapper .formWrapper {
- margin: 20px 0;
-}
-.gbpWrapper .icon-remove.align-right {
- float: right;
-}
-.gbpWrapper .icon-remove.align-right.padding {
- margin: 5px 5px 0 0;
-}
-.gbpWrapper .icon-exclamation-sign.red {
- color: red;
-}
-.gbpWrapper .sigmaWrapper {
- position: relative;
-}
-.gbpWrapper .sigmaWrapper .sigmaModalWrapper {
- position: absolute;
- top: 30px;
- left: 45px;
- z-index: 1;
-}
-.gbpWrapper .sigmaWrapper .sigmaModalWrapper .icon-remove {
- position: absolute;
- top: 5px;
- right: 5px;
-}
-.gbpWrapper .sigmaWrapper .sigmaModalWrapper .tableWrapper {
- position: relative;
- background: #f5f5f5;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
- -ms-border-radius: 5px;
- -o-border-radius: 5px;
- border-radius: 5px;
- min-width: 400px;
- min-height: 100px;
- margin-top: 20px;
- padding: 20px;
-}
-.gbpWrapper .sigmaWrapper .sigmaModalWrapper .tableWrapper .dataWrapper {
- overflow-y: scroll;
- max-height: 350px;
-}
-.gbpWrapper .sigmaWrapper .sigmaModalWrapper .tableWrapper .rowWrapper {
- padding: 10px;
- margin-bottom: 10px;
- -webkit-border-radius: 5px;
- -moz-border-radius: 5px;
- -ms-border-radius: 5px;
- -o-border-radius: 5px;
- border-radius: 5px;
- border: 1px solid #d5d5d5;
-}
-.modal-dialog {
- z-index: 100;
- height: 700px;
- width: 700px;
- background-color: white;
- position: fixed;
- opacity: 1;
- top: 50%;
- left: 50%;
- margin: -350px 0 0 -400px;
-}
-.modal-dialog .modal-header {
- height: 70px;
- padding: 10px 15px;
-}
-.modal-dialog .modal-navigation {
- float: left;
- width: 150px;
- height: 630px;
- border-right: 1px solid #e5e5e5;
- background-color: #eeeeee;
-}
-.modal-dialog .modal-navigation ul {
- -webkit-padding-start: 0;
- list-style-type: none;
-}
-.modal-dialog .modal-navigation ul li.navigation-item {
- height: 54px;
- width: 100%;
- background-color: #eeeeee;
- color: #666;
- font-weight: bold;
- padding: 20px;
-}
-.modal-dialog .modal-navigation ul li.navigation-item.selected {
- background-color: #428bca;
- border-color: #357ebd;
- color: #ffffff;
-}
-.modal-dialog .modal-content-container {
- float: right;
- width: 550px;
- height: 630px;
-}
-.modal-dialog .modal-content-container .content {
- overflow-y: scroll;
- padding: 0 50px 0 20px;
- height: 580px;
-}
-.modal-dialog .modal-content-container .bottom-navigation {
- height: 50px;
- bottom: 0;
- float: right;
- margin: 8px 30px;
-}
-.modal-canvas {
- position: fixed;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- z-index: 10;
- background-color: #000;
- opacity: .15;
-}
-.link-tools .tool-remove {
- display: none;
-}
-.link-tools .tool-options {
- display: none;
-}
-.connection-wrap,
-.marker-arrowheads {
- display: none;
-}/*-------------------YangUI import START-------------------*/
-.gbpWrapper .customContainer {
- border-left: 1px solid #7a7a7a;
- margin: 35px 5px 5px 15px;
- padding: 5px;
- /*z-index: 10;*/
- width: auto;
- position: relative;
-}
-.gbpWrapper .customContainer.withoutBorder {
- border-left: 0;
- padding-bottom: 0;
-}
-.gbpWrapper .customContainer.withoutBorder .treeBullet.containerBullet {
- left: -25px;
- top: -25px;
-}
-.gbpWrapper .topContainerPart {
- margin-left: -19px;
- margin-top: -28px;
- margin-bottom: 10px;
-}
-.gbpWrapper .treeBullet {
- font-size: 25px;
- color: #7a7a7a;
- position: absolute;
- left: -15px;
- top: 0;
-}
-.gbpWrapper .treeBullet.containerBullet {
- top: -25px;
- left: -25px;
-}
-.gbpWrapper .btn-name {
- -webkit-border-radius: 5px;
- border-radius: 5px;
- background: transparent;
- font-weight: bold;
- color: #393939;
- border: 2px solid #393939;
- cursor: auto;
-}
-.gbpWrapper button.yangButton,
-.gbpWrapper div.yangButton {
- cursor: pointer;
- position: relative;
- width: 24px;
- height: 24px;
- border: 0;
- margin: 2px;
- display: -moz-inline-stack;
- display: inline-block;
- vertical-align: top;
- zoom: 1;
- *display: inline;
-}
-.gbpWrapper button.yangButton.iconArrowDown,
-.gbpWrapper div.yangButton.iconArrowDown {
- background: transparent url('images/yang-ui-icons/icon-arrow-down.tpl.html') no-repeat center top;
-}
-.gbpWrapper button.yangButton.iconArrowRight,
-.gbpWrapper div.yangButton.iconArrowRight {
- background: transparent url('images/yang-ui-icons/icon-arrow-right.tpl.html') no-repeat center top;
-}
-.gbpWrapper button.yangButton.iconNext,
-.gbpWrapper div.yangButton.iconNext {
- background: transparent url('images/yang-ui-icons/icon-next.tpl.html') no-repeat center top;
-}
-.gbpWrapper button.yangButton.iconPrev,
-.gbpWrapper div.yangButton.iconPrev {
- background: transparent url('images/yang-ui-icons/icon-prev.tpl.html') no-repeat center top;
-}
-.gbpWrapper button.yangButton:hover,
-.gbpWrapper div.yangButton:hover {
- background-position: center -24px;
-}
-.gbpWrapper button.yangButton.disabled,
-.gbpWrapper div.yangButton.disabled {
- -ms-filter: 'progid:DXImageTransform.Microsoft.Alpha(Opacity= 40 )' !important;
- filter: alpha(opacity= 40 ) !important;
- -moz-opacity: 0.4 !important;
- -khtml-opacity: 0.4 !important;
- opacity: 0.4 !important;
-}
-.gbpWrapper button.yangButton.disabled:hover,
-.gbpWrapper div.yangButton.disabled:hover {
- background-position: center top;
-}
-.gbpWrapper .btn-slim {
- padding-top: 2px;
- padding-bottom: 2px;
-}
-.gbpWrapper .inlineBlock {
- display: -moz-inline-stack;
- display: inline-block;
- vertical-align: top;
- zoom: 1;
- *display: inline;
-}
-.gbpWrapper .leaf {
- margin: 5px;
- padding-left: 5px;
- position: relative;
-}
-.gbpWrapper .leaf-label {
- margin-right: 10px;
- font-weight: bold;
- display: -moz-inline-stack;
- display: inline-block;
- vertical-align: top;
- zoom: 1;
- *display: inline;
- /*width: 170px;*/
- padding-top: 6px;
-}
-.gbpWrapper .leaf-label button.iconQuestion {
- margin-top: -2px;
-}
-.gbpWrapper .leaf-label i.icon-key {
- font-size: 1.3em;
- padding-left: 5px;
-}
-.gbpWrapper .clear {
- clear: both;
-}
-.gbpWrapper .borderArrow {
- color: #393939;
- position: absolute;
- bottom: -6px;
- left: -6px;
- font-size: 1.3em;
-}
-.gbpWrapper .tooltip-inner {
- color: #fff;
- white-space: pre-wrap;
- /* CSS3 */
- white-space: -moz-pre-wrap;
- /* Firefox */
- white-space: -pre-wrap;
- /* Opera <7 */
- white-space: -o-pre-wrap;
- /* Opera 7 */
- word-wrap: break-word;
- /* IE */
-}
-/*-------------------YangUI import END-------------------*/
-/*
--------------------JointJS Graph START-------------------
-.html-element {
- position: absolute;
- background: #3498DB;
- pointer-events: none;
- -webkit-user-select: none;
- border-radius: 4px;
- border: 2px solid #2980B9;
- box-shadow: inset 0 0 5px black, 2px 2px 1px gray;
- padding: 5px;
- box-sizing: border-box;
- z-index: 2;
- pointer-events: auto;
- bottom: 0;
- left: 0;
- right: 0;
- color: #333;
- height: 16px;
- margin-top: 107px;
- margin-left: 16px;
- width: 50px !important;
- height: 20px !important;
-}
--------------------JointJS Graph END-------------------
-*/
-/*GBP END*/
-
-.gbpWrapper .btn-like-tab {
- text-decoration: none;
- color: #464646;
- border: 0;
- line-height: 32px;
- padding: 0 15px;
- background: transparent !important;
- border-bottom: 3px solid transparent;
- margin: 0 10px;
- -webkit-border-radius: 0;
- -moz-border-radius: 0;
- -ms-border-radius: 0;
- -o-border-radius: 0;
- border-radius: 0;
- -webkit-transition: 150ms;
- transition: 150ms;
- -webkit-transition: all 150ms linear;
- -moz-transition: all 150ms linear;
- -ms-transition: all 150ms linear;
- -o-transition: all 150ms linear;
- transition: all 150ms linear;
-}
-.gbpWrapper .btn-like-tab.btn-selected,
-.gbpWrapper .btn-like-tab:hover {
- border-bottom: 3px solid #1baafd;
- background: transparent !important;
-}
-
-.gbpWrapper h1, .gbpWrapper h2, .gbpWrapper h3 {
- color: #393939;
-}
-
-#page_logo {
- display:none;
-}
-
-
+++ /dev/null
-/*GBP*/
-.pl0{padding-left: 0!important};
-.pr0{padding-right: 0!important};
-
-.mt10{margin-top: 10px};
-.mt20{margin-top: 20px};
-.mt30{margin-top: 30px};
-.mt40{margin-top: 40px};
-
-.mb50{margin-bottom: 50px};
-.mb0{margin-bottom: 0px!important};
-
-.ml10{margin-left: 10px!important};
-.ml20{margin-left: 20px!important};
-.ml30{margin-left: 30px!important};
-
-.maxHeight500{
- max-height: 500px;
- overflow-y: scroll;
-}
-
-.gbpGlobalWrapper{
- background: #f5f5f5;
- margin-bottom: 0!important;
- min-height: 100%;
- padding-bottom: 60px;
-
- span, label {
- color: #393939;
- }
-
- h2{
- color: #666;
- }
-
- .form-control, .main input[type="text"]{
- background: #fff;
- color: #858585;
-
- &[disabled]{
- background: #eeeeee;
- }
- }
-
-
- .form-control{
- &.narrow-input-left{
- width: 45%;
- float: left;
- }
- &.narrow-input-right{
- width: 45%;
- float: right;
- }
- }
-
- .row-param{
- margin-bottom: 15px;
- float: left;
- }
-
- .param-label{
- width:100%;
- float: left;
- }
-
- .ep-filter{
- margin-bottom: 20px;
- DIV{
- width: 48%;
- }
- }
-
- .float-left{
- float: left;
- }
-
- .float-right{
- float: right;
- }
-
- .full-width{
- width: 100%;
-
- .btn{
- width: 50px;
- }
-
- label{
- margin-top: 10px;
- }
- }
-}
-
-.gbpWrapper{
-
- .btn-primary{
- color: #ffffff;
- background-color: #428bca;
- border-color: #357ebd;
- font-weight: normal;
-
- &:hover {
- background-color: #1BAAFD;
- border-color: #1BAAFD;
- }
-
- &.bottom-buttons {
- bottom: 0;
- position: absolute;
- margin-bottom: 0 !important;
- background-color: #FF7300;
- border-color: #FF7300;
- width: 45%;
-
- &.back {
- right:0;
- margin-right: 15px;
- }
-
- &.home {
- left:0;
- margin-left: 15px;
- }
-
- &:hover {
- background-color: #FF8f33;
- border-color: #FF8f33;
- }
-
- &.full-width{
- width: calc(~'100% - 30px');
- left: 0;
- margin-left: 15px;
- }
-
- &.wizard-button{
- bottom: 40px;
- }
- }
-
- &.btn-big{
- padding: 20px;
- font-size: 1.5em;
- white-space: normal;
- }
- }
-
- .noPadding{
- padding: 0!important;
- }
-
- .basicLabel{
- padding: 0;
- font-weight: normal;
- }
-
- .rowWrapper{
- margin-bottom: 5px;
- }
-
- .inline-block{
- display: inline-block;
- }
-
- #graph{
- overflow: auto;
- width: 100%;
- height: 100%;
- }
-
- .graphWrapper{
- position: relative;
-
- .controlPanelButtons{
- position: absolute;
- top: 50px;
- right: 0px;
-
- .line{
- margin: 5px 0;
- }
- }
-
- .btn{
- min-width: 22px;
- line-height: 22px;
- text-align: center;
- padding: 0!important;
- }
- }
-
- //SIMPLE BOX
- .simpleBox{
- .roundedCorners(5px);
- border: 1px solid #e5e5e5;
- background: #fff;
- padding: 20px;
-
- h2{
- margin-top: 0;
- }
- }
-
- .sectionTitle{
- padding: 20px;
- label{
- font-size: 25px;
- }
- }
-
- //LEGEND BOX
- .legendBox{
- position: absolute;
- top: 50px;
- right: 50px;
- z-index: 10;
- ul{
- padding: 0;
- list-style: none;
-
- .item{
- padding-top: 5px;
- margin-bottom: 10px;
- }
-
- .line{
- .inlineBlock;
- margin: 9px 5px 0 0;
- width: 50px;
-
- &.blue{
- border-top: 2px solid blue;
- }
-
- &.green{
- border-top: 2px solid green;
- }
- }
- }
- }
-
- //MAIN NAVIGATION
- .mainNavigationWrapper{
- padding-bottom: 50px;
- overflow-x: scroll;
- }
- .mainNavigation{
- padding-top: 5%;
- min-width: 1450px;
- .topButtonsWrapper, .bottomButtonsWrapper{
- text-align: center;
- width: 400px;
- margin: 0 auto 15px;
- padding: 0 0 20px;
- border-bottom: 5px solid #393939;
- }
-
- .bottomButtonsWrapper{
- border-bottom: 0;
- border-top: 5px solid #393939;
- padding: 20px 0 0;
- margin: 15px auto 0;
- }
-
- .middleButtonsWrapper{
- text-align: center;
-
- .buttonWrapper{
- margin-top: 25px;
-
- }
-
- .iconWrapper{
- .inlineBlock;
- padding-top: 10px;
- }
- }
-
- .middleBox{
- .inlineBlock;
- width: 500px;
- height: 150px;
- border-left: 5px solid #393939;
- border-right: 5px solid #393939;
-
- .infinityIcon{
- background: transparent url('../../src/app/gbp/images/infinity-loop.tpl.html') no-repeat center center;
- width: 128px;
- height: 128px;
- margin: 11px auto 0;
- cursor: pointer;
- }
- }
-
- .buttonWrapper{
- text-align: center;
- // width: 300px;
- // margin: 0 auto;
- .inlineBlock;
-
- .btn-primary{
- font-size: 2em;
- padding: 25px 0;
- width: 350px;
- .inlineBlock;
- }
-
- .icon-large{
- &:before{
- font-size: 5em;
- }
- }
- }
- }
-
- //RIGHT PANEL
- aside{
- &.col-md-3{
- min-height: 800px;
-
- .inWrapper{
- height: 100%;
- }
- }
- }
-
- .panelWrapper{
- padding: 20px 0 50px;
- height: calc(~'100% - 109px');
- &.no-padd-top{
- padding-top: 0px;
- }
- button{
- &.btn{
- margin-bottom: 5px;
- }
- &.btn-list{
- margin-top: 25px;
- }
- &.btn-default:hover {
- background-color: #e6e6e6 !important;
- }
- &.btn-default:focus {
- background-color: #fff;
- }
- &.activated, &.activated:focus {
- background-color: #e6e6e6 !important;
- }
- }
- }
-
- .breadcrumbs{
- padding: 10px 0px;
- font-weight: bold;
- border: 0;
- line-height: initial;
- }
-
- section.sigmaWrapper {
- div.legend{
- margin-bottom: 25px;
-
- span, .text{
- color: #fff;
- }
-
- ul{
- padding: 0;
- margin: 0;
- list-style: none;
- }
- li{
- margin-bottom: 5px;
- .textHidden{
- display: none;
- }
- .text{
- margin-left: 10px;
- line-height: 18px;
- }
- .showChckbx{
- position: relative;
- top: 2px;
- left: 5px;
- }
- .itemWrapper{
- &:hover{
- .text{
- display: block !important;
- }
- }
- }
-
- }
- div.color{
- /*margin-right: 15px;*/
- width: 18px;
- height: 18px;
- -webkit-border-radius: 9px;
- border-radius: 9px;
- cursor: pointer;
- }
- }
- }
-
- #graph-container{
- // background: transparent;
- padding: 0;
- height: 800px;
- }
-
- .selectWrapper{
- padding-left: 0;
- &.col-md-12{
- padding: 0;
- margin-bottom: 5px;
- }
- }
-
- .inputWrapper{
- &.leftInput{
- padding-left: 0;
- }
-
- &.rightInput{
- padding-right: 0;
- }
- }
-
- .separator{
- padding-bottom: 10px;
- margin-top: 15px;
- height: 1px;
- padding-left: 0px;
- padding-right: 15px;
- }
-
- .inner-separator{
- border-bottom: 1px solid #858585;
- width: 100%;
- float: left;
- }
-
- .btn-group{
- padding: 0;
- }
-
- .formWrapper{
- margin: 20px 0;
- }
-
- .icon-remove {
- &.align-right {
- float: right;
-
- &.padding {
- margin: 5px 5px 0 0;
- }
- }
- }
-
- .icon-exclamation-sign{
- &.red {
- color: red;
- }
- }
-
- .sigmaWrapper{
- position: relative;
-
- .sigmaModalWrapper{
- position: absolute;
- top: 30px;
- left: 45px;
- z-index: 1;
-
- .icon-remove{
- position: absolute;
- top: 5px;
- right: 5px;
- }
-
- .tableWrapper{
- position: relative;
- background: #f5f5f5;
- .roundedCorners(5px);
- min-width: 400px;
- min-height: 100px;
- margin-top: 20px;
- padding: 20px;
-
- .dataWrapper{
- overflow-y: scroll;
- max-height: 350px;
- }
-
- .rowWrapper{
- padding: 10px;
- margin-bottom: 10px;
- .roundedCorners(5px);
- border: 1px solid #d5d5d5;
- }
- }
- }
- }
-}
-
-.modal-dialog {
- z-index: 100;
- height: 700px;
- width: 700px;
- background-color: white;
- position: fixed;
- opacity: 1;
- top:50%;
- left:50%;
- margin:-350px 0 0 -400px;
-
- .modal-header {
- height: 70px;
- padding: 10px 15px;
- }
-
- .modal-navigation {
- float:left;
- width: 150px;
- height: 630px;
- border-right: 1px solid #e5e5e5;
- background-color: #eeeeee;
-
- ul {
- -webkit-padding-start: 0;
- list-style-type: none;
-
- li.navigation-item {
- height: 54px;
- width: 100%;
- background-color: #eeeeee;
- color: #666;
- font-weight: bold;
- padding: 20px;
-
- &.selected {
- background-color: #428bca;
- border-color: #357ebd;
- color: #ffffff;
- }
- }
- }
- }
-
- .modal-content-container {
- float: right;
- width: 550px;
- height: 630px;
-
- .content {
- overflow-y: scroll;
- padding: 0 50px 0 20px;
- height: 580px;
- }
-
- .bottom-navigation {
- height: 50px;
- bottom: 0;
- float: right;
- margin: 8px 30px
- }
- }
-
-
-
-
-}
-
-.modal-canvas {
- position: fixed;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- z-index: 10;
- background-color: #000;
- opacity: .15;
-}
-
-.link-tools .tool-remove { display: none }
-.link-tools .tool-options { display: none }
-.connection-wrap, .marker-arrowheads { display: none }
-
-/*-------------------YangUI import START-------------------*/
-
-@iconsRootPath : 'images/yang-ui-icons/';
-.gbpWrapper{
- .customContainer{
- border-left: 1px solid #7a7a7a;
- margin: 35px 5px 5px 15px;
- padding: 5px;
- /*z-index: 10;*/
- width:auto;
- position: relative;
- &.withoutBorder{
- border-left: 0;
- padding-bottom: 0;
- .treeBullet.containerBullet{
- left: -25px;
- top: -25px;
- }
- }
- }
-
- .topContainerPart{
- margin-left: -19px;
- margin-top: -28px;
- margin-bottom: 10px;
- }
-
- .treeBullet{
- font-size: 25px;
- color: #7a7a7a;
- position: absolute;
- left: -15px;
- top: 0;
- &.containerBullet{
- top: -25px;
- left: -25px;
- }
- }
-
- .btn-name{
- -webkit-border-radius: 5px;
- border-radius: 5px;
- background: transparent;
- font-weight: bold;
- color: @text-color;
- border: 2px solid @text-color;
- cursor: auto;
- }
-
- button, div{
- &.yangButton{
- cursor: pointer;
- position: relative;
- width: 24px;
- height: 24px;
- border: 0;
- margin: 2px;
- .inlineBlock;
- &.iconArrowDown{
- background: transparent url('@{iconsRootPath}icon-arrow-down.png') no-repeat center top;
- }
- &.iconArrowRight{
- background: transparent url('@{iconsRootPath}icon-arrow-right.png') no-repeat center top;
- }
- &.iconNext{
- background: transparent url('@{iconsRootPath}icon-next.png') no-repeat center top;
- }
- &.iconPrev{
- background: transparent url('@{iconsRootPath}icon-prev.png') no-repeat center top;
- }
- &:hover{
- background-position: center -24px;
- }
- &.disabled{
- .opacityDeph(0.4)!important;
- &:hover{
- background-position: center top;
- }
- }
- }
- }
-
- .btn-slim {
- padding-top: 2px;
- padding-bottom: 2px;
- }
-
- .inlineBlock {
- display: -moz-inline-stack;
- display: inline-block;
- vertical-align: top;
- zoom: 1;
- *display: inline;
- }
-
- .leaf {
- margin: 5px;
- padding-left: 5px;
- position: relative;
- }
-
- .leaf-label {
- margin-right: 10px;
- font-weight: bold;
- .inlineBlock;
- /*width: 170px;*/
- padding-top: 6px;
- button.iconQuestion{
- margin-top: -2px;
- }
-
- i.icon-key {
- font-size: 1.3em;
- padding-left: 5px;
- }
- }
-
- .clear{
- clear: both;
- }
-
- .borderArrow{
- color: @text-color;
- position: absolute;
- bottom: -6px;
- left: -6px;
- font-size: 1.3em;
- }
-
- .tooltip-inner{
- color: #fff;
- white-space: pre-wrap; /* CSS3 */
- white-space: -moz-pre-wrap; /* Firefox */
- white-space: -pre-wrap; /* Opera <7 */
- white-space: -o-pre-wrap; /* Opera 7 */
- word-wrap: break-word; /* IE */
- }
-}
-/*-------------------YangUI import END-------------------*/
-
-/*
--------------------JointJS Graph START-------------------
-.html-element {
- position: absolute;
- background: #3498DB;
- pointer-events: none;
- -webkit-user-select: none;
- border-radius: 4px;
- border: 2px solid #2980B9;
- box-shadow: inset 0 0 5px black, 2px 2px 1px gray;
- padding: 5px;
- box-sizing: border-box;
- z-index: 2;
- pointer-events: auto;
- bottom: 0;
- left: 0;
- right: 0;
- color: #333;
- height: 16px;
- margin-top: 107px;
- margin-left: 16px;
- width: 50px !important;
- height: 20px !important;
-}
--------------------JointJS Graph END-------------------
-*/
-
-/*GBP END*/
\ No newline at end of file
+++ /dev/null
-define(['angularAMD', 'app/routingConfig', 'ui-bootstrap', 'Restangular', 'angular-translate-loader-partial'], function() {
-
- var gbpOld = angular.module('app.gbpOld', ['ui.router.state','app.core', 'ui.bootstrap', 'restangular', 'pascalprecht.translate']);
-
- gbpOld.register = gbpOld;
-
- gbpOld.config(function ($stateProvider, $compileProvider, $controllerProvider, $provide, $translateProvider,
- $translatePartialLoaderProvider, NavHelperProvider, $filterProvider) {
-
- //$translatePartialLoaderProvider.addPart('app/gbp/assets/data/locale');
-
- gbpOld.register = {
- directive : $compileProvider.directive,
- controller : $controllerProvider.register,
- filter: $filterProvider.register,
- factory : $provide.factory,
- service : $provide.service
- };
-
- NavHelperProvider.addControllerUrl('app/gbp-old/gbp.controller');
- NavHelperProvider.addToMenu('gbpOld', {
- "link": "#/gbpOld/index",
- "active": "main.gbpOld",
- "title": "GBP old",
- "icon": "icon-level-down",
- "page": {
- "title": "GBP old",
- "description": "GBP old ui"
- }
- });
-
- var access = routingConfig.accessLevels;
- $stateProvider.state('main.gbpOld', {
- url: 'gbpOld',
- abstract: true,
- views : {
- 'content' : {
- templateUrl: 'src/app/gbp-old/views/root.tpl.html'
- }
- }
- });
-
- $stateProvider.state('main.gbpOld.index', {
- url: '/index',
- access: access.admin,
- views: {
- '': {
- controller: 'gbpCtrl',
- templateUrl: 'src/app/gbp-old/views/index.tpl.html'
- }
- }
- });
- });
-
- return gbpOld;
-});
+++ /dev/null
-define(['app/gbp-old/gbp.module', 'app/gbp-old/js/joint.clean.build'], function(gbpOld, joint) {
-
- gbpOld.register.factory('GBPRestangular', function(Restangular, ENV) {
- return Restangular.withConfig(function(RestangularConfig) {
- RestangularConfig.setBaseUrl(ENV.getBaseURL("MD_SAL"));
- });
- });
-
- gbpOld.register.factory('GBPConstants', function() {
- var c = { colors: {'graph' : {}}, strings: {}, jointElements: {}, objType: {}, numbers: {}};
-
- c.strings.flood = 'flood';
- c.strings.bridge = 'bridge';
- c.strings.l3ctx = 'l3ctx';
- c.strings.subnet = 'subnet';
- c.strings.linklabel = 'linklabel';
- c.strings.in = 'in';
- c.strings.out = 'out';
- c.strings.bi = 'bidirectional';
-
- c.strings.config = 'CONFIG';
- c.strings.oper = 'OPERATIONAL';
- c.strings.l2l3 = 'L2L3';
- c.strings.mock = 'MOCK';
- c.strings.sigmaTopoDefaultText = 'SIGMATOPODEFAULTTEXT';
- c.strings.sigmaTopoDefault = 'SIGMATOPODEFAULTTEXT';
-
- c.colors[c.strings.flood] = '#DF0101';
- c.colors[c.strings.bridge] = '#0080FF';
- c.colors[c.strings.l3ctx] = '#3ADF00';
- c.colors[c.strings.subnet] = '#FF9933';
- c.colors[c.strings.sigmaTopoDefaultText] = '#fff';
- c.colors[c.strings.epg] = '#8fde70';
- c.colors[c.strings.linklabel] = '#3366CC';
-
- c.colors[c.strings.flood+'-'+c.strings.bridge] = '#6666FF';
- c.colors[c.strings.bridge+'-'+c.strings.l3ctx] = '#6666FF';
-
- c.colors[c.strings.subnet+'-'] = '#6666FF';
-
- c.colors['graph']['subject'] = '#FFFFD4';
- c.colors['graph']['cns'] = '#8EEDFF';
- c.colors['graph']['pns'] = '#FF9C9C';
-
- c.jointElements.minWidth = 100;
- c.jointElements.maxWidth = 300;
- c.jointElements.minHeight = 50;
- c.jointElements.maxHeight = 300;
-
- c.objType.contract = 'contract';
- c.objType.epg = 'epg';
- c.objType.consumer = 'consumer';
- c.objType.provider = 'provider';
- c.objType.subject = 'subject';
- c.objType.rule = 'rule';
-
- c.numbers.displayLabelLength = 40;
-
- return c;
- });
-
- gbpOld.register.factory('MockServices', function() {
-
- var ms = {};
-
- ms.mockTopoData = function() {
- var lid = 0,
- nodeRaw = [0, 1, 2, 3],
- linkRaw = [[0, 1], [2, 3], [3, 0], [0, 3]],
- nodes = nodeRaw.map(function(data) {
- return {
- 'id': 'n' + data,
- 'label': 'LABEL'+data,
- 'size': 3,
- 'x': Math.random(),
- 'y': Math.random(),
- 'color': GBPConstants.colors[GBPConstants.strings.sigmaTopoDefault]
- };
- }),
- links = linkRaw.map(function(data) {
- var obj = {
- id: 'e' + lid,
- source: 'n' + data[0],
- target: 'n' + data[1],
- color: GBPConstants.colors[GBPConstants.strings.sigmaTopoDefault]
- };
- lid = lid + 1;
- return obj;
- });
-
- return {nodes: nodes, links: links};
- };
-
- return ms;
- });
-
- gbpOld.register.factory('TopologyDataLoaders', function(GBPRestangular, GBPConstants) {
- var tdl = {};
-
- tdl.getSubjectsBetweenEndpointGroups = function(storage, tenantId, successCbk, errorCbk) {
- var restObj = GBPRestangular.one('restconf').one('operations'),
- rpcRes = 'ui-backend:get-subjects-between-endpoint-groups',
- reqData = { "input": { "tenant-id": tenantId }};
-
- if(storage) {
- reqData.input['from-oper-data'] = {};
- }
-
- restObj.post(rpcRes, reqData).then(function(data) {
- // console.info('got data', data.output);
- successCbk(data);
- }, function(res) {
- errorCbk(res);
- });
- };
-
- //Policies are representing links in PGN topology
- tdl.getGroupRulesBetweenEndpointGroups = function(successCbk, errorCbk) {
- var restObj = GBPRestangular.one('restconf').one('operations'),
- rpcRes = 'pgn-application:get-group-rules-between-endpoint-groups',
- reqData = { "input": { "endpoint-group-pair":[] }};
-
- restObj.post(rpcRes, reqData).then(function(data) {
- successCbk(data); //set topology links
- }, function(res) {
- errorCbk(res);
- });
- };
-
- //Groups are representing nodes in PGN topology
- tdl.getEndpointGroups = function(successCbk, errorCbk) {
- var tenantId = getId(idTypes.tenant),
- restObj = GBPRestangular.one('restconf').one('operations'),
- rpcRes = 'pgn-application:get-endpoint-groups',
- reqData = {
- "input": {
- "endpoint-group-id":[
- {
- "pgn-application:tenant-id": tenantId
- }
- ]
- }
- };
-
- restObj.post(rpcRes, reqData).then(function(data) {
- successCbk(data); //set topology nodes
- }, function(res) {
- errorCbk(res);
- });
-
- };
-
- tdl.getEndpointsFromEndpointGroup = function(tenantId, epgId, successCbk, errorCbk) {
- var restObj = GBPRestangular.one('restconf').one('operations'),
- rpcRes = 'ui-backend:get-endpoints-from-endpoint-group',
- reqData = {
- "input": {
- "tenant-id": tenantId,
- "endpoint-group-id":epgId
- }
- };
-
- restObj.post(rpcRes, reqData).then(function(data) {
- successCbk(data); //set topology nodes
- }, function(res) {
- errorCbk(res);
- });
-
- };
-
- tdl.getEpgTopo = function(data){
- var epgData = data.output['endpoint-group-pair-with-subject'],
- nodes = [],
- edges = [],
- setNode = function(obj){
- var nodeObj = {
- 'id': 'n' + nodes.length,
- 'label': obj.name || obj.id,
- 'name': obj.name,
- 'size': 1,
- 'x': Math.random(),
- 'y': Math.random(),
- 'color': GBPConstants.colors[GBPConstants.strings.sigmaTopoDefault],
- 'type': obj.type
- };
-
- nodes.push(nodeObj);
- return nodeObj.id;
- },
- setEdge = function(sourceId, destId, data, direction) {
- var obj = {
- 'id': 'e' + edges.length,
- 'source': sourceId,
- 'target': destId,
- 'color': GBPConstants.colors[GBPConstants.strings.sigmaTopoDefault],
- 'data': data,
- 'direction' : direction
- // 'type': 'curve',
- // 'size' : 100
- };
-
- edges.push(obj);
- },
- getObjByProp = function(val, prop, list) {
- return list.filter(function(i){
- return i[prop] === val;
- });
- },
- getDirection = function(subjects){
- var directions = [];
- if ( subjects ) {
- subjects.forEach(function(s){
- if ( s['ui-rule'] ) {
- s['ui-rule'].forEach(function(rule){
- if ( rule['classifier-ref'] ) {
- rule['classifier-ref'].forEach(function(classifier){
- if ( classifier.direction && directions.indexOf(classifier.direction) === -1 ){
- directions.push(classifier.direction);
- }
- });
- }
- });
- }
- });
- }
- return directions.length === 1 ? directions[0] : directions.length > 1 ? 'bidirectional' : null;
-
- };
-
- if(epgData) {
- epgData.forEach(function(e){
- var cepgnId = null,
- pepgnId = null;
-
- if ( !getObjByProp(e['consumer-endpoint-group-id'],'name', nodes).length ) {
- var objCepg = {
- type: 'epg',
- name: e['consumer-endpoint-group-id']
- };
- cepgnId = setNode(objCepg);
- } else {
- cepgnId = getObjByProp(e['consumer-endpoint-group-id'],'name', nodes)[0].id;
- }
- if ( !getObjByProp(e['provider-endpoint-group-id'],'name', nodes).length ) {
- var objPepg = {
- type: 'epg',
- name: e['provider-endpoint-group-id']
- };
- pepgnId = setNode(objPepg);
- } else {
- pepgnId = getObjByProp(e['provider-endpoint-group-id'],'name', nodes)[0].id;
- }
-
- var direction = getDirection(e['ui-subject']);
-
- if ( cepgnId && pepgnId ) {
- setEdge(cepgnId, pepgnId, e['ui-subject'], direction);
- }
- });
- }
-
- return {
- nodes: nodes,
- links: edges
- };
- };
-
-
- tdl.getL2L3 = function(storage, tenantId, successCbk, errorCbk) {
- //l2-bridge-domain
- var lid = 0,
- nid = 0,
- getL2L3Label = function(node) {
- return node.name || node.id;
- },
- getSubnetLabel = function(node) {
- return node['ip-prefix'] || node.id;
- },
- getNodeColor = function(src) {
- return GBPConstants.colors[src] || GBPConstants.colors[GBPConstants.strings.sigmaTopoDefault];
- },
- getLinkColor = function(from, to) {
- return GBPConstants.colors[from+'-'+to] || GBPConstants.colors[GBPConstants.strings.sigmaTopoDefault];
- },
- getNodes = function(data, srcDesc, getLabelCbk) {
- var nodes = data.map(function(elem) {
- var obj = {
- 'id': 'n' + nid,
- 'label': getLabelCbk(elem),
- 'uuid': elem.id,
- 'size': 3,
- 'x': Math.random(),
- 'y': Math.random(),
- 'color': getNodeColor(srcDesc),
- 'elemType': srcDesc
- };
-
- nid += 1;
- return obj;
- });
-
- return nodes;
- },
- getLinks = function(data, srcNodes, targetNodes, fromDesc, toDesc) {
- var findByUUID = function(array, uuid) {
- return array.filter(function(elem) {
- return elem.uuid === uuid;
- })[0];
- };
-
- var links = data.map(function(elem) {
- var obj = null,
- src = findByUUID(srcNodes, elem.id),
- trg = findByUUID(targetNodes, elem.parent);
-
- if(src && trg) {
- obj = {
- 'id': 'e' + lid,
- 'source': src.id,
- 'target': trg.id,
- 'color': getLinkColor(fromDesc, toDesc)
- };
- lid += 1;
- }
-
- return obj;
- }).filter(function(elem) {
- return elem !== null;
- });
-
- return links;
- };
-
- restObj = GBPRestangular.one('restconf').one(storage).one('policy:tenants').one('tenant').one(tenantId);
-
- restObj.get().then(function(data) {
- var l2FloodNodes = getNodes(data.tenant[0]['l2-flood-domain'] || [], GBPConstants.strings.flood, getL2L3Label),
- l2BridgeNodes = getNodes(data.tenant[0]['l2-bridge-domain'] || [], GBPConstants.strings.bridge, getL2L3Label),
- l3ContextNodes = getNodes(data.tenant[0]['l3-context'] || [], GBPConstants.strings.l3ctx, getL2L3Label),
- subnetNodes = getNodes(data.tenant[0]['subnet'] || [], GBPConstants.strings.subnet, getSubnetLabel),
- l2FloodLinks = getLinks(data.tenant[0]['l2-flood-domain'] || [], l2FloodNodes, l2BridgeNodes, GBPConstants.strings.flood, GBPConstants.strings.bridge),
- l2BridgeLinks = getLinks(data.tenant[0]['l2-bridge-domain'] || [], l2BridgeNodes, l3ContextNodes, GBPConstants.strings.bridge, GBPConstants.strings.l3ctx),
- subnetLinks = getLinks(data.tenant[0]['subnet'] || [], subnetNodes, l2BridgeNodes.concat(l2FloodNodes).concat(l3ContextNodes), GBPConstants.strings.subnet, ''),
- allNodes = l2BridgeNodes.concat(l2FloodNodes).concat(l3ContextNodes).concat(subnetNodes),
- allLinks = l2BridgeLinks.concat(l2FloodLinks).concat(subnetLinks);
-
- successCbk(allNodes, allLinks);
- }, function(res) {
- errorCbk(res.data, res.status);
- });
- };
-
- tdl.getClassifierInstances = function() {
-
- };
-
- return tdl;
- });
-
- gbpOld.register.factory('TopoServices', function(TopologyDataLoaders, MockServices, GBPConstants) {
-
- var ts = {};
-
- var loaders = {};
-
- var legends = {};
-
- var transformPGNTopoNodes = function(data) {
- return data.output['endpoint-group'].map(function(d) {
- return {
- id: d.id,
- group: d.name,
- sgt: d['security-group-tag']
- };
- });
- };
-
- var transformPGNTopoLinks = function(data) {
- return data.output['endpoint-group-pair-with-rules'].map(function(d) {
- return {
- source: d['provider-group-id'],
- target: d['consumer-group-id'],
- policy: d['group-rule'][0]['action-ref'].map(function(r) {
- return r.name;
- })
- };
- });
- };
-
- var gbpLegend = {
- 'epg' : GBPConstants.colors[GBPConstants.strings.sigmaTopoDefault]
- };
-
- legends[GBPConstants.strings.empty] = {};
- legends[GBPConstants.strings.config] = gbpLegend;
- legends[GBPConstants.strings.oper] = gbpLegend;
- legends[GBPConstants.strings.mock] = gbpLegend;
- legends[GBPConstants.strings.l2l3] = {
- 'l2-flood': GBPConstants.colors[GBPConstants.strings.flood],
- 'l2-bridge': GBPConstants.colors[GBPConstants.strings.bridge],
- 'l3-context': GBPConstants.colors[GBPConstants.strings.l3ctx],
- 'subnet': GBPConstants.colors[GBPConstants.strings.subnet],
- 'link': GBPConstants.colors[GBPConstants.strings.subnet+'-']
- };
-
- loaders[GBPConstants.strings.empty] = function(successCbk, errorCbk) {
- successCbk([], []);
- };
-
- loaders[GBPConstants.strings.config] = function(successCbk, errorCbk, args) {
- var storage = args.storage || 'config',
- tenantId = args.tenantId;
-
-
- TopologyDataLoaders.getSubjectsBetweenEndpointGroups(false, tenantId, function(data){
- var topo = TopologyDataLoaders.getEpgTopo(data);
- successCbk(topo.nodes, topo.links);
- //successCbk
- }, errorCbk);
- };
-
- loaders[GBPConstants.strings.oper] = function(successCbk, errorCbk, args) {
- var storage = args.storage || 'config',
- tenantId = args.tenantId;
-
- TopologyDataLoaders.getSubjectsBetweenEndpointGroups(true, tenantId, function(data){
- var topo = TopologyDataLoaders.getEpgTopo(data);
- successCbk(topo.nodes, topo.links);
- //successCbk
- }, errorCbk);
- };
-
- loaders[GBPConstants.strings.l2l3] = function(successCbk, errorCbk, args) {
- var storage = args.storage || 'config',
- tenantId = args.tenantId;
-
- if(storage && tenantId) {
- TopologyDataLoaders.getL2L3(storage, tenantId, successCbk, errorCbk);
- } else {
- //different kind of error
- errorCbk();
- }
- };
-
- loaders[GBPConstants.strings.mock] = function(successCbk, errorCbk) {
- var data = MockServices.mockTopoData();
- successCbk(data.nodes, data.links);
- };
-
- ts.getConsProvLabel = function(edge, topo){
- var provName = '',
- conName = '';
-
- topo.nodes.forEach(function(n){
-
- if ( edge.source === n.id ) {
- provName = n.name;
- }
-
- if ( edge.target === n.id ) {
- conName = n.name;
- }
- });
-
- return provName + ':' + conName;
- };
-
- ts.getLegend = function(type) {
- if(type === null || legends.hasOwnProperty(type) === false) {
- type = GBPConstants.strings.empty;
- }
-
- return legends[type];
- };
-
- ts.loadTopology = function(type, successCbk, errorCbk, args) {
- if(type === null || loaders.hasOwnProperty(type) === false) {
- type = GBPConstants.strings.empty;
- }
-
- loaders[type](successCbk, errorCbk, args);
- };
-
- return ts;
- });
-
- gbpOld.register.factory('GPBServices', function(GBPRestangular) {
-
- var s = {};
-
- s.getDefinitions = function(successCbk, errorCbk) {
- var restObj = GBPRestangular.one('restconf').one('operational').one('policy:subject-feature-definitions');
-
- restObj.get().then(function(data) {
- if(data['subject-feature-definitions']) {
- var classifiersDefs = data['subject-feature-definitions']['classifier-definition'] || [],
- actionsDefs = data['subject-feature-definitions']['action-definition'] || [];
- successCbk(classifiersDefs, actionsDefs);
- } else {
- //TODO log error
- }
- }, function(res) {
- // errorCbk(res);
- });
- };
-
- s.getServiceFunctionChains = function(successCbk, errorCbk) {
- var restObj = GBPRestangular.one('restconf').one('config').one('service-function-chain:service-function-chains');
-
- restObj.get().then(function(data) {
- if(data['service-function-chains']) {
- successCbk(data['service-function-chains']['service-function-chain']);
- } else {
- //TODO log error
- }
- }, function(res) {
- // errorCbk(res);
- });
- };
-
- s.getUUIDnumber = function() {
- var d = new Date().getTime();
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
- var r = (d + Math.random()*16)%16 | 0;
- d = Math.floor(d/16);
- return (c=='x' ? r : (r&0x3|0x8)).toString(16);
- });
- };
-
- s.createRestObj = function(storage) {
- storage = storage || 'config';
- restObj = GBPRestangular.one('restconf').one(storage);
-
- return restObj;
- };
-
- s.send = function(restObj, reqData, successCbk, errorCbk) {
- restObj.customPUT(reqData).then(function(data) {
- successCbk(data);
- }, function(res) {
- errorCbk(res.data, res.status);
- });
- };
-
- s.post = function(restObj, reqData, successCbk, errorCbk) {
- restObj.customPOST(reqData).then(function(data) {
- successCbk(data);
- }, function(res) {
- errorCbk(res.data, res.status);
- });
- };
-
- s.delete = function(restObj, successCbk, errorCbk) {
- restObj.remove().then(function(data) {
- successCbk(data);
- }, function(res) {
- errorCbk(res.data, res.status);
- });
- };
-
- s.load = function(restObj, transformCallback, successCbk, errorCbk) {
- restObj.get().then(function(data) {
- var objs = transformCallback(data) || [];
- successCbk(objs);
- }, function(res) {
- errorCbk(res.data, res.status);
- });
- };
-
- s.stripNullValues = function(obj) {
- Object.keys(obj).forEach(function(k) {
- if(obj[k] === null) {
- delete obj[k];
- }
- });
-
- return obj;
- };
-
- s.removeEmptyElementsFromList = function(list) {
- return list.filter(function(e) {
- return e !== "";
- });
- };
-
- s.createParamObj = function(name, type, value) {
- var obj = { name: name };
-
- obj[type+'-value'] = value;
-
- return obj;
- };
-
- s.getInstanceParamValue = function(param) {
- return param['int-value'] || param['string-value'] || param['range-value'];
- };
-
- s.getDefinitionObjParams = function(defObj, id) {
- var obj = defObj.filter(function(def) {
- return def.id === id;
- })[0],
- params = (obj && obj.parameter) ? obj.parameter : [];
-
- return params;
-
- };
-
- s.getPropFromListByProp = function(list, propSrc, targetValue, propDst) {
- var output = null,
- selectedObj = list.filter(function(e) {
- return e[propSrc] === targetValue;
- })[0];
-
- if(selectedObj) {
- if(propDst) {
- output = selectedObj[propDst];
- } else {
- output = selectedObj;
- }
- }
-
- return output;
- };
-
- return s;
-
- });
-
- gbpOld.register.factory('GBPGovernanceServices', function(TopologyDataLoaders) {
- var s = {};
-
- var subjectInList = function(subjectName, subjectList) {
- return subjectList.some(function(s) {
- return s.name === subjectName;
- });
- };
-
- var EPG = function(epgId, tenantId) {
- this.id = epgId;
- this.tenantId = tenantId;
- };
-
- var Subject = function(name) {
- this.name = name;
- this.rules = [];
- this.providers = [];
- this.consumers = [];
-
- this.addProvider = function(providingEpg) {
- if(this.providers.indexOf(providingEpg) === -1) {
- this.providers.push(providingEpg);
- }
- };
-
- this.addConsumer = function(consumingEpg) {
- if(this.consumers.indexOf(consumingEpg) === -1) {
- this.consumers.push(consumingEpg);
- }
- };
-
- this.addRule = function(rule, classifierInstances) {
- if(rule['classifier-ref'] && rule['classifier-ref'].length > 0) {
-
- rule['classifier-ref'].forEach(function(cr) {
- //cr['parameters'] = [];
- classifierInstances.forEach(function(ci) {
- if(ci['name'] === cr['instance-name']) {
- cr['parameters'] = ci['parameter-value'];
- }
- });
- });
- }
-
- this.rules.push(rule);
- };
- };
-
- var addEpg = function(epgList, epgId, tenantId) {
- var addedEpg = null;
-
- if(epgList.some(function(epg) {
- return epg.id === epgId && epg.tenantId === tenantId;
- }) === false) {
- addedEpg = new EPG(epgId, tenantId);
- }
-
- if(addedEpg !== null) {
- epgList.push(addedEpg);
- }
-
- return addedEpg;
- },
- addSubject = function(subject, subjects, providerEpg, consumerEpg, classifierInstances) {
- //console.log('classifierInstances:', classifierInstances);
- var existingSubject = subjects.filter(function(s) {
- return s.name === subject.name;
- })[0],
- newSubject = (existingSubject === undefined);
-
- if(newSubject) {
- existingSubject = new Subject(subject.name);
- }
-
- existingSubject.addProvider(providerEpg);
- existingSubject.addConsumer(consumerEpg);
-
- if(subject['ui-rule'] && subject['ui-rule'].length > 0) {
- subject['ui-rule'].forEach(function(r) {
- existingSubject.addRule(r, classifierInstances);
- });
- }
-
- if(newSubject) {
- subjects.push(existingSubject);
- }
- },
- processPairData = function(providers, consumers, subjects, pairData, classifierInstances) {
- addEpg(providers, pairData['provider-endpoint-group-id'], pairData['provider-tenant-id']);
- addEpg(consumers, pairData['consumer-endpoint-group-id'], pairData['consumer-tenant-id']);
-
- pairData['ui-subject'].forEach(function(s) {
- addSubject(s, subjects, pairData['provider-endpoint-group-id'], pairData['consumer-endpoint-group-id'], classifierInstances);
- });
- };
-
- s.getEPGsAndSubjects = function(tenantId, classifierInstances, successCbk, errorCbk) {
- TopologyDataLoaders.getSubjectsBetweenEndpointGroups(false, tenantId,
- function(data) {
- var epgPairs = data.output['endpoint-group-pair-with-subject'],
- consumers = [],
- providers = [],
- subjects = [];
-
- if(epgPairs) {
- epgPairs.forEach(function(p) {
- processPairData(providers, consumers, subjects, p, classifierInstances);
- });
- }
-
- successCbk({providers: providers, consumers: consumers, subjects: subjects});
- },
- function() {
- //TODO log error
- });
- };
-
- return s;
- });
-
- gbpOld.register.factory('GBPTenantServices', function(GPBServices) {
-
- var s = {};
-
- var Tenant = function(id, name, description) {
- this.id = id || GPBServices.getUUIDnumber();
- this.name = name || null;
- this.description = description || null;
- };
-
- var createBaseRestObj = function() {
- return GPBServices
- .createRestObj().one('policy:tenants');
- };
-
- var createRestObj = function(pathObj) {
- return createBaseRestObj().one('tenant').one(pathObj.tenantId);
- };
-
- var transformCallback = function(rawData) {
- // return rawData.map(function(rawObj){
- // return new Tenant(rawObj.id, rawObj.name, rawObj.description);
- // });
- return rawData.tenants.tenant;
- };
-
- var createData = function(obj) {
- return { tenant : [ GPBServices.stripNullValues(obj) ] };
- };
-
- s.createPathObj = function(tenantId) {
- return {
- tenantId: tenantId
- };
- };
-
- s.createObj = function() {
- return new Tenant();
- };
-
- s.send = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path),
- reqData = createData(obj);
-
- GPBServices.send(restObj, reqData, successCbk, errorCbk);
- };
-
- s.modify = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path),
- reqData = createData(obj);
-
- GPBServices.send(restObj, reqData, successCbk, errorCbk);
- };
-
- s.delete = function(path, successCbk, errorCbk) {
- var restObj = createRestObj(path);
-
- GPBServices.delete(restObj, successCbk, errorCbk);
- };
-
- s.load = function(successCbk, errorCbk) {
- var restObj = createBaseRestObj();
- GPBServices.load(restObj, transformCallback, successCbk, errorCbk);
- };
-
- return s;
-
- });
-
- gbpOld.register.factory('GBPContractServices', function(GPBServices) {
-
- var s = {};
-
- var Contract = function(id, description, parent) {
- this.id = id || GPBServices.getUUIDnumber();
- this.description = description || null;
- this.parent = parent || null;
- };
-
- var createBaseRestObj = function(pathObj) {
- return GPBServices.createRestObj().one('policy:tenants').one('tenant').one(pathObj.tenantId);
- };
-
- var createRestObj = function(pathObj) {
- return createBaseRestObj(pathObj).one('contract').one(pathObj.contractId);
- };
-
- var transformCallback = function(rawData) {
- // return rawData.map(function(rawObj){
- // return new Contract(rawObj.id, rawObj.description);
- // });
- return rawData.tenant[0].contract;
- };
-
- var createData = function(obj) {
- return { contract : [ GPBServices.stripNullValues(obj) ] };
- };
-
- s.createPathObj = function(tenantId, contractId) {
- return {
- tenantId: tenantId,
- contractId: contractId
- };
- };
-
- s.createObj = function() {
- return new Contract();
- };
-
- s.send = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path),
- reqData = createData(obj);
-
- GPBServices.send(restObj, reqData, successCbk, errorCbk);
- };
-
- s.delete = function(path, successCbk, errorCbk) {
- var restObj = createRestObj(path);
-
- GPBServices.delete(restObj, successCbk, errorCbk);
- };
-
- s.load = function(path, successCbk, errorCbk) {
- var restObj = createBaseRestObj(path);
-
- GPBServices.load(restObj, transformCallback, successCbk, errorCbk);
- };
-
- return s;
-
- });
-
- gbpOld.register.factory('GBPClauseServices', function(GPBServices) {
-
- var s = {};
-
- var Clause = function(name, subjectRefs) {
- this.name = name || null;
- this['subject-refs'] = subjectRefs || [];
- };
-
- var createBaseRestObj = function(pathObj) {
- return GPBServices.createRestObj()
- .one('policy:tenants').one('tenant').one(pathObj.tenantId)
- .one('contract').one(pathObj.contractId);
- };
-
- var createRestObj = function(pathObj) {
- return createBaseRestObj(pathObj).one('clause').one(pathObj.clauseId);
- };
-
- var transformCallback = function(rawData) {
- var data = null,
- clauseData = rawData.contract[0].clause;
-
- if(clauseData) {
- data = clauseData.map(function(elem) {
- if(elem.hasOwnProperty('subject-refs') === false) {
- elem['subject-refs'] = [];
- }
- return elem;
- });
- }
-
- return data;
- };
-
- var createData = function(obj) {
- var o = GPBServices.stripNullValues(obj);
-
- if(o['subject-refs']) {
- o['subject-refs'] = GPBServices.removeEmptyElementsFromList(o['subject-refs']);
- }
-
- return { clause : [ o ] };
- };
-
- s.createPathObj = function(tenantId, contractId, clauseId) {
- return {
- tenantId: tenantId,
- contractId: contractId,
- clauseId: clauseId
- };
- };
-
- s.createObj = function() {
- return new Clause();
- };
-
- s.send = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path),
- reqData = createData(obj);
-
- GPBServices.send(restObj, reqData, successCbk, errorCbk);
- };
-
- s.delete = function(path, successCbk, errorCbk) {
- var restObj = createRestObj(path);
-
- GPBServices.delete(restObj, successCbk, errorCbk);
- };
-
- s.load = function(path, successCbk, errorCbk) {
- var restObj = createBaseRestObj(path);
-
- GPBServices.load(restObj, transformCallback, successCbk, errorCbk);
- };
-
- return s;
-
- });
-
- gbpOld.register.factory('GBPSubjectServices', function(GPBServices) {
-
- var s = {};
-
- var Subject = function(name, order) {
- this.name = name || null;
- this.order = order || null;
- };
-
- var createBaseRestObj = function(pathObj) {
- return GPBServices.createRestObj()
- .one('policy:tenants').one('tenant').one(pathObj.tenantId)
- .one('contract').one(pathObj.contractId);
- };
-
- var createRestObj = function(pathObj) {
- return createBaseRestObj(pathObj).one('subject').one(pathObj.subjectId);
- };
-
- var transformCallback = function(rawData) {
- // return rawData.map(function(rawObj){
- // return new Subject(rawObj.name, rawObj.order);
- // });
- return rawData.contract[0].subject;
- };
-
- var createData = function(obj) {
- return { subject : [ GPBServices.stripNullValues(obj) ] };
- };
-
- s.createPathObj = function(tenantId, contractId, subjectId) {
- return {
- tenantId: tenantId,
- contractId: contractId,
- subjectId: subjectId
- };
- };
-
- s.createObj = function() {
- return new Subject();
- };
-
- s.send = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path),
- reqData = createData(obj);
-
- GPBServices.send(restObj, reqData, successCbk, errorCbk);
- };
-
- s.delete = function(path, successCbk, errorCbk) {
- var restObj = createRestObj(path);
-
- GPBServices.delete(restObj, successCbk, errorCbk);
- };
-
- s.load = function(path, successCbk, errorCbk) {
- var restObj = createBaseRestObj(path);
-
- GPBServices.load(restObj, transformCallback, successCbk, errorCbk);
- };
-
- return s;
-
- });
-
- gbpOld.register.factory('GBPRuleServices', function(GPBServices) {
-
- var s = {};
-
- var Rule = function(name, order) {
- this.name = name || null;
- this.order = order || null;
- };
-
- var createBaseRestObj = function(pathObj) {
- return GPBServices.createRestObj()
- .one('policy:tenants').one('tenant')
- .one(pathObj.tenantId).one('contract').one(pathObj.contractId)
- .one('subject').one(pathObj.subjectId);
- };
-
- var createRestObj = function(pathObj) {
- return createBaseRestObj(pathObj).one('rule').one(pathObj.ruleId);
- };
-
- var transformCallback = function(rawData) {
- // return rawData.map(function(rawObj){
- // return new Rule(rawObj.name, rawObj.order);
- // });
- return rawData.subject[0].rule;
- };
-
- var createData = function(obj) {
- return { rule : [ GPBServices.stripNullValues(obj) ] };
- };
-
- s.createPathObj = function(tenantId, contractId, subjectId, ruleId) {
- return {
- tenantId: tenantId,
- contractId: contractId,
- subjectId: subjectId,
- ruleId: ruleId
- };
- };
-
- s.createObj = function() {
- return new Rule();
- };
-
- s.send = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path),
- reqData = createData(obj);
-
- GPBServices.send(restObj, reqData, successCbk, errorCbk);
- };
-
- s.delete = function(path, successCbk, errorCbk) {
- var restObj = createRestObj(path);
-
- GPBServices.delete(restObj, successCbk, errorCbk);
- };
-
- s.load = function(path, successCbk, errorCbk) {
- var restObj = createBaseRestObj(path);
-
- GPBServices.load(restObj, transformCallback, successCbk, errorCbk);
- };
-
- return s;
-
- });
-
- gbpOld.register.factory('GBPClassifierRefsServices', function(GPBServices) {
-
- var s = {};
-
- var ClassifierRef = function(name, direction, instanceName, connectionTracking) {
- this.name = name || null;
- this.direction = direction || null;
- this['instance-name'] = instanceName || null;
- this['connection-tracking'] = connectionTracking || null;
- };
-
- var createBaseRestObj = function(pathObj) {
- return GPBServices.createRestObj()
- .one('policy:tenants').one('tenant')
- .one(pathObj.tenantId).one('contract').one(pathObj.contractId)
- .one('subject').one(pathObj.subjectId)
- .one('rule').one(pathObj.ruleId);
- };
-
- var createRestObj = function(pathObj) {
- return createBaseRestObj(pathObj).one('classifier-ref').one(pathObj.classifierRefId);
- };
-
- var transformCallback = function(rawData) {
- // return rawData.map(function(rawObj){
- // return new ClassifierRef(rawObj.name, rawObj.direction, rawObj['instance-name']);
- // });
- return rawData.rule[0]['classifier-ref'];
- };
-
- var createData = function(obj) {
- return { 'classifier-ref' : [ GPBServices.stripNullValues(obj) ] };
- };
-
- s.createPathObj = function(tenantId, contractId, subjectId, ruleId, classifierRefId) {
- return {
- tenantId: tenantId,
- contractId: contractId,
- subjectId: subjectId,
- ruleId: ruleId,
- classifierRefId: classifierRefId
- };
- };
-
- s.createObj = function() {
- return new ClassifierRef();
- };
-
- s.send = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path),
- reqData = createData(obj);
-
- GPBServices.send(restObj, reqData, successCbk, errorCbk);
- };
-
- s.delete = function(path, successCbk, errorCbk) {
- var restObj = createRestObj(path);
-
- GPBServices.delete(restObj, successCbk, errorCbk);
- };
-
- s.load = function(path, successCbk, errorCbk) {
- var restObj = createBaseRestObj(path);
-
- GPBServices.load(restObj, transformCallback, successCbk, errorCbk);
- };
-
- return s;
-
- });
-
- gbpOld.register.factory('GBPActionRefsServices', function(GPBServices) {
-
- var s = {};
-
- var ActionRef = function(name, order, instanceName) {
- this.name = name || null;
- this.order = order || null;
- };
-
- var createBaseRestObj = function(pathObj) {
- return GPBServices.createRestObj()
- .one('policy:tenants').one('tenant')
- .one(pathObj.tenantId).one('contract').one(pathObj.contractId)
- .one('subject').one(pathObj.subjectId)
- .one('rule').one(pathObj.ruleId);
- };
-
- var createRestObj = function(pathObj) {
- return createBaseRestObj(pathObj).one('action-ref').one(pathObj.actionRefId);
- };
-
- var transformCallback = function(rawData) {
- // return rawData.map(function(rawObj){
- // return new ActionRef(rawObj.name, rawObj.order);
- // });
- return rawData.rule[0]['action-ref'];
- };
-
- var createData = function(obj) {
- return { 'action-ref' : [ GPBServices.stripNullValues(obj) ] };
- };
-
- s.createPathObj = function(tenantId, contractId, subjectId, ruleId, actionRefId) {
- return {
- tenantId: tenantId,
- contractId: contractId,
- subjectId: subjectId,
- ruleId: ruleId,
- actionRefId: actionRefId
- };
- };
-
- s.createObj = function() {
- return new ActionRef();
- };
-
- s.send = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path),
- reqData = createData(obj);
-
- GPBServices.send(restObj, reqData, successCbk, errorCbk);
- };
-
- s.delete = function(path, successCbk, errorCbk) {
- var restObj = createRestObj(path);
-
- GPBServices.delete(restObj, successCbk, errorCbk);
- };
-
- s.load = function(path, successCbk, errorCbk) {
- var restObj = createBaseRestObj(path);
-
- GPBServices.load(restObj, transformCallback, successCbk, errorCbk);
- };
-
- return s;
-
- });
-
- gbpOld.register.factory('GBPL2FloodDomainServices', function(GPBServices) {
-
- var s = {};
-
- var L2FloodDomain = function(id, name, description, parent) {
- this.id = id || GPBServices.getUUIDnumber();
- this.name = name || null;
- this.description = description || null;
- this.parent = parent || null;
- };
-
- var createBaseRestObj = function(pathObj) {
- return GPBServices.createRestObj()
- .one('policy:tenants').one('tenant').one(pathObj.tenantId);
- };
-
- var createRestObj = function(pathObj) {
- return createBaseRestObj(pathObj).one('l2-flood-domain').one(pathObj.l2FloodDomain);
- };
-
- var transformCallback = function(rawData) {
- // return rawData.map(function(rawObj){
- // return new L2FloodDomain(rawObj.id, rawObj.name, rawObj.description, rawObj.parent);
- // });
- return rawData.tenant[0]['l2-flood-domain'];
- };
-
- var createData = function(obj) {
- return { 'l2-flood-domain' : [ GPBServices.stripNullValues(obj) ] };
- };
-
- s.createPathObj = function(tenantId, l2FloodDomain) {
- return {
- tenantId: tenantId,
- l2FloodDomain: l2FloodDomain
- };
- };
-
- s.createObj = function() {
- return new L2FloodDomain();
- };
-
- s.send = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path),
- reqData = createData(obj);
-
- GPBServices.send(restObj, reqData, successCbk, errorCbk);
- };
-
- s.delete = function(path, successCbk, errorCbk) {
- var restObj = createRestObj(path);
-
- GPBServices.delete(restObj, successCbk, errorCbk);
- };
-
- s.load = function(path, successCbk, errorCbk) {
- var restObj = createBaseRestObj(path);
-
- GPBServices.load(restObj, transformCallback, successCbk, errorCbk);
- };
-
- return s;
-
- });
-
- gbpOld.register.factory('GBPL2BridgeDomainServices', function(GPBServices) {
-
- var s = {};
-
- var L2BridgeDomain = function(id, name, description, parent) {
- this.id = id || GPBServices.getUUIDnumber();
- this.name = name || null;
- this.description = description || null;
- this.parent = parent || null;
- };
-
- var createBaseRestObj = function(pathObj) {
- return GPBServices.createRestObj()
- .one('policy:tenants').one('tenant')
- .one(pathObj.tenantId);
- };
-
- var createRestObj = function(pathObj) {
- return createBaseRestObj(pathObj).one('l2-bridge-domain').one(pathObj.l2BridgeDomain);
- };
-
- var transformCallback = function(rawData) {
- // return rawData.map(function(rawObj){
- // return new L2BridgeDomain(rawObj.id, rawObj.name, rawObj.description, rawObj.parent);
- // });
- return rawData.tenant[0]['l2-bridge-domain'];
- };
-
- var createData = function(obj) {
- return { 'l2-bridge-domain' : [ GPBServices.stripNullValues(obj) ] };
- };
-
- s.createPathObj = function(tenantId, l2BridgeDomain) {
- return {
- tenantId: tenantId,
- l2BridgeDomain: l2BridgeDomain
- };
- };
-
- s.createObj = function() {
- return new L2BridgeDomain();
- };
-
- s.send = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path),
- reqData = createData(obj);
-
- GPBServices.send(restObj, reqData, successCbk, errorCbk);
- };
-
- s.delete = function(path, successCbk, errorCbk) {
- var restObj = createRestObj(path);
-
- GPBServices.delete(restObj, successCbk, errorCbk);
- };
-
- s.load = function(path, successCbk, errorCbk) {
- var restObj = createBaseRestObj(path);
-
- GPBServices.load(restObj, transformCallback, successCbk, errorCbk);
- };
-
- return s;
-
- });
-
- gbpOld.register.factory('GBPL3ContextServices', function(GPBServices) {
-
- var s = {};
-
- var L3Context = function(id, name, description) {
- this.id = id || GPBServices.getUUIDnumber();
- this.name = name || null;
- this.description = description || null;
- };
-
- var createBaseRestObj = function(pathObj) {
- return GPBServices.createRestObj()
- .one('policy:tenants').one('tenant').one(pathObj.tenantId);
- };
-
- var createRestObj = function(pathObj) {
- return createBaseRestObj(pathObj).one('l3-context').one(pathObj.l3Context);
- };
-
- var transformCallback = function(rawData) {
- // return rawData.map(function(rawObj){
- // return new L3Context(rawObj.id, rawObj.name, rawObj.description);
- // });
- return rawData.tenant[0]['l3-context'];
- };
-
- var createData = function(obj) {
- return { 'l3-context' : [ GPBServices.stripNullValues(obj) ] };
- };
-
- s.createPathObj = function(tenantId, l3Context) {
- return {
- tenantId: tenantId,
- l3Context: l3Context
- };
- };
-
- s.createObj = function() {
- return new L3Context();
- };
-
- s.send = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path),
- reqData = createData(obj);
-
- GPBServices.send(restObj, reqData, successCbk, errorCbk);
- };
-
- s.delete = function(path, successCbk, errorCbk) {
- var restObj = createRestObj(path);
-
- GPBServices.delete(restObj, successCbk, errorCbk);
- };
-
- s.load = function(path, successCbk, errorCbk) {
- var restObj = createBaseRestObj(path);
-
- GPBServices.load(restObj, transformCallback, successCbk, errorCbk);
- };
-
- return s;
-
- });
-
- gbpOld.register.factory('GBPSubnetServices', function(GPBServices) {
-
- var s = {};
-
- var Subnet = function(id, name, description, parent, ipPrefix, virtualRouterIp) {
- this.id = id || GPBServices.getUUIDnumber();
- this.name = name || null;
- this.description = description || null;
- this.parent = parent || null;
- this['ip-prefix'] = ipPrefix || null;
- this['virtual-router-ip'] = virtualRouterIp || null;
- };
-
- var createBaseRestObj = function(pathObj) {
- return GPBServices.createRestObj()
- .one('policy:tenants').one('tenant').one(pathObj.tenantId);
- };
-
- var createRestObj = function(pathObj) {
- return createBaseRestObj(pathObj).one('subnet').one(pathObj.subnet);
- };
-
- var transformCallback = function(rawData) {
- // return rawData.map(function(rawObj){
- // return new L3Context(rawObj.id, rawObj.name, rawObj.description);
- // });
- return rawData.tenant[0]['subnet'];
- };
-
- var createData = function(obj) {
- return { 'subnet' : [ GPBServices.stripNullValues(obj) ] };
- };
-
- s.createPathObj = function(tenantId, subnet) {
- return {
- tenantId: tenantId,
- subnet: subnet
- };
- };
-
- s.createObj = function() {
- return new Subnet();
- };
-
- s.send = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path),
- reqData = createData(obj);
-
- GPBServices.send(restObj, reqData, successCbk, errorCbk);
- };
-
- s.delete = function(path, successCbk, errorCbk) {
- var restObj = createRestObj(path);
-
- GPBServices.delete(restObj, successCbk, errorCbk);
- };
-
- s.load = function(path, successCbk, errorCbk) {
- var restObj = createBaseRestObj(path);
-
- GPBServices.load(restObj, transformCallback, successCbk, errorCbk);
- };
-
- return s;
-
- });
-
- gbpOld.register.factory('GBPGatewayServices', function(GPBServices) {
-
- var s = {};
-
- var Gateway = function(gateway) {
- this.gateway = gateway || null;
- };
-
- var createBaseRestObj = function(pathObj) {
- return GPBServices.createRestObj()
- .one('policy:tenants').one('tenant').one(pathObj.tenantId).one('subnet').one(pathObj.subnetId);
- };
-
- var createRestObj = function(pathObj) {
- return createBaseRestObj(pathObj).one('gateways').one(pathObj.gateway);
- };
-
- var transformCallback = function(rawData) {
- // return rawData.map(function(rawObj){
- // return new L3Context(rawObj.id, rawObj.name, rawObj.description);
- // });
- return rawData.subnet[0]['gateways'];
- };
-
- var createData = function(obj) {
- return { 'gateways' : [ GPBServices.stripNullValues(obj) ] };
- };
-
- s.createPathObj = function(tenantId, subnetId, gateway) {
- return {
- tenantId: tenantId,
- subnetId: subnetId,
- gateway: gateway
- };
- };
-
- s.createObj = function() {
- return new Gateway();
- };
-
- s.send = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path),
- reqData = createData(obj);
-
- GPBServices.send(restObj, reqData, successCbk, errorCbk);
- };
-
- s.delete = function(path, successCbk, errorCbk) {
- var restObj = createRestObj(path);
-
- GPBServices.delete(restObj, successCbk, errorCbk);
- };
-
- s.load = function(path, successCbk, errorCbk) {
- var restObj = createBaseRestObj(path);
-
- GPBServices.load(restObj, transformCallback, successCbk, errorCbk);
- };
-
- return s;
-
- });
-
- gbpOld.register.factory('GBPPrefixServices', function(GPBServices) {
-
- var s = {};
-
- var Prefix = function(prefix) {
- this.prefix = prefix || null;
- };
-
- var createBaseRestObj = function(pathObj) {
- return GPBServices.createRestObj()
- .one('policy:tenants').one('tenant').one(pathObj.tenantId).one('subnet').one(pathObj.subnetId).one('gateways').one(pathObj.gatewayId);
- };
-
- var createRestObj = function(pathObj) {
- return createBaseRestObj(pathObj).one('prefixes').one(pathObj.prefixId);
- };
-
- var transformCallback = function(rawData) {
- // return rawData.map(function(rawObj){
- // return new L3Context(rawObj.id, rawObj.name, rawObj.description);
- // });
- return rawData.gateways[0].prefixes;
- };
-
- var createData = function(obj) {
- return { 'prefixes' : [ GPBServices.stripNullValues(obj) ] };
- };
-
- s.createPathObj = function(tenantId, subnetId, gatewayId, prefixId) {
- return {
- tenantId: tenantId,
- subnetId: subnetId,
- gatewayId: gatewayId,
- prefixId: prefixId ? prefixId.replace("/", "%2F") : prefixId
- };
- };
-
- s.createObj = function() {
- return new Prefix();
- };
-
- s.send = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path),
- reqData = createData(obj);
-
- GPBServices.send(restObj, reqData, successCbk, errorCbk);
- };
-
- s.delete = function(path, successCbk, errorCbk) {
- var restObj = createRestObj(path);
-
- GPBServices.delete(restObj, successCbk, errorCbk);
- };
-
- s.load = function(path, successCbk, errorCbk) {
- var restObj = createBaseRestObj(path);
-
- GPBServices.load(restObj, transformCallback, successCbk, errorCbk);
- };
-
- return s;
-
- });
-
- gbpOld.register.factory('GBPClassifierInstanceServices', function(GPBServices) {
-
- var s = {};
-
- var ClassifierService = function(name, classifierDefId) {
- this.name = name || null;
- this['classifier-definition-id'] = classifierDefId || null;
- this['parameter-value'] = [];
- };
-
- var createBaseRestObj = function(pathObj) {
- return GPBServices.createRestObj()
- .one('policy:tenants').one('tenant').one(pathObj.tenantId).one('subject-feature-instances');
- };
-
- var createRestObj = function(pathObj) {
- return createBaseRestObj(pathObj).one('classifier-instance').one(pathObj.classfierInstanceId);
- };
-
- var transformCallback = function(rawData) {
- return rawData['subject-feature-instances']['classifier-instance'];
- };
-
- var createData = function(obj) {
- return { 'classifier-instance' : [ GPBServices.stripNullValues(obj) ] };
- };
-
- s.createPathObj = function(tenantId, classfierInstanceId) {
- return {
- tenantId: tenantId,
- classfierInstanceId: classfierInstanceId
- };
- };
-
- s.createObj = function() {
- return new ClassifierService();
- };
-
- s.send = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path),
- reqData = createData(obj);
-
- GPBServices.send(restObj, reqData, successCbk, errorCbk);
- };
-
- s.delete = function(path, successCbk, errorCbk) {
- var restObj = createRestObj(path);
-
- GPBServices.delete(restObj, successCbk, errorCbk);
- };
-
- s.load = function(path, successCbk, errorCbk) {
- var restObj = createBaseRestObj(path);
-
- GPBServices.load(restObj, transformCallback, successCbk, errorCbk);
- };
-
- return s;
-
- });
-
- gbpOld.register.factory('GBPActionInstanceServices', function(GPBServices) {
-
- var s = {};
-
- var ActionService = function(name, actionDefId) {
- this.name = name || null;
- this['action-definition-id'] = actionDefId || null;
- this['parameter-value'] = [];
- };
-
- var createBaseRestObj = function(pathObj) {
- return GPBServices.createRestObj()
- .one('policy:tenants').one('tenant').one(pathObj.tenantId).one('subject-feature-instances');
- };
-
- var createRestObj = function(pathObj) {
- return createBaseRestObj(pathObj).one('action-instance').one(pathObj.actionInstanceId);
- };
-
- var transformCallback = function(rawData) {
- return rawData['subject-feature-instances']['action-instance'];
- };
-
- var createData = function(obj) {
- return { 'action-instance' : [ GPBServices.stripNullValues(obj) ] };
- };
-
- s.createPathObj = function(tenantId, actionInstanceId) {
- return {
- tenantId: tenantId,
- actionInstanceId: actionInstanceId
- };
- };
-
- s.createObj = function() {
- return new ActionService();
- };
-
- s.send = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path),
- reqData = createData(obj);
-
- GPBServices.send(restObj, reqData, successCbk, errorCbk);
- };
-
- s.delete = function(path, successCbk, errorCbk) {
- var restObj = createRestObj(path);
-
- GPBServices.delete(restObj, successCbk, errorCbk);
- };
-
- s.load = function(path, successCbk, errorCbk) {
- var restObj = createBaseRestObj(path);
-
- GPBServices.load(restObj, transformCallback, successCbk, errorCbk);
- };
-
- s.getDefinitions = function(successCbk, errorCbk) {
- var restObj = GBPRestangular.one('restconf').one('operational').one('policy:subject-feature-definitions');
-
- restObj.get().then(function(data) {
- successCbk(data['subject-feature-definitions']['action-definition']);
- }, function(res) {
- // errorCbk(res);
- });
- };
-
- return s;
-
- });
-
- gbpOld.register.factory('GBPEpgServices', function(GPBServices) {
-
- var s = {};
-
- var EPG = function(name, description, intraGroupPolicy, networkDomain, id, parent) {
- this.id = id || GPBServices.getUUIDnumber();
- this.name = name || null;
- this.description = description || null;
- this['intra-group-policy'] = intraGroupPolicy || null;
- this['network-domain'] = networkDomain || null;
- this.parent = parent || null;
- };
-
- var createBaseRestObj = function(pathObj) {
- return GPBServices.createRestObj()
- .one('policy:tenants').one('tenant').one(pathObj.tenantId);
- };
-
- var createRestObj = function(pathObj) {
- return createBaseRestObj(pathObj).one('endpoint-group').one(pathObj.epgId);
- };
-
- var transformCallback = function(rawData) {
- return rawData.tenant[0]['endpoint-group'];
- };
-
- var createData = function(obj) {
- return { 'endpoint-group' : [ GPBServices.stripNullValues(obj) ] };
- };
-
- s.createPathObj = function(tenantId, epgId) {
- return {
- tenantId: tenantId,
- epgId: epgId
- };
- };
-
- s.createObj = function() {
- return new EPG();
- };
-
- s.send = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path),
- reqData = createData(obj);
-
- GPBServices.send(restObj, reqData, successCbk, errorCbk);
- };
-
- s.delete = function(path, successCbk, errorCbk) {
- var restObj = createRestObj(path);
-
- GPBServices.delete(restObj, successCbk, errorCbk);
- };
-
- s.load = function(path, successCbk, errorCbk) {
- var restObj = createBaseRestObj(path);
-
- GPBServices.load(restObj, transformCallback, successCbk, errorCbk);
- };
-
- return s;
-
- });
-
- gbpOld.register.factory('GBPConNamedSelServices', function(GPBServices) {
-
- var s = {};
-
- var ConsumerNamedSelector = function(name, contract) {
- this.name = name || null;
- this.contract = contract || [];
- };
-
- var createBaseRestObj = function(pathObj) {
- return GPBServices.createRestObj()
- .one('policy:tenants').one('tenant').one(pathObj.tenantId).one('endpoint-group').one(pathObj.epgId);
- };
-
- var createRestObj = function(pathObj) {
- return createBaseRestObj(pathObj).one('consumer-named-selector').one(pathObj.cnsId);
- };
-
- var transformCallback = function(rawData) {
- var data = null,
- consumerData = rawData['endpoint-group'][0]['consumer-named-selector'];
-
- if(consumerData) {
- data = consumerData.map(function(elem) {
- if(elem.hasOwnProperty('contract') === false) {
- elem.contract = [];
- }
- return elem;
- });
- }
-
- return data;
- };
-
- var createData = function(obj) {
- var o = GPBServices.stripNullValues(obj);
-
- if(o.contract) {
- o.contract = GPBServices.removeEmptyElementsFromList(o.contract);
- }
-
- return { 'consumer-named-selector' : [ o ] };
- };
-
- s.createPathObj = function(tenantId, epgId, cnsId) {
- return {
- tenantId: tenantId,
- epgId: epgId,
- cnsId: cnsId
- };
- };
-
- s.createObj = function() {
- return new ConsumerNamedSelector();
- };
-
- s.send = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path),
- reqData = createData(obj);
-
- GPBServices.send(restObj, reqData, successCbk, errorCbk);
- };
-
- s.delete = function(path, successCbk, errorCbk) {
- var restObj = createRestObj(path);
-
- GPBServices.delete(restObj, successCbk, errorCbk);
- };
-
- s.load = function(path, successCbk, errorCbk) {
- var restObj = createBaseRestObj(path);
-
- GPBServices.load(restObj, transformCallback, successCbk, errorCbk);
- };
-
- return s;
-
- });
-
-
- gbpOld.register.factory('GBPProNamedSelServices', function(GPBServices) {
-
- var s = {};
-
- var ProviderNamedSelector = function(name, contract) {
- this.name = name || null;
- this.contract = contract || [];
- };
-
- var createBaseRestObj = function(pathObj) {
- return GPBServices.createRestObj()
- .one('policy:tenants').one('tenant').one(pathObj.tenantId).one('endpoint-group').one(pathObj.epgId);
- };
-
- var createRestObj = function(pathObj) {
- return createBaseRestObj(pathObj).one('provider-named-selector').one(pathObj.cnsId);
- };
-
- var transformCallback = function(rawData) {
- var data = null,
- provderData = rawData['endpoint-group'][0]['provider-named-selector'];
-
- if(provderData) {
- data = provderData.map(function(elem) {
- if(elem.hasOwnProperty('contract') === false) {
- elem.contract = [];
- }
- return elem;
- });
- }
-
- return data;
- };
-
- var createData = function(obj) {
- var o = GPBServices.stripNullValues(obj);
-
- if(o.contract) {
- o.contract = GPBServices.removeEmptyElementsFromList(o.contract);
- }
-
- return { 'provider-named-selector' : [ o ] };
- };
-
- s.createPathObj = function(tenantId, epgId, cnsId) {
- return {
- tenantId: tenantId,
- epgId: epgId,
- cnsId: cnsId
- };
- };
-
- s.createObj = function() {
- return new ProviderNamedSelector();
- };
-
- s.send = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path),
- reqData = createData(obj);
-
- GPBServices.send(restObj, reqData, successCbk, errorCbk);
- };
-
- s.delete = function(path, successCbk, errorCbk) {
- var restObj = createRestObj(path);
-
- GPBServices.delete(restObj, successCbk, errorCbk);
- };
-
- s.load = function(path, successCbk, errorCbk) {
- var restObj = createBaseRestObj(path);
-
- GPBServices.load(restObj, transformCallback, successCbk, errorCbk);
- };
-
- return s;
-
- });
-
- gbpOld.register.factory('GBPEndpointServices', function(GPBServices) {
-
- var s = {};
-
- var Endpoint = function(tenantId) {
- this.tenant = tenantId || null;
- this['network-containment'] = null;
- this['endpoint-group'] = null;
- this['endpoint-groups'] = [];
- this.condition = [];
- this['l2-context'] = null;
- this['mac-address'] = null;
- this['l3-address'] = [];
- };
-
- var createRestObj = function() {
- return GPBServices.createRestObj('operations');
- };
-
- var transformCallback = function(rawData) {
- return rawData.endpoints.endpoint;
- };
-
- var createBaseData = function(obj) {
- var o = GPBServices.stripNullValues(obj);
-
- if(o.condition) {
- o.condition = GPBServices.removeEmptyElementsFromList(o.condition);
- }
-
- if(o['endpoint-groups']) {
- o['endpoint-groups'] = GPBServices.removeEmptyElementsFromList(o['endpoint-groups']);
- }
-
- if(o['l3-address']) {
- o['l3-address'] = GPBServices.removeEmptyElementsFromList(o['l3-address']);
- }
-
- return o;
- };
-
- var createSendData = function(obj) {
- var o = createBaseData(obj);
- return { 'input': o };
- };
-
- var createDeleteData = function(obj) {
- var o = {
- 'input': {
- 'l3': obj['l3-address'],
- 'l2': [
- {
- 'l2-context': obj['l2-context'],
- 'mac-address': obj['mac-address']
- }
- ]
- }
- };
-
- return o;
- };
-
- s.createObj = function(tenantId) {
- return new Endpoint(tenantId);
- };
-
- s.send = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj().one('endpoint:register-endpoint'),
- reqData = createSendData(obj);
-
- GPBServices.post(restObj, reqData, successCbk, errorCbk);
- };
-
- s.delete = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path).one('endpoint:unregister-endpoint'),
- reqData = createDeleteData(obj);
- GPBServices.post(restObj, reqData, successCbk, errorCbk);
- };
-
- s.load = function(path, successCbk, errorCbk) {
- var restObj = GPBServices.createRestObj('operational').one('endpoint:endpoints');
-
- GPBServices.load(restObj, transformCallback, successCbk, errorCbk);
- };
-
- return s;
-
- });
-
- gbpOld.register.factory('GBPEndpointL3Services', function(GPBServices) {
-
- var s = {};
-
- var EndpointL3 = function(tenantId) {
- this.tenant = tenantId || null;
- this['endpoint-group'] = null;
- this['endpoint-groups'] = [];
- this.condition = [];
- this['l3-context'] = null;
- this['ip-prefix'] = null;
- this['endpoint-l2-gateways'] = [];
- this['endpoint-l3-gateways'] = [];
- };
-
- var createRestObj = function() {
- return GPBServices.createRestObj('operations');
- };
-
- var transformCallback = function(rawData) {
- return rawData.endpoints['endpoint-l3-prefix'];
- };
-
- var createBaseData = function(obj) {
- var o = GPBServices.stripNullValues(obj);
-
- if(o.condition) {
- o.condition = GPBServices.removeEmptyElementsFromList(o.condition);
- }
-
- if(o['endpoint-groups']) {
- o['endpoint-groups'] = GPBServices.removeEmptyElementsFromList(o['endpoint-groups']);
- }
-
- if(o['endpoint-l2-gateways']) {
- o['endpoint-l2-gateways'] = GPBServices.removeEmptyElementsFromList(o['endpoint-l2-gateways']);
- }
-
- if(o['endpoint-l3-gateways']) {
- o['endpoint-l3-gateways'] = GPBServices.removeEmptyElementsFromList(o['endpoint-l3-gateways']);
- }
-
- return o;
- };
-
- var createSendData = function(obj) {
- var o = createBaseData(obj);
- return { 'input': o };
- };
-
- var createDeleteData = function(obj) {
- var o = {
- 'input': {
- 'l3-prefix': [
- {
- 'l3-context': obj['l3-context'],
- 'ip-prefix': obj['ip-prefix']
- }
- ],
- 'l2': obj['endpoint-l2-gateways'],
- 'l3': obj['endpoint-l3-gateways']
- }
- };
-
- return o;
- };
-
- s.createObj = function(tenantId) {
- return new EndpointL3(tenantId);
- };
-
- s.send = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj().one('endpoint:register-l3-prefix-endpoint'),
- reqData = createSendData(obj);
-
- GPBServices.post(restObj, reqData, successCbk, errorCbk);
- };
-
- s.delete = function(path, obj, successCbk, errorCbk) {
- var restObj = createRestObj(path).one('endpoint:unregister-endpoint'),
- reqData = createDeleteData(obj);
-
- GPBServices.post(restObj, reqData, successCbk, errorCbk);
- };
-
- s.load = function(path, successCbk, errorCbk) {
- var restObj = GPBServices.createRestObj('operational').one('endpoint:endpoints');
-
- GPBServices.load(restObj, transformCallback, successCbk, errorCbk);
- };
-
- return s;
-
- });
-
- gbpOld.register.factory('PGNServices', function(GBPRestangular) {
-
- var s = {};
-
- var idGetter = {};
-
- var idTypes = {
- tenant: 'TENANT',
- uuid: 'UUID',
- l3ctx: 'L3CTX',
- pathAction: 'PATHACTION',
- accessAction: 'ACCESSACTION'
- };
-
- idGetter[idTypes.tenant] = function() {
- return 1;
- };
-
- idGetter[idTypes.uuid] = function() {
- return 2;
- };
-
- idGetter[idTypes.l3ctx] = function() {
- return 3;
- };
-
- idGetter[idTypes.pathAction] = function() {
- return 4;
- };
-
- idGetter[idTypes.accessAction] = function() {
- return 5;
- };
-
- var getId = function(type) {
- if(idGetter.hasOwnProperty(type)) {
- return id = idGetter[type]();
- } else {
- throw "Cannot get idGetter for type " + type;
- }
- };
-
- s.addReplaceEndpointGroup = function(successCbk, errorCbk, groupName, sgt, description) {
- var tenantId = getId(idTypes.tenant),
- uuid = getId(idTypes.uuid),
- restObj = GBPRestangular.one('restconf').one('operations'),
- rpcRes = 'pgn-application:create-or-replace-endpoint-groups',
- reqData = {
- "input":
- {
- "endpoint-group":[
- {
- "pgn-application:tenant-id": tenantID,
- "pgn-application:id":uuid,
- "pgn-application:security-group-tag":sgt,
- "pgn-application:name":groupName,
- "pgn-application:description":description
- }
- ]
- }
- };
-
- restObj.post(rpcRes, reqData).then(function(data) {
- successCbk(data);
- }, function(res) {
- errorCbk(res);
- });
- };
-
- s.deleteEndpointGroup = function(successCbk, errorCbk, uuid) {
- var tenantId = getId(idTypes.tenant),
- restObj = GBPRestangular.one('restconf').one('operations'),
- rpcRes = 'pgn-application:delete-endpoint-groups',
- reqData = {
- "input": {
- "endpoint-group":[
- {
- "pgn-application:tenant-id": tenantId,
- "pgn-application:id":uuid
- }
- ]
- }
- };
-
- restObj.post(rpcRes, reqData).then(function(data) {
- successCbk(data);
- }, function(res) {
- errorCbk(res);
- });
- };
-
- s.getActions = function(successCbk, errorCbk) {
- var tenantId = getId(idTypes.tenant),
- pathActionId = getId(idTypes.pathAction),
- accessActionId = getId(idTypes.accessAction),
- restObj = GBPRestangular.one('restconf').one('config').one('policy:tenants', tenantId).one('subject-feature-instances');
-
- restObj.get().then(function(data) {
- successCbk(data); //TODO fill actions
- }, function(res) {
- errorCbk(res);
- });
- };
-
- s.applyPolicy = function(successCbk, errorCbk, providerId, consumerId, pathSelRule, accessCtrlRule) {
- var restObj = GBPRestangular.one('restconf').one('operations'),
- rpcRes = 'pgn-application:wire-endpoint-groups',
- actionRefName = (pathSelRule ? pathSelRule : '') + (accessCtrlRule ? accessCtrlRule : ''),
- reqData = {
- "input": {
- "endpoint-group-pair-with-rules": {
- "pgn-application:provider-tenant-id": tenantID,
- "pgn-application:consumer-tenant-id": tenantID,
- "pgn-application:provider-group-id":providerId,
- "pgn-application:consumer-group-id":consumerId,
- "pgn-application:group-rule": [
- {
- "action-ref": [pathSelRule, accessCtrlRule].map(function(r) {
- return { "name":r };
- }),
- "name":actionRefName
- }
- ]
- }
- }
- };
-
- restObj.post(rpcRes, reqData).then(function(data) {
- successCbk(data); //TODO reload policies
- }, function(res) {
- errorCbk(res);
- });
- };
-
- s.deletePolicy = function(successCbk, errorCbk, providerId, consumerId) {
- var tenantId = getId(idTypes.tenant),
- restObj = GBPRestangular.one('restconf').one('operations'),
- rpcRes = 'pgn-application:unwire-endpoint-groups',
- reqData = {
- "input":
- {
- "endpoint-group-pair":[
- {
- "pgn-application:provider-tenant-id": tenantId,
- "pgn-application:consumer-tenant-id": tenantId,
- "pgn-application:provider-group-id":providerId,
- "pgn-application:consumer-group-id":consumerId
- }
- ]
- }
- };
-
- restObj.post(rpcRes, reqData).then(function(data) {
- successCbk(data); //TODO reload policies
- }, function(res) {
- errorCbk(res);
- });
- };
-
- s.addEndPoint = function(successCbk, errorCbk, ipAddress, groupId) {
- var l3ctxId = getId(idTypes.l3ctx),
- tenantId = getId(idTypes.tenant),
- restObj = GBPRestangular.one('restconf').one('operations'),
- rpcRes = 'endpoint:register-endpoint',
- reqData = {
- "input": {
- "endpoint-group": groupId,
- "l3-address": [
- {
- "ip-address": ipAddress,
- "l3-context": l3ctxId
- }
- ],
- "tenant": tenantId
- }
- };
-
- restObj.post(rpcRes, reqData).then(function(data) {
- successCbk(data);
- }, function(res) {
- errorCbk(res);
- });
- };
-
- s.getUUIDnumber = function() {
- var d = new Date().getTime();
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
- var r = (d + Math.random()*16)%16 | 0;
- d = Math.floor(d/16);
- return (c=='x' ? r : (r&0x3|0x8)).toString(16);
- });
- };
-
- return s;
- });
-
- gbpOld.register.factory('DesignGbpFactory', function(){
-
- var dvf = {};
-
- dvf.setMainClass = function(){
- if ( $('.gbpWrapper').length ) {
- $('.gbpWrapper').closest('.col-xs-12').addClass('gbpGlobalWrapper');
- }
- };
-
- return dvf;
-
- });
-
- gbpOld.register.factory('JointGraphOffsetFactory', function(GBPConstants){
- var jgof = {};
-
- jgof.createWHObj = function(w, h) {
- return {w: w || 0, h: h || 0};
- };
-
- jgof.updateOffsets = function(delta, offset, margin, maximums, paper) {
- offset.w = offset.w + delta.w + margin.w;
-
- if(offset.w >= maximums.w) {
- paper.setDimensions(offset.w + 30, paper.options.height);
- offset.w = offset.ow;
- offset.h = offset.h + margin.h;
- }
-
- };
-
- jgof.resetOffsets = function(offset, w, h) {
- offset.w = w;
- offset.h = h;
- };
-
- jgof.getCurrentOffset = function(array, type) {
- var max = 0;
- array.forEach(function(item){
- max = item.attributes.position[type] > max ? item.attributes.position[type] : max;
- });
-
- return max;
- };
-
- jgof.checkObjsHoffsets = function(array, size, paper) {
- var lastPosY = 0,
- addOffset = false,
- cellBottomOffset = 80,
- setItemPosition = function(item, type) {
- while (item.attributes.position[type] < size + cellBottomOffset) {
- item.translate(null, cellBottomOffset);
- }
- };
-
- array.forEach(function(item){
- addOffset = (size + cellBottomOffset) >= item.attributes.position.y;
-
- if ( addOffset ) {
- setItemPosition(item, 'y');
- }
-
- if ( item.attributes.position.y + cellBottomOffset > paper.options.height ) {
- paper.setDimensions(paper.options.width, paper.options.height + cellBottomOffset);
- }
- });
- };
-
- return jgof;
- });
-
- gbpOld.register.factory('JointGraphFactory', function(GBPConstants){
- var defaulColor = 'blue';
-
- var jgf = {};
-
- jgf.getLabelLength = function(length) {
- return length * 10 > 200 ? 200 : length * 10;
- };
-
- jgf.createGraph = function() {
- var graph = new joint.dia.Graph();
-
- var paper = new joint.dia.Paper({
- el: $('#graph'),
- width: 1300,
- height: 650,
- model: graph,
- gridSize: 1,
- interactive: { vertexAdd: false }
- });
-
- return paper;
- };
-
- jgf.resetGraphDimension = function(paper, element, paddingT, paddingL){
- paddingT = paddingT ? paddingT : 0;
- paddingL = paddingL ? paddingL : paddingT;
-
- var paperWidth = element.width() - paddingL,
- paperHeight = element.height() - paddingT - 5;
-
- paper.setDimensions(paperWidth, paperHeight);
- };
-
- jgf.reloadGraph = function(graph) {
- graph.clear();
- };
-
- jgf.createElement = function(elementName, posx, posy, width, height, objectType, object, tooltip, bgcolor, titleName) {
- var setWidth = function(width) {
- return width < GBPConstants.jointElements.minWidth ? GBPConstants.jointElements.minWidth :
- width > GBPConstants.jointElements.maxWidth ? GBPConstants.jointElements.maxWidth : width;
- };
-
- var setHeight = function(height) {
- return height < GBPConstants.jointElements.minHeight ? GBPConstants.jointElements.minHeight :
- height > GBPConstants.jointElements.maxHeight ? GBPConstants.jointElements.maxHeight : height;
- };
-
- // joint.shapes.basic.Rect = joint.shapes.basic.Generic.extend({
- joint.shapes.html = {};
- joint.shapes.html.Element = joint.shapes.basic.Generic.extend({
-
- markup: '<g class="rotatable"><g class="scalable"><rect/><title /></g><text class="text1"></text><text class="text2"></text><title /></g>',
-
- defaults: joint.util.deepSupplement({
- type: 'html.Element',
- attrs: {
- 'rect': { fill: bgcolor, stroke: 'black', 'follow-scale': true, width: 80, height: 40, cursor: 'pointer' },
- '.text1': { ref: 'rect', 'ref-x': 0.5, 'ref-y': 0.3, 'y-alignment': 'middle', 'x-alignment': 'middle', cursor: 'pointer', 'font-weight' : 'bold'},
- '.text2': { ref: 'rect', 'ref-x': 0.5, 'ref-y': 0.7, 'y-alignment': 'middle', 'x-alignment': 'middle', cursor: 'pointer'},
- 'title': {text: tooltip},
- }
-
- }, joint.shapes.basic.Generic.prototype.defaults)
- });
-
- // joint.shapes.html.ElementView = joint.dia.ElementView.extend({
-
- // template: [
- // '<input class="html-element" type="text" value="'+elementName+'"/>',
- // ''
- // ].join(''),
-
- // initialize: function() {
- // _.bindAll(this, 'updateBox');
- // joint.dia.ElementView.prototype.initialize.apply(this, arguments);
-
- // this.$box = $(_.template(this.template)());
- // // Prevent paper from handling pointerdown.
- // this.$box.find('input,select').on('mousedown click', function(evt) { evt.stopPropagation(); });
- // // This is an example of reacting on the input change and storing the input data in the cell model.
- // this.$box.find('input').on('change', _.bind(function(evt) {
- // this.model.set('input', $(evt.target).val());
- // }, this));
- // this.$box.find('button').on('click', _.bind(function(evt) {
- // this.model.set('button', $('.divc').css('display','block'));
- // }, this));
- // // Update the box position whenever the underlying model changes.
- // this.model.on('change', this.updateBox, this);
-
- // this.updateBox();
- // },
- // render: function() {
- // joint.dia.ElementView.prototype.render.apply(this, arguments);
- // this.paper.$el.prepend(this.$box);
- // this.updateBox();
- // return this;
- // },
- // updateBox: function() {
- // // Set the position and dimension of the box so that it covers the JointJS element.
- // var bbox = this.model.getBBox();
- // // Example of updating the HTML with a data stored in the cell model.
- // this.$box.css({ width: bbox.width, height: bbox.height, left: bbox.x, top: bbox.y, transform: 'rotate(' + (this.model.get('angle') || 0) + 'deg)' });
- // },
- // removeBox: function(evt) {
- // this.$box.remove();
- // }
- // });
-
- elementName = elementName.length > 20 ? elementName.slice(0,20) + '...' : elementName;
- // width = width > 200 ? 200 : width;
-
- // return new joint.shapes.basic.Rect({
- return new joint.shapes.html.Element({
- position: { x: posx || 0, y: posy || 0 },
- size: { width: width || GBPConstants.jointElements.minWidth, height: height || GBPConstants.jointElements.minHeight },
- attrs: { rect: { fill: bgcolor }, '.text1': { fill: 'black', text: titleName}, '.text2': { fill: 'black', text: elementName }},
- objType: objectType,
- objData: object
- });
- };
-
- jgf.transformElement = function(element, transformX, transformY) {
- return element.translate(transformX, transformY);
- };
-
- jgf.addItem = function(graph, item) {
- graph.addCells([item]);
- };
-
- jgf.addItemList = function(graph, listItem) {
- graph.addCells(listItem);
- };
-
- jgf.createLink = function(srcId, targetId, colorIn, colorOut, direction, objData) {
- colorIn = colorIn || defaulColor;
- colorOut = colorOut || defaulColor;
-
- var labelTextColor = GBPConstants.colors[GBPConstants.strings.sigmaTopoDefaultText],
- labelBckColor = GBPConstants.colors[GBPConstants.strings.linklabel];
-
- var linkObj = {
- source: { id: srcId },
- target: { id: targetId },
- attrs: {
- '.connection': { stroke: colorIn, 'stroke-width': 2, name: 'normal' },
- '.connection-wrap': { 'stroke-width': 10 }
- },
- objData: objData
- };
-
- if(direction === 'in' || direction == 'bidirectional' || direction === undefined || direction === null) {
- linkObj.attrs['.marker-target'] = { fill: colorIn, d: 'M 10 0 L 0 5 L 10 10 z' };
- }
-
- if(direction === 'out' || direction == 'bidirectional') {
- linkObj.attrs['.marker-source'] = { fill: colorOut, d: 'M 10 0 L 0 5 L 10 10 z' };
- }
-
- var link = new joint.dia.Link(linkObj);
-
- // if(labelText) {
- // link.label(0, { position: 0.3, attrs: { text: { text: labelText, fill: labelTextColor }, rect: { stroke: labelBckColor, 'stroke-width': 20 }}});
- // }
-
-
- return link;
- };
-
- return jgf;
- });
-
- gbpOld.register.factory('GBPJointGraphBuilder', function(GBPRestangular, GBPConstants, JointGraphFactory, JointGraphOffsetFactory, TopologyDataLoaders){
- var jgb = {};
-
- var builders = {};
-
- var buildJointData = function(paper, nodes, links) {
-
- };
-
- var setOperConfigTopoData = function(paper, data){
- var topo = TopologyDataLoaders.getEpgTopo(data);
-
- var offsetObj = {
- ow: 100,
- oh: 100,
- w: 100,
- h: 100
- },
- marginObj = {
- w: 50,
- h: 80
- },
- offsetHobj = {
- pEpg: 0,
- cEpg: 0,
- subject: 0
- },
- itemsArray = {
- epg: []
- },
- linksArray = [];
-
- JointGraphFactory.resetGraphDimension(paper, $('.policyGraphWrapper'));
- JointGraphFactory.reloadGraph(paper.model);
-
- var deg2rad = function(deg){
- return deg * Math.PI / 180;
- };
-
- var getXYInCircle = function(elementIndex, elementsCount, paperCenterX, paperCenterY, elementWidth, elementHeight){
- var result = {x:0, y:0};
- circleMargin = 100;
- r = (paperCenterX < paperCenterY ? paperCenterX : paperCenterY ) - circleMargin;
- degs = 360 / elementsCount * (elementIndex+1) + 180;
- rads = deg2rad(degs);
-
- elementWidth = elementWidth ? elementWidth : GBPConstants.jointElements.minWidth;
- elementHeight = elementHeight ? elementHeight : GBPConstants.jointElements.minHeight;
-
- if(elementWidth < GBPConstants.jointElements.minWidth){elementWidth = GBPConstants.jointElements.minWidth;}
- if(elementWidth > GBPConstants.jointElements.maxWidth){elementWidth = GBPConstants.jointElements.maxWidth;}
- if(elementHeight < GBPConstants.jointElements.minHeight){elementHeight = GBPConstants.jointElements.minHeight;}
- if(elementHeight > GBPConstants.jointElements.maxHeight){elementHeight = GBPConstants.jointElements.maxHeight;}
-
- result.x = paperCenterX + r * Math.cos(rads);
- result.y = paperCenterY + r * Math.sin(rads);
-
- degs = degs % 360;
- if(degs > 90 && degs < 270){
- result.x = result.x - elementWidth;
- }
- if(degs == 90 || degs == 270){
- result.x = result.x - elementWidth / 2;
- }
- if(degs > 180 && degs < 360){
- result.y = result.y - elementHeight;
- }
- if(degs === 0 || degs == 180){
- result.y = result.y - elementHeight / 2;
- }
- return result;
- };
-
- var paperCenterX = (paper.options.width) / 2;
- var paperCenterY = (paper.options.height) / 2;
- topo.nodes.forEach(function(i, index){
- var label = i.label,
- header = 'Epg',
- width = Math.max(JointGraphFactory.getLabelLength(label.length), JointGraphFactory.getLabelLength(header.length)),
- color = GBPConstants.colors[GBPConstants.strings.epg];
-
- var itemPos = getXYInCircle(index, topo.nodes.length, paperCenterX, paperCenterY, width, null);
- var item = JointGraphFactory.createElement(label, itemPos.x, itemPos.y, width, null, GBPConstants.strings.epg , i, label, color, header);
-
- itemsArray.epg.push(item);
-
- // JointGraphOffsetFactory.updateOffsets(JointGraphOffsetFactory.createWHObj(width), offsetObj, marginObj, JointGraphOffsetFactory.createWHObj(paper.options.width, paper.options.height), paper);
- JointGraphFactory.addItem(paper.model, item);
- });
-
- var getItemById = function(id, array){
- var item = array.filter(function(i){
- return i.attributes.objData.id === id;
- });
-
- return item.length ? item[0] : null;
- };
-
- topo.links.forEach(function(l){
- var sourceItem = getItemById(l.source, itemsArray.epg),
- targetItem = getItemById(l.target, itemsArray.epg);
-
- if (sourceItem && targetItem) {
- var link = JointGraphFactory.createLink(sourceItem.id, targetItem.id, 'blue', 'green', l.direction, l.data);
- linksArray.push(link);
- }
- });
-
- JointGraphFactory.addItemList(paper.model, linksArray);
- };
-
- jgb.loadTopology = function(args, paper, type) {
- if(type === null || builders.hasOwnProperty(type) === false) {
- type = GBPConstants.strings.empty;
- }
-
- builders[type](args, paper);
- };
-
- builders[GBPConstants.strings.empty] = function(args, paper) {
- JointGraphFactory.reloadGraph(paper.model);
- };
-
- builders[GBPConstants.strings.config] = function(args, paper) {
- var storage = args.storage || 'config',
- tenantId = args.tenantId;
-
-
- TopologyDataLoaders.getSubjectsBetweenEndpointGroups(false, tenantId, function(data){
- setOperConfigTopoData(paper, data);
- }, function(){});
- };
-
- builders[GBPConstants.strings.oper] = function(args, paper) {
- var storage = args.storage || 'config',
- tenantId = args.tenantId;
-
- TopologyDataLoaders.getSubjectsBetweenEndpointGroups(true, tenantId, function(data){
- setOperConfigTopoData(paper, data);
- }, function(){});
- };
-
- builders[GBPConstants.strings.l2l3] = function(args, paper) {
- var storage = args.storage || 'config',
- tenantId = args.tenantId;
-
- if(storage && tenantId) {
- restObj = GBPRestangular.one('restconf').one(storage).one('policy:tenants').one('tenant').one(tenantId);
-
- restObj.get().then(function(data) {
- var createLinks = function(srcList, srcItems, dstItems) {
- var linkItems = srcList.map(function(srcObj) {
- var linkItem = null;
- if(srcObj.parent && dstItems[srcObj.parent]) {
- linkItem = JointGraphFactory.createLink(srcItems[srcObj.id].id, dstItems[srcObj.parent].id, 'blue');
- }
- return linkItem;
- }).filter(function(linkObj) {
- return linkObj !== null;
- });
-
- return linkItems;
- };
-
- var offsetObj = {
- ow: 100,
- oh: 100,
- w: 100,
- h: 100
- },
- marginObj = {
- w: 50,
- h: 80
- },
- itemsArray = {
- l3: {},
- l2bridge: {},
- l2flood: {},
- subnets: {}
- };
-
- JointGraphFactory.reloadGraph(paper.model);
-
- data.tenant[0]['l3-context'].forEach(function(c, i) {
- var label = c.name || c.id,
- header = 'L3 context',
- color = GBPConstants.colors[GBPConstants.strings.l3ctx],
- width = Math.max(JointGraphFactory.getLabelLength(label.length), JointGraphFactory.getLabelLength(header.length));
- item = JointGraphFactory.createElement(label, offsetObj.w, offsetObj.h, width, null, GBPConstants.strings.l3ctx , c, null, color, header);
-
- itemsArray.l3[c.id] = item;
-
- JointGraphOffsetFactory.updateOffsets(JointGraphOffsetFactory.createWHObj(width), offsetObj, marginObj, JointGraphOffsetFactory.createWHObj(paper.options.width, paper.options.height), paper);
- JointGraphFactory.addItem(paper.model, item);
- });
-
- JointGraphOffsetFactory.resetOffsets(offsetObj, offsetObj.ow, offsetObj.h + 100);
-
- data.tenant[0]['l2-bridge-domain'].forEach(function(c, i) {
- var label = c.name || c.id,
- header = 'L2 bridge domain',
- color = GBPConstants.colors[GBPConstants.strings.bridge],
- width = Math.max(JointGraphFactory.getLabelLength(label.length), JointGraphFactory.getLabelLength(header.length));
- item = JointGraphFactory.createElement(label, offsetObj.w, offsetObj.h, width, null, GBPConstants.strings.bridge , c, null, color, header);
-
- itemsArray.l2bridge[c.id] = item;
-
- JointGraphOffsetFactory.updateOffsets(JointGraphOffsetFactory.createWHObj(width), offsetObj, marginObj, JointGraphOffsetFactory.createWHObj(paper.options.width, paper.options.height), paper);
- JointGraphFactory.addItem(paper.model, item);
- });
-
- JointGraphOffsetFactory.resetOffsets(offsetObj, offsetObj.ow, offsetObj.h + 100);
-
- data.tenant[0]['l2-flood-domain'].forEach(function(c, i) {
- var label = c.name || c.id,
- header = 'L2 flood domain',
- color = GBPConstants.colors[GBPConstants.strings.flood],
- width = Math.max(JointGraphFactory.getLabelLength(label.length), JointGraphFactory.getLabelLength(header.length));
- item = JointGraphFactory.createElement(label, offsetObj.w, offsetObj.h, width, null, GBPConstants.strings.flood , c, null, color, header);
-
- itemsArray.l2flood[c.id] = item;
-
- JointGraphOffsetFactory.updateOffsets(JointGraphOffsetFactory.createWHObj(width), offsetObj, marginObj, JointGraphOffsetFactory.createWHObj(paper.options.width, paper.options.height), paper);
- JointGraphFactory.addItem(paper.model, item);
- });
-
- JointGraphOffsetFactory.resetOffsets(offsetObj, offsetObj.ow, offsetObj.h + 100);
-
- data.tenant[0]['subnet'].forEach(function(c, i) {
- var label = c.name || c.id,
- header = 'Subnet',
- color = GBPConstants.colors[GBPConstants.strings.subnet],
- width = Math.max(JointGraphFactory.getLabelLength(label.length), JointGraphFactory.getLabelLength(header.length));
- item = JointGraphFactory.createElement(label, offsetObj.w, offsetObj.h, width, null, GBPConstants.strings.subnet , c, null, color, header);
-
- itemsArray.subnets[c.id] = item;
-
- JointGraphOffsetFactory.updateOffsets(JointGraphOffsetFactory.createWHObj(width), offsetObj, marginObj, JointGraphOffsetFactory.createWHObj(paper.options.width, paper.options.height), paper);
- JointGraphFactory.addItem(paper.model, item);
- });
-
- JointGraphOffsetFactory.resetOffsets(offsetObj, offsetObj.ow, offsetObj.oh);
-
- var l2bridgeL3 = createLinks(data.tenant[0]['l2-bridge-domain'], itemsArray.l2bridge, itemsArray.l3);
- JointGraphFactory.addItemList(paper.model, l2bridgeL3);
-
- var l2floodL2bridge = createLinks(data.tenant[0]['l2-flood-domain'], itemsArray.l2flood, itemsArray.l2bridge);
- JointGraphFactory.addItemList(paper.model, l2floodL2bridge);
-
- var l2floodSubnet = createLinks(data.tenant[0]['subnet'], itemsArray.subnets, itemsArray.l2flood);
- JointGraphFactory.addItemList(paper.model, l2floodSubnet);
-
- var l2bridgeSubnet = createLinks(data.tenant[0]['subnet'], itemsArray.subnets, itemsArray.l2bridge);
- JointGraphFactory.addItemList(paper.model, l2bridgeSubnet);
-
- var l3Subnet = createLinks(data.tenant[0]['subnet'], itemsArray.subnets, itemsArray.l3);
- JointGraphFactory.addItemList(paper.model, l3Subnet);
-
- }, function() {
-
- });
- }
- };
-
-
- return jgb;
- });
-});
+++ /dev/null
-(function(t){var e=typeof self=="object"&&self.self==self&&self||typeof global=="object"&&global.global==global&&global;if(typeof define==="function"&&define.amd){define(["underscore","jquery","exports"],function(i,r,s){e.Backbone=t(e,s,i,r)})}else if(typeof exports!=="undefined"){var i=require("underscore"),r;try{r=require("jquery")}catch(s){}t(e,exports,i,r)}else{e.Backbone=t(e,{},e._,e.jQuery||e.Zepto||e.ender||e.$)}})(function(t,e,i,r){var s=t.Backbone;var n=[];var a=n.slice;e.VERSION="1.2.0";e.$=r;e.noConflict=function(){t.Backbone=s;return this};e.emulateHTTP=false;e.emulateJSON=false;var o=e.Events={};var h=/\s+/;var u=function(t,e,r,s,n){var a=0,o;if(r&&typeof r==="object"){for(o=i.keys(r);a<o.length;a++){e=t(e,o[a],r[o[a]],n)}}else if(r&&h.test(r)){for(o=r.split(h);a<o.length;a++){e=t(e,o[a],s,n)}}else{e=t(e,r,s,n)}return e};o.on=function(t,e,i){return l(this,t,e,i)};var l=function(t,e,i,r,s){t._events=u(c,t._events||{},e,i,{context:r,ctx:t,listening:s});if(s){var n=t._listeners||(t._listeners={});n[s.id]=s}return t};o.listenTo=function(t,e,r){if(!t)return this;var s=t._listenId||(t._listenId=i.uniqueId("l"));var n=this._listeningTo||(this._listeningTo={});var a=n[s];if(!a){var o=this._listenId||(this._listenId=i.uniqueId("l"));a=n[s]={obj:t,objId:s,id:o,listeningTo:n,count:0}}l(t,e,r,this,a);return this};var c=function(t,e,i,r){if(i){var s=t[e]||(t[e]=[]);var n=r.context,a=r.ctx,o=r.listening;if(o)o.count++;s.push({callback:i,context:n,ctx:n||a,listening:o})}return t};o.off=function(t,e,i){if(!this._events)return this;this._events=u(f,this._events,t,e,{context:i,listeners:this._listeners});return this};o.stopListening=function(t,e,r){var s=this._listeningTo;if(!s)return this;var n=t?[t._listenId]:i.keys(s);for(var a=0;a<n.length;a++){var o=s[n[a]];if(!o)break;o.obj.off(e,r,this)}if(i.isEmpty(s))this._listeningTo=void 0;return this};var f=function(t,e,r,s){if(!t)return;var n=0,a,o;var h=s.context,u=s.listeners;if(!e&&!r&&!h){var l=i.keys(u);for(;n<l.length;n++){o=u[l[n]];delete u[o.id];delete o.listeningTo[o.objId]}return}var c=e?[e]:i.keys(t);for(;n<c.length;n++){e=c[n];var f=t[e];if(!f)break;var d=[];for(var v=0;v<f.length;v++){var g=f[v];if(r&&r!==g.callback&&r!==g.callback._callback||h&&h!==g.context){d.push(g)}else{o=g.listening;if(o&&--o.count===0){delete u[o.id];delete o.listeningTo[o.objId]}}}if(d.length){t[e]=d}else{delete t[e]}}if(i.size(t))return t};o.once=function(t,e,r){var s=u(d,{},t,e,i.bind(this.off,this));return this.on(s,void 0,r)};o.listenToOnce=function(t,e,r){var s=u(d,{},e,r,i.bind(this.stopListening,this,t));return this.listenTo(t,s)};var d=function(t,e,r,s){if(r){var n=t[e]=i.once(function(){s(e,n);r.apply(this,arguments)});n._callback=r}return t};o.trigger=function(t){if(!this._events)return this;var e=Math.max(0,arguments.length-1);var i=Array(e);for(var r=0;r<e;r++)i[r]=arguments[r+1];u(v,this._events,t,void 0,i);return this};var v=function(t,e,i,r){if(t){var s=t[e];var n=t.all;if(s&&n)n=n.slice();if(s)g(s,r);if(n)g(n,[e].concat(r))}return t};var g=function(t,e){var i,r=-1,s=t.length,n=e[0],a=e[1],o=e[2];switch(e.length){case 0:while(++r<s)(i=t[r]).callback.call(i.ctx);return;case 1:while(++r<s)(i=t[r]).callback.call(i.ctx,n);return;case 2:while(++r<s)(i=t[r]).callback.call(i.ctx,n,a);return;case 3:while(++r<s)(i=t[r]).callback.call(i.ctx,n,a,o);return;default:while(++r<s)(i=t[r]).callback.apply(i.ctx,e);return}};var p=function(t,e,r){switch(t){case 1:return function(){return i[e](this[r])};case 2:return function(t){return i[e](this[r],t)};case 3:return function(t,s){return i[e](this[r],t,s)};case 4:return function(t,s,n){return i[e](this[r],t,s,n)};default:return function(){var t=a.call(arguments);t.unshift(this[r]);return i[e].apply(i,t)}}};var m=function(t,e,r){i.each(e,function(e,s){if(i[s])t.prototype[s]=p(e,s,r)})};o.bind=o.on;o.unbind=o.off;i.extend(e,o);var _=e.Model=function(t,e){var r=t||{};e||(e={});this.cid=i.uniqueId(this.cidPrefix);this.attributes={};if(e.collection)this.collection=e.collection;if(e.parse)r=this.parse(r,e)||{};r=i.defaults({},r,i.result(this,"defaults"));this.set(r,e);this.changed={};this.initialize.apply(this,arguments)};i.extend(_.prototype,o,{changed:null,validationError:null,idAttribute:"id",cidPrefix:"c",initialize:function(){},toJSON:function(t){return i.clone(this.attributes)},sync:function(){return e.sync.apply(this,arguments)},get:function(t){return this.attributes[t]},escape:function(t){return i.escape(this.get(t))},has:function(t){return this.get(t)!=null},matches:function(t){return!!i.iteratee(t,this)(this.attributes)},set:function(t,e,r){var s,n,a,o,h,u,l,c;if(t==null)return this;if(typeof t==="object"){n=t;r=e}else{(n={})[t]=e}r||(r={});if(!this._validate(n,r))return false;a=r.unset;h=r.silent;o=[];u=this._changing;this._changing=true;if(!u){this._previousAttributes=i.clone(this.attributes);this.changed={}}c=this.attributes,l=this._previousAttributes;if(this.idAttribute in n)this.id=n[this.idAttribute];for(s in n){e=n[s];if(!i.isEqual(c[s],e))o.push(s);if(!i.isEqual(l[s],e)){this.changed[s]=e}else{delete this.changed[s]}a?delete c[s]:c[s]=e}if(!h){if(o.length)this._pending=r;for(var f=0;f<o.length;f++){this.trigger("change:"+o[f],this,c[o[f]],r)}}if(u)return this;if(!h){while(this._pending){r=this._pending;this._pending=false;this.trigger("change",this,r)}}this._pending=false;this._changing=false;return this},unset:function(t,e){return this.set(t,void 0,i.extend({},e,{unset:true}))},clear:function(t){var e={};for(var r in this.attributes)e[r]=void 0;return this.set(e,i.extend({},t,{unset:true}))},hasChanged:function(t){if(t==null)return!i.isEmpty(this.changed);return i.has(this.changed,t)},changedAttributes:function(t){if(!t)return this.hasChanged()?i.clone(this.changed):false;var e,r=false;var s=this._changing?this._previousAttributes:this.attributes;for(var n in t){if(i.isEqual(s[n],e=t[n]))continue;(r||(r={}))[n]=e}return r},previous:function(t){if(t==null||!this._previousAttributes)return null;return this._previousAttributes[t]},previousAttributes:function(){return i.clone(this._previousAttributes)},fetch:function(t){t=t?i.clone(t):{};if(t.parse===void 0)t.parse=true;var e=this;var r=t.success;t.success=function(i){if(!e.set(e.parse(i,t),t))return false;if(r)r.call(t.context,e,i,t);e.trigger("sync",e,i,t)};F(this,t);return this.sync("read",this,t)},save:function(t,e,r){var s,n,a,o=this.attributes,h;if(t==null||typeof t==="object"){s=t;r=e}else{(s={})[t]=e}r=i.extend({validate:true},r);h=r.wait;if(s&&!h){if(!this.set(s,r))return false}else{if(!this._validate(s,r))return false}if(s&&h){this.attributes=i.extend({},o,s)}if(r.parse===void 0)r.parse=true;var u=this;var l=r.success;r.success=function(t){u.attributes=o;var e=r.parse?u.parse(t,r):t;if(h)e=i.extend(s||{},e);if(i.isObject(e)&&!u.set(e,r)){return false}if(l)l.call(r.context,u,t,r);u.trigger("sync",u,t,r)};F(this,r);n=this.isNew()?"create":r.patch?"patch":"update";if(n==="patch"&&!r.attrs)r.attrs=s;a=this.sync(n,this,r);if(s&&h)this.attributes=o;return a},destroy:function(t){t=t?i.clone(t):{};var e=this;var r=t.success;var s=t.wait;var n=function(){e.stopListening();e.trigger("destroy",e,e.collection,t)};t.success=function(i){if(s)n();if(r)r.call(t.context,e,i,t);if(!e.isNew())e.trigger("sync",e,i,t)};var a=false;if(this.isNew()){i.defer(t.success)}else{F(this,t);a=this.sync("delete",this,t)}if(!s)n();return a},url:function(){var t=i.result(this,"urlRoot")||i.result(this.collection,"url")||q();if(this.isNew())return t;var e=this.id||this.attributes[this.idAttribute];return t.replace(/([^\/])$/,"$1/")+encodeURIComponent(e)},parse:function(t,e){return t},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return!this.has(this.idAttribute)},isValid:function(t){return this._validate({},i.extend(t||{},{validate:true}))},_validate:function(t,e){if(!e.validate||!this.validate)return true;t=i.extend({},this.attributes,t);var r=this.validationError=this.validate(t,e)||null;if(!r)return true;this.trigger("invalid",this,r,i.extend(e,{validationError:r}));return false}});var y={keys:1,values:1,pairs:1,invert:1,pick:0,omit:0,chain:1,isEmpty:1};m(_,y,"attributes");var b=e.Collection=function(t,e){e||(e={});if(e.model)this.model=e.model;if(e.comparator!==void 0)this.comparator=e.comparator;this._reset();this.initialize.apply(this,arguments);if(t)this.reset(t,i.extend({silent:true},e))};var x={add:true,remove:true,merge:true};var w={add:true,remove:false};i.extend(b.prototype,o,{model:_,initialize:function(){},toJSON:function(t){return this.map(function(e){return e.toJSON(t)})},sync:function(){return e.sync.apply(this,arguments)},add:function(t,e){return this.set(t,i.extend({merge:false},e,w))},remove:function(t,e){var r=!i.isArray(t),s;t=r?[t]:i.clone(t);e||(e={});s=this._removeModels(t,e);if(!e.silent&&s)this.trigger("update",this,e);return r?t[0]:t},set:function(t,e){e=i.defaults({},e,x);if(e.parse)t=this.parse(t,e);var r=!i.isArray(t);t=r?t?[t]:[]:t.slice();var s,n,a,o,h;var u=e.at;if(u!=null)u=+u;if(u<0)u+=this.length+1;var l=this.comparator&&u==null&&e.sort!==false;var c=i.isString(this.comparator)?this.comparator:null;var f=[],d=[],v={};var g=e.add,p=e.merge,m=e.remove;var _=!l&&g&&m?[]:false;var y=false;for(var b=0;b<t.length;b++){a=t[b];if(o=this.get(a)){if(m)v[o.cid]=true;if(p&&a!==o){a=this._isModel(a)?a.attributes:a;if(e.parse)a=o.parse(a,e);o.set(a,e);if(l&&!h&&o.hasChanged(c))h=true}t[b]=o}else if(g){n=t[b]=this._prepareModel(a,e);if(!n)continue;f.push(n);this._addReference(n,e)}n=o||n;if(!n)continue;s=this.modelId(n.attributes);if(_&&(n.isNew()||!v[s])){_.push(n);y=y||!this.models[b]||n.cid!==this.models[b].cid}v[s]=true}if(m){for(var b=0;b<this.length;b++){if(!v[(n=this.models[b]).cid])d.push(n)}if(d.length)this._removeModels(d,e)}if(f.length||y){if(l)h=true;this.length+=f.length;if(u!=null){for(var b=0;b<f.length;b++){this.models.splice(u+b,0,f[b])}}else{if(_)this.models.length=0;var w=_||f;for(var b=0;b<w.length;b++){this.models.push(w[b])}}}if(h)this.sort({silent:true});if(!e.silent){var E=u!=null?i.clone(e):e;for(var b=0;b<f.length;b++){if(u!=null)E.index=u+b;(n=f[b]).trigger("add",n,this,E)}if(h||y)this.trigger("sort",this,e);if(f.length||d.length)this.trigger("update",this,e)}return r?t[0]:t},reset:function(t,e){e=e?i.clone(e):{};for(var r=0;r<this.models.length;r++){this._removeReference(this.models[r],e)}e.previousModels=this.models;this._reset();t=this.add(t,i.extend({silent:true},e));if(!e.silent)this.trigger("reset",this,e);return t},push:function(t,e){return this.add(t,i.extend({at:this.length},e))},pop:function(t){var e=this.at(this.length-1);this.remove(e,t);return e},unshift:function(t,e){return this.add(t,i.extend({at:0},e))},shift:function(t){var e=this.at(0);this.remove(e,t);return e},slice:function(){return a.apply(this.models,arguments)},get:function(t){if(t==null)return void 0;var e=this.modelId(this._isModel(t)?t.attributes:t);return this._byId[t]||this._byId[e]||this._byId[t.cid]},at:function(t){if(t<0)t+=this.length;return this.models[t]},where:function(t,e){var r=i.matches(t);return this[e?"find":"filter"](function(t){return r(t.attributes)})},findWhere:function(t){return this.where(t,true)},sort:function(t){if(!this.comparator)throw new Error("Cannot sort a set without a comparator");t||(t={});if(i.isString(this.comparator)||this.comparator.length===1){this.models=this.sortBy(this.comparator,this)}else{this.models.sort(i.bind(this.comparator,this))}if(!t.silent)this.trigger("sort",this,t);return this},pluck:function(t){return i.invoke(this.models,"get",t)},fetch:function(t){t=t?i.clone(t):{};if(t.parse===void 0)t.parse=true;var e=t.success;var r=this;t.success=function(i){var s=t.reset?"reset":"set";r[s](i,t);if(e)e.call(t.context,r,i,t);r.trigger("sync",r,i,t)};F(this,t);return this.sync("read",this,t)},create:function(t,e){e=e?i.clone(e):{};var r=e.wait;if(!(t=this._prepareModel(t,e)))return false;if(!r)this.add(t,e);var s=this;var n=e.success;e.success=function(t,e,i){if(r)s.add(t,i);if(n)n.call(i.context,t,e,i)};t.save(null,e);return t},parse:function(t,e){return t},clone:function(){return new this.constructor(this.models,{model:this.model,comparator:this.comparator})},modelId:function(t){return t[this.model.prototype.idAttribute||"id"]},_reset:function(){this.length=0;this.models=[];this._byId={}},_prepareModel:function(t,e){if(this._isModel(t)){if(!t.collection)t.collection=this;return t}e=e?i.clone(e):{};e.collection=this;var r=new this.model(t,e);if(!r.validationError)return r;this.trigger("invalid",this,r.validationError,e);return false},_removeModels:function(t,e){var i,r,s,n,a=false;for(var i=0,o=0;i<t.length;i++){var n=t[i]=this.get(t[i]);if(!n)continue;var h=this.modelId(n.attributes);if(h!=null)delete this._byId[h];delete this._byId[n.cid];var s=this.indexOf(n);this.models.splice(s,1);this.length--;if(!e.silent){e.index=s;n.trigger("remove",n,this,e)}t[o++]=n;this._removeReference(n,e);a=true}if(t.length!==o)t=t.slice(0,o);return a},_isModel:function(t){return t instanceof _},_addReference:function(t,e){this._byId[t.cid]=t;var i=this.modelId(t.attributes);if(i!=null)this._byId[i]=t;t.on("all",this._onModelEvent,this)},_removeReference:function(t,e){if(this===t.collection)delete t.collection;t.off("all",this._onModelEvent,this)},_onModelEvent:function(t,e,i,r){if((t==="add"||t==="remove")&&i!==this)return;if(t==="destroy")this.remove(e,r);if(t==="change"){var s=this.modelId(e.previousAttributes());var n=this.modelId(e.attributes);if(s!==n){if(s!=null)delete this._byId[s];if(n!=null)this._byId[n]=e}}this.trigger.apply(this,arguments)}});var E={forEach:3,each:3,map:3,collect:3,reduce:4,foldl:4,inject:4,reduceRight:4,foldr:4,find:3,detect:3,filter:3,select:3,reject:3,every:3,all:3,some:3,any:3,include:2,contains:2,invoke:2,max:3,min:3,toArray:1,size:1,first:3,head:3,take:3,initial:3,rest:3,tail:3,drop:3,last:3,without:0,difference:0,indexOf:3,shuffle:1,lastIndexOf:3,isEmpty:1,chain:1,sample:3,partition:3};m(b,E,"models");var k=["groupBy","countBy","sortBy","indexBy"];i.each(k,function(t){if(!i[t])return;b.prototype[t]=function(e,r){var s=i.isFunction(e)?e:function(t){return t.get(e)};return i[t](this.models,s,r)}});var S=e.View=function(t){this.cid=i.uniqueId("view");t||(t={});i.extend(this,i.pick(t,T));this._ensureElement();this.initialize.apply(this,arguments)};var I=/^(\S+)\s*(.*)$/;var T=["model","collection","el","id","attributes","className","tagName","events"];i.extend(S.prototype,o,{tagName:"div",$:function(t){return this.$el.find(t)},initialize:function(){},render:function(){return this},remove:function(){this._removeElement();this.stopListening();return this},_removeElement:function(){this.$el.remove()},setElement:function(t){this.undelegateEvents();this._setElement(t);this.delegateEvents();return this},_setElement:function(t){this.$el=t instanceof e.$?t:e.$(t);this.el=this.$el[0]},delegateEvents:function(t){if(!(t||(t=i.result(this,"events"))))return this;this.undelegateEvents();for(var e in t){var r=t[e];if(!i.isFunction(r))r=this[t[e]];if(!r)continue;var s=e.match(I);this.delegate(s[1],s[2],i.bind(r,this))}return this},delegate:function(t,e,i){this.$el.on(t+".delegateEvents"+this.cid,e,i)},undelegateEvents:function(){if(this.$el)this.$el.off(".delegateEvents"+this.cid);return this},undelegate:function(t,e,i){this.$el.off(t+".delegateEvents"+this.cid,e,i)},_createElement:function(t){return document.createElement(t)},_ensureElement:function(){if(!this.el){var t=i.extend({},i.result(this,"attributes"));if(this.id)t.id=i.result(this,"id");if(this.className)t["class"]=i.result(this,"className");this.setElement(this._createElement(i.result(this,"tagName")));this._setAttributes(t)}else{this.setElement(i.result(this,"el"))}},_setAttributes:function(t){this.$el.attr(t)}});e.sync=function(t,r,s){var n=P[t];i.defaults(s||(s={}),{emulateHTTP:e.emulateHTTP,emulateJSON:e.emulateJSON});var a={type:n,dataType:"json"};if(!s.url){a.url=i.result(r,"url")||q()}if(s.data==null&&r&&(t==="create"||t==="update"||t==="patch")){a.contentType="application/json";a.data=JSON.stringify(s.attrs||r.toJSON(s))}if(s.emulateJSON){a.contentType="application/x-www-form-urlencoded";a.data=a.data?{model:a.data}:{}}if(s.emulateHTTP&&(n==="PUT"||n==="DELETE"||n==="PATCH")){a.type="POST";if(s.emulateJSON)a.data._method=n;var o=s.beforeSend;s.beforeSend=function(t){t.setRequestHeader("X-HTTP-Method-Override",n);if(o)return o.apply(this,arguments)}}if(a.type!=="GET"&&!s.emulateJSON){a.processData=false}var h=s.error;s.error=function(t,e,i){s.textStatus=e;s.errorThrown=i;if(h)h.call(s.context,t,e,i)};var u=s.xhr=e.ajax(i.extend(a,s));r.trigger("request",r,u,s);return u};var P={create:"POST",update:"PUT",patch:"PATCH","delete":"DELETE",read:"GET"};e.ajax=function(){return e.$.ajax.apply(e.$,arguments)};var H=e.Router=function(t){t||(t={});if(t.routes)this.routes=t.routes;this._bindRoutes();this.initialize.apply(this,arguments)};var $=/\((.*?)\)/g;var A=/(\(\?)?:\w+/g;var C=/\*\w+/g;var N=/[\-{}\[\]+?.,\\\^$|#\s]/g;i.extend(H.prototype,o,{initialize:function(){},route:function(t,r,s){if(!i.isRegExp(t))t=this._routeToRegExp(t);if(i.isFunction(r)){s=r;r=""}if(!s)s=this[r];var n=this;e.history.route(t,function(i){var a=n._extractParameters(t,i);if(n.execute(s,a,r)!==false){n.trigger.apply(n,["route:"+r].concat(a));n.trigger("route",r,a);e.history.trigger("route",n,r,a)}});return this},execute:function(t,e,i){if(t)t.apply(this,e)},navigate:function(t,i){e.history.navigate(t,i);return this},_bindRoutes:function(){if(!this.routes)return;this.routes=i.result(this,"routes");var t,e=i.keys(this.routes);while((t=e.pop())!=null){this.route(t,this.routes[t])}},_routeToRegExp:function(t){t=t.replace(N,"\\$&").replace($,"(?:$1)?").replace(A,function(t,e){return e?t:"([^/?]+)"}).replace(C,"([^?]*?)");return new RegExp("^"+t+"(?:\\?([\\s\\S]*))?$")},_extractParameters:function(t,e){var r=t.exec(e).slice(1);return i.map(r,function(t,e){if(e===r.length-1)return t||null;return t?decodeURIComponent(t):null})}});var R=e.History=function(){this.handlers=[];i.bindAll(this,"checkUrl");if(typeof window!=="undefined"){this.location=window.location;this.history=window.history}};var j=/^[#\/]|\s+$/g;var O=/^\/+|\/+$/g;var U=/#.*$/;R.started=false;i.extend(R.prototype,o,{interval:50,atRoot:function(){var t=this.location.pathname.replace(/[^\/]$/,"$&/");return t===this.root&&!this.getSearch()},matchRoot:function(){var t=this.decodeFragment(this.location.pathname);var e=t.slice(0,this.root.length-1)+"/";return e===this.root},decodeFragment:function(t){return decodeURI(t.replace(/%25/g,"%2525"))},getSearch:function(){var t=this.location.href.replace(/#.*/,"").match(/\?.+/);return t?t[0]:""},getHash:function(t){var e=(t||this).location.href.match(/#(.*)$/);return e?e[1]:""},getPath:function(){var t=this.decodeFragment(this.location.pathname+this.getSearch()).slice(this.root.length-1);return t.charAt(0)==="/"?t.slice(1):t},getFragment:function(t){if(t==null){if(this._usePushState||!this._wantsHashChange){t=this.getPath()}else{t=this.getHash()}}return t.replace(j,"")},start:function(t){if(R.started)throw new Error("Backbone.history has already been started");R.started=true;this.options=i.extend({root:"/"},this.options,t);this.root=this.options.root;this._wantsHashChange=this.options.hashChange!==false;this._hasHashChange="onhashchange"in window;this._useHashChange=this._wantsHashChange&&this._hasHashChange;this._wantsPushState=!!this.options.pushState;this._hasPushState=!!(this.history&&this.history.pushState);this._usePushState=this._wantsPushState&&this._hasPushState;this.fragment=this.getFragment();this.root=("/"+this.root+"/").replace(O,"/");if(this._wantsHashChange&&this._wantsPushState){if(!this._hasPushState&&!this.atRoot()){var e=this.root.slice(0,-1)||"/";this.location.replace(e+"#"+this.getPath());return true}else if(this._hasPushState&&this.atRoot()){this.navigate(this.getHash(),{replace:true})}}if(!this._hasHashChange&&this._wantsHashChange&&!this._usePushState){var r=document.createElement("iframe");r.src="javascript:0";r.style.display="none";r.tabIndex=-1;var s=document.body;this.iframe=s.insertBefore(r,s.firstChild).contentWindow;this.iframe.document.open().close();this.iframe.location.hash="#"+this.fragment}var n=window.addEventListener||function(t,e){return attachEvent("on"+t,e)};if(this._usePushState){n("popstate",this.checkUrl,false)}else if(this._useHashChange&&!this.iframe){n("hashchange",this.checkUrl,false)}else if(this._wantsHashChange){this._checkUrlInterval=setInterval(this.checkUrl,this.interval)}if(!this.options.silent)return this.loadUrl()},stop:function(){var t=window.removeEventListener||function(t,e){return detachEvent("on"+t,e)};if(this._usePushState){t("popstate",this.checkUrl,false)}else if(this._useHashChange&&!this.iframe){t("hashchange",this.checkUrl,false)}if(this.iframe){document.body.removeChild(this.iframe.frameElement);this.iframe=null}if(this._checkUrlInterval)clearInterval(this._checkUrlInterval);R.started=false},route:function(t,e){this.handlers.unshift({route:t,callback:e})},checkUrl:function(t){var e=this.getFragment();if(e===this.fragment&&this.iframe){e=this.getHash(this.iframe)}if(e===this.fragment)return false;if(this.iframe)this.navigate(e);this.loadUrl()},loadUrl:function(t){if(!this.matchRoot())return false;t=this.fragment=this.getFragment(t);return i.any(this.handlers,function(e){if(e.route.test(t)){e.callback(t);return true}})},navigate:function(t,e){if(!R.started)return false;if(!e||e===true)e={trigger:!!e};t=this.getFragment(t||"");var i=this.root;if(t===""||t.charAt(0)==="?"){i=i.slice(0,-1)||"/"}var r=i+t;t=this.decodeFragment(t.replace(U,""));if(this.fragment===t)return;this.fragment=t;if(this._usePushState){this.history[e.replace?"replaceState":"pushState"]({},document.title,r)}else if(this._wantsHashChange){this._updateHash(this.location,t,e.replace);if(this.iframe&&t!==this.getHash(this.iframe)){if(!e.replace)this.iframe.document.open().close();this._updateHash(this.iframe.location,t,e.replace)}}else{return this.location.assign(r)}if(e.trigger)return this.loadUrl(t)},_updateHash:function(t,e,i){if(i){var r=t.href.replace(/(javascript:|#).*$/,"");t.replace(r+"#"+e)}else{t.hash="#"+e}}});e.history=new R;var M=function(t,e){var r=this;var s;if(t&&i.has(t,"constructor")){s=t.constructor}else{s=function(){return r.apply(this,arguments)}}i.extend(s,r,e);var n=function(){this.constructor=s};n.prototype=r.prototype;s.prototype=new n;if(t)i.extend(s.prototype,t);s.__super__=r.prototype;return s};_.extend=b.extend=H.extend=S.extend=R.extend=M;var q=function(){throw new Error('A "url" property or function must be specified')};var F=function(t,e){var i=e.error;e.error=function(r){if(i)i.call(e.context,t,r,e);t.trigger("error",t,r,e)}};return e});
-//# sourceMappingURL=backbone-min.map
\ No newline at end of file
+++ /dev/null
-/*! JointJS v0.9.3 - JavaScript diagramming library 2015-05-22
-
-
-This Source Code Form is subject to the terms of the Mozilla Public
-License, v. 2.0. If a copy of the MPL was not distributed with this
-file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-// Geometry library.
-// (c) 2011-2013 client IO
-
-(function(root, factory) {
-
- if (typeof define === 'function' && define.amd) {
-
- // AMD. Register as an anonymous module.
- define([], factory);
-
- } else if (typeof exports === 'object') {
-
- // Node. Does not work with strict CommonJS, but
- // only CommonJS-like environments that support module.exports,
- // like Node.
- module.exports = factory();
-
- } else {
-
- // Browser globals.
- root.g = factory();
-
- }
-
-}(this, function() {
-
- // Declare shorthands to the most used math functions.
- var math = Math;
- var abs = math.abs;
- var cos = math.cos;
- var sin = math.sin;
- var sqrt = math.sqrt;
- var mmin = math.min;
- var mmax = math.max;
- var atan = math.atan;
- var atan2 = math.atan2;
- var acos = math.acos;
- var round = math.round;
- var floor = math.floor;
- var PI = math.PI;
- var random = math.random;
- var toDeg = function(rad) { return (180 * rad / PI) % 360; };
- var toRad = function(deg, over360) {
- over360 = over360 || false;
- deg = over360 ? deg : (deg % 360);
- return deg * PI / 180;
- };
- var snapToGrid = function(val, gridSize) { return gridSize * Math.round(val / gridSize); };
- var normalizeAngle = function(angle) { return (angle % 360) + (angle < 0 ? 360 : 0); };
-
- // Point
- // -----
-
- // Point is the most basic object consisting of x/y coordinate,.
-
- // Possible instantiations are:
-
- // * `point(10, 20)`
- // * `new point(10, 20)`
- // * `point('10 20')`
- // * `point(point(10, 20))`
- function point(x, y) {
- if (!(this instanceof point))
- return new point(x, y);
- var xy;
- if (y === undefined && Object(x) !== x) {
- xy = x.split(x.indexOf('@') === -1 ? ' ' : '@');
- this.x = parseInt(xy[0], 10);
- this.y = parseInt(xy[1], 10);
- } else if (Object(x) === x) {
- this.x = x.x;
- this.y = x.y;
- } else {
- this.x = x;
- this.y = y;
- }
- }
-
- point.prototype = {
- toString: function() {
- return this.x + '@' + this.y;
- },
- // If point lies outside rectangle `r`, return the nearest point on the boundary of rect `r`,
- // otherwise return point itself.
- // (see Squeak Smalltalk, Point>>adhereTo:)
- adhereToRect: function(r) {
- if (r.containsPoint(this)) {
- return this;
- }
- this.x = mmin(mmax(this.x, r.x), r.x + r.width);
- this.y = mmin(mmax(this.y, r.y), r.y + r.height);
- return this;
- },
- // Compute the angle between me and `p` and the x axis.
- // (cartesian-to-polar coordinates conversion)
- // Return theta angle in degrees.
- theta: function(p) {
- p = point(p);
- // Invert the y-axis.
- var y = -(p.y - this.y);
- var x = p.x - this.x;
- // Makes sure that the comparison with zero takes rounding errors into account.
- var PRECISION = 10;
- // Note that `atan2` is not defined for `x`, `y` both equal zero.
- var rad = (y.toFixed(PRECISION) == 0 && x.toFixed(PRECISION) == 0) ? 0 : atan2(y, x);
-
- // Correction for III. and IV. quadrant.
- if (rad < 0) {
- rad = 2 * PI + rad;
- }
- return 180 * rad / PI;
- },
- // Returns distance between me and point `p`.
- distance: function(p) {
- return line(this, p).length();
- },
- // Returns a manhattan (taxi-cab) distance between me and point `p`.
- manhattanDistance: function(p) {
- return abs(p.x - this.x) + abs(p.y - this.y);
- },
- // Offset me by the specified amount.
- offset: function(dx, dy) {
- this.x += dx || 0;
- this.y += dy || 0;
- return this;
- },
- magnitude: function() {
- return sqrt((this.x * this.x) + (this.y * this.y)) || 0.01;
- },
- update: function(x, y) {
- this.x = x || 0;
- this.y = y || 0;
- return this;
- },
- round: function(decimals) {
- this.x = decimals ? this.x.toFixed(decimals) : round(this.x);
- this.y = decimals ? this.y.toFixed(decimals) : round(this.y);
- return this;
- },
- // Scale the line segment between (0,0) and me to have a length of len.
- normalize: function(len) {
- var s = (len || 1) / this.magnitude();
- this.x = s * this.x;
- this.y = s * this.y;
- return this;
- },
- difference: function(p) {
- return point(this.x - p.x, this.y - p.y);
- },
- // Return the bearing between me and point `p`.
- bearing: function(p) {
- return line(this, p).bearing();
- },
- // Converts rectangular to polar coordinates.
- // An origin can be specified, otherwise it's 0@0.
- toPolar: function(o) {
- o = (o && point(o)) || point(0, 0);
- var x = this.x;
- var y = this.y;
- this.x = sqrt((x - o.x) * (x - o.x) + (y - o.y) * (y - o.y)); // r
- this.y = toRad(o.theta(point(x, y)));
- return this;
- },
- // Rotate point by angle around origin o.
- rotate: function(o, angle) {
- angle = (angle + 360) % 360;
- this.toPolar(o);
- this.y += toRad(angle);
- var p = point.fromPolar(this.x, this.y, o);
- this.x = p.x;
- this.y = p.y;
- return this;
- },
- // Move point on line starting from ref ending at me by
- // distance distance.
- move: function(ref, distance) {
- var theta = toRad(point(ref).theta(this));
- return this.offset(cos(theta) * distance, -sin(theta) * distance);
- },
- // Returns change in angle from my previous position (-dx, -dy) to my new position
- // relative to ref point.
- changeInAngle: function(dx, dy, ref) {
- // Revert the translation and measure the change in angle around x-axis.
- return point(this).offset(-dx, -dy).theta(ref) - this.theta(ref);
- },
- equals: function(p) {
- return this.x === p.x && this.y === p.y;
- },
- snapToGrid: function(gx, gy) {
- this.x = snapToGrid(this.x, gx);
- this.y = snapToGrid(this.y, gy || gx);
- return this;
- },
- // Returns a point that is the reflection of me with
- // the center of inversion in ref point.
- reflection: function(ref) {
- return point(ref).move(this, this.distance(ref));
- }
- };
- // Alternative constructor, from polar coordinates.
- // @param {number} r Distance.
- // @param {number} angle Angle in radians.
- // @param {point} [optional] o Origin.
- point.fromPolar = function(r, angle, o) {
- o = (o && point(o)) || point(0, 0);
- var x = abs(r * cos(angle));
- var y = abs(r * sin(angle));
- var deg = normalizeAngle(toDeg(angle));
-
- if (deg < 90) {
- y = -y;
- } else if (deg < 180) {
- x = -x;
- y = -y;
- } else if (deg < 270) {
- x = -x;
- }
-
- return point(o.x + x, o.y + y);
- };
-
- // Create a point with random coordinates that fall into the range `[x1, x2]` and `[y1, y2]`.
- point.random = function(x1, x2, y1, y2) {
- return point(floor(random() * (x2 - x1 + 1) + x1), floor(random() * (y2 - y1 + 1) + y1));
- };
-
- // Line.
- // -----
- function line(p1, p2) {
- if (!(this instanceof line))
- return new line(p1, p2);
- this.start = point(p1);
- this.end = point(p2);
- }
-
- line.prototype = {
- toString: function() {
- return this.start.toString() + ' ' + this.end.toString();
- },
- // @return {double} length of the line
- length: function() {
- return sqrt(this.squaredLength());
- },
- // @return {integer} length without sqrt
- // @note for applications where the exact length is not necessary (e.g. compare only)
- squaredLength: function() {
- var x0 = this.start.x;
- var y0 = this.start.y;
- var x1 = this.end.x;
- var y1 = this.end.y;
- return (x0 -= x1) * x0 + (y0 -= y1) * y0;
- },
- // @return {point} my midpoint
- midpoint: function() {
- return point((this.start.x + this.end.x) / 2,
- (this.start.y + this.end.y) / 2);
- },
- // @return {point} Point where I'm intersecting l.
- // @see Squeak Smalltalk, LineSegment>>intersectionWith:
- intersection: function(l) {
- var pt1Dir = point(this.end.x - this.start.x, this.end.y - this.start.y);
- var pt2Dir = point(l.end.x - l.start.x, l.end.y - l.start.y);
- var det = (pt1Dir.x * pt2Dir.y) - (pt1Dir.y * pt2Dir.x);
- var deltaPt = point(l.start.x - this.start.x, l.start.y - this.start.y);
- var alpha = (deltaPt.x * pt2Dir.y) - (deltaPt.y * pt2Dir.x);
- var beta = (deltaPt.x * pt1Dir.y) - (deltaPt.y * pt1Dir.x);
-
- if (det === 0 ||
- alpha * det < 0 ||
- beta * det < 0) {
- // No intersection found.
- return null;
- }
- if (det > 0) {
- if (alpha > det || beta > det) {
- return null;
- }
- } else {
- if (alpha < det || beta < det) {
- return null;
- }
- }
- return point(this.start.x + (alpha * pt1Dir.x / det),
- this.start.y + (alpha * pt1Dir.y / det));
- },
-
- // @return the bearing (cardinal direction) of the line. For example N, W, or SE.
- // @returns {String} One of the following bearings : NE, E, SE, S, SW, W, NW, N.
- bearing: function() {
-
- var lat1 = toRad(this.start.y);
- var lat2 = toRad(this.end.y);
- var lon1 = this.start.x;
- var lon2 = this.end.x;
- var dLon = toRad(lon2 - lon1);
- var y = sin(dLon) * cos(lat2);
- var x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon);
- var brng = toDeg(atan2(y, x));
-
- var bearings = ['NE', 'E', 'SE', 'S', 'SW', 'W', 'NW', 'N'];
-
- var index = brng - 22.5;
- if (index < 0)
- index += 360;
- index = parseInt(index / 45);
-
- return bearings[index];
- },
-
- // @return {point} my point at 't' <0,1>
- pointAt: function(t) {
- var x = (1 - t) * this.start.x + t * this.end.x;
- var y = (1 - t) * this.start.y + t * this.end.y;
- return point(x, y);
- },
-
- // @return {number} the offset of the point `p` from the line. + if the point `p` is on the right side of the line, - if on the left and 0 if on the line.
- pointOffset: function(p) {
- // Find the sign of the determinant of vectors (start,end), where p is the query point.
- return ((this.end.x - this.start.x) * (p.y - this.start.y) - (this.end.y - this.start.y) * (p.x - this.start.x)) / 2;
- }
- };
-
- // Rectangle.
- // ----------
- function rect(x, y, w, h) {
- if (!(this instanceof rect))
- return new rect(x, y, w, h);
- if (y === undefined) {
- y = x.y;
- w = x.width;
- h = x.height;
- x = x.x;
- }
- this.x = x;
- this.y = y;
- this.width = w;
- this.height = h;
- }
-
- rect.prototype = {
- toString: function() {
- return this.origin().toString() + ' ' + this.corner().toString();
- },
- origin: function() {
- return point(this.x, this.y);
- },
- corner: function() {
- return point(this.x + this.width, this.y + this.height);
- },
- topRight: function() {
- return point(this.x + this.width, this.y);
- },
- bottomLeft: function() {
- return point(this.x, this.y + this.height);
- },
- center: function() {
- return point(this.x + this.width / 2, this.y + this.height / 2);
- },
- // @return {boolean} true if rectangles intersect
- intersect: function(r) {
- var myOrigin = this.origin();
- var myCorner = this.corner();
- var rOrigin = r.origin();
- var rCorner = r.corner();
-
- if (rCorner.x <= myOrigin.x ||
- rCorner.y <= myOrigin.y ||
- rOrigin.x >= myCorner.x ||
- rOrigin.y >= myCorner.y) return false;
- return true;
- },
- // @return {string} (left|right|top|bottom) side which is nearest to point
- // @see Squeak Smalltalk, Rectangle>>sideNearestTo:
- sideNearestToPoint: function(p) {
- p = point(p);
- var distToLeft = p.x - this.x;
- var distToRight = (this.x + this.width) - p.x;
- var distToTop = p.y - this.y;
- var distToBottom = (this.y + this.height) - p.y;
- var closest = distToLeft;
- var side = 'left';
-
- if (distToRight < closest) {
- closest = distToRight;
- side = 'right';
- }
- if (distToTop < closest) {
- closest = distToTop;
- side = 'top';
- }
- if (distToBottom < closest) {
- closest = distToBottom;
- side = 'bottom';
- }
- return side;
- },
- // @return {bool} true if point p is insight me
- containsPoint: function(p) {
- p = point(p);
- if (p.x >= this.x && p.x <= this.x + this.width &&
- p.y >= this.y && p.y <= this.y + this.height) {
- return true;
- }
- return false;
- },
- // Algorithm ported from java.awt.Rectangle from OpenJDK.
- // @return {bool} true if rectangle `r` is inside me.
- containsRect: function(r) {
- var nr = rect(r).normalize();
- var W = nr.width;
- var H = nr.height;
- var X = nr.x;
- var Y = nr.y;
- var w = this.width;
- var h = this.height;
- if ((w | h | W | H) < 0) {
- // At least one of the dimensions is negative...
- return false;
- }
- // Note: if any dimension is zero, tests below must return false...
- var x = this.x;
- var y = this.y;
- if (X < x || Y < y) {
- return false;
- }
- w += x;
- W += X;
- if (W <= X) {
- // X+W overflowed or W was zero, return false if...
- // either original w or W was zero or
- // x+w did not overflow or
- // the overflowed x+w is smaller than the overflowed X+W
- if (w >= x || W > w) return false;
- } else {
- // X+W did not overflow and W was not zero, return false if...
- // original w was zero or
- // x+w did not overflow and x+w is smaller than X+W
- if (w >= x && W > w) return false;
- }
- h += y;
- H += Y;
- if (H <= Y) {
- if (h >= y || H > h) return false;
- } else {
- if (h >= y && H > h) return false;
- }
- return true;
- },
- // @return {point} a point on my boundary nearest to p
- // @see Squeak Smalltalk, Rectangle>>pointNearestTo:
- pointNearestToPoint: function(p) {
- p = point(p);
- if (this.containsPoint(p)) {
- var side = this.sideNearestToPoint(p);
- switch (side){
- case 'right': return point(this.x + this.width, p.y);
- case 'left': return point(this.x, p.y);
- case 'bottom': return point(p.x, this.y + this.height);
- case 'top': return point(p.x, this.y);
- }
- }
- return p.adhereToRect(this);
- },
- // Find point on my boundary where line starting
- // from my center ending in point p intersects me.
- // @param {number} angle If angle is specified, intersection with rotated rectangle is computed.
- intersectionWithLineFromCenterToPoint: function(p, angle) {
- p = point(p);
- var center = point(this.x + this.width / 2, this.y + this.height / 2);
- var result;
- if (angle) p.rotate(center, angle);
-
- // (clockwise, starting from the top side)
- var sides = [
- line(this.origin(), this.topRight()),
- line(this.topRight(), this.corner()),
- line(this.corner(), this.bottomLeft()),
- line(this.bottomLeft(), this.origin())
- ];
- var connector = line(center, p);
-
- for (var i = sides.length - 1; i >= 0; --i) {
- var intersection = sides[i].intersection(connector);
- if (intersection !== null) {
- result = intersection;
- break;
- }
- }
- if (result && angle) result.rotate(center, -angle);
- return result;
- },
- // Move and expand me.
- // @param r {rectangle} representing deltas
- moveAndExpand: function(r) {
- this.x += r.x || 0;
- this.y += r.y || 0;
- this.width += r.width || 0;
- this.height += r.height || 0;
- return this;
- },
- round: function(decimals) {
- this.x = decimals ? this.x.toFixed(decimals) : round(this.x);
- this.y = decimals ? this.y.toFixed(decimals) : round(this.y);
- this.width = decimals ? this.width.toFixed(decimals) : round(this.width);
- this.height = decimals ? this.height.toFixed(decimals) : round(this.height);
- return this;
- },
- // Normalize the rectangle; i.e., make it so that it has a non-negative width and height.
- // If width < 0 the function swaps the left and right corners,
- // and it swaps the top and bottom corners if height < 0
- // like in http://qt-project.org/doc/qt-4.8/qrectf.html#normalized
- normalize: function() {
- var newx = this.x;
- var newy = this.y;
- var newwidth = this.width;
- var newheight = this.height;
- if (this.width < 0) {
- newx = this.x + this.width;
- newwidth = -this.width;
- }
- if (this.height < 0) {
- newy = this.y + this.height;
- newheight = -this.height;
- }
- this.x = newx;
- this.y = newy;
- this.width = newwidth;
- this.height = newheight;
- return this;
- },
- // Find my bounding box when I'm rotated with the center of rotation in the center of me.
- // @return r {rectangle} representing a bounding box
- bbox: function(angle) {
- var theta = toRad(angle || 0);
- var st = abs(sin(theta));
- var ct = abs(cos(theta));
- var w = this.width * ct + this.height * st;
- var h = this.width * st + this.height * ct;
- return rect(this.x + (this.width - w) / 2, this.y + (this.height - h) / 2, w, h);
- }
- };
-
- // Ellipse.
- // --------
- function ellipse(c, a, b) {
- if (!(this instanceof ellipse))
- return new ellipse(c, a, b);
- c = point(c);
- this.x = c.x;
- this.y = c.y;
- this.a = a;
- this.b = b;
- }
-
- ellipse.prototype = {
- toString: function() {
- return point(this.x, this.y).toString() + ' ' + this.a + ' ' + this.b;
- },
- bbox: function() {
- return rect(this.x - this.a, this.y - this.b, 2 * this.a, 2 * this.b);
- },
- // Find point on me where line from my center to
- // point p intersects my boundary.
- // @param {number} angle If angle is specified, intersection with rotated ellipse is computed.
- intersectionWithLineFromCenterToPoint: function(p, angle) {
- p = point(p);
- if (angle) p.rotate(point(this.x, this.y), angle);
- var dx = p.x - this.x;
- var dy = p.y - this.y;
- var result;
- if (dx === 0) {
- result = this.bbox().pointNearestToPoint(p);
- if (angle) return result.rotate(point(this.x, this.y), -angle);
- return result;
- }
- var m = dy / dx;
- var mSquared = m * m;
- var aSquared = this.a * this.a;
- var bSquared = this.b * this.b;
- var x = sqrt(1 / ((1 / aSquared) + (mSquared / bSquared)));
-
- x = dx < 0 ? -x : x;
- var y = m * x;
- result = point(this.x + x, this.y + y);
- if (angle) return result.rotate(point(this.x, this.y), -angle);
- return result;
- }
- };
-
- // Bezier curve.
- // -------------
- var bezier = {
- // Cubic Bezier curve path through points.
- // Ported from C# implementation by Oleg V. Polikarpotchkin and Peter Lee (http://www.codeproject.com/KB/graphics/BezierSpline.aspx).
- // @param {array} points Array of points through which the smooth line will go.
- // @return {array} SVG Path commands as an array
- curveThroughPoints: function(points) {
- var controlPoints = this.getCurveControlPoints(points);
- var path = ['M', points[0].x, points[0].y];
-
- for (var i = 0; i < controlPoints[0].length; i++) {
- path.push('C', controlPoints[0][i].x, controlPoints[0][i].y, controlPoints[1][i].x, controlPoints[1][i].y, points[i + 1].x, points[i + 1].y);
- }
- return path;
- },
-
- // Get open-ended Bezier Spline Control Points.
- // @param knots Input Knot Bezier spline points (At least two points!).
- // @param firstControlPoints Output First Control points. Array of knots.length - 1 length.
- // @param secondControlPoints Output Second Control points. Array of knots.length - 1 length.
- getCurveControlPoints: function(knots) {
- var firstControlPoints = [];
- var secondControlPoints = [];
- var n = knots.length - 1;
- var i;
-
- // Special case: Bezier curve should be a straight line.
- if (n == 1) {
- // 3P1 = 2P0 + P3
- firstControlPoints[0] = point((2 * knots[0].x + knots[1].x) / 3,
- (2 * knots[0].y + knots[1].y) / 3);
- // P2 = 2P1 – P0
- secondControlPoints[0] = point(2 * firstControlPoints[0].x - knots[0].x,
- 2 * firstControlPoints[0].y - knots[0].y);
- return [firstControlPoints, secondControlPoints];
- }
-
- // Calculate first Bezier control points.
- // Right hand side vector.
- var rhs = [];
-
- // Set right hand side X values.
- for (i = 1; i < n - 1; i++) {
- rhs[i] = 4 * knots[i].x + 2 * knots[i + 1].x;
- }
- rhs[0] = knots[0].x + 2 * knots[1].x;
- rhs[n - 1] = (8 * knots[n - 1].x + knots[n].x) / 2.0;
- // Get first control points X-values.
- var x = this.getFirstControlPoints(rhs);
-
- // Set right hand side Y values.
- for (i = 1; i < n - 1; ++i) {
- rhs[i] = 4 * knots[i].y + 2 * knots[i + 1].y;
- }
- rhs[0] = knots[0].y + 2 * knots[1].y;
- rhs[n - 1] = (8 * knots[n - 1].y + knots[n].y) / 2.0;
- // Get first control points Y-values.
- var y = this.getFirstControlPoints(rhs);
-
- // Fill output arrays.
- for (i = 0; i < n; i++) {
- // First control point.
- firstControlPoints.push(point(x[i], y[i]));
- // Second control point.
- if (i < n - 1) {
- secondControlPoints.push(point(2 * knots [i + 1].x - x[i + 1],
- 2 * knots[i + 1].y - y[i + 1]));
- } else {
- secondControlPoints.push(point((knots[n].x + x[n - 1]) / 2,
- (knots[n].y + y[n - 1]) / 2));
- }
- }
- return [firstControlPoints, secondControlPoints];
- },
-
- // Solves a tridiagonal system for one of coordinates (x or y) of first Bezier control points.
- // @param rhs Right hand side vector.
- // @return Solution vector.
- getFirstControlPoints: function(rhs) {
- var n = rhs.length;
- // `x` is a solution vector.
- var x = [];
- var tmp = [];
- var b = 2.0;
-
- x[0] = rhs[0] / b;
- // Decomposition and forward substitution.
- for (var i = 1; i < n; i++) {
- tmp[i] = 1 / b;
- b = (i < n - 1 ? 4.0 : 3.5) - tmp[i];
- x[i] = (rhs[i] - x[i - 1]) / b;
- }
- for (i = 1; i < n; i++) {
- // Backsubstitution.
- x[n - i - 1] -= tmp[n - i] * x[n - i];
- }
- return x;
- },
-
- // Solves an inversion problem -- Given the (x, y) coordinates of a point which lies on
- // a parametric curve x = x(t)/w(t), y = y(t)/w(t), find the parameter value t
- // which corresponds to that point.
- // @param control points (start, control start, control end, end)
- // @return a function accepts a point and returns t.
- getInversionSolver: function(p0, p1, p2, p3) {
- var pts = arguments;
- function l(i, j) {
- // calculates a determinant 3x3
- // [p.x p.y 1]
- // [pi.x pi.y 1]
- // [pj.x pj.y 1]
- var pi = pts[i];
- var pj = pts[j];
- return function(p) {
- var w = (i % 3 ? 3 : 1) * (j % 3 ? 3 : 1);
- var lij = p.x * (pi.y - pj.y) + p.y * (pj.x - pi.x) + pi.x * pj.y - pi.y * pj.x;
- return w * lij;
- };
- }
- return function solveInversion(p) {
- var ct = 3 * l(2, 3)(p1);
- var c1 = l(1, 3)(p0) / ct;
- var c2 = -l(2, 3)(p0) / ct;
- var la = c1 * l(3, 1)(p) + c2 * (l(3, 0)(p) + l(2, 1)(p)) + l(2, 0)(p);
- var lb = c1 * l(3, 0)(p) + c2 * l(2, 0)(p) + l(1, 0)(p);
- return lb / (lb - la);
- };
- },
-
- // Divide a Bezier curve into two at point defined by value 't' <0,1>.
- // Using deCasteljau algorithm. http://math.stackexchange.com/a/317867
- // @param control points (start, control start, control end, end)
- // @return a function accepts t and returns 2 curves each defined by 4 control points.
- getCurveDivider: function(p0, p1, p2, p3) {
- return function divideCurve(t) {
- var l = line(p0, p1).pointAt(t);
- var m = line(p1, p2).pointAt(t);
- var n = line(p2, p3).pointAt(t);
- var p = line(l, m).pointAt(t);
- var q = line(m, n).pointAt(t);
- var r = line(p, q).pointAt(t);
- return [{ p0: p0, p1: l, p2: p, p3: r }, { p0: r, p1: q, p2: n, p3: p3 }];
- };
- }
- };
-
- // Scale.
- var scale = {
-
- // Return the `value` from the `domain` interval scaled to the `range` interval.
- linear: function(domain, range, value) {
-
- var domainSpan = domain[1] - domain[0];
- var rangeSpan = range[1] - range[0];
- return (((value - domain[0]) / domainSpan) * rangeSpan + range[0]) || 0;
- }
- };
-
- return {
- toDeg: toDeg,
- toRad: toRad,
- snapToGrid: snapToGrid,
- normalizeAngle: normalizeAngle,
- point: point,
- line: line,
- rect: rect,
- ellipse: ellipse,
- bezier: bezier,
- scale: scale
- };
-
-}));
\ No newline at end of file
+++ /dev/null
-/*! JointJS v0.9.3 - JavaScript diagramming library 2015-05-22
-
-
-This Source Code Form is subject to the terms of the Mozilla Public
-License, v. 2.0. If a copy of the MPL was not distributed with this
-file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-(function(root, factory) {
-
- if (typeof define === 'function' && define.amd) {
-
- // For AMD.
-
- define(['app/gbp-old/js/geometry', 'app/gbp-old/js/vectorizer', 'jquery', 'app/gbp-old/js/lodash.min', 'app/gbp-old/js/backbone-min'], function(g, V, $, _, Backbone) {
-
- Backbone.$ = $;
-
- return factory(root, Backbone, _, $, g, V);
- });
-
- } else if (typeof exports !== 'undefined') {
-
- // For Node.js or CommonJS.
-
- var Backbone = require('backbone');
- var _ = require('lodash');
- var $ = Backbone.$ = require('jquery');
- var g = require('./geometry');
- var V = require('./vectorizer');
-
- module.exports = factory(root, Backbone, _, $, g, V);
-
- } else {
-
- // As a browser global.
-
- var Backbone = root.Backbone;
- var _ = root._;
- var $ = Backbone.$ = root.jQuery || root.$;
- var g = root.g;
- var V = root.V;
-
- root.joint = factory(root, Backbone, _, $, g, V);
-
- }
-
-}(this, function(root, Backbone, _, $, g, V) {
-
-/*! JointJS v0.9.3 - JavaScript diagramming library 2015-05-22
-
-
-This Source Code Form is subject to the terms of the Mozilla Public
-License, v. 2.0. If a copy of the MPL was not distributed with this
-file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-// JointJS library.
-// (c) 2011-2013 client IO
-
-// Global namespace.
-
-var joint = {
-
- version: '0.9.3',
-
- // `joint.dia` namespace.
- dia: {},
-
- // `joint.ui` namespace.
- ui: {},
-
- // `joint.layout` namespace.
- layout: {},
-
- // `joint.shapes` namespace.
- shapes: {},
-
- // `joint.format` namespace.
- format: {},
-
- // `joint.connectors` namespace.
- connectors: {},
-
- // `joint.routers` namespace.
- routers: {},
-
- util: {
-
- // Return a simple hash code from a string. See http://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/.
- hashCode: function(str) {
-
- var hash = 0;
- if (str.length == 0) return hash;
- for (var i = 0; i < str.length; i++) {
- var c = str.charCodeAt(i);
- hash = ((hash << 5) - hash) + c;
- hash = hash & hash; // Convert to 32bit integer
- }
- return hash;
- },
-
- getByPath: function(obj, path, delim) {
-
- delim = delim || '.';
- var keys = path.split(delim);
- var key;
-
- while (keys.length) {
- key = keys.shift();
- if (Object(obj) === obj && key in obj) {
- obj = obj[key];
- } else {
- return undefined;
- }
- }
- return obj;
- },
-
- setByPath: function(obj, path, value, delim) {
-
- delim = delim || '.';
-
- var keys = path.split(delim);
- var diver = obj;
- var i = 0;
-
- if (path.indexOf(delim) > -1) {
-
- for (var len = keys.length; i < len - 1; i++) {
- // diver creates an empty object if there is no nested object under such a key.
- // This means that one can populate an empty nested object with setByPath().
- diver = diver[keys[i]] || (diver[keys[i]] = {});
- }
- diver[keys[len - 1]] = value;
- } else {
- obj[path] = value;
- }
- return obj;
- },
-
- unsetByPath: function(obj, path, delim) {
-
- delim = delim || '.';
-
- // index of the last delimiter
- var i = path.lastIndexOf(delim);
-
- if (i > -1) {
-
- // unsetting a nested attribute
- var parent = joint.util.getByPath(obj, path.substr(0, i), delim);
-
- if (parent) {
- delete parent[path.slice(i + 1)];
- }
-
- } else {
-
- // unsetting a primitive attribute
- delete obj[path];
- }
-
- return obj;
- },
-
- flattenObject: function(obj, delim, stop) {
-
- delim = delim || '.';
- var ret = {};
-
- for (var key in obj) {
-
- if (!obj.hasOwnProperty(key)) continue;
-
- var shouldGoDeeper = typeof obj[key] === 'object';
- if (shouldGoDeeper && stop && stop(obj[key])) {
- shouldGoDeeper = false;
- }
-
- if (shouldGoDeeper) {
-
- var flatObject = this.flattenObject(obj[key], delim, stop);
-
- for (var flatKey in flatObject) {
- if (!flatObject.hasOwnProperty(flatKey)) continue;
- ret[key + delim + flatKey] = flatObject[flatKey];
- }
-
- } else {
-
- ret[key] = obj[key];
- }
- }
-
- return ret;
- },
-
- uuid: function() {
-
- // credit: http://stackoverflow.com/posts/2117523/revisions
-
- return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(c) {
- var r = Math.random() * 16|0;
- var v = c == 'x' ? r : (r&0x3|0x8);
- return v.toString(16);
- });
- },
-
- // Generate global unique id for obj and store it as a property of the object.
- guid: function(obj) {
-
- this.guid.id = this.guid.id || 1;
- obj.id = (obj.id === undefined ? 'j_' + this.guid.id++ : obj.id);
- return obj.id;
- },
-
- // Copy all the properties to the first argument from the following arguments.
- // All the properties will be overwritten by the properties from the following
- // arguments. Inherited properties are ignored.
- mixin: function() {
-
- var target = arguments[0];
-
- for (var i = 1, l = arguments.length; i < l; i++) {
-
- var extension = arguments[i];
-
- // Only functions and objects can be mixined.
-
- if ((Object(extension) !== extension) &&
- !_.isFunction(extension) &&
- (extension === null || extension === undefined)) {
-
- continue;
- }
-
- _.each(extension, function(copy, key) {
-
- if (this.mixin.deep && (Object(copy) === copy)) {
-
- if (!target[key]) {
-
- target[key] = _.isArray(copy) ? [] : {};
- }
-
- this.mixin(target[key], copy);
- return;
- }
-
- if (target[key] !== copy) {
-
- if (!this.mixin.supplement || !target.hasOwnProperty(key)) {
-
- target[key] = copy;
- }
-
- }
-
- }, this);
- }
-
- return target;
- },
-
- // Copy all properties to the first argument from the following
- // arguments only in case if they don't exists in the first argument.
- // All the function propererties in the first argument will get
- // additional property base pointing to the extenders same named
- // property function's call method.
- supplement: function() {
-
- this.mixin.supplement = true;
- var ret = this.mixin.apply(this, arguments);
- this.mixin.supplement = false;
- return ret;
- },
-
- // Same as `mixin()` but deep version.
- deepMixin: function() {
-
- this.mixin.deep = true;
- var ret = this.mixin.apply(this, arguments);
- this.mixin.deep = false;
- return ret;
- },
-
- // Same as `supplement()` but deep version.
- deepSupplement: function() {
-
- this.mixin.deep = this.mixin.supplement = true;
- var ret = this.mixin.apply(this, arguments);
- this.mixin.deep = this.mixin.supplement = false;
- return ret;
- },
-
- normalizeEvent: function(evt) {
-
- return (evt.originalEvent && evt.originalEvent.changedTouches && evt.originalEvent.changedTouches.length) ? evt.originalEvent.changedTouches[0] : evt;
- },
-
- nextFrame:(function() {
-
- var raf;
- var client = typeof window != 'undefined';
-
- if (client) {
-
- raf = window.requestAnimationFrame ||
- window.webkitRequestAnimationFrame ||
- window.mozRequestAnimationFrame ||
- window.oRequestAnimationFrame ||
- window.msRequestAnimationFrame;
- }
-
- if (!raf) {
-
- var lastTime = 0;
-
- raf = function(callback) {
-
- var currTime = new Date().getTime();
- var timeToCall = Math.max(0, 16 - (currTime - lastTime));
- var id = setTimeout(function() { callback(currTime + timeToCall); }, timeToCall);
-
- lastTime = currTime + timeToCall;
-
- return id;
- };
- }
-
- return client ? _.bind(raf, window) : raf;
-
- })(),
-
- cancelFrame: (function() {
-
- var caf;
- var client = typeof window != 'undefined';
-
- if (client) {
-
- caf = window.cancelAnimationFrame ||
- window.webkitCancelAnimationFrame ||
- window.webkitCancelRequestAnimationFrame ||
- window.msCancelAnimationFrame ||
- window.msCancelRequestAnimationFrame ||
- window.oCancelAnimationFrame ||
- window.oCancelRequestAnimationFrame ||
- window.mozCancelAnimationFrame ||
- window.mozCancelRequestAnimationFrame;
- }
-
- caf = caf || clearTimeout;
-
- return client ? _.bind(caf, window) : caf;
-
- })(),
-
- shapePerimeterConnectionPoint: function(linkView, view, magnet, reference) {
-
- var bbox;
- var spot;
-
- if (!magnet) {
-
- // There is no magnet, try to make the best guess what is the
- // wrapping SVG element. This is because we want this "smart"
- // connection points to work out of the box without the
- // programmer to put magnet marks to any of the subelements.
- // For example, we want the functoin to work on basic.Path elements
- // without any special treatment of such elements.
- // The code below guesses the wrapping element based on
- // one simple assumption. The wrapping elemnet is the
- // first child of the scalable group if such a group exists
- // or the first child of the rotatable group if not.
- // This makese sense because usually the wrapping element
- // is below any other sub element in the shapes.
- var scalable = view.$('.scalable')[0];
- var rotatable = view.$('.rotatable')[0];
-
- if (scalable && scalable.firstChild) {
-
- magnet = scalable.firstChild;
-
- } else if (rotatable && rotatable.firstChild) {
-
- magnet = rotatable.firstChild;
- }
- }
-
- if (magnet) {
-
- spot = V(magnet).findIntersection(reference, linkView.paper.viewport);
- if (!spot) {
- bbox = g.rect(V(magnet).bbox(false, linkView.paper.viewport));
- }
-
- } else {
-
- bbox = view.model.getBBox();
- spot = bbox.intersectionWithLineFromCenterToPoint(reference);
- }
- return spot || bbox.center();
- },
-
- breakText: function(text, size, styles, opt) {
-
- opt = opt || {};
-
- var width = size.width;
- var height = size.height;
-
- var svgDocument = opt.svgDocument || V('svg').node;
- var textElement = V('<text><tspan></tspan></text>').attr(styles || {}).node;
- var textSpan = textElement.firstChild;
- var textNode = document.createTextNode('');
-
- textSpan.appendChild(textNode);
-
- svgDocument.appendChild(textElement);
-
- if (!opt.svgDocument) {
-
- document.body.appendChild(svgDocument);
- }
-
- var words = text.split(' ');
- var full = [];
- var lines = [];
- var p;
-
- for (var i = 0, l = 0, len = words.length; i < len; i++) {
-
- var word = words[i];
-
- textNode.data = lines[l] ? lines[l] + ' ' + word : word;
-
- if (textSpan.getComputedTextLength() <= width) {
-
- // the current line fits
- lines[l] = textNode.data;
-
- if (p) {
- // We were partitioning. Put rest of the word onto next line
- full[l++] = true;
-
- // cancel partitioning
- p = 0;
- }
-
- } else {
-
- if (!lines[l] || p) {
-
- var partition = !!p;
-
- p = word.length - 1;
-
- if (partition || !p) {
-
- // word has only one character.
- if (!p) {
-
- if (!lines[l]) {
-
- // we won't fit this text within our rect
- lines = [];
-
- break;
- }
-
- // partitioning didn't help on the non-empty line
- // try again, but this time start with a new line
-
- // cancel partitions created
- words.splice(i, 2, word + words[i + 1]);
-
- // adjust word length
- len--;
-
- full[l++] = true;
- i--;
-
- continue;
- }
-
- // move last letter to the beginning of the next word
- words[i] = word.substring(0, p);
- words[i + 1] = word.substring(p) + words[i + 1];
-
- } else {
-
- // We initiate partitioning
- // split the long word into two words
- words.splice(i, 1, word.substring(0, p), word.substring(p));
-
- // adjust words length
- len++;
-
- if (l && !full[l - 1]) {
- // if the previous line is not full, try to fit max part of
- // the current word there
- l--;
- }
- }
-
- i--;
-
- continue;
- }
-
- l++;
- i--;
- }
-
- // if size.height is defined we have to check whether the height of the entire
- // text exceeds the rect height
- if (typeof height !== 'undefined') {
-
- // get line height as text height / 0.8 (as text height is approx. 0.8em
- // and line height is 1em. See vectorizer.text())
- var lh = lh || textElement.getBBox().height * 1.25;
-
- if (lh * lines.length > height) {
-
- // remove overflowing lines
- lines.splice(Math.floor(height / lh));
-
- break;
- }
- }
- }
-
- if (opt.svgDocument) {
-
- // svg document was provided, remove the text element only
- svgDocument.removeChild(textElement);
-
- } else {
-
- // clean svg document
- document.body.removeChild(svgDocument);
- }
-
- return lines.join('\n');
- },
-
- imageToDataUri: function(url, callback) {
-
- if (!url || url.substr(0, 'data:'.length) === 'data:') {
- // No need to convert to data uri if it is already in data uri.
-
- // This not only convenient but desired. For example,
- // IE throws a security error if data:image/svg+xml is used to render
- // an image to the canvas and an attempt is made to read out data uri.
- // Now if our image is already in data uri, there is no need to render it to the canvas
- // and so we can bypass this error.
-
- // Keep the async nature of the function.
- return setTimeout(function() { callback(null, url); }, 0);
- }
-
- var canvas = document.createElement('canvas');
- var img = document.createElement('img');
-
- img.onload = function() {
-
- var ctx = canvas.getContext('2d');
-
- canvas.width = img.width;
- canvas.height = img.height;
-
- ctx.drawImage(img, 0, 0);
-
- try {
-
- // Guess the type of the image from the url suffix.
- var suffix = (url.split('.').pop()) || 'png';
- // A little correction for JPEGs. There is no image/jpg mime type but image/jpeg.
- var type = 'image/' + (suffix === 'jpg') ? 'jpeg' : suffix;
- var dataUri = canvas.toDataURL(type);
-
- } catch (e) {
-
- if (/\.svg$/.test(url)) {
- // IE throws a security error if we try to render an SVG into the canvas.
- // Luckily for us, we don't need canvas at all to convert
- // SVG to data uri. We can just use AJAX to load the SVG string
- // and construct the data uri ourselves.
- var xhr = window.XMLHttpRequest ? new XMLHttpRequest : new ActiveXObject('Microsoft.XMLHTTP');
- xhr.open('GET', url, false);
- xhr.send(null);
- var svg = xhr.responseText;
-
- return callback(null, 'data:image/svg+xml,' + encodeURIComponent(svg));
- }
-
- console.error(img.src, 'fails to convert', e);
- }
-
- callback(null, dataUri);
- };
-
- img.ononerror = function() {
-
- callback(new Error('Failed to load image.'));
- };
-
- img.src = url;
- },
-
- timing: {
-
- linear: function(t) {
- return t;
- },
-
- quad: function(t) {
- return t * t;
- },
-
- cubic: function(t) {
- return t * t * t;
- },
-
- inout: function(t) {
- if (t <= 0) return 0;
- if (t >= 1) return 1;
- var t2 = t * t;
- var t3 = t2 * t;
- return 4 * (t < .5 ? t3 : 3 * (t - t2) + t3 - .75);
- },
-
- exponential: function(t) {
- return Math.pow(2, 10 * (t - 1));
- },
-
- bounce: function(t) {
- for (var a = 0, b = 1; 1; a += b, b /= 2) {
- if (t >= (7 - 4 * a) / 11) {
- var q = (11 - 6 * a - 11 * t) / 4;
- return -q * q + b * b;
- }
- }
- },
-
- reverse: function(f) {
- return function(t) {
- return 1 - f(1 - t);
- };
- },
-
- reflect: function(f) {
- return function(t) {
- return .5 * (t < .5 ? f(2 * t) : (2 - f(2 - 2 * t)));
- };
- },
-
- clamp: function(f, n, x) {
- n = n || 0;
- x = x || 1;
- return function(t) {
- var r = f(t);
- return r < n ? n : r > x ? x : r;
- };
- },
-
- back: function(s) {
- if (!s) s = 1.70158;
- return function(t) {
- return t * t * ((s + 1) * t - s);
- };
- },
-
- elastic: function(x) {
- if (!x) x = 1.5;
- return function(t) {
- return Math.pow(2, 10 * (t - 1)) * Math.cos(20 * Math.PI * x / 3 * t);
- };
- }
- },
-
- interpolate: {
-
- number: function(a, b) {
- var d = b - a;
- return function(t) { return a + d * t; };
- },
-
- object: function(a, b) {
- var s = _.keys(a);
- return function(t) {
- var i, p;
- var r = {};
- for (i = s.length - 1; i != -1; i--) {
- p = s[i];
- r[p] = a[p] + (b[p] - a[p]) * t;
- }
- return r;
- };
- },
-
- hexColor: function(a, b) {
-
- var ca = parseInt(a.slice(1), 16);
- var cb = parseInt(b.slice(1), 16);
- var ra = ca & 0x0000ff;
- var rd = (cb & 0x0000ff) - ra;
- var ga = ca & 0x00ff00;
- var gd = (cb & 0x00ff00) - ga;
- var ba = ca & 0xff0000;
- var bd = (cb & 0xff0000) - ba;
-
- return function(t) {
-
- var r = (ra + rd * t) & 0x000000ff;
- var g = (ga + gd * t) & 0x0000ff00;
- var b = (ba + bd * t) & 0x00ff0000;
-
- return '#' + (1 << 24 | r | g | b ).toString(16).slice(1);
- };
- },
-
- unit: function(a, b) {
-
- var r = /(-?[0-9]*.[0-9]*)(px|em|cm|mm|in|pt|pc|%)/;
- var ma = r.exec(a);
- var mb = r.exec(b);
- var p = mb[1].indexOf('.');
- var f = p > 0 ? mb[1].length - p - 1 : 0;
- a = +ma[1];
- var d = +mb[1] - a;
- var u = ma[2];
-
- return function(t) {
- return (a + d * t).toFixed(f) + u;
- };
- }
- },
-
- // SVG filters.
- filter: {
-
- // `x` ... horizontal blur
- // `y` ... vertical blur (optional)
- blur: function(args) {
-
- var x = _.isFinite(args.x) ? args.x : 2;
-
- return _.template('<filter><feGaussianBlur stdDeviation="${stdDeviation}"/></filter>', {
- stdDeviation: _.isFinite(args.y) ? [x, args.y] : x
- });
- },
-
- // `dx` ... horizontal shift
- // `dy` ... vertical shift
- // `blur` ... blur
- // `color` ... color
- // `opacity` ... opacity
- dropShadow: function(args) {
-
- var tpl = 'SVGFEDropShadowElement' in window
- ? '<filter><feDropShadow stdDeviation="${blur}" dx="${dx}" dy="${dy}" flood-color="${color}" flood-opacity="${opacity}"/></filter>'
- : '<filter><feGaussianBlur in="SourceAlpha" stdDeviation="${blur}"/><feOffset dx="${dx}" dy="${dy}" result="offsetblur"/><feFlood flood-color="${color}"/><feComposite in2="offsetblur" operator="in"/><feComponentTransfer><feFuncA type="linear" slope="${opacity}"/></feComponentTransfer><feMerge><feMergeNode/><feMergeNode in="SourceGraphic"/></feMerge></filter>';
-
- return _.template(tpl, {
- dx: args.dx || 0,
- dy: args.dy || 0,
- opacity: _.isFinite(args.opacity) ? args.opacity : 1,
- color: args.color || 'black',
- blur: _.isFinite(args.blur) ? args.blur : 4
- });
- },
-
- // `amount` ... the proportion of the conversion. A value of 1 is completely grayscale. A value of 0 leaves the input unchanged.
- grayscale: function(args) {
-
- var amount = _.isFinite(args.amount) ? args.amount : 1;
-
- return _.template('<filter><feColorMatrix type="matrix" values="${a} ${b} ${c} 0 0 ${d} ${e} ${f} 0 0 ${g} ${b} ${h} 0 0 0 0 0 1 0"/></filter>', {
- a: 0.2126 + 0.7874 * (1 - amount),
- b: 0.7152 - 0.7152 * (1 - amount),
- c: 0.0722 - 0.0722 * (1 - amount),
- d: 0.2126 - 0.2126 * (1 - amount),
- e: 0.7152 + 0.2848 * (1 - amount),
- f: 0.0722 - 0.0722 * (1 - amount),
- g: 0.2126 - 0.2126 * (1 - amount),
- h: 0.0722 + 0.9278 * (1 - amount)
- });
- },
-
- // `amount` ... the proportion of the conversion. A value of 1 is completely sepia. A value of 0 leaves the input unchanged.
- sepia: function(args) {
-
- var amount = _.isFinite(args.amount) ? args.amount : 1;
-
- return _.template('<filter><feColorMatrix type="matrix" values="${a} ${b} ${c} 0 0 ${d} ${e} ${f} 0 0 ${g} ${h} ${i} 0 0 0 0 0 1 0"/></filter>', {
- a: 0.393 + 0.607 * (1 - amount),
- b: 0.769 - 0.769 * (1 - amount),
- c: 0.189 - 0.189 * (1 - amount),
- d: 0.349 - 0.349 * (1 - amount),
- e: 0.686 + 0.314 * (1 - amount),
- f: 0.168 - 0.168 * (1 - amount),
- g: 0.272 - 0.272 * (1 - amount),
- h: 0.534 - 0.534 * (1 - amount),
- i: 0.131 + 0.869 * (1 - amount)
- });
- },
-
- // `amount` ... the proportion of the conversion. A value of 0 is completely un-saturated. A value of 1 leaves the input unchanged.
- saturate: function(args) {
-
- var amount = _.isFinite(args.amount) ? args.amount : 1;
-
- return _.template('<filter><feColorMatrix type="saturate" values="${amount}"/></filter>', {
- amount: 1 - amount
- });
- },
-
- // `angle` ... the number of degrees around the color circle the input samples will be adjusted.
- hueRotate: function(args) {
-
- return _.template('<filter><feColorMatrix type="hueRotate" values="${angle}"/></filter>', {
- angle: args.angle || 0
- });
- },
-
- // `amount` ... the proportion of the conversion. A value of 1 is completely inverted. A value of 0 leaves the input unchanged.
- invert: function(args) {
-
- var amount = _.isFinite(args.amount) ? args.amount : 1;
-
- return _.template('<filter><feComponentTransfer><feFuncR type="table" tableValues="${amount} ${amount2}"/><feFuncG type="table" tableValues="${amount} ${amount2}"/><feFuncB type="table" tableValues="${amount} ${amount2}"/></feComponentTransfer></filter>', {
- amount: amount,
- amount2: 1 - amount
- });
- },
-
- // `amount` ... proportion of the conversion. A value of 0 will create an image that is completely black. A value of 1 leaves the input unchanged.
- brightness: function(args) {
-
- return _.template('<filter><feComponentTransfer><feFuncR type="linear" slope="${amount}"/><feFuncG type="linear" slope="${amount}"/><feFuncB type="linear" slope="${amount}"/></feComponentTransfer></filter>', {
- amount: _.isFinite(args.amount) ? args.amount : 1
- });
- },
-
- // `amount` ... proportion of the conversion. A value of 0 will create an image that is completely black. A value of 1 leaves the input unchanged.
- contrast: function(args) {
-
- var amount = _.isFinite(args.amount) ? args.amount : 1;
-
- return _.template('<filter><feComponentTransfer><feFuncR type="linear" slope="${amount}" intercept="${amount2}"/><feFuncG type="linear" slope="${amount}" intercept="${amount2}"/><feFuncB type="linear" slope="${amount}" intercept="${amount2}"/></feComponentTransfer></filter>', {
- amount: amount,
- amount2: .5 - amount / 2
- });
- }
- },
-
- format: {
-
- // Formatting numbers via the Python Format Specification Mini-language.
- // See http://docs.python.org/release/3.1.3/library/string.html#format-specification-mini-language.
- // Heavilly inspired by the D3.js library implementation.
- number: function(specifier, value, locale) {
-
- locale = locale || {
-
- currency: ['$', ''],
- decimal: '.',
- thousands: ',',
- grouping: [3]
- };
-
- // See Python format specification mini-language: http://docs.python.org/release/3.1.3/library/string.html#format-specification-mini-language.
- // [[fill]align][sign][symbol][0][width][,][.precision][type]
- var re = /(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i;
-
- var match = re.exec(specifier);
- var fill = match[1] || ' ';
- var align = match[2] || '>';
- var sign = match[3] || '';
- var symbol = match[4] || '';
- var zfill = match[5];
- var width = +match[6];
- var comma = match[7];
- var precision = match[8];
- var type = match[9];
- var scale = 1;
- var prefix = '';
- var suffix = '';
- var integer = false;
-
- if (precision) precision = +precision.substring(1);
-
- if (zfill || fill === '0' && align === '=') {
- zfill = fill = '0';
- align = '=';
- if (comma) width -= Math.floor((width - 1) / 4);
- }
-
- switch (type) {
- case 'n': comma = true; type = 'g'; break;
- case '%': scale = 100; suffix = '%'; type = 'f'; break;
- case 'p': scale = 100; suffix = '%'; type = 'r'; break;
- case 'b':
- case 'o':
- case 'x':
- case 'X': if (symbol === '#') prefix = '0' + type.toLowerCase();
- case 'c':
- case 'd': integer = true; precision = 0; break;
- case 's': scale = -1; type = 'r'; break;
- }
-
- if (symbol === '$') {
- prefix = locale.currency[0];
- suffix = locale.currency[1];
- }
-
- // If no precision is specified for `'r'`, fallback to general notation.
- if (type == 'r' && !precision) type = 'g';
-
- // Ensure that the requested precision is in the supported range.
- if (precision != null) {
- if (type == 'g') precision = Math.max(1, Math.min(21, precision));
- else if (type == 'e' || type == 'f') precision = Math.max(0, Math.min(20, precision));
- }
-
- var zcomma = zfill && comma;
-
- // Return the empty string for floats formatted as ints.
- if (integer && (value % 1)) return '';
-
- // Convert negative to positive, and record the sign prefix.
- var negative = value < 0 || value === 0 && 1 / value < 0 ? (value = -value, '-') : sign;
-
- var fullSuffix = suffix;
-
- // Apply the scale, computing it from the value's exponent for si format.
- // Preserve the existing suffix, if any, such as the currency symbol.
- if (scale < 0) {
- var unit = this.prefix(value, precision);
- value = unit.scale(value);
- fullSuffix = unit.symbol + suffix;
- } else {
- value *= scale;
- }
-
- // Convert to the desired precision.
- value = this.convert(type, value, precision);
-
- // Break the value into the integer part (before) and decimal part (after).
- var i = value.lastIndexOf('.');
- var before = i < 0 ? value : value.substring(0, i);
- var after = i < 0 ? '' : locale.decimal + value.substring(i + 1);
-
- function formatGroup(value) {
-
- var i = value.length;
- var t = [];
- var j = 0;
- var g = locale.grouping[0];
- while (i > 0 && g > 0) {
- t.push(value.substring(i -= g, i + g));
- g = locale.grouping[j = (j + 1) % locale.grouping.length];
- }
- return t.reverse().join(locale.thousands);
- }
-
- // If the fill character is not `'0'`, grouping is applied before padding.
- if (!zfill && comma && locale.grouping) {
-
- before = formatGroup(before);
- }
-
- var length = prefix.length + before.length + after.length + (zcomma ? 0 : negative.length);
- var padding = length < width ? new Array(length = width - length + 1).join(fill) : '';
-
- // If the fill character is `'0'`, grouping is applied after padding.
- if (zcomma) before = formatGroup(padding + before);
-
- // Apply prefix.
- negative += prefix;
-
- // Rejoin integer and decimal parts.
- value = before + after;
-
- return (align === '<' ? negative + value + padding
- : align === '>' ? padding + negative + value
- : align === '^' ? padding.substring(0, length >>= 1) + negative + value + padding.substring(length)
- : negative + (zcomma ? value : padding + value)) + fullSuffix;
- },
-
- // Formatting string via the Python Format string.
- // See https://docs.python.org/2/library/string.html#format-string-syntax)
- string: function(formatString, value) {
-
- var fieldDelimiterIndex;
- var fieldDelimiter = '{';
- var endPlaceholder = false;
- var formattedStringArray = [];
-
- while ((fieldDelimiterIndex = formatString.indexOf(fieldDelimiter)) !== -1) {
-
- var pieceFormatedString, formatSpec, fieldName;
-
- pieceFormatedString = formatString.slice(0, fieldDelimiterIndex);
-
- if (endPlaceholder) {
- formatSpec = pieceFormatedString.split(':');
- fieldName = formatSpec.shift().split('.');
- pieceFormatedString = value;
-
- for (var i = 0; i < fieldName.length; i++)
- pieceFormatedString = pieceFormatedString[fieldName[i]];
-
- if (formatSpec.length)
- pieceFormatedString = this.number(formatSpec, pieceFormatedString);
- }
-
- formattedStringArray.push(pieceFormatedString);
-
- formatString = formatString.slice(fieldDelimiterIndex + 1);
- fieldDelimiter = (endPlaceholder = !endPlaceholder) ? '}' : '{';
- }
- formattedStringArray.push(formatString);
-
- return formattedStringArray.join('');
- },
-
- convert: function(type, value, precision) {
-
- switch (type) {
- case 'b': return value.toString(2);
- case 'c': return String.fromCharCode(value);
- case 'o': return value.toString(8);
- case 'x': return value.toString(16);
- case 'X': return value.toString(16).toUpperCase();
- case 'g': return value.toPrecision(precision);
- case 'e': return value.toExponential(precision);
- case 'f': return value.toFixed(precision);
- case 'r': return (value = this.round(value, this.precision(value, precision))).toFixed(Math.max(0, Math.min(20, this.precision(value * (1 + 1e-15), precision))));
- default: return value + '';
- }
- },
-
- round: function(value, precision) {
-
- return precision
- ? Math.round(value * (precision = Math.pow(10, precision))) / precision
- : Math.round(value);
- },
-
- precision: function(value, precision) {
-
- return precision - (value ? Math.ceil(Math.log(value) / Math.LN10) : 1);
- },
-
- prefix: function(value, precision) {
-
- var prefixes = _.map(['y', 'z', 'a', 'f', 'p', 'n', 'µ', 'm', '', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y'], function(d, i) {
- var k = Math.pow(10, abs(8 - i) * 3);
- return {
- scale: i > 8 ? function(d) { return d / k; } : function(d) { return d * k; },
- symbol: d
- };
- });
-
- var i = 0;
- if (value) {
- if (value < 0) value *= -1;
- if (precision) value = this.round(value, this.precision(value, precision));
- i = 1 + Math.floor(1e-12 + Math.log(value) / Math.LN10);
- i = Math.max(-24, Math.min(24, Math.floor((i <= 0 ? i + 1 : i - 1) / 3) * 3));
- }
- return prefixes[8 + i / 3];
- }
- }
- }
-};
-
-// JointJS, the JavaScript diagramming library.
-// (c) 2011-2013 client IO
-
-joint.dia.GraphCells = Backbone.Collection.extend({
-
- initialize: function() {
-
- // Backbone automatically doesn't trigger re-sort if models attributes are changed later when
- // they're already in the collection. Therefore, we're triggering sort manually here.
- this.on('change:z', this.sort, this);
- },
-
- model: function(attrs, options) {
-
- if (attrs.type === 'link') {
-
- return new joint.dia.Link(attrs, options);
- }
-
- var module = attrs.type.split('.')[0];
- var entity = attrs.type.split('.')[1];
-
- if (joint.shapes[module] && joint.shapes[module][entity]) {
-
- return new joint.shapes[module][entity](attrs, options);
- }
-
- return new joint.dia.Element(attrs, options);
- },
-
- // `comparator` makes it easy to sort cells based on their `z` index.
- comparator: function(model) {
-
- return model.get('z') || 0;
- },
-
- // Get all inbound and outbound links connected to the cell `model`.
- getConnectedLinks: function(model, opt) {
-
- opt = opt || {};
-
- if (_.isUndefined(opt.inbound) && _.isUndefined(opt.outbound)) {
- opt.inbound = opt.outbound = true;
- }
-
- var links = this.filter(function(cell) {
-
- var source = cell.get('source');
- var target = cell.get('target');
-
- return (source && source.id === model.id && opt.outbound) ||
- (target && target.id === model.id && opt.inbound);
- });
-
- // option 'deep' returns all links that are connected to any of the descendent cell
- // and are not descendents itself
- if (opt.deep) {
-
- var embeddedCells = model.getEmbeddedCells({ deep: true });
-
- _.each(this.difference(links, embeddedCells), function(cell) {
-
- if (opt.outbound) {
-
- var source = cell.get('source');
-
- if (source && source.id && _.find(embeddedCells, { id: source.id })) {
- links.push(cell);
- return; // prevent a loop link to be pushed twice
- }
- }
-
- if (opt.inbound) {
-
- var target = cell.get('target');
-
- if (target && target.id && _.find(embeddedCells, { id: target.id })) {
- links.push(cell);
- }
- }
- });
- }
-
- return links;
- },
-
- getCommonAncestor: function(/* cells */) {
-
- var cellsAncestors = _.map(arguments, function(cell) {
-
- var ancestors = [cell.id];
- var parentId = cell.get('parent');
-
- while (parentId) {
-
- ancestors.push(parentId);
- parentId = this.get(parentId).get('parent');
- }
-
- return ancestors;
-
- }, this);
-
- cellsAncestors = _.sortBy(cellsAncestors, 'length');
-
- var commonAncestor = _.find(cellsAncestors.shift(), function(ancestor) {
-
- return _.every(cellsAncestors, function(cellAncestors) {
- return _.contains(cellAncestors, ancestor);
- });
- });
-
- return this.get(commonAncestor);
- },
-
- // Return the bounding box of all cells in array provided. If no array
- // provided returns bounding box of all cells. Links are being ignored.
- getBBox: function(cells) {
-
- cells = cells || this.models;
-
- var origin = { x: Infinity, y: Infinity };
- var corner = { x: -Infinity, y: -Infinity };
-
- _.each(cells, function(cell) {
-
- // Links has no bounding box defined on the model.
- if (cell.isLink()) return;
-
- var bbox = cell.getBBox();
- origin.x = Math.min(origin.x, bbox.x);
- origin.y = Math.min(origin.y, bbox.y);
- corner.x = Math.max(corner.x, bbox.x + bbox.width);
- corner.y = Math.max(corner.y, bbox.y + bbox.height);
- });
-
- return g.rect(origin.x, origin.y, corner.x - origin.x, corner.y - origin.y);
- }
-});
-
-
-joint.dia.Graph = Backbone.Model.extend({
-
- initialize: function(attrs, opt) {
-
- // Passing `cellModel` function in the options object to graph allows for
- // setting models based on attribute objects. This is especially handy
- // when processing JSON graphs that are in a different than JointJS format.
- this.set('cells', new joint.dia.GraphCells([], { model: opt && opt.cellModel }));
-
- // Make all the events fired in the `cells` collection available.
- // to the outside world.
- this.get('cells').on('all', this.trigger, this);
-
- this.get('cells').on('remove', this.removeCell, this);
- },
-
- toJSON: function() {
-
- // Backbone does not recursively call `toJSON()` on attributes that are themselves models/collections.
- // It just clones the attributes. Therefore, we must call `toJSON()` on the cells collection explicitely.
- var json = Backbone.Model.prototype.toJSON.apply(this, arguments);
- json.cells = this.get('cells').toJSON();
- return json;
- },
-
- fromJSON: function(json, opt) {
-
- if (!json.cells) {
-
- throw new Error('Graph JSON must contain cells array.');
- }
-
- this.set(_.omit(json, 'cells'), opt);
- this.resetCells(json.cells, opt);
- },
-
- clear: function(opt) {
-
- this.trigger('batch:start');
- this.get('cells').remove(this.get('cells').models, opt);
- this.trigger('batch:stop');
- },
-
- _prepareCell: function(cell) {
-
- if (cell instanceof Backbone.Model && _.isUndefined(cell.get('z'))) {
-
- cell.set('z', this.maxZIndex() + 1, { silent: true });
-
- } else if (_.isUndefined(cell.z)) {
-
- cell.z = this.maxZIndex() + 1;
- }
-
- return cell;
- },
-
- maxZIndex: function() {
-
- var lastCell = this.get('cells').last();
- return lastCell ? (lastCell.get('z') || 0) : 0;
- },
-
- addCell: function(cell, options) {
-
- if (_.isArray(cell)) {
-
- return this.addCells(cell, options);
- }
-
- this.get('cells').add(this._prepareCell(cell), options || {});
-
- return this;
- },
-
- addCells: function(cells, options) {
-
- options = options || {};
- options.position = cells.length;
-
- _.each(cells, function(cell) {
- options.position--;
- this.addCell(cell, options);
- }, this);
-
- return this;
- },
-
- // When adding a lot of cells, it is much more efficient to
- // reset the entire cells collection in one go.
- // Useful for bulk operations and optimizations.
- resetCells: function(cells, opt) {
-
- this.get('cells').reset(_.map(cells, this._prepareCell, this), opt);
-
- return this;
- },
-
- removeCell: function(cell, collection, options) {
-
- // Applications might provide a `disconnectLinks` option set to `true` in order to
- // disconnect links when a cell is removed rather then removing them. The default
- // is to remove all the associated links.
- if (options && options.disconnectLinks) {
-
- this.disconnectLinks(cell, options);
-
- } else {
-
- this.removeLinks(cell, options);
- }
-
- // Silently remove the cell from the cells collection. Silently, because
- // `joint.dia.Cell.prototype.remove` already triggers the `remove` event which is
- // then propagated to the graph model. If we didn't remove the cell silently, two `remove` events
- // would be triggered on the graph model.
- this.get('cells').remove(cell, { silent: true });
- },
-
- // Get a cell by `id`.
- getCell: function(id) {
-
- return this.get('cells').get(id);
- },
-
- getElements: function() {
-
- return this.get('cells').filter(function(cell) {
-
- return cell instanceof joint.dia.Element;
- });
- },
-
- getLinks: function() {
-
- return this.get('cells').filter(function(cell) {
-
- return cell instanceof joint.dia.Link;
- });
- },
-
- // Get all inbound and outbound links connected to the cell `model`.
- getConnectedLinks: function(model, opt) {
-
- return this.get('cells').getConnectedLinks(model, opt);
- },
-
- getNeighbors: function(el) {
-
- var links = this.getConnectedLinks(el);
- var neighbors = [];
- var cells = this.get('cells');
-
- _.each(links, function(link) {
-
- var source = link.get('source');
- var target = link.get('target');
-
- // Discard if it is a point.
- if (!source.x) {
- var sourceElement = cells.get(source.id);
- if (sourceElement !== el) {
-
- neighbors.push(sourceElement);
- }
- }
- if (!target.x) {
- var targetElement = cells.get(target.id);
- if (targetElement !== el) {
-
- neighbors.push(targetElement);
- }
- }
- });
-
- return neighbors;
- },
-
- // Disconnect links connected to the cell `model`.
- disconnectLinks: function(model, options) {
-
- _.each(this.getConnectedLinks(model), function(link) {
-
- link.set(link.get('source').id === model.id ? 'source' : 'target', g.point(0, 0), options);
- });
- },
-
- // Remove links connected to the cell `model` completely.
- removeLinks: function(model, options) {
-
- _.invoke(this.getConnectedLinks(model), 'remove', options);
- },
-
- // Find all views at given point
- findModelsFromPoint: function(p) {
-
- return _.filter(this.getElements(), function(el) {
- return el.getBBox().containsPoint(p);
- });
- },
-
- // Find all views in given area
- findModelsInArea: function(r) {
-
- return _.filter(this.getElements(), function(el) {
- return el.getBBox().intersect(r);
- });
- },
-
- // Return the bounding box of all `elements`.
- getBBox: function(/* elements */) {
-
- var collection = this.get('cells');
- return collection.getBBox.apply(collection, arguments);
- },
-
- getCommonAncestor: function(/* cells */) {
-
- var collection = this.get('cells');
- return collection.getCommonAncestor.apply(collection, arguments);
- }
-});
-
-// JointJS.
-// (c) 2011-2013 client IO
-
-// joint.dia.Cell base model.
-// --------------------------
-
-joint.dia.Cell = Backbone.Model.extend({
-
- // This is the same as Backbone.Model with the only difference that is uses _.merge
- // instead of just _.extend. The reason is that we want to mixin attributes set in upper classes.
- constructor: function(attributes, options) {
-
- var defaults;
- var attrs = attributes || {};
- this.cid = _.uniqueId('c');
- this.attributes = {};
- if (options && options.collection) this.collection = options.collection;
- if (options && options.parse) attrs = this.parse(attrs, options) || {};
- if (defaults = _.result(this, 'defaults')) {
- //<custom code>
- // Replaced the call to _.defaults with _.merge.
- attrs = _.merge({}, defaults, attrs);
- //</custom code>
- }
- this.set(attrs, options);
- this.changed = {};
- this.initialize.apply(this, arguments);
- },
-
- toJSON: function() {
-
- var defaultAttrs = this.constructor.prototype.defaults.attrs || {};
- var attrs = this.attributes.attrs;
- var finalAttrs = {};
-
- // Loop through all the attributes and
- // omit the default attributes as they are implicitly reconstructable by the cell 'type'.
- _.each(attrs, function(attr, selector) {
-
- var defaultAttr = defaultAttrs[selector];
-
- _.each(attr, function(value, name) {
-
- // attr is mainly flat though it might have one more level (consider the `style` attribute).
- // Check if the `value` is object and if yes, go one level deep.
- if (_.isObject(value) && !_.isArray(value)) {
-
- _.each(value, function(value2, name2) {
-
- if (!defaultAttr || !defaultAttr[name] || !_.isEqual(defaultAttr[name][name2], value2)) {
-
- finalAttrs[selector] = finalAttrs[selector] || {};
- (finalAttrs[selector][name] || (finalAttrs[selector][name] = {}))[name2] = value2;
- }
- });
-
- } else if (!defaultAttr || !_.isEqual(defaultAttr[name], value)) {
- // `value` is not an object, default attribute for such a selector does not exist
- // or it is different than the attribute value set on the model.
-
- finalAttrs[selector] = finalAttrs[selector] || {};
- finalAttrs[selector][name] = value;
- }
- });
- });
-
- var attributes = _.cloneDeep(_.omit(this.attributes, 'attrs'));
- //var attributes = JSON.parse(JSON.stringify(_.omit(this.attributes, 'attrs')));
- attributes.attrs = finalAttrs;
-
- return attributes;
- },
-
- initialize: function(options) {
-
- if (!options || !options.id) {
-
- this.set('id', joint.util.uuid(), { silent: true });
- }
-
- this._transitionIds = {};
-
- // Collect ports defined in `attrs` and keep collecting whenever `attrs` object changes.
- this.processPorts();
- this.on('change:attrs', this.processPorts, this);
- },
-
- processPorts: function() {
-
- // Whenever `attrs` changes, we extract ports from the `attrs` object and store it
- // in a more accessible way. Also, if any port got removed and there were links that had `target`/`source`
- // set to that port, we remove those links as well (to follow the same behaviour as
- // with a removed element).
-
- var previousPorts = this.ports;
-
- // Collect ports from the `attrs` object.
- var ports = {};
- _.each(this.get('attrs'), function(attrs, selector) {
-
- if (attrs && attrs.port) {
-
- // `port` can either be directly an `id` or an object containing an `id` (and potentially other data).
- if (!_.isUndefined(attrs.port.id)) {
- ports[attrs.port.id] = attrs.port;
- } else {
- ports[attrs.port] = { id: attrs.port };
- }
- }
- });
-
- // Collect ports that have been removed (compared to the previous ports) - if any.
- // Use hash table for quick lookup.
- var removedPorts = {};
- _.each(previousPorts, function(port, id) {
-
- if (!ports[id]) removedPorts[id] = true;
- });
-
- // Remove all the incoming/outgoing links that have source/target port set to any of the removed ports.
- if (this.collection && !_.isEmpty(removedPorts)) {
-
- var inboundLinks = this.collection.getConnectedLinks(this, { inbound: true });
- _.each(inboundLinks, function(link) {
-
- if (removedPorts[link.get('target').port]) link.remove();
- });
-
- var outboundLinks = this.collection.getConnectedLinks(this, { outbound: true });
- _.each(outboundLinks, function(link) {
-
- if (removedPorts[link.get('source').port]) link.remove();
- });
- }
-
- // Update the `ports` object.
- this.ports = ports;
- },
-
- remove: function(opt) {
-
- opt = opt || {};
-
- var collection = this.collection;
-
- if (collection) {
- collection.trigger('batch:start', { batchName: 'remove' });
- }
-
- // First, unembed this cell from its parent cell if there is one.
- var parentCellId = this.get('parent');
- if (parentCellId) {
-
- var parentCell = this.collection && this.collection.get(parentCellId);
- parentCell.unembed(this);
- }
-
- _.invoke(this.getEmbeddedCells(), 'remove', opt);
-
- this.trigger('remove', this, this.collection, opt);
-
- if (collection) {
- collection.trigger('batch:stop', { batchName: 'remove' });
- }
-
- return this;
- },
-
- toFront: function(opt) {
-
- if (this.collection) {
-
- opt = opt || {};
-
- var z = (this.collection.last().get('z') || 0) + 1;
-
- this.trigger('batch:start', { batchName: 'to-front' }).set('z', z, opt);
-
- if (opt.deep) {
-
- var cells = this.getEmbeddedCells({ deep: true, breadthFirst: true });
- _.each(cells, function(cell) { cell.set('z', ++z, opt); });
-
- }
-
- this.trigger('batch:stop', { batchName: 'to-front' });
- }
-
- return this;
- },
-
- toBack: function(opt) {
-
- if (this.collection) {
-
- opt = opt || {};
-
- var z = (this.collection.first().get('z') || 0) - 1;
-
- this.trigger('batch:start', { batchName: 'to-back' });
-
- if (opt.deep) {
-
- var cells = this.getEmbeddedCells({ deep: true, breadthFirst: true });
- _.eachRight(cells, function(cell) { cell.set('z', z--, opt); });
- }
-
- this.set('z', z, opt).trigger('batch:stop', { batchName: 'to-back' });
- }
-
- return this;
- },
-
- embed: function(cell, opt) {
-
- if (this == cell || this.isEmbeddedIn(cell)) {
-
- throw new Error('Recursive embedding not allowed.');
-
- } else {
-
- this.trigger('batch:start', { batchName: 'embed' });
-
- var embeds = _.clone(this.get('embeds') || []);
-
- // We keep all element ids after links ids.
- embeds[cell.isLink() ? 'unshift' : 'push'](cell.id);
-
- cell.set('parent', this.id, opt);
- this.set('embeds', _.uniq(embeds), opt);
-
- this.trigger('batch:stop', { batchName: 'embed' });
- }
-
- return this;
- },
-
- unembed: function(cell, opt) {
-
- this.trigger('batch:start', { batchName: 'unembed' });
-
- cell.unset('parent', opt);
- this.set('embeds', _.without(this.get('embeds'), cell.id), opt);
-
- this.trigger('batch:stop', { batchName: 'unembed' });
-
- return this;
- },
-
- // Return an array of ancestor cells.
- // The array is ordered from the parent of the cell
- // to the most distant ancestor.
- getAncestors: function() {
-
- var ancestors = [];
- var parentId = this.get('parent');
-
- if (this.collection === undefined)
- return ancestors;
-
- while (parentId !== undefined) {
- var parent = this.collection.get(parentId);
- if (parent !== undefined) {
- ancestors.push(parent);
- parentId = parent.get('parent');
- } else {
- break;
- }
- }
-
- return ancestors;
- },
-
- getEmbeddedCells: function(opt) {
-
- opt = opt || {};
-
- // Cell models can only be retrieved when this element is part of a collection.
- // There is no way this element knows about other cells otherwise.
- // This also means that calling e.g. `translate()` on an element with embeds before
- // adding it to a graph does not translate its embeds.
- if (this.collection) {
-
- var cells;
-
- if (opt.deep) {
-
- if (opt.breadthFirst) {
-
- // breadthFirst algorithm
- cells = [];
- var queue = this.getEmbeddedCells();
-
- while (queue.length > 0) {
-
- var parent = queue.shift();
- cells.push(parent);
- queue.push.apply(queue, parent.getEmbeddedCells());
- }
-
- } else {
-
- // depthFirst algorithm
- cells = this.getEmbeddedCells();
- _.each(cells, function(cell) {
- cells.push.apply(cells, cell.getEmbeddedCells(opt));
- });
- }
-
- } else {
-
- cells = _.map(this.get('embeds'), this.collection.get, this.collection);
- }
-
- return cells;
- }
- return [];
- },
-
- isEmbeddedIn: function(cell, opt) {
-
- var cellId = _.isString(cell) ? cell : cell.id;
- var parentId = this.get('parent');
-
- opt = _.defaults({ deep: true }, opt);
-
- // See getEmbeddedCells().
- if (this.collection && opt.deep) {
-
- while (parentId) {
- if (parentId == cellId) {
- return true;
- }
- parentId = this.collection.get(parentId).get('parent');
- }
-
- return false;
-
- } else {
-
- // When this cell is not part of a collection check
- // at least whether it's a direct child of given cell.
- return parentId == cellId;
- }
- },
-
- clone: function(opt) {
-
- opt = opt || {};
-
- var clone = Backbone.Model.prototype.clone.apply(this, arguments);
-
- // We don't want the clone to have the same ID as the original.
- clone.set('id', joint.util.uuid(), { silent: true });
- clone.set('embeds', '');
-
- if (!opt.deep) return clone;
-
- // The rest of the `clone()` method deals with embeds. If `deep` option is set to `true`,
- // the return value is an array of all the embedded clones created.
-
- var embeds = _.sortBy(this.getEmbeddedCells(), function(cell) {
- // Sort embeds that links come before elements.
- return cell instanceof joint.dia.Element;
- });
-
- var clones = [clone];
-
- // This mapping stores cloned links under the `id`s of they originals.
- // This prevents cloning a link more then once. Consider a link 'self loop' for example.
- var linkCloneMapping = {};
-
- _.each(embeds, function(embed) {
-
- var embedClones = embed.clone({ deep: true });
-
- // Embed the first clone returned from `clone({ deep: true })` above. The first
- // cell is always the clone of the cell that called the `clone()` method, i.e. clone of `embed` in this case.
- clone.embed(embedClones[0]);
-
- _.each(embedClones, function(embedClone) {
-
- if (embedClone instanceof joint.dia.Link) {
-
- if (embedClone.get('source').id == this.id) {
-
- embedClone.prop('source', { id: clone.id });
- }
-
- if (embedClone.get('target').id == this.id) {
-
- embedClone.prop('target', { id: clone.id });
- }
-
- linkCloneMapping[embed.id] = embedClone;
-
- // Skip links. Inbound/outbound links are not relevant for them.
- return;
- }
-
- clones.push(embedClone);
-
- // Collect all inbound links, clone them (if not done already) and set their target to the `embedClone.id`.
- var inboundLinks = this.collection.getConnectedLinks(embed, { inbound: true });
-
- _.each(inboundLinks, function(link) {
-
- var linkClone = linkCloneMapping[link.id] || link.clone();
-
- // Make sure we don't clone a link more then once.
- linkCloneMapping[link.id] = linkClone;
-
- linkClone.prop('target', { id: embedClone.id });
- });
-
- // Collect all inbound links, clone them (if not done already) and set their source to the `embedClone.id`.
- var outboundLinks = this.collection.getConnectedLinks(embed, { outbound: true });
-
- _.each(outboundLinks, function(link) {
-
- var linkClone = linkCloneMapping[link.id] || link.clone();
-
- // Make sure we don't clone a link more then once.
- linkCloneMapping[link.id] = linkClone;
-
- linkClone.prop('source', { id: embedClone.id });
- });
-
- }, this);
-
- }, this);
-
- // Add link clones to the array of all the new clones.
- clones = clones.concat(_.values(linkCloneMapping));
-
- return clones;
- },
-
- // A convenient way to set nested properties.
- // This method merges the properties you'd like to set with the ones
- // stored in the cell and makes sure change events are properly triggered.
- // You can either set a nested property with one object
- // or use a property path.
- // The most simple use case is:
- // `cell.prop('name/first', 'John')` or
- // `cell.prop({ name: { first: 'John' } })`.
- // Nested arrays are supported too:
- // `cell.prop('series/0/data/0/degree', 50)` or
- // `cell.prop({ series: [ { data: [ { degree: 50 } ] } ] })`.
- prop: function(props, value, opt) {
-
- var delim = '/';
-
- if (_.isString(props)) {
- // Get/set an attribute by a special path syntax that delimits
- // nested objects by the colon character.
-
- if (arguments.length > 1) {
-
- var path = props;
- var pathArray = path.split('/');
- var property = pathArray[0];
-
- opt = opt || {};
- opt.propertyPath = path;
- opt.propertyValue = value;
-
- if (pathArray.length == 1) {
- // Property is not nested. We can simply use `set()`.
- return this.set(property, value, opt);
- }
-
- var update = {};
- // Initialize the nested object. Subobjects are either arrays or objects.
- // An empty array is created if the sub-key is an integer. Otherwise, an empty object is created.
- // Note that this imposes a limitation on object keys one can use with Inspector.
- // Pure integer keys will cause issues and are therefore not allowed.
- var initializer = update;
- var prevProperty = property;
- _.each(_.rest(pathArray), function(key) {
- initializer = initializer[prevProperty] = (_.isFinite(Number(key)) ? [] : {});
- prevProperty = key;
- });
- // Fill update with the `value` on `path`.
- update = joint.util.setByPath(update, path, value, '/');
-
- var baseAttributes = _.merge({}, this.attributes);
- // if rewrite mode enabled, we replace value referenced by path with
- // the new one (we don't merge).
- opt.rewrite && joint.util.unsetByPath(baseAttributes, path, '/');
-
- // Merge update with the model attributes.
- var attributes = _.merge(baseAttributes, update);
- // Finally, set the property to the updated attributes.
- return this.set(property, attributes[property], opt);
-
- } else {
-
- return joint.util.getByPath(this.attributes, props, delim);
- }
- }
-
- return this.set(_.merge({}, this.attributes, props), value);
- },
-
- // A convient way to unset nested properties
- removeProp: function(path, opt) {
-
- // Once a property is removed from the `attrs` attribute
- // the cellView will recognize a `dirty` flag and rerender itself
- // in order to remove the attribute from SVG element.
- opt = opt || {};
- opt.dirty = true;
-
- var pathArray = path.split('/');
-
- if (pathArray.length === 1) {
- // A top level property
- return this.unset(path, opt);
- }
-
- // A nested property
- var property = pathArray[0];
- var nestedPath = pathArray.slice(1).join('/');
- var propertyValue = _.merge({}, this.get(property));
-
- joint.util.unsetByPath(propertyValue, nestedPath, '/');
-
- return this.set(property, propertyValue, opt);
- },
-
- // A convenient way to set nested attributes.
- attr: function(attrs, value, opt) {
-
- var args = Array.prototype.slice.call(arguments);
-
- if (_.isString(attrs)) {
- // Get/set an attribute by a special path syntax that delimits
- // nested objects by the colon character.
- args[0] = 'attrs/' + attrs;
-
- } else {
-
- args[0] = { 'attrs' : attrs };
- }
-
- return this.prop.apply(this, args);
- },
-
- // A convenient way to unset nested attributes
- removeAttr: function(path, opt) {
-
- if (_.isArray(path)) {
- _.each(path, function(p) { this.removeAttr(p, opt); }, this);
- return this;
- }
-
- return this.removeProp('attrs/' + path, opt);
- },
-
- transition: function(path, value, opt, delim) {
-
- delim = delim || '/';
-
- var defaults = {
- duration: 100,
- delay: 10,
- timingFunction: joint.util.timing.linear,
- valueFunction: joint.util.interpolate.number
- };
-
- opt = _.extend(defaults, opt);
-
- var firstFrameTime = 0;
- var interpolatingFunction;
-
- var setter = _.bind(function(runtime) {
-
- var id, progress, propertyValue, status;
-
- firstFrameTime = firstFrameTime || runtime;
- runtime -= firstFrameTime;
- progress = runtime / opt.duration;
-
- if (progress < 1) {
- this._transitionIds[path] = id = joint.util.nextFrame(setter);
- } else {
- progress = 1;
- delete this._transitionIds[path];
- }
-
- propertyValue = interpolatingFunction(opt.timingFunction(progress));
-
- opt.transitionId = id;
-
- this.prop(path, propertyValue, opt);
-
- if (!id) this.trigger('transition:end', this, path);
-
- }, this);
-
- var initiator = _.bind(function(callback) {
-
- this.stopTransitions(path);
-
- interpolatingFunction = opt.valueFunction(joint.util.getByPath(this.attributes, path, delim), value);
-
- this._transitionIds[path] = joint.util.nextFrame(callback);
-
- this.trigger('transition:start', this, path);
-
- }, this);
-
- return _.delay(initiator, opt.delay, setter);
- },
-
- getTransitions: function() {
- return _.keys(this._transitionIds);
- },
-
- stopTransitions: function(path, delim) {
-
- delim = delim || '/';
-
- var pathArray = path && path.split(delim);
-
- _(this._transitionIds).keys().filter(pathArray && function(key) {
-
- return _.isEqual(pathArray, key.split(delim).slice(0, pathArray.length));
-
- }).each(function(key) {
-
- joint.util.cancelFrame(this._transitionIds[key]);
-
- delete this._transitionIds[key];
-
- this.trigger('transition:end', this, key);
-
- }, this);
-
- return this;
- },
-
- // A shorcut making it easy to create constructs like the following:
- // `var el = (new joint.shapes.basic.Rect).addTo(graph)`.
- addTo: function(graph, opt) {
-
- graph.addCell(this, opt);
- return this;
- },
-
- // A shortcut for an equivalent call: `paper.findViewByModel(cell)`
- // making it easy to create constructs like the following:
- // `cell.findView(paper).highlight()`
- findView: function(paper) {
-
- return paper.findViewByModel(this);
- },
-
- isLink: function() {
-
- return false;
- }
-});
-
-// joint.dia.CellView base view and controller.
-// --------------------------------------------
-
-// This is the base view and controller for `joint.dia.ElementView` and `joint.dia.LinkView`.
-
-joint.dia.CellView = Backbone.View.extend({
-
- tagName: 'g',
-
- attributes: function() {
-
- return { 'model-id': this.model.id };
- },
-
- constructor: function(options) {
-
- this._configure(options);
- Backbone.View.apply(this, arguments);
- },
-
- _configure: function(options) {
-
- if (this.options) options = _.extend({}, _.result(this, 'options'), options);
- this.options = options;
- // Make sure a global unique id is assigned to this view. Store this id also to the properties object.
- // The global unique id makes sure that the same view can be rendered on e.g. different machines and
- // still be associated to the same object among all those clients. This is necessary for real-time
- // collaboration mechanism.
- this.options.id = this.options.id || joint.util.guid(this);
- },
-
- initialize: function() {
-
- _.bindAll(this, 'remove', 'update');
-
- // Store reference to this to the <g> DOM element so that the view is accessible through the DOM tree.
- this.$el.data('view', this);
-
- this.listenTo(this.model, 'remove', this.remove);
- this.listenTo(this.model, 'change:attrs', this.onChangeAttrs);
- },
-
- onChangeAttrs: function(cell, attrs, opt) {
-
- if (opt.dirty) {
-
- // dirty flag could be set when a model attribute was removed and it needs to be cleared
- // also from the DOM element. See cell.removeAttr().
- return this.render();
- }
-
- return this.update();
- },
-
- // Override the Backbone `_ensureElement()` method in order to create a `<g>` node that wraps
- // all the nodes of the Cell view.
- _ensureElement: function() {
-
- var el;
-
- if (!this.el) {
-
- var attrs = _.extend({ id: this.id }, _.result(this, 'attributes'));
- if (this.className) attrs['class'] = _.result(this, 'className');
- el = V(_.result(this, 'tagName'), attrs).node;
-
- } else {
-
- el = _.result(this, 'el');
- }
-
- this.setElement(el, false);
- },
-
- findBySelector: function(selector) {
-
- // These are either descendants of `this.$el` of `this.$el` itself.
- // `.` is a special selector used to select the wrapping `<g>` element.
- var $selected = selector === '.' ? this.$el : this.$el.find(selector);
- return $selected;
- },
-
- notify: function(evt) {
-
- if (this.paper) {
-
- var args = Array.prototype.slice.call(arguments, 1);
-
- // Trigger the event on both the element itself and also on the paper.
- this.trigger.apply(this, [evt].concat(args));
-
- // Paper event handlers receive the view object as the first argument.
- this.paper.trigger.apply(this.paper, [evt, this].concat(args));
- }
- },
-
- getStrokeBBox: function(el) {
- // Return a bounding box rectangle that takes into account stroke.
- // Note that this is a naive and ad-hoc implementation that does not
- // works only in certain cases and should be replaced as soon as browsers will
- // start supporting the getStrokeBBox() SVG method.
- // @TODO any better solution is very welcome!
-
- var isMagnet = !!el;
-
- el = el || this.el;
- var bbox = V(el).bbox(false, this.paper.viewport);
-
- var strokeWidth;
- if (isMagnet) {
-
- strokeWidth = V(el).attr('stroke-width');
-
- } else {
-
- strokeWidth = this.model.attr('rect/stroke-width') || this.model.attr('circle/stroke-width') || this.model.attr('ellipse/stroke-width') || this.model.attr('path/stroke-width');
- }
-
- strokeWidth = parseFloat(strokeWidth) || 0;
-
- return g.rect(bbox).moveAndExpand({ x: -strokeWidth / 2, y: -strokeWidth / 2, width: strokeWidth, height: strokeWidth });
- },
-
- getBBox: function() {
-
- return V(this.el).bbox();
- },
-
- highlight: function(el, opt) {
-
- el = !el ? this.el : this.$(el)[0] || this.el;
-
- // set partial flag if the highlighted element is not the entire view.
- opt = opt || {};
- opt.partial = el != this.el;
-
- this.notify('cell:highlight', el, opt);
- return this;
- },
-
- unhighlight: function(el, opt) {
-
- el = !el ? this.el : this.$(el)[0] || this.el;
-
- opt = opt || {};
- opt.partial = el != this.el;
-
- this.notify('cell:unhighlight', el, opt);
- return this;
- },
-
- // Find the closest element that has the `magnet` attribute set to `true`. If there was not such
- // an element found, return the root element of the cell view.
- findMagnet: function(el) {
-
- var $el = this.$(el);
-
- if ($el.length === 0 || $el[0] === this.el) {
-
- // If the overall cell has set `magnet === false`, then return `undefined` to
- // announce there is no magnet found for this cell.
- // This is especially useful to set on cells that have 'ports'. In this case,
- // only the ports have set `magnet === true` and the overall element has `magnet === false`.
- var attrs = this.model.get('attrs') || {};
- if (attrs['.'] && attrs['.']['magnet'] === false) {
- return undefined;
- }
-
- return this.el;
- }
-
- if ($el.attr('magnet')) {
-
- return $el[0];
- }
-
- return this.findMagnet($el.parent());
- },
-
- // `selector` is a CSS selector or `'.'`. `filter` must be in the special JointJS filter format:
- // `{ name: <name of the filter>, args: { <arguments>, ... }`.
- // An example is: `{ filter: { name: 'blur', args: { radius: 5 } } }`.
- applyFilter: function(selector, filter) {
-
- var $selected = this.findBySelector(selector);
-
- // Generate a hash code from the stringified filter definition. This gives us
- // a unique filter ID for different definitions.
- var filterId = filter.name + this.paper.svg.id + joint.util.hashCode(JSON.stringify(filter));
-
- // If the filter already exists in the document,
- // we're done and we can just use it (reference it using `url()`).
- // If not, create one.
- if (!this.paper.svg.getElementById(filterId)) {
-
- var filterSVGString = joint.util.filter[filter.name] && joint.util.filter[filter.name](filter.args || {});
- if (!filterSVGString) {
- throw new Error('Non-existing filter ' + filter.name);
- }
- var filterElement = V(filterSVGString);
- // Set the filter area to be 3x the bounding box of the cell
- // and center the filter around the cell.
- filterElement.attr({
- filterUnits: 'objectBoundingBox',
- x: -1, y: -1, width: 3, height: 3
- });
- if (filter.attrs) filterElement.attr(filter.attrs);
- filterElement.node.id = filterId;
- V(this.paper.svg).defs().append(filterElement);
- }
-
- $selected.each(function() {
-
- V(this).attr('filter', 'url(#' + filterId + ')');
- });
- },
-
- // `selector` is a CSS selector or `'.'`. `attr` is either a `'fill'` or `'stroke'`.
- // `gradient` must be in the special JointJS gradient format:
- // `{ type: <linearGradient|radialGradient>, stops: [ { offset: <offset>, color: <color> }, ... ]`.
- // An example is: `{ fill: { type: 'linearGradient', stops: [ { offset: '10%', color: 'green' }, { offset: '50%', color: 'blue' } ] } }`.
- applyGradient: function(selector, attr, gradient) {
-
- var $selected = this.findBySelector(selector);
-
- // Generate a hash code from the stringified filter definition. This gives us
- // a unique filter ID for different definitions.
- var gradientId = gradient.type + this.paper.svg.id + joint.util.hashCode(JSON.stringify(gradient));
-
- // If the gradient already exists in the document,
- // we're done and we can just use it (reference it using `url()`).
- // If not, create one.
- if (!this.paper.svg.getElementById(gradientId)) {
-
- var gradientSVGString = [
- '<' + gradient.type + '>',
- _.map(gradient.stops, function(stop) {
- return '<stop offset="' + stop.offset + '" stop-color="' + stop.color + '" stop-opacity="' + (_.isFinite(stop.opacity) ? stop.opacity : 1) + '" />';
- }).join(''),
- '</' + gradient.type + '>'
- ].join('');
-
- var gradientElement = V(gradientSVGString);
- if (gradient.attrs) { gradientElement.attr(gradient.attrs); }
- gradientElement.node.id = gradientId;
- V(this.paper.svg).defs().append(gradientElement);
- }
-
- $selected.each(function() {
-
- V(this).attr(attr, 'url(#' + gradientId + ')');
- });
- },
-
- // Construct a unique selector for the `el` element within this view.
- // `prevSelector` is being collected through the recursive call.
- // No value for `prevSelector` is expected when using this method.
- getSelector: function(el, prevSelector) {
-
- if (el === this.el) {
- return prevSelector;
- }
-
- var nthChild = V(el).index() + 1;
- var selector = el.tagName + ':nth-child(' + nthChild + ')';
-
- if (prevSelector) {
- selector += ' > ' + prevSelector;
- }
-
- return this.getSelector(el.parentNode, selector);
- },
-
- // Interaction. The controller part.
- // ---------------------------------
-
- // Interaction is handled by the paper and delegated to the view in interest.
- // `x` & `y` parameters passed to these functions represent the coordinates already snapped to the paper grid.
- // If necessary, real coordinates can be obtained from the `evt` event object.
-
- // These functions are supposed to be overriden by the views that inherit from `joint.dia.Cell`,
- // i.e. `joint.dia.Element` and `joint.dia.Link`.
-
- pointerdblclick: function(evt, x, y) {
-
- this.notify('cell:pointerdblclick', evt, x, y);
- },
-
- pointerclick: function(evt, x, y) {
-
- this.notify('cell:pointerclick', evt, x, y);
- },
-
- pointerdown: function(evt, x, y) {
-
- if (this.model.collection) {
- this.model.trigger('batch:start', { batchName: 'pointer' });
- this._collection = this.model.collection;
- }
-
- this.notify('cell:pointerdown', evt, x, y);
- },
-
- pointermove: function(evt, x, y) {
-
- this.notify('cell:pointermove', evt, x, y);
- },
-
- pointerup: function(evt, x, y) {
-
- this.notify('cell:pointerup', evt, x, y);
-
- if (this._collection) {
- // we don't want to trigger event on model as model doesn't
- // need to be member of collection anymore (remove)
- this._collection.trigger('batch:stop', { batchName: 'pointer' });
- delete this._collection;
- }
- },
-
- mouseover: function(evt) {
-
- this.notify('cell:mouseover', evt);
- },
-
- mouseout: function(evt) {
-
- this.notify('cell:mouseout', evt);
- }
-});
-
-// JointJS library.
-// (c) 2011-2013 client IO
-
-// joint.dia.Element base model.
-// -----------------------------
-
-joint.dia.Element = joint.dia.Cell.extend({
-
- defaults: {
- position: { x: 0, y: 0 },
- size: { width: 1, height: 1 },
- angle: 0
- },
-
- position: function(x, y, opt) {
-
- var isSetter = _.isNumber(y);
-
- opt = (isSetter ? opt : x) || {};
-
- // option `parentRelative` for setting the position relative to the element's parent.
- if (opt.parentRelative) {
-
- // Getting the parent's position requires the collection.
- // Cell.get('parent') helds cell id only.
- if (!this.collection) throw new Error('Element must be part of a collection.');
-
- var parent = this.collection.get(this.get('parent'));
- var parentPosition = parent && !parent.isLink()
- ? parent.get('position')
- : { x: 0, y: 0 };
- }
-
- if (isSetter) {
-
- if (opt.parentRelative) {
- x += parentPosition.x;
- y += parentPosition.y;
- }
-
- return this.set('position', { x: x, y: y }, opt);
-
- } else { // Getter returns a geometry point.
-
- var elementPosition = g.point(this.get('position'));
-
- return opt.parentRelative
- ? elementPosition.difference(parentPosition)
- : elementPosition;
- }
- },
-
- translate: function(tx, ty, opt) {
-
- ty = ty || 0;
-
- if (tx === 0 && ty === 0) {
- // Like nothing has happened.
- return this;
- }
-
- opt = opt || {};
- // Pass the initiator of the translation.
- opt.translateBy = opt.translateBy || this.id;
- // To find out by how much an element was translated in event 'change:position' handlers.
- opt.tx = tx;
- opt.ty = ty;
-
- var position = this.get('position') || { x: 0, y: 0 };
- var translatedPosition = { x: position.x + tx || 0, y: position.y + ty || 0 };
-
- if (opt.transition) {
-
- if (!_.isObject(opt.transition)) opt.transition = {};
-
- this.transition('position', translatedPosition, _.extend({}, opt.transition, {
- valueFunction: joint.util.interpolate.object
- }));
-
- } else {
-
- this.set('position', translatedPosition, opt);
-
- // Recursively call `translate()` on all the embeds cells.
- _.invoke(this.getEmbeddedCells(), 'translate', tx, ty, opt);
- }
-
- return this;
- },
-
- resize: function(width, height, opt) {
-
- this.trigger('batch:start', { batchName: 'resize' });
- this.set('size', { width: width, height: height }, opt);
- this.trigger('batch:stop', { batchName: 'resize' });
-
- return this;
- },
-
- fitEmbeds: function(opt) {
-
- opt = opt || 0;
-
- var collection = this.collection;
-
- // Getting the children's size and position requires the collection.
- // Cell.get('embdes') helds an array of cell ids only.
- if (!collection) throw new Error('Element must be part of a collection.');
-
- var embeddedCells = this.getEmbeddedCells();
-
- if (embeddedCells.length > 0) {
-
- this.trigger('batch:start', { batchName: 'fit-embeds' });
-
- if (opt.deep) {
- // Recursively apply fitEmbeds on all embeds first.
- _.invoke(embeddedCells, 'fitEmbeds', opt);
- }
-
- // Compute cell's size and position based on the children bbox
- // and given padding.
- var bbox = collection.getBBox(embeddedCells);
- var padding = opt.padding || 0;
-
- if (_.isNumber(padding)) {
- padding = {
- left: padding,
- right: padding,
- top: padding,
- bottom: padding
- };
- } else {
- padding = {
- left: padding.left || 0,
- right: padding.right || 0,
- top: padding.top || 0,
- bottom: padding.bottom || 0
- };
- }
-
- // Apply padding computed above to the bbox.
- bbox.moveAndExpand({
- x: - padding.left,
- y: - padding.top,
- width: padding.right + padding.left,
- height: padding.bottom + padding.top
- });
-
- // Set new element dimensions finally.
- this.set({
- position: { x: bbox.x, y: bbox.y },
- size: { width: bbox.width, height: bbox.height }
- }, opt);
-
- this.trigger('batch:stop', { batchName: 'fit-embeds' });
- }
-
- return this;
- },
-
- // Rotate element by `angle` degrees, optionally around `origin` point.
- // If `origin` is not provided, it is considered to be the center of the element.
- // If `absolute` is `true`, the `angle` is considered is abslute, i.e. it is not
- // the difference from the previous angle.
- rotate: function(angle, absolute, origin) {
-
- if (origin) {
-
- var center = this.getBBox().center();
- var size = this.get('size');
- var position = this.get('position');
- center.rotate(origin, this.get('angle') - angle);
- var dx = center.x - size.width / 2 - position.x;
- var dy = center.y - size.height / 2 - position.y;
- this.trigger('batch:start', { batchName: 'rotate' });
- this.translate(dx, dy);
- this.rotate(angle, absolute);
- this.trigger('batch:stop', { batchName: 'rotate' });
-
- } else {
-
- this.set('angle', absolute ? angle : (this.get('angle') + angle) % 360);
- }
-
- return this;
- },
-
- getBBox: function() {
-
- var position = this.get('position');
- var size = this.get('size');
-
- return g.rect(position.x, position.y, size.width, size.height);
- }
-});
-
-// joint.dia.Element base view and controller.
-// -------------------------------------------
-
-joint.dia.ElementView = joint.dia.CellView.extend({
-
- className: function() {
- return 'element ' + this.model.get('type').split('.').join(' ');
- },
-
- initialize: function() {
-
- _.bindAll(this, 'translate', 'resize', 'rotate');
-
- joint.dia.CellView.prototype.initialize.apply(this, arguments);
-
- this.listenTo(this.model, 'change:position', this.translate);
- this.listenTo(this.model, 'change:size', this.resize);
- this.listenTo(this.model, 'change:angle', this.rotate);
- },
-
- // Default is to process the `attrs` object and set attributes on subelements based on the selectors.
- update: function(cell, renderingOnlyAttrs) {
-
- var allAttrs = this.model.get('attrs');
-
- var rotatable = V(this.$('.rotatable')[0]);
- if (rotatable) {
-
- var rotation = rotatable.attr('transform');
- rotatable.attr('transform', '');
- }
-
- var relativelyPositioned = [];
-
- _.each(renderingOnlyAttrs || allAttrs, function(attrs, selector) {
-
- // Elements that should be updated.
- var $selected = this.findBySelector(selector);
-
- // No element matched by the `selector` was found. We're done then.
- if ($selected.length === 0) return;
-
- // Special attributes are treated by JointJS, not by SVG.
- var specialAttributes = ['style', 'text', 'html', 'ref-x', 'ref-y', 'ref-dx', 'ref-dy', 'ref-width', 'ref-height', 'ref', 'x-alignment', 'y-alignment', 'port'];
-
- // If the `filter` attribute is an object, it is in the special JointJS filter format and so
- // it becomes a special attribute and is treated separately.
- if (_.isObject(attrs.filter)) {
-
- specialAttributes.push('filter');
- this.applyFilter(selector, attrs.filter);
- }
-
- // If the `fill` or `stroke` attribute is an object, it is in the special JointJS gradient format and so
- // it becomes a special attribute and is treated separately.
- if (_.isObject(attrs.fill)) {
-
- specialAttributes.push('fill');
- this.applyGradient(selector, 'fill', attrs.fill);
- }
- if (_.isObject(attrs.stroke)) {
-
- specialAttributes.push('stroke');
- this.applyGradient(selector, 'stroke', attrs.stroke);
- }
-
- // Make special case for `text` attribute. So that we can set text content of the `<text>` element
- // via the `attrs` object as well.
- // Note that it's important to set text before applying the rest of the final attributes.
- // Vectorizer `text()` method sets on the element its own attributes and it has to be possible
- // to rewrite them, if needed. (i.e display: 'none')
- if (!_.isUndefined(attrs.text)) {
-
- $selected.each(function() {
-
- V(this).text(attrs.text + '', { lineHeight: attrs.lineHeight, textPath: attrs.textPath });
- });
- specialAttributes.push('lineHeight', 'textPath');
- }
-
- // Set regular attributes on the `$selected` subelement. Note that we cannot use the jQuery attr()
- // method as some of the attributes might be namespaced (e.g. xlink:href) which fails with jQuery attr().
- var finalAttributes = _.omit(attrs, specialAttributes);
-
- $selected.each(function() {
-
- V(this).attr(finalAttributes);
- });
-
- // `port` attribute contains the `id` of the port that the underlying magnet represents.
- if (attrs.port) {
-
- $selected.attr('port', _.isUndefined(attrs.port.id) ? attrs.port : attrs.port.id);
- }
-
- // `style` attribute is special in the sense that it sets the CSS style of the subelement.
- if (attrs.style) {
-
- $selected.css(attrs.style);
- }
-
- if (!_.isUndefined(attrs.html)) {
-
- $selected.each(function() {
-
- $(this).html(attrs.html + '');
- });
- }
-
- // Special `ref-x` and `ref-y` attributes make it possible to set both absolute or
- // relative positioning of subelements.
- if (!_.isUndefined(attrs['ref-x']) ||
- !_.isUndefined(attrs['ref-y']) ||
- !_.isUndefined(attrs['ref-dx']) ||
- !_.isUndefined(attrs['ref-dy']) ||
- !_.isUndefined(attrs['x-alignment']) ||
- !_.isUndefined(attrs['y-alignment']) ||
- !_.isUndefined(attrs['ref-width']) ||
- !_.isUndefined(attrs['ref-height'])
- ) {
-
- _.each($selected, function(el, index, list) {
- var $el = $(el);
- // copy original list selector to the element
- $el.selector = list.selector;
- relativelyPositioned.push($el);
- });
- }
-
- }, this);
-
- // We don't want the sub elements to affect the bounding box of the root element when
- // positioning the sub elements relatively to the bounding box.
- //_.invoke(relativelyPositioned, 'hide');
- //_.invoke(relativelyPositioned, 'show');
-
- // Note that we're using the bounding box without transformation because we are already inside
- // a transformed coordinate system.
- var bbox = this.el.getBBox();
-
- renderingOnlyAttrs = renderingOnlyAttrs || {};
-
- _.each(relativelyPositioned, function($el) {
-
- // if there was a special attribute affecting the position amongst renderingOnlyAttributes
- // we have to merge it with rest of the element's attributes as they are necessary
- // to update the position relatively (i.e `ref`)
- var renderingOnlyElAttrs = renderingOnlyAttrs[$el.selector];
- var elAttrs = renderingOnlyElAttrs
- ? _.merge({}, allAttrs[$el.selector], renderingOnlyElAttrs)
- : allAttrs[$el.selector];
-
- this.positionRelative($el, bbox, elAttrs);
-
- }, this);
-
- if (rotatable) {
-
- rotatable.attr('transform', rotation || '');
- }
- },
-
- positionRelative: function($el, bbox, elAttrs) {
-
- var ref = elAttrs['ref'];
- var refX = parseFloat(elAttrs['ref-x']);
- var refY = parseFloat(elAttrs['ref-y']);
- var refDx = parseFloat(elAttrs['ref-dx']);
- var refDy = parseFloat(elAttrs['ref-dy']);
- var yAlignment = elAttrs['y-alignment'];
- var xAlignment = elAttrs['x-alignment'];
- var refWidth = parseFloat(elAttrs['ref-width']);
- var refHeight = parseFloat(elAttrs['ref-height']);
-
- // `ref` is the selector of the reference element. If no `ref` is passed, reference
- // element is the root element.
-
- var isScalable = _.contains(_.pluck(_.pluck($el.parents('g'), 'className'), 'baseVal'), 'scalable');
-
- if (ref) {
-
- // Get the bounding box of the reference element relative to the root `<g>` element.
- bbox = V(this.findBySelector(ref)[0]).bbox(false, this.el);
- }
-
- var vel = V($el[0]);
-
- // Remove the previous translate() from the transform attribute and translate the element
- // relative to the root bounding box following the `ref-x` and `ref-y` attributes.
- if (vel.attr('transform')) {
-
- vel.attr('transform', vel.attr('transform').replace(/translate\([^)]*\)/g, '').trim() || '');
- }
-
- function isDefined(x) {
- return _.isNumber(x) && !_.isNaN(x);
- }
-
- // The final translation of the subelement.
- var tx = 0;
- var ty = 0;
-
- // 'ref-width'/'ref-height' defines the width/height of the subelement relatively to
- // the reference element size
- // val in 0..1 ref-width = 0.75 sets the width to 75% of the ref. el. width
- // val < 0 || val > 1 ref-height = -20 sets the height to the the ref. el. height shorter by 20
-
- if (isDefined(refWidth)) {
-
- if (refWidth >= 0 && refWidth <= 1) {
-
- vel.attr('width', refWidth * bbox.width);
-
- } else {
-
- vel.attr('width', Math.max(refWidth + bbox.width, 0));
- }
- }
-
- if (isDefined(refHeight)) {
-
- if (refHeight >= 0 && refHeight <= 1) {
-
- vel.attr('height', refHeight * bbox.height);
-
- } else {
-
- vel.attr('height', Math.max(refHeight + bbox.height, 0));
- }
- }
-
- // `ref-dx` and `ref-dy` define the offset of the subelement relative to the right and/or bottom
- // coordinate of the reference element.
- if (isDefined(refDx)) {
-
- if (isScalable) {
-
- // Compensate for the scale grid in case the elemnt is in the scalable group.
- var scale = V(this.$('.scalable')[0]).scale();
- tx = bbox.x + bbox.width + refDx / scale.sx;
-
- } else {
-
- tx = bbox.x + bbox.width + refDx;
- }
- }
- if (isDefined(refDy)) {
-
- if (isScalable) {
-
- // Compensate for the scale grid in case the elemnt is in the scalable group.
- var scale = V(this.$('.scalable')[0]).scale();
- ty = bbox.y + bbox.height + refDy / scale.sy;
- } else {
-
- ty = bbox.y + bbox.height + refDy;
- }
- }
-
- // if `refX` is in [0, 1] then `refX` is a fraction of bounding box width
- // if `refX` is < 0 then `refX`'s absolute values is the right coordinate of the bounding box
- // otherwise, `refX` is the left coordinate of the bounding box
- // Analogical rules apply for `refY`.
- if (isDefined(refX)) {
-
- if (refX > 0 && refX < 1) {
-
- tx = bbox.x + bbox.width * refX;
-
- } else if (isScalable) {
-
- // Compensate for the scale grid in case the elemnt is in the scalable group.
- var scale = V(this.$('.scalable')[0]).scale();
- tx = bbox.x + refX / scale.sx;
-
- } else {
-
- tx = bbox.x + refX;
- }
- }
- if (isDefined(refY)) {
-
- if (refY > 0 && refY < 1) {
-
- ty = bbox.y + bbox.height * refY;
-
- } else if (isScalable) {
-
- // Compensate for the scale grid in case the elemnt is in the scalable group.
- var scale = V(this.$('.scalable')[0]).scale();
- ty = bbox.y + refY / scale.sy;
-
- } else {
-
- ty = bbox.y + refY;
- }
- }
-
- var velbbox = vel.bbox(false, this.paper.viewport);
- // `y-alignment` when set to `middle` causes centering of the subelement around its new y coordinate.
- if (yAlignment === 'middle') {
-
- ty -= velbbox.height / 2;
-
- } else if (isDefined(yAlignment)) {
-
- ty += (yAlignment > -1 && yAlignment < 1) ? velbbox.height * yAlignment : yAlignment;
- }
-
- // `x-alignment` when set to `middle` causes centering of the subelement around its new x coordinate.
- if (xAlignment === 'middle') {
-
- tx -= velbbox.width / 2;
-
- } else if (isDefined(xAlignment)) {
-
- tx += (xAlignment > -1 && xAlignment < 1) ? velbbox.width * xAlignment : xAlignment;
- }
-
- vel.translate(tx, ty);
- },
-
- // `prototype.markup` is rendered by default. Set the `markup` attribute on the model if the
- // default markup is not desirable.
- renderMarkup: function() {
-
- var markup = this.model.markup || this.model.get('markup');
-
- if (markup) {
-
- var nodes = V(markup);
- V(this.el).append(nodes);
-
- } else {
-
- throw new Error('properties.markup is missing while the default render() implementation is used.');
- }
- },
-
- render: function() {
-
- this.$el.empty();
-
- this.renderMarkup();
-
- this.update();
-
- this.resize();
- this.rotate();
- this.translate();
-
- return this;
- },
-
- // Scale the whole `<g>` group. Note the difference between `scale()` and `resize()` here.
- // `resize()` doesn't scale the whole `<g>` group but rather adjusts the `box.sx`/`box.sy` only.
- // `update()` is then responsible for scaling only those elements that have the `follow-scale`
- // attribute set to `true`. This is desirable in elements that have e.g. a `<text>` subelement
- // that is not supposed to be scaled together with a surrounding `<rect>` element that IS supposed
- // be be scaled.
- scale: function(sx, sy) {
-
- // TODO: take into account the origin coordinates `ox` and `oy`.
- V(this.el).scale(sx, sy);
- },
-
- resize: function() {
-
- var size = this.model.get('size') || { width: 1, height: 1 };
- var angle = this.model.get('angle') || 0;
-
- var scalable = V(this.$('.scalable')[0]);
- if (!scalable) {
- // If there is no scalable elements, than there is nothing to resize.
- return;
- }
- var scalableBbox = scalable.bbox(true);
- // Make sure `scalableBbox.width` and `scalableBbox.height` are not zero which can happen if the element does not have any content. By making
- // the width/height 1, we prevent HTML errors of the type `scale(Infinity, Infinity)`.
- scalable.attr('transform', 'scale(' + (size.width / (scalableBbox.width || 1)) + ',' + (size.height / (scalableBbox.height || 1)) + ')');
-
- // Now the interesting part. The goal is to be able to store the object geometry via just `x`, `y`, `angle`, `width` and `height`
- // Order of transformations is significant but we want to reconstruct the object always in the order:
- // resize(), rotate(), translate() no matter of how the object was transformed. For that to work,
- // we must adjust the `x` and `y` coordinates of the object whenever we resize it (because the origin of the
- // rotation changes). The new `x` and `y` coordinates are computed by canceling the previous rotation
- // around the center of the resized object (which is a different origin then the origin of the previous rotation)
- // and getting the top-left corner of the resulting object. Then we clean up the rotation back to what it originally was.
-
- // Cancel the rotation but now around a different origin, which is the center of the scaled object.
- var rotatable = V(this.$('.rotatable')[0]);
- var rotation = rotatable && rotatable.attr('transform');
- if (rotation && rotation !== 'null') {
-
- rotatable.attr('transform', rotation + ' rotate(' + (-angle) + ',' + (size.width / 2) + ',' + (size.height / 2) + ')');
- var rotatableBbox = scalable.bbox(false, this.paper.viewport);
-
- // Store new x, y and perform rotate() again against the new rotation origin.
- this.model.set('position', { x: rotatableBbox.x, y: rotatableBbox.y });
- this.rotate();
- }
-
- // Update must always be called on non-rotated element. Otherwise, relative positioning
- // would work with wrong (rotated) bounding boxes.
- this.update();
- },
-
- translate: function(model, changes, opt) {
-
- var position = this.model.get('position') || { x: 0, y: 0 };
-
- V(this.el).attr('transform', 'translate(' + position.x + ',' + position.y + ')');
- },
-
- rotate: function() {
-
- var rotatable = V(this.$('.rotatable')[0]);
- if (!rotatable) {
- // If there is no rotatable elements, then there is nothing to rotate.
- return;
- }
-
- var angle = this.model.get('angle') || 0;
- var size = this.model.get('size') || { width: 1, height: 1 };
-
- var ox = size.width / 2;
- var oy = size.height / 2;
-
-
- rotatable.attr('transform', 'rotate(' + angle + ',' + ox + ',' + oy + ')');
- },
-
- getBBox: function(opt) {
-
- if (opt && opt.useModelGeometry) {
- var noTransformationBBox = this.model.getBBox().bbox(this.model.get('angle'));
- var transformationMatrix = this.paper.viewport.getCTM();
- return V.transformRect(noTransformationBBox, transformationMatrix);
- }
-
- return joint.dia.CellView.prototype.getBBox.apply(this, arguments);
- },
-
- // Embedding mode methods
- // ----------------------
-
- findParentsByKey: function(key) {
-
- var bbox = this.model.getBBox();
-
- return key == 'bbox'
- ? this.paper.model.findModelsInArea(bbox)
- : this.paper.model.findModelsFromPoint(bbox[key]());
- },
-
- prepareEmbedding: function() {
-
- // Bring the model to the front with all his embeds.
- this.model.toFront({ deep: true, ui: true });
-
- // Move to front also all the inbound and outbound links that are connected
- // to any of the element descendant. If we bring to front only embedded elements,
- // links connected to them would stay in the background.
- _.invoke(this.paper.model.getConnectedLinks(this.model, { deep: true }), 'toFront', { ui: true });
-
- // Before we start looking for suitable parent we remove the current one.
- var parentId = this.model.get('parent');
- parentId && this.paper.model.getCell(parentId).unembed(this.model, { ui: true });
- },
-
- processEmbedding: function(opt) {
-
- opt = opt || this.paper.options;
-
- var candidates = this.findParentsByKey(opt.findParentBy);
-
- // don't account element itself or any of its descendents
- candidates = _.reject(candidates, function(el) {
- return this.model.id == el.id || el.isEmbeddedIn(this.model);
- }, this);
-
- if (opt.frontParentOnly) {
- // pick the element with the highest `z` index
- candidates = candidates.slice(-1);
- }
-
- var newCandidateView = null;
- var prevCandidateView = this._candidateEmbedView;
-
- // iterate over all candidates starting from the last one (has the highest z-index).
- for (var i = candidates.length - 1; i >= 0; i--) {
-
- var candidate = candidates[i];
-
- if (prevCandidateView && prevCandidateView.model.id == candidate.id) {
-
- // candidate remains the same
- newCandidateView = prevCandidateView;
- break;
-
- } else {
-
- var view = candidate.findView(this.paper);
- if (opt.validateEmbedding.call(this.paper, this, view)) {
-
- // flip to the new candidate
- newCandidateView = view;
- break;
- }
- }
- }
-
- if (newCandidateView && newCandidateView != prevCandidateView) {
- // A new candidate view found. Highlight the new one.
- prevCandidateView && prevCandidateView.unhighlight(null, { embedding: true });
- this._candidateEmbedView = newCandidateView.highlight(null, { embedding: true });
- }
-
- if (!newCandidateView && prevCandidateView) {
- // No candidate view found. Unhighlight the previous candidate.
- prevCandidateView.unhighlight(null, { embedding: true });
- delete this._candidateEmbedView;
- }
- },
-
- finalizeEmbedding: function() {
-
- var candidateView = this._candidateEmbedView;
-
- if (candidateView) {
-
- // We finished embedding. Candidate view is chosen to become the parent of the model.
- candidateView.model.embed(this.model, { ui: true });
- candidateView.unhighlight(null, { embedding: true });
-
- delete this._candidateEmbedView;
- }
-
- _.invoke(this.paper.model.getConnectedLinks(this.model, { deep: true }), 'reparent', { ui: true });
- },
-
- // Interaction. The controller part.
- // ---------------------------------
-
- pointerdown: function(evt, x, y) {
-
- // target is a valid magnet start linking
- if (evt.target.getAttribute('magnet') && this.paper.options.validateMagnet.call(this.paper, this, evt.target)) {
-
- this.model.trigger('batch:start', { batchName: 'add-link' });
-
- var link = this.paper.getDefaultLink(this, evt.target);
- link.set({
- source: {
- id: this.model.id,
- selector: this.getSelector(evt.target),
- port: $(evt.target).attr('port')
- },
- target: { x: x, y: y }
- });
-
- this.paper.model.addCell(link);
-
- this._linkView = this.paper.findViewByModel(link);
- this._linkView.pointerdown(evt, x, y);
- this._linkView.startArrowheadMove('target');
-
- } else {
- this._dx = x;
- this._dy = y;
-
- joint.dia.CellView.prototype.pointerdown.apply(this, arguments);
- this.notify('element:pointerdown', evt, x, y);
- }
- },
-
- pointermove: function(evt, x, y) {
-
- if (this._linkView) {
-
- // let the linkview deal with this event
- this._linkView.pointermove(evt, x, y);
-
- } else {
-
- var grid = this.paper.options.gridSize;
- var interactive = _.isFunction(this.options.interactive)
- ? this.options.interactive(this, 'pointermove')
- : this.options.interactive;
-
- if (interactive !== false) {
-
- var position = this.model.get('position');
-
- // Make sure the new element's position always snaps to the current grid after
- // translate as the previous one could be calculated with a different grid size.
- this.model.translate(
- g.snapToGrid(position.x, grid) - position.x + g.snapToGrid(x - this._dx, grid),
- g.snapToGrid(position.y, grid) - position.y + g.snapToGrid(y - this._dy, grid)
- );
-
- if (this.paper.options.embeddingMode) {
-
- if (!this._inProcessOfEmbedding) {
- // Prepare the element for embedding only if the pointer moves.
- // We don't want to do unnecessary action with the element
- // if an user only clicks/dblclicks on it.
- this.prepareEmbedding();
- this._inProcessOfEmbedding = true;
- }
-
- this.processEmbedding();
- }
- }
-
- this._dx = g.snapToGrid(x, grid);
- this._dy = g.snapToGrid(y, grid);
-
-
- joint.dia.CellView.prototype.pointermove.apply(this, arguments);
- this.notify('element:pointermove', evt, x, y);
- }
- },
-
- pointerup: function(evt, x, y) {
-
- if (this._linkView) {
-
- // let the linkview deal with this event
- this._linkView.pointerup(evt, x, y);
- delete this._linkView;
-
- this.model.trigger('batch:stop', { batchName: 'add-link' });
-
- } else {
-
- if (this._inProcessOfEmbedding) {
- this.finalizeEmbedding();
- this._inProcessOfEmbedding = false;
- }
-
- this.notify('element:pointerup', evt, x, y);
- joint.dia.CellView.prototype.pointerup.apply(this, arguments);
-
- }
- }
-
-});
-
-// JointJS diagramming library.
-// (c) 2011-2013 client IO
-
-// joint.dia.Link base model.
-// --------------------------
-joint.dia.Link = joint.dia.Cell.extend({
-
- // The default markup for links.
- markup: [
- '<path class="connection" stroke="black"/>',
- '<path class="marker-source" fill="black" stroke="black" />',
- '<path class="marker-target" fill="black" stroke="black" />',
- '<path class="connection-wrap"/>',
- '<g class="labels"/>',
- '<g class="marker-vertices"/>',
- '<g class="marker-arrowheads"/>',
- '<g class="link-tools"/>'
- ].join(''),
-
- labelMarkup: [
- '<g class="label">',
- '<rect />',
- '<text />',
- '</g>'
- ].join(''),
-
- toolMarkup: [
- '<g class="link-tool">',
- '<g class="tool-remove" event="remove">',
- '<circle r="11" />',
- '<path transform="scale(.8) translate(-16, -16)" d="M24.778,21.419 19.276,15.917 24.777,10.415 21.949,7.585 16.447,13.087 10.945,7.585 8.117,10.415 13.618,15.917 8.116,21.419 10.946,24.248 16.447,18.746 21.948,24.248z"/>',
- '<title>Remove link.</title>',
- '</g>',
- '<g class="tool-options" event="link:options">',
- '<circle r="11" transform="translate(25)"/>',
- '<path fill="white" transform="scale(.55) translate(29, -16)" d="M31.229,17.736c0.064-0.571,0.104-1.148,0.104-1.736s-0.04-1.166-0.104-1.737l-4.377-1.557c-0.218-0.716-0.504-1.401-0.851-2.05l1.993-4.192c-0.725-0.91-1.549-1.734-2.458-2.459l-4.193,1.994c-0.647-0.347-1.334-0.632-2.049-0.849l-1.558-4.378C17.165,0.708,16.588,0.667,16,0.667s-1.166,0.041-1.737,0.105L12.707,5.15c-0.716,0.217-1.401,0.502-2.05,0.849L6.464,4.005C5.554,4.73,4.73,5.554,4.005,6.464l1.994,4.192c-0.347,0.648-0.632,1.334-0.849,2.05l-4.378,1.557C0.708,14.834,0.667,15.412,0.667,16s0.041,1.165,0.105,1.736l4.378,1.558c0.217,0.715,0.502,1.401,0.849,2.049l-1.994,4.193c0.725,0.909,1.549,1.733,2.459,2.458l4.192-1.993c0.648,0.347,1.334,0.633,2.05,0.851l1.557,4.377c0.571,0.064,1.148,0.104,1.737,0.104c0.588,0,1.165-0.04,1.736-0.104l1.558-4.377c0.715-0.218,1.399-0.504,2.049-0.851l4.193,1.993c0.909-0.725,1.733-1.549,2.458-2.458l-1.993-4.193c0.347-0.647,0.633-1.334,0.851-2.049L31.229,17.736zM16,20.871c-2.69,0-4.872-2.182-4.872-4.871c0-2.69,2.182-4.872,4.872-4.872c2.689,0,4.871,2.182,4.871,4.872C20.871,18.689,18.689,20.871,16,20.871z"/>',
- '<title>Link options.</title>',
- '</g>',
- '</g>'
- ].join(''),
-
- // The default markup for showing/removing vertices. These elements are the children of the .marker-vertices element (see `this.markup`).
- // Only .marker-vertex and .marker-vertex-remove element have special meaning. The former is used for
- // dragging vertices (changin their position). The latter is used for removing vertices.
- vertexMarkup: [
- '<g class="marker-vertex-group" transform="translate(, )">',
- '<circle class="marker-vertex" idx="" r="10" />',
- '<path class="marker-vertex-remove-area" idx="" d="M16,5.333c-7.732,0-14,4.701-14,10.5c0,1.982,0.741,3.833,2.016,5.414L2,25.667l5.613-1.441c2.339,1.317,5.237,2.107,8.387,2.107c7.732,0,14-4.701,14-10.5C30,10.034,23.732,5.333,16,5.333z" transform="translate(5, -33)"/>',
- '<path class="marker-vertex-remove" idx="" transform="scale(.8) translate(9.5, -37)" d="M24.778,21.419 19.276,15.917 24.777,10.415 21.949,7.585 16.447,13.087 10.945,7.585 8.117,10.415 13.618,15.917 8.116,21.419 10.946,24.248 16.447,18.746 21.948,24.248z">',
- '<title>Remove vertex.</title>',
- '</path>',
- '</g>'
- ].join(''),
-
- arrowheadMarkup: [
- '<g class="marker-arrowhead-group marker-arrowhead-group-">',
- '<path class="marker-arrowhead" end="" d="M 26 0 L 0 13 L 26 26 z" />',
- '</g>'
- ].join(''),
-
- defaults: {
-
- type: 'link',
- source: {},
- target: {}
- },
-
- disconnect: function() {
-
- return this.set({ source: g.point(0, 0), target: g.point(0, 0) });
- },
-
- // A convenient way to set labels. Currently set values will be mixined with `value` if used as a setter.
- label: function(idx, value) {
-
- idx = idx || 0;
-
- var labels = this.get('labels') || [];
-
- // Is it a getter?
- if (arguments.length === 0 || arguments.length === 1) {
-
- return labels[idx];
- }
-
- var newValue = _.merge({}, labels[idx], value);
-
- var newLabels = labels.slice();
- newLabels[idx] = newValue;
-
- return this.set({ labels: newLabels });
- },
-
- translate: function(tx, ty, opt) {
-
- var attrs = {};
- var source = this.get('source');
- var target = this.get('target');
- var vertices = this.get('vertices');
-
- if (!source.id) {
- attrs.source = { x: source.x + tx, y: source.y + ty };
- }
-
- if (!target.id) {
- attrs.target = { x: target.x + tx, y: target.y + ty };
- }
-
- if (vertices && vertices.length) {
- attrs.vertices = _.map(vertices, function(vertex) {
- return { x: vertex.x + tx, y: vertex.y + ty };
- });
- }
-
- return this.set(attrs, opt);
- },
-
- reparent: function(opt) {
-
- var newParent;
-
- if (this.collection) {
-
- var source = this.collection.get(this.get('source').id);
- var target = this.collection.get(this.get('target').id);
- var prevParent = this.collection.get(this.get('parent'));
-
- if (source && target) {
- newParent = this.collection.getCommonAncestor(source, target);
- }
-
- if (prevParent && (!newParent || newParent.id != prevParent.id)) {
- // Unembed the link if source and target has no common ancestor
- // or common ancestor changed
- prevParent.unembed(this, opt);
- }
-
- if (newParent) {
- newParent.embed(this, opt);
- }
- }
-
- return newParent;
- },
-
- isLink: function() {
-
- return true;
- },
-
- hasLoop: function() {
-
- var sourceId = this.get('source').id;
- var targetId = this.get('target').id;
-
- return sourceId && targetId && sourceId == targetId;
- }
-});
-
-
-// joint.dia.Link base view and controller.
-// ----------------------------------------
-
-joint.dia.LinkView = joint.dia.CellView.extend({
-
- className: function() {
- return _.unique(this.model.get('type').split('.').concat('link')).join(' ');
- },
-
- options: {
-
- shortLinkLength: 100,
- doubleLinkTools: false,
- longLinkLength: 160,
- linkToolsOffset: 40,
- doubleLinkToolsOffset: 60,
- sampleInterval: 50
- },
-
- initialize: function(options) {
-
- joint.dia.CellView.prototype.initialize.apply(this, arguments);
-
- // create methods in prototype, so they can be accessed from any instance and
- // don't need to be create over and over
- if (typeof this.constructor.prototype.watchSource !== 'function') {
- this.constructor.prototype.watchSource = this.createWatcher('source');
- this.constructor.prototype.watchTarget = this.createWatcher('target');
- }
-
- // `_.labelCache` is a mapping of indexes of labels in the `this.get('labels')` array to
- // `<g class="label">` nodes wrapped by Vectorizer. This allows for quick access to the
- // nodes in `updateLabelPosition()` in order to update the label positions.
- this._labelCache = {};
-
- // keeps markers bboxes and positions again for quicker access
- this._markerCache = {};
-
- // bind events
- this.startListening();
- },
-
- startListening: function() {
-
- this.listenTo(this.model, 'change:markup', this.render);
- this.listenTo(this.model, 'change:smooth change:manhattan change:router change:connector', this.update);
- this.listenTo(this.model, 'change:toolMarkup', function() {
- this.renderTools().updateToolsPosition();
- });
- this.listenTo(this.model, 'change:labels change:labelMarkup', function() {
- this.renderLabels().updateLabelPositions();
- });
- this.listenTo(this.model, 'change:vertices change:vertexMarkup', function(cell, changed, opt) {
- this.renderVertexMarkers();
- // If the vertices have been changed by a translation we do update only if the link was
- // only one translated. If the link was translated via another element which the link
- // is embedded in, this element will be translated as well and that triggers an update.
- // Note that all embeds in a model are sorted - first comes links, then elements.
- if (!opt.translateBy || (opt.translateBy == this.model.id || this.model.hasLoop())) {
- this.update();
- }
- });
- this.listenTo(this.model, 'change:source', function(cell, source) {
- this.watchSource(cell, source).update();
- });
- this.listenTo(this.model, 'change:target', function(cell, target) {
- this.watchTarget(cell, target).update();
- });
- },
-
- // Rendering
- //----------
-
- render: function() {
-
- this.$el.empty();
-
- // A special markup can be given in the `properties.markup` property. This might be handy
- // if e.g. arrowhead markers should be `<image>` elements or any other element than `<path>`s.
- // `.connection`, `.connection-wrap`, `.marker-source` and `.marker-target` selectors
- // of elements with special meaning though. Therefore, those classes should be preserved in any
- // special markup passed in `properties.markup`.
- var children = V(this.model.get('markup') || this.model.markup);
-
- // custom markup may contain only one children
- if (!_.isArray(children)) children = [children];
-
- // Cache all children elements for quicker access.
- this._V = {}; // vectorized markup;
- _.each(children, function(child) {
- var c = child.attr('class');
- c && (this._V[$.camelCase(c)] = child);
- }, this);
-
- // Only the connection path is mandatory
- if (!this._V.connection) throw new Error('link: no connection path in the markup');
-
- // partial rendering
- this.renderTools();
- this.renderVertexMarkers();
- this.renderArrowheadMarkers();
-
- V(this.el).append(children);
-
- // rendering labels has to be run after the link is appended to DOM tree. (otherwise <Text> bbox
- // returns zero values)
- this.renderLabels();
-
- // start watching the ends of the link for changes
- this.watchSource(this.model, this.model.get('source'))
- .watchTarget(this.model, this.model.get('target'))
- .update();
-
- return this;
- },
-
- renderLabels: function() {
-
- if (!this._V.labels) return this;
-
- this._labelCache = {};
- var $labels = $(this._V.labels.node).empty();
-
- var labels = this.model.get('labels') || [];
- if (!labels.length) return this;
-
- var labelTemplate = _.template(this.model.get('labelMarkup') || this.model.labelMarkup);
- // This is a prepared instance of a vectorized SVGDOM node for the label element resulting from
- // compilation of the labelTemplate. The purpose is that all labels will just `clone()` this
- // node to create a duplicate.
- var labelNodeInstance = V(labelTemplate());
-
- var canLabelMove = this.can('labelMove');
-
- _.each(labels, function(label, idx) {
-
- var labelNode = labelNodeInstance.clone().node;
- V(labelNode).attr('label-idx', idx);
- if (canLabelMove) {
- V(labelNode).attr('cursor', 'move');
- }
-
- // Cache label nodes so that the `updateLabels()` can just update the label node positions.
- this._labelCache[idx] = V(labelNode);
-
- var $text = $(labelNode).find('text');
- var $rect = $(labelNode).find('rect');
-
- // Text attributes with the default `text-anchor` and font-size set.
- var textAttributes = _.extend({ 'text-anchor': 'middle', 'font-size': 14 }, joint.util.getByPath(label, 'attrs/text', '/'));
-
- $text.attr(_.omit(textAttributes, 'text'));
-
- if (!_.isUndefined(textAttributes.text)) {
-
- V($text[0]).text(textAttributes.text + '');
- }
-
- // Note that we first need to append the `<text>` element to the DOM in order to
- // get its bounding box.
- $labels.append(labelNode);
-
- // `y-alignment` - center the text element around its y coordinate.
- var textBbox = V($text[0]).bbox(true, $labels[0]);
- V($text[0]).translate(0, -textBbox.height / 2);
-
- // Add default values.
- var rectAttributes = _.extend({
-
- fill: 'white',
- rx: 3,
- ry: 3
-
- }, joint.util.getByPath(label, 'attrs/rect', '/'));
-
- $rect.attr(_.extend(rectAttributes, {
- x: textBbox.x,
- y: textBbox.y - textBbox.height / 2, // Take into account the y-alignment translation.
- width: textBbox.width,
- height: textBbox.height
- }));
-
- }, this);
-
- return this;
- },
-
- renderTools: function() {
-
- if (!this._V.linkTools) return this;
-
- // Tools are a group of clickable elements that manipulate the whole link.
- // A good example of this is the remove tool that removes the whole link.
- // Tools appear after hovering the link close to the `source` element/point of the link
- // but are offset a bit so that they don't cover the `marker-arrowhead`.
-
- var $tools = $(this._V.linkTools.node).empty();
- var toolTemplate = _.template(this.model.get('toolMarkup') || this.model.toolMarkup);
- var tool = V(toolTemplate());
-
- $tools.append(tool.node);
-
- // Cache the tool node so that the `updateToolsPosition()` can update the tool position quickly.
- this._toolCache = tool;
-
- // If `doubleLinkTools` is enabled, we render copy of the tools on the other side of the
- // link as well but only if the link is longer than `longLinkLength`.
- if (this.options.doubleLinkTools) {
-
- var tool2 = tool.clone();
- $tools.append(tool2.node);
- this._tool2Cache = tool2;
- }
-
- return this;
- },
-
- renderVertexMarkers: function() {
-
- if (!this._V.markerVertices) return this;
-
- var $markerVertices = $(this._V.markerVertices.node).empty();
-
- // A special markup can be given in the `properties.vertexMarkup` property. This might be handy
- // if default styling (elements) are not desired. This makes it possible to use any
- // SVG elements for .marker-vertex and .marker-vertex-remove tools.
- var markupTemplate = _.template(this.model.get('vertexMarkup') || this.model.vertexMarkup);
-
- _.each(this.model.get('vertices'), function(vertex, idx) {
-
- $markerVertices.append(V(markupTemplate(_.extend({ idx: idx }, vertex))).node);
- });
-
- return this;
- },
-
- renderArrowheadMarkers: function() {
-
- // Custom markups might not have arrowhead markers. Therefore, jump of this function immediately if that's the case.
- if (!this._V.markerArrowheads) return this;
-
- var $markerArrowheads = $(this._V.markerArrowheads.node);
-
- $markerArrowheads.empty();
-
- // A special markup can be given in the `properties.vertexMarkup` property. This might be handy
- // if default styling (elements) are not desired. This makes it possible to use any
- // SVG elements for .marker-vertex and .marker-vertex-remove tools.
- var markupTemplate = _.template(this.model.get('arrowheadMarkup') || this.model.arrowheadMarkup);
-
- this._V.sourceArrowhead = V(markupTemplate({ end: 'source' }));
- this._V.targetArrowhead = V(markupTemplate({ end: 'target' }));
-
- $markerArrowheads.append(this._V.sourceArrowhead.node, this._V.targetArrowhead.node);
-
- return this;
- },
-
- // Updating
- //---------
-
- // Default is to process the `attrs` object and set attributes on subelements based on the selectors.
- update: function() {
-
- // Update attributes.
- _.each(this.model.get('attrs'), function(attrs, selector) {
-
- var processedAttributes = [];
-
- // If the `fill` or `stroke` attribute is an object, it is in the special JointJS gradient format and so
- // it becomes a special attribute and is treated separately.
- if (_.isObject(attrs.fill)) {
-
- this.applyGradient(selector, 'fill', attrs.fill);
- processedAttributes.push('fill');
- }
-
- if (_.isObject(attrs.stroke)) {
-
- this.applyGradient(selector, 'stroke', attrs.stroke);
- processedAttributes.push('stroke');
- }
-
- // If the `filter` attribute is an object, it is in the special JointJS filter format and so
- // it becomes a special attribute and is treated separately.
- if (_.isObject(attrs.filter)) {
-
- this.applyFilter(selector, attrs.filter);
- processedAttributes.push('filter');
- }
-
- // remove processed special attributes from attrs
- if (processedAttributes.length > 0) {
-
- processedAttributes.unshift(attrs);
- attrs = _.omit.apply(_, processedAttributes);
- }
-
- this.findBySelector(selector).attr(attrs);
-
- }, this);
-
- // Path finding
- var vertices = this.route = this.findRoute(this.model.get('vertices') || []);
-
- // finds all the connection points taking new vertices into account
- this._findConnectionPoints(vertices);
-
- var pathData = this.getPathData(vertices);
-
- // The markup needs to contain a `.connection`
- this._V.connection.attr('d', pathData);
- this._V.connectionWrap && this._V.connectionWrap.attr('d', pathData);
-
- this._translateAndAutoOrientArrows(this._V.markerSource, this._V.markerTarget);
-
- //partials updates
- this.updateLabelPositions();
- this.updateToolsPosition();
- this.updateArrowheadMarkers();
-
- delete this.options.perpendicular;
- // Mark that postponed update has been already executed.
- this.updatePostponed = false;
-
- return this;
- },
-
- _findConnectionPoints: function(vertices) {
-
- // cache source and target points
- var sourcePoint, targetPoint, sourceMarkerPoint, targetMarkerPoint;
-
- var firstVertex = _.first(vertices);
-
- sourcePoint = this.getConnectionPoint(
- 'source', this.model.get('source'), firstVertex || this.model.get('target')
- ).round();
-
- var lastVertex = _.last(vertices);
-
- targetPoint = this.getConnectionPoint(
- 'target', this.model.get('target'), lastVertex || sourcePoint
- ).round();
-
- // Move the source point by the width of the marker taking into account
- // its scale around x-axis. Note that scale is the only transform that
- // makes sense to be set in `.marker-source` attributes object
- // as all other transforms (translate/rotate) will be replaced
- // by the `translateAndAutoOrient()` function.
- var cache = this._markerCache;
-
- if (this._V.markerSource) {
-
- cache.sourceBBox = cache.sourceBBox || this._V.markerSource.bbox(true);
-
- sourceMarkerPoint = g.point(sourcePoint).move(
- firstVertex || targetPoint,
- cache.sourceBBox.width * this._V.markerSource.scale().sx * -1
- ).round();
- }
-
- if (this._V.markerTarget) {
-
- cache.targetBBox = cache.targetBBox || this._V.markerTarget.bbox(true);
-
- targetMarkerPoint = g.point(targetPoint).move(
- lastVertex || sourcePoint,
- cache.targetBBox.width * this._V.markerTarget.scale().sx * -1
- ).round();
- }
-
- // if there was no markup for the marker, use the connection point.
- cache.sourcePoint = sourceMarkerPoint || sourcePoint;
- cache.targetPoint = targetMarkerPoint || targetPoint;
-
- // make connection points public
- this.sourcePoint = sourcePoint;
- this.targetPoint = targetPoint;
- },
-
- updateLabelPositions: function() {
-
- if (!this._V.labels) return this;
-
- // This method assumes all the label nodes are stored in the `this._labelCache` hash table
- // by their indexes in the `this.get('labels')` array. This is done in the `renderLabels()` method.
-
- var labels = this.model.get('labels') || [];
- if (!labels.length) return this;
-
- var connectionElement = this._V.connection.node;
- var connectionLength = connectionElement.getTotalLength();
-
- // Firefox returns connectionLength=NaN in odd cases (for bezier curves).
- // In that case we won't update labels at all.
- if (!_.isNaN(connectionLength)) {
-
- var samples;
-
- _.each(labels, function(label, idx) {
-
- var position = label.position;
- var distance = _.isObject(position) ? position.distance : position;
- var offset = _.isObject(position) ? position.offset : { x: 0, y: 0 };
-
- distance = (distance > connectionLength) ? connectionLength : distance; // sanity check
- distance = (distance < 0) ? connectionLength + distance : distance;
- distance = (distance > 1) ? distance : connectionLength * distance;
-
- var labelCoordinates = connectionElement.getPointAtLength(distance);
-
- if (_.isObject(offset)) {
-
- // Just offset the label by the x,y provided in the offset object.
- labelCoordinates = g.point(labelCoordinates).offset(offset.x, offset.y);
-
- } else if (_.isNumber(offset)) {
-
- if (!samples) {
- samples = this._samples || this._V.connection.sample(this.options.sampleInterval);
- }
-
- // Offset the label by the amount provided in `offset` to an either
- // side of the link.
-
- // 1. Find the closest sample & its left and right neighbours.
- var minSqDistance = Infinity;
- var closestSample;
- var closestSampleIndex;
- var p;
- var sqDistance;
- for (var i = 0, len = samples.length; i < len; i++) {
- p = samples[i];
- sqDistance = g.line(p, labelCoordinates).squaredLength();
- if (sqDistance < minSqDistance) {
- minSqDistance = sqDistance;
- closestSample = p;
- closestSampleIndex = i;
- }
- }
- var prevSample = samples[closestSampleIndex - 1];
- var nextSample = samples[closestSampleIndex + 1];
-
- // 2. Offset the label on the perpendicular line between
- // the current label coordinate ("at `distance`") and
- // the next sample.
- var angle = 0;
- if (nextSample) {
- angle = g.point(labelCoordinates).theta(nextSample);
- } else if (prevSample) {
- angle = g.point(prevSample).theta(labelCoordinates);
- }
- labelCoordinates = g.point(labelCoordinates).offset(offset).rotate(labelCoordinates, angle - 90);
- }
-
- this._labelCache[idx].attr('transform', 'translate(' + labelCoordinates.x + ', ' + labelCoordinates.y + ')');
-
- }, this);
- }
-
- return this;
- },
-
-
- updateToolsPosition: function() {
-
- if (!this._V.linkTools) return this;
-
- // Move the tools a bit to the target position but don't cover the `sourceArrowhead` marker.
- // Note that the offset is hardcoded here. The offset should be always
- // more than the `this.$('.marker-arrowhead[end="source"]')[0].bbox().width` but looking
- // this up all the time would be slow.
-
- var scale = '';
- var offset = this.options.linkToolsOffset;
- var connectionLength = this.getConnectionLength();
-
- // Firefox returns connectionLength=NaN in odd cases (for bezier curves).
- // In that case we won't update tools position at all.
- if (!_.isNaN(connectionLength)) {
-
- // If the link is too short, make the tools half the size and the offset twice as low.
- if (connectionLength < this.options.shortLinkLength) {
- scale = 'scale(.5)';
- offset /= 2;
- }
-
- var toolPosition = this.getPointAtLength(offset);
-
- this._toolCache.attr('transform', 'translate(' + toolPosition.x + ', ' + toolPosition.y + ') ' + scale);
-
- if (this.options.doubleLinkTools && connectionLength >= this.options.longLinkLength) {
-
- var doubleLinkToolsOffset = this.options.doubleLinkToolsOffset || offset;
-
- toolPosition = this.getPointAtLength(connectionLength - doubleLinkToolsOffset);
- this._tool2Cache.attr('transform', 'translate(' + toolPosition.x + ', ' + toolPosition.y + ') ' + scale);
- this._tool2Cache.attr('visibility', 'visible');
-
- } else if (this.options.doubleLinkTools) {
-
- this._tool2Cache.attr('visibility', 'hidden');
- }
- }
-
- return this;
- },
-
-
- updateArrowheadMarkers: function() {
-
- if (!this._V.markerArrowheads) return this;
-
- // getting bbox of an element with `display="none"` in IE9 ends up with access violation
- if ($.css(this._V.markerArrowheads.node, 'display') === 'none') return this;
-
- var sx = this.getConnectionLength() < this.options.shortLinkLength ? .5 : 1;
- this._V.sourceArrowhead.scale(sx);
- this._V.targetArrowhead.scale(sx);
-
- this._translateAndAutoOrientArrows(this._V.sourceArrowhead, this._V.targetArrowhead);
-
- return this;
- },
-
- // Returns a function observing changes on an end of the link. If a change happens and new end is a new model,
- // it stops listening on the previous one and starts listening to the new one.
- createWatcher: function(endType) {
-
- // create handler for specific end type (source|target).
- var onModelChange = _.partial(this.onEndModelChange, endType);
-
- function watchEndModel(link, end) {
-
- end = end || {};
-
- var endModel = null;
- var previousEnd = link.previous(endType) || {};
-
- if (previousEnd.id) {
- this.stopListening(this.paper.getModelById(previousEnd.id), 'change', onModelChange);
- }
-
- if (end.id) {
- // If the observed model changes, it caches a new bbox and do the link update.
- endModel = this.paper.getModelById(end.id);
- this.listenTo(endModel, 'change', onModelChange);
- }
-
- onModelChange.call(this, endModel, { cacheOnly: true });
-
- return this;
- }
-
- return watchEndModel;
- },
-
- onEndModelChange: function(endType, endModel, opt) {
-
- var doUpdate = !opt.cacheOnly;
- var end = this.model.get(endType) || {};
-
- if (endModel) {
-
- var selector = this.constructor.makeSelector(end);
- var oppositeEndType = endType == 'source' ? 'target' : 'source';
- var oppositeEnd = this.model.get(oppositeEndType) || {};
- var oppositeSelector = oppositeEnd.id && this.constructor.makeSelector(oppositeEnd);
-
- // Caching end models bounding boxes
- if (opt.isLoop && selector == oppositeSelector) {
-
- // Source and target elements are identical. We are handling `change` event for the
- // second time now. There is no need to calculate bbox and find magnet element again.
- // It was calculated already for opposite link end.
- this[endType + 'BBox'] = this[oppositeEndType + 'BBox'];
- this[endType + 'View'] = this[oppositeEndType + 'View'];
- this[endType + 'Magnet'] = this[oppositeEndType + 'Magnet'];
-
- } else if (opt.translateBy) {
-
- var bbox = this[endType + 'BBox'];
- bbox.x += opt.tx;
- bbox.y += opt.ty;
-
- } else {
-
- var view = this.paper.findViewByModel(end.id);
- var magnetElement = view.el.querySelector(selector);
-
- this[endType + 'BBox'] = view.getStrokeBBox(magnetElement);
- this[endType + 'View'] = view;
- this[endType + 'Magnet'] = magnetElement;
- }
-
- if (opt.isLoop && opt.translateBy &&
- this.model.isEmbeddedIn(endModel) &&
- !_.isEmpty(this.model.get('vertices'))) {
- // If the link is embedded, has a loop and vertices and the end model
- // has been translated, do not update yet. There are vertices still to be updated.
- doUpdate = false;
- }
-
- if (!this.updatePostponed && oppositeEnd.id) {
-
- var oppositeEndModel = this.paper.getModelById(oppositeEnd.id);
-
- // Passing `isLoop` flag via event option.
- // Note that if we are listening to the same model for event 'change' twice.
- // The same event will be handled by this method also twice.
- opt.isLoop = end.id == oppositeEnd.id;
-
- if (opt.isLoop || (opt.translateBy && oppositeEndModel.isEmbeddedIn(opt.translateBy))) {
-
- // Here are two options:
- // - Source and target are connected to the same model (not necessary the same port)
- // - both end models are translated by same ancestor. We know that opposte end
- // model will be translated in the moment as well.
- // In both situations there will be more changes on model that will trigger an
- // update. So there is no need to update the linkView yet.
- this.updatePostponed = true;
- doUpdate = false;
- }
- }
-
- } else {
-
- // the link end is a point ~ rect 1x1
- this[endType + 'BBox'] = g.rect(end.x || 0, end.y || 0, 1, 1);
- this[endType + 'View'] = this[endType + 'Magnet'] = null;
- }
-
- // keep track which end had been changed very last
- this.lastEndChange = endType;
-
- doUpdate && this.update();
- },
-
- _translateAndAutoOrientArrows: function(sourceArrow, targetArrow) {
-
- // Make the markers "point" to their sticky points being auto-oriented towards
- // `targetPosition`/`sourcePosition`. And do so only if there is a markup for them.
- if (sourceArrow) {
- sourceArrow.translateAndAutoOrient(
- this.sourcePoint,
- _.first(this.route) || this.targetPoint,
- this.paper.viewport
- );
- }
-
- if (targetArrow) {
- targetArrow.translateAndAutoOrient(
- this.targetPoint,
- _.last(this.route) || this.sourcePoint,
- this.paper.viewport
- );
- }
- },
-
- removeVertex: function(idx) {
-
- var vertices = _.clone(this.model.get('vertices'));
-
- if (vertices && vertices.length) {
-
- vertices.splice(idx, 1);
- this.model.set('vertices', vertices, { ui: true });
- }
-
- return this;
- },
-
- // This method ads a new vertex to the `vertices` array of `.connection`. This method
- // uses a heuristic to find the index at which the new `vertex` should be placed at assuming
- // the new vertex is somewhere on the path.
- addVertex: function(vertex) {
-
- // As it is very hard to find a correct index of the newly created vertex,
- // a little heuristics is taking place here.
- // The heuristics checks if length of the newly created
- // path is lot more than length of the old path. If this is the case,
- // new vertex was probably put into a wrong index.
- // Try to put it into another index and repeat the heuristics again.
-
- var vertices = (this.model.get('vertices') || []).slice();
- // Store the original vertices for a later revert if needed.
- var originalVertices = vertices.slice();
-
- // A `<path>` element used to compute the length of the path during heuristics.
- var path = this._V.connection.node.cloneNode(false);
-
- // Length of the original path.
- var originalPathLength = path.getTotalLength();
- // Current path length.
- var pathLength;
- // Tolerance determines the highest possible difference between the length
- // of the old and new path. The number has been chosen heuristically.
- var pathLengthTolerance = 20;
- // Total number of vertices including source and target points.
- var idx = vertices.length + 1;
-
- // Loop through all possible indexes and check if the difference between
- // path lengths changes significantly. If not, the found index is
- // most probably the right one.
- while (idx--) {
-
- vertices.splice(idx, 0, vertex);
- V(path).attr('d', this.getPathData(this.findRoute(vertices)));
-
- pathLength = path.getTotalLength();
-
- // Check if the path lengths changed significantly.
- if (pathLength - originalPathLength > pathLengthTolerance) {
-
- // Revert vertices to the original array. The path length has changed too much
- // so that the index was not found yet.
- vertices = originalVertices.slice();
-
- } else {
-
- break;
- }
- }
-
- if (idx === -1) {
- // If no suitable index was found for such a vertex, make the vertex the first one.
- idx = 0;
- vertices.splice(idx, 0, vertex);
- }
-
- this.model.set('vertices', vertices, { ui: true });
-
- return idx;
- },
-
- // Send a token (an SVG element, usually a circle) along the connection path.
- // Example: `paper.findViewByModel(link).sendToken(V('circle', { r: 7, fill: 'green' }).node)`
- // `duration` is optional and is a time in milliseconds that the token travels from the source to the target of the link. Default is `1000`.
- // `callback` is optional and is a function to be called once the token reaches the target.
- sendToken: function(token, duration, callback) {
-
- duration = duration || 1000;
-
- V(this.paper.viewport).append(token);
- V(token).animateAlongPath({ dur: duration + 'ms', repeatCount: 1 }, this._V.connection.node);
- _.delay(function() { V(token).remove(); callback && callback(); }, duration);
- },
-
- findRoute: function(oldVertices) {
-
- var router = this.model.get('router');
-
- if (!router) {
-
- if (this.model.get('manhattan')) {
- // backwards compability
- router = { name: 'orthogonal' };
- } else {
-
- return oldVertices;
- }
- }
-
- var fn = joint.routers[router.name];
-
- if (!_.isFunction(fn)) {
-
- throw 'unknown router: ' + router.name;
- }
-
- var newVertices = fn.call(this, oldVertices || [], router.args || {}, this);
-
- return newVertices;
- },
-
- // Return the `d` attribute value of the `<path>` element representing the link
- // between `source` and `target`.
- getPathData: function(vertices) {
-
- var connector = this.model.get('connector');
-
- if (!connector) {
-
- // backwards compability
- connector = this.model.get('smooth') ? { name: 'smooth' } : { name: 'normal' };
- }
-
- if (!_.isFunction(joint.connectors[connector.name])) {
-
- throw 'unknown connector: ' + connector.name;
- }
-
- var pathData = joint.connectors[connector.name].call(
- this,
- this._markerCache.sourcePoint, // Note that the value is translated by the size
- this._markerCache.targetPoint, // of the marker. (We'r not using this.sourcePoint)
- vertices || (this.model.get('vertices') || {}),
- connector.args || {}, // options
- this
- );
-
- return pathData;
- },
-
- // Find a point that is the start of the connection.
- // If `selectorOrPoint` is a point, then we're done and that point is the start of the connection.
- // If the `selectorOrPoint` is an element however, we need to know a reference point (or element)
- // that the link leads to in order to determine the start of the connection on the original element.
- getConnectionPoint: function(end, selectorOrPoint, referenceSelectorOrPoint) {
-
- var spot;
-
- // If the `selectorOrPoint` (or `referenceSelectorOrPoint`) is `undefined`, the `source`/`target` of the link model is `undefined`.
- // We want to allow this however so that one can create links such as `var link = new joint.dia.Link` and
- // set the `source`/`target` later.
- _.isEmpty(selectorOrPoint) && (selectorOrPoint = { x: 0, y: 0 });
- _.isEmpty(referenceSelectorOrPoint) && (referenceSelectorOrPoint = { x: 0, y: 0 });
-
- if (!selectorOrPoint.id) {
-
- // If the source is a point, we don't need a reference point to find the sticky point of connection.
- spot = g.point(selectorOrPoint);
-
- } else {
-
- // If the source is an element, we need to find a point on the element boundary that is closest
- // to the reference point (or reference element).
- // Get the bounding box of the spot relative to the paper viewport. This is necessary
- // in order to follow paper viewport transformations (scale/rotate).
- // `_sourceBbox` (`_targetBbox`) comes from `_sourceBboxUpdate` (`_sourceBboxUpdate`)
- // method, it exists since first render and are automatically updated
- var spotBbox = end === 'source' ? this.sourceBBox : this.targetBBox;
-
- var reference;
-
- if (!referenceSelectorOrPoint.id) {
-
- // Reference was passed as a point, therefore, we're ready to find the sticky point of connection on the source element.
- reference = g.point(referenceSelectorOrPoint);
-
- } else {
-
- // Reference was passed as an element, therefore we need to find a point on the reference
- // element boundary closest to the source element.
- // Get the bounding box of the spot relative to the paper viewport. This is necessary
- // in order to follow paper viewport transformations (scale/rotate).
- var referenceBbox = end === 'source' ? this.targetBBox : this.sourceBBox;
-
- reference = g.rect(referenceBbox).intersectionWithLineFromCenterToPoint(g.rect(spotBbox).center());
- reference = reference || g.rect(referenceBbox).center();
- }
-
- // If `perpendicularLinks` flag is set on the paper and there are vertices
- // on the link, then try to find a connection point that makes the link perpendicular
- // even though the link won't point to the center of the targeted object.
- if (this.paper.options.perpendicularLinks || this.options.perpendicular) {
-
- var horizontalLineRect = g.rect(0, reference.y, this.paper.options.width, 1);
- var verticalLineRect = g.rect(reference.x, 0, 1, this.paper.options.height);
- var nearestSide;
-
- if (horizontalLineRect.intersect(g.rect(spotBbox))) {
-
- nearestSide = g.rect(spotBbox).sideNearestToPoint(reference);
- switch (nearestSide) {
- case 'left':
- spot = g.point(spotBbox.x, reference.y);
- break;
- case 'right':
- spot = g.point(spotBbox.x + spotBbox.width, reference.y);
- break;
- default:
- spot = g.rect(spotBbox).center();
- break;
- }
-
- } else if (verticalLineRect.intersect(g.rect(spotBbox))) {
-
- nearestSide = g.rect(spotBbox).sideNearestToPoint(reference);
- switch (nearestSide) {
- case 'top':
- spot = g.point(reference.x, spotBbox.y);
- break;
- case 'bottom':
- spot = g.point(reference.x, spotBbox.y + spotBbox.height);
- break;
- default:
- spot = g.rect(spotBbox).center();
- break;
- }
-
- } else {
-
- // If there is no intersection horizontally or vertically with the object bounding box,
- // then we fall back to the regular situation finding straight line (not perpendicular)
- // between the object and the reference point.
-
- spot = g.rect(spotBbox).intersectionWithLineFromCenterToPoint(reference);
- spot = spot || g.rect(spotBbox).center();
- }
-
- } else if (this.paper.options.linkConnectionPoint) {
-
- var view = end === 'target' ? this.targetView : this.sourceView;
- var magnet = end === 'target' ? this.targetMagnet : this.sourceMagnet;
-
- spot = this.paper.options.linkConnectionPoint(this, view, magnet, reference);
-
- } else {
-
- spot = g.rect(spotBbox).intersectionWithLineFromCenterToPoint(reference);
- spot = spot || g.rect(spotBbox).center();
- }
- }
-
- return spot;
- },
-
- // Public API
- // ----------
-
- getConnectionLength: function() {
-
- return this._V.connection.node.getTotalLength();
- },
-
- getPointAtLength: function(length) {
-
- return this._V.connection.node.getPointAtLength(length);
- },
-
- // Interaction. The controller part.
- // ---------------------------------
-
- _beforeArrowheadMove: function() {
-
- this._z = this.model.get('z');
- this.model.toFront();
-
- // Let the pointer propagate throught the link view elements so that
- // the `evt.target` is another element under the pointer, not the link itself.
- this.el.style.pointerEvents = 'none';
-
- if (this.paper.options.markAvailable) {
- this._markAvailableMagnets();
- }
- },
-
- _afterArrowheadMove: function() {
-
- if (this._z) {
- this.model.set('z', this._z, { ui: true });
- delete this._z;
- }
-
- // Put `pointer-events` back to its original value. See `startArrowheadMove()` for explanation.
- // Value `auto` doesn't work in IE9. We force to use `visiblePainted` instead.
- // See `https://developer.mozilla.org/en-US/docs/Web/CSS/pointer-events`.
- this.el.style.pointerEvents = 'visiblePainted';
-
- if (this.paper.options.markAvailable) {
- this._unmarkAvailableMagnets();
- }
- },
-
- _createValidateConnectionArgs: function(arrowhead) {
- // It makes sure the arguments for validateConnection have the following form:
- // (source view, source magnet, target view, target magnet and link view)
- var args = [];
-
- args[4] = arrowhead;
- args[5] = this;
-
- var oppositeArrowhead;
- var i = 0;
- var j = 0;
-
- if (arrowhead === 'source') {
- i = 2;
- oppositeArrowhead = 'target';
- } else {
- j = 2;
- oppositeArrowhead = 'source';
- }
-
- var end = this.model.get(oppositeArrowhead);
-
- if (end.id) {
- args[i] = this.paper.findViewByModel(end.id);
- args[i + 1] = end.selector && args[i].el.querySelector(end.selector);
- }
-
- function validateConnectionArgs(cellView, magnet) {
- args[j] = cellView;
- args[j + 1] = cellView.el === magnet ? undefined : magnet;
- return args;
- }
-
- return validateConnectionArgs;
- },
-
- _markAvailableMagnets: function() {
-
- var elements = this.paper.model.getElements();
- var validate = this.paper.options.validateConnection;
-
- _.chain(elements).map(this.paper.findViewByModel, this.paper).each(function(view) {
-
- var isElementAvailable = view.el.getAttribute('magnet') !== 'false' &&
- validate.apply(this.paper, this._validateConnectionArgs(view, null));
-
- var availableMagnets = _.filter(view.el.querySelectorAll('[magnet]'), function(magnet) {
- return validate.apply(this.paper, this._validateConnectionArgs(view, magnet));
- }, this);
-
- if (isElementAvailable) {
- V(view.el).addClass('available-magnet');
- }
-
- _.each(availableMagnets, function(magnet) {
- V(magnet).addClass('available-magnet');
- });
-
- if (isElementAvailable || availableMagnets.length) {
- V(view.el).addClass('available-cell');
- }
-
- }, this);
- },
-
- _unmarkAvailableMagnets: function() {
-
- _.each(this.paper.el.querySelectorAll('.available-cell, .available-magnet'), function(magnet) {
- V(magnet).removeClass('available-magnet').removeClass('available-cell');
- });
- },
-
- startArrowheadMove: function(end) {
- // Allow to delegate events from an another view to this linkView in order to trigger arrowhead
- // move without need to click on the actual arrowhead dom element.
- this._action = 'arrowhead-move';
- this._arrowhead = end;
- this._validateConnectionArgs = this._createValidateConnectionArgs(this._arrowhead);
- this._beforeArrowheadMove();
- },
-
- // Return `true` if the link is allowed to perform a certain UI `feature`.
- // Example: `can('vertexMove')`, `can('labelMove')`.
- can: function(feature) {
-
- var interactive = _.isFunction(this.options.interactive) ? this.options.interactive(this, 'pointerdown') : this.options.interactive;
- if (!_.isObject(interactive) || interactive[feature] !== false) return true;
- return false;
- },
-
- pointerdown: function(evt, x, y) {
-
- joint.dia.CellView.prototype.pointerdown.apply(this, arguments);
- this.notify('link:pointerdown', evt, x, y);
-
- this._dx = x;
- this._dy = y;
-
- // if are simulating pointerdown on a link during a magnet click, skip link interactions
- if (evt.target.getAttribute('magnet') != null) return;
-
- var interactive = _.isFunction(this.options.interactive) ? this.options.interactive(this, 'pointerdown') : this.options.interactive;
- if (interactive === false) return;
-
- var className = evt.target.getAttribute('class');
- var parentClassName = evt.target.parentNode.getAttribute('class');
- var labelNode;
- if (parentClassName === 'label') {
- className = parentClassName;
- labelNode = evt.target.parentNode;
- } else {
- labelNode = evt.target;
- }
-
- switch (className) {
-
- case 'marker-vertex':
- if (this.can('vertexMove')) {
- this._action = 'vertex-move';
- this._vertexIdx = evt.target.getAttribute('idx');
- }
- break;
-
- case 'marker-vertex-remove':
- case 'marker-vertex-remove-area':
- if (this.can('vertexRemove')) {
- this.removeVertex(evt.target.getAttribute('idx'));
- }
- break;
-
- case 'marker-arrowhead':
- if (this.can('arrowheadMove')) {
- this.startArrowheadMove(evt.target.getAttribute('end'));
- }
- break;
-
- case 'label':
- if (this.can('labelMove')) {
- this._action = 'label-move';
- this._labelIdx = parseInt(V(labelNode).attr('label-idx'), 10);
- // Precalculate samples so that we don't have to do that
- // over and over again while dragging the label.
- this._samples = this._V.connection.sample(1);
- this._linkLength = this._V.connection.node.getTotalLength();
- }
- break;
-
- default:
-
- var targetParentEvent = evt.target.parentNode.getAttribute('event');
- if (targetParentEvent) {
-
- // `remove` event is built-in. Other custom events are triggered on the paper.
- if (targetParentEvent === 'remove') {
- this.model.remove();
- } else {
- this.paper.trigger(targetParentEvent, evt, this, x, y);
- }
-
- } else {
- if (this.can('vertexAdd')) {
-
- // Store the index at which the new vertex has just been placed.
- // We'll be update the very same vertex position in `pointermove()`.
- this._vertexIdx = this.addVertex({ x: x, y: y });
- this._action = 'vertex-move';
- }
- }
- }
- },
-
- pointermove: function(evt, x, y) {
-
- switch (this._action) {
-
- case 'vertex-move':
-
- var vertices = _.clone(this.model.get('vertices'));
- vertices[this._vertexIdx] = { x: x, y: y };
- this.model.set('vertices', vertices, { ui: true });
- break;
-
- case 'label-move':
-
- var dragPoint = { x: x, y: y };
- var label = this.model.get('labels')[this._labelIdx];
- var samples = this._samples;
- var minSqDistance = Infinity;
- var closestSample;
- var closestSampleIndex;
- var p;
- var sqDistance;
- for (var i = 0, len = samples.length; i < len; i++) {
- p = samples[i];
- sqDistance = g.line(p, dragPoint).squaredLength();
- if (sqDistance < minSqDistance) {
- minSqDistance = sqDistance;
- closestSample = p;
- closestSampleIndex = i;
- }
- }
- var prevSample = samples[closestSampleIndex - 1];
- var nextSample = samples[closestSampleIndex + 1];
-
- var closestSampleDistance = g.point(closestSample).distance(dragPoint);
- var offset = 0;
- if (prevSample && nextSample) {
- offset = g.line(prevSample, nextSample).pointOffset(dragPoint);
- } else if (prevSample) {
- offset = g.line(prevSample, closestSample).pointOffset(dragPoint);
- } else if (nextSample) {
- offset = g.line(closestSample, nextSample).pointOffset(dragPoint);
- }
-
- this.model.label(this._labelIdx, {
- position: {
- distance: closestSample.distance / this._linkLength,
- offset: offset
- }
- });
- break;
-
- case 'arrowhead-move':
-
- if (this.paper.options.snapLinks) {
-
- // checking view in close area of the pointer
-
- var r = this.paper.options.snapLinks.radius || 50;
- var viewsInArea = this.paper.findViewsInArea({ x: x - r, y: y - r, width: 2 * r, height: 2 * r });
-
- this._closestView && this._closestView.unhighlight(this._closestEnd.selector, { connecting: true, snapping: true });
- this._closestView = this._closestEnd = null;
-
- var distance;
- var minDistance = Number.MAX_VALUE;
- var pointer = g.point(x, y);
-
- _.each(viewsInArea, function(view) {
-
- // skip connecting to the element in case '.': { magnet: false } attribute present
- if (view.el.getAttribute('magnet') !== 'false') {
-
- // find distance from the center of the model to pointer coordinates
- distance = view.model.getBBox().center().distance(pointer);
-
- // the connection is looked up in a circle area by `distance < r`
- if (distance < r && distance < minDistance) {
-
- if (this.paper.options.validateConnection.apply(
- this.paper, this._validateConnectionArgs(view, null)
- )) {
- minDistance = distance;
- this._closestView = view;
- this._closestEnd = { id: view.model.id };
- }
- }
- }
-
- view.$('[magnet]').each(_.bind(function(index, magnet) {
-
- var bbox = V(magnet).bbox(false, this.paper.viewport);
-
- distance = pointer.distance({
- x: bbox.x + bbox.width / 2,
- y: bbox.y + bbox.height / 2
- });
-
- if (distance < r && distance < minDistance) {
-
- if (this.paper.options.validateConnection.apply(
- this.paper, this._validateConnectionArgs(view, magnet)
- )) {
- minDistance = distance;
- this._closestView = view;
- this._closestEnd = {
- id: view.model.id,
- selector: view.getSelector(magnet),
- port: magnet.getAttribute('port')
- };
- }
- }
-
- }, this));
-
- }, this);
-
- this._closestView && this._closestView.highlight(this._closestEnd.selector, { connecting: true, snapping: true });
-
- this.model.set(this._arrowhead, this._closestEnd || { x: x, y: y }, { ui: true });
-
- } else {
-
- // checking views right under the pointer
-
- // Touchmove event's target is not reflecting the element under the coordinates as mousemove does.
- // It holds the element when a touchstart triggered.
- var target = (evt.type === 'mousemove')
- ? evt.target
- : document.elementFromPoint(evt.clientX, evt.clientY);
-
- if (this._targetEvent !== target) {
- // Unhighlight the previous view under pointer if there was one.
- this._magnetUnderPointer && this._viewUnderPointer.unhighlight(this._magnetUnderPointer, { connecting: true });
- this._viewUnderPointer = this.paper.findView(target);
- if (this._viewUnderPointer) {
- // If we found a view that is under the pointer, we need to find the closest
- // magnet based on the real target element of the event.
- this._magnetUnderPointer = this._viewUnderPointer.findMagnet(target);
-
- if (this._magnetUnderPointer && this.paper.options.validateConnection.apply(
- this.paper,
- this._validateConnectionArgs(this._viewUnderPointer, this._magnetUnderPointer)
- )) {
- // If there was no magnet found, do not highlight anything and assume there
- // is no view under pointer we're interested in reconnecting to.
- // This can only happen if the overall element has the attribute `'.': { magnet: false }`.
- this._magnetUnderPointer && this._viewUnderPointer.highlight(this._magnetUnderPointer, { connecting: true });
- } else {
- // This type of connection is not valid. Disregard this magnet.
- this._magnetUnderPointer = null;
- }
- } else {
- // Make sure we'll delete previous magnet
- this._magnetUnderPointer = null;
- }
- }
-
- this._targetEvent = target;
-
- this.model.set(this._arrowhead, { x: x, y: y }, { ui: true });
- }
-
- break;
- }
-
- this._dx = x;
- this._dy = y;
-
- joint.dia.CellView.prototype.pointermove.apply(this, arguments);
- this.notify('link:pointermove', evt, x, y);
- },
-
- pointerup: function(evt, x, y) {
-
- if (this._action === 'label-move') {
-
- this._samples = null;
-
- } else if (this._action === 'arrowhead-move') {
-
- if (this.paper.options.snapLinks) {
-
- this._closestView && this._closestView.unhighlight(this._closestEnd.selector, { connecting: true, snapping: true });
- this._closestView = this._closestEnd = null;
-
- } else {
-
- if (this._magnetUnderPointer) {
- this._viewUnderPointer.unhighlight(this._magnetUnderPointer, { connecting: true });
- // Find a unique `selector` of the element under pointer that is a magnet. If the
- // `this._magnetUnderPointer` is the root element of the `this._viewUnderPointer` itself,
- // the returned `selector` will be `undefined`. That means we can directly pass it to the
- // `source`/`target` attribute of the link model below.
- this.model.set(this._arrowhead, {
- id: this._viewUnderPointer.model.id,
- selector: this._viewUnderPointer.getSelector(this._magnetUnderPointer),
- port: $(this._magnetUnderPointer).attr('port')
- }, { ui: true });
- }
-
- delete this._viewUnderPointer;
- delete this._magnetUnderPointer;
- }
-
- // Reparent the link if embedding is enabled
- if (this.paper.options.embeddingMode && this.model.reparent()) {
-
- // Make sure we don't reverse to the original 'z' index (see afterArrowheadMove()).
- delete this._z;
- }
-
- this._afterArrowheadMove();
- }
-
- delete this._action;
-
- this.notify('link:pointerup', evt, x, y);
- joint.dia.CellView.prototype.pointerup.apply(this, arguments);
-
- }
-
-}, {
-
- makeSelector: function(end) {
-
- var selector = '[model-id="' + end.id + '"]';
- // `port` has a higher precendence over `selector`. This is because the selector to the magnet
- // might change while the name of the port can stay the same.
- if (end.port) {
- selector += ' [port="' + end.port + '"]';
- } else if (end.selector) {
- selector += ' ' + end.selector;
- }
-
- return selector;
- }
-
-});
-
-// JointJS library.
-// (c) 2011-2013 client IO
-
-
-joint.dia.Paper = Backbone.View.extend({
-
- className: 'paper',
-
- options: {
-
- width: 800,
- height: 600,
- origin: { x: 0, y: 0 }, // x,y coordinates in top-left corner
- gridSize: 50,
- perpendicularLinks: false,
- elementView: joint.dia.ElementView,
- linkView: joint.dia.LinkView,
- snapLinks: false, // false, true, { radius: value }
-
- // Marks all available magnets with 'available-magnet' class name and all available cells with
- // 'available-cell' class name. Marks them when dragging a link is started and unmark
- // when the dragging is stopped.
- markAvailable: false,
-
- // Defines what link model is added to the graph after an user clicks on an active magnet.
- // Value could be the Backbone.model or a function returning the Backbone.model
- // defaultLink: function(elementView, magnet) { return condition ? new customLink1() : new customLink2() }
- defaultLink: new joint.dia.Link,
-
- /* CONNECTING */
-
- // Check whether to add a new link to the graph when user clicks on an a magnet.
- validateMagnet: function(cellView, magnet) {
- return magnet.getAttribute('magnet') !== 'passive';
- },
-
- // Check whether to allow or disallow the link connection while an arrowhead end (source/target)
- // being changed.
- validateConnection: function(cellViewS, magnetS, cellViewT, magnetT, end, linkView) {
- return (end === 'target' ? cellViewT : cellViewS) instanceof joint.dia.ElementView;
- },
-
- /* EMBEDDING */
-
- // Enables embedding. Reparents the dragged element with elements under it and makes sure that
- // all links and elements are visible taken the level of embedding into account.
- embeddingMode: false,
-
- // Check whether to allow or disallow the element embedding while an element being translated.
- validateEmbedding: function(childView, parentView) {
- // by default all elements can be in relation child-parent
- return true;
- },
-
- // Determines the way how a cell finds a suitable parent when it's dragged over the paper.
- // The cell with the highest z-index (visually on the top) will be choosen.
- findParentBy: 'bbox', // 'bbox'|'center'|'origin'|'corner'|'topRight'|'bottomLeft'
-
- // If enabled only the element on the very front is taken into account for the embedding.
- // If disabled the elements under the dragged view are tested one by one
- // (from front to back) until a valid parent found.
- frontParentOnly: true,
-
- // Interactive flags. See online docs for the complete list of interactive flags.
- interactive: {
- labelMove: false
- }
- },
-
- events: {
-
- 'mousedown': 'pointerdown',
- 'dblclick': 'mousedblclick',
- 'click': 'mouseclick',
- 'touchstart': 'pointerdown',
- 'mousemove': 'pointermove',
- 'touchmove': 'pointermove',
- 'mouseover .element': 'cellMouseover',
- 'mouseover .link': 'cellMouseover',
- 'mouseout .element': 'cellMouseout',
- 'mouseout .link': 'cellMouseout'
- },
-
- constructor: function(options) {
-
- this._configure(options);
- Backbone.View.apply(this, arguments);
- },
-
- _configure: function(options) {
-
- if (this.options) options = _.extend({}, _.result(this, 'options'), options);
- this.options = options;
- },
-
- initialize: function() {
-
- _.bindAll(this, 'addCell', 'sortCells', 'resetCells', 'pointerup', 'asyncRenderCells');
-
- this.svg = V('svg').node;
- this.viewport = V('g').addClass('viewport').node;
- this.defs = V('defs').node;
-
- // Append `<defs>` element to the SVG document. This is useful for filters and gradients.
- V(this.svg).append([this.viewport, this.defs]);
-
- this.$el.append(this.svg);
-
- this.setOrigin();
- this.setDimensions();
-
- this.listenTo(this.model, 'add', this.onAddCell);
- this.listenTo(this.model, 'reset', this.resetCells);
- this.listenTo(this.model, 'sort', this.sortCells);
-
- $(document).on('mouseup touchend', this.pointerup);
-
- // Hold the value when mouse has been moved: when mouse moved, no click event will be triggered.
- this._mousemoved = false;
-
- // default cell highlighting
- this.on({ 'cell:highlight': this.onCellHighlight, 'cell:unhighlight': this.onCellUnhighlight });
- },
-
- remove: function() {
-
- //clean up all DOM elements/views to prevent memory leaks
- this.removeCells();
-
- $(document).off('mouseup touchend', this.pointerup);
-
- Backbone.View.prototype.remove.call(this);
- },
-
- setDimensions: function(width, height) {
-
- width = this.options.width = width || this.options.width;
- height = this.options.height = height || this.options.height;
-
- V(this.svg).attr({ width: width, height: height });
-
- this.trigger('resize', width, height);
- },
-
- setOrigin: function(ox, oy) {
-
- this.options.origin.x = ox || 0;
- this.options.origin.y = oy || 0;
-
- V(this.viewport).translate(ox, oy, { absolute: true });
-
- this.trigger('translate', ox, oy);
- },
-
- // Expand/shrink the paper to fit the content. Snap the width/height to the grid
- // defined in `gridWidth`, `gridHeight`. `padding` adds to the resulting width/height of the paper.
- // When options { fitNegative: true } it also translates the viewport in order to make all
- // the content visible.
- fitToContent: function(gridWidth, gridHeight, padding, opt) { // alternatively function(opt)
-
- if (_.isObject(gridWidth)) {
- // first parameter is an option object
- opt = gridWidth;
- gridWidth = opt.gridWidth || 1;
- gridHeight = opt.gridHeight || 1;
- padding = opt.padding || 0;
-
- } else {
-
- opt = opt || {};
- gridWidth = gridWidth || 1;
- gridHeight = gridHeight || 1;
- padding = padding || 0;
- }
-
- padding = _.isNumber(padding)
- ? { left: padding, right: padding, top: padding, bottom: padding }
- : { left: padding.left || 0, right: padding.right || 0, top: padding.top || 0, bottom: padding.bottom || 0 };
-
- // Calculate the paper size to accomodate all the graph's elements.
- var bbox = V(this.viewport).bbox(true, this.svg);
-
- var currentScale = V(this.viewport).scale();
-
- bbox.x *= currentScale.sx;
- bbox.y *= currentScale.sy;
- bbox.width *= currentScale.sx;
- bbox.height *= currentScale.sy;
-
- var calcWidth = Math.max(Math.ceil((bbox.width + bbox.x) / gridWidth), 1) * gridWidth;
- var calcHeight = Math.max(Math.ceil((bbox.height + bbox.y) / gridHeight), 1) * gridHeight;
-
- var tx = 0;
- var ty = 0;
-
- if ((opt.allowNewOrigin == 'negative' && bbox.x < 0) || (opt.allowNewOrigin == 'positive' && bbox.x >= 0) || opt.allowNewOrigin == 'any') {
- tx = Math.ceil(-bbox.x / gridWidth) * gridWidth;
- tx += padding.left;
- calcWidth += tx;
- }
-
- if ((opt.allowNewOrigin == 'negative' && bbox.y < 0) || (opt.allowNewOrigin == 'positive' && bbox.y >= 0) || opt.allowNewOrigin == 'any') {
- ty = Math.ceil(-bbox.y / gridHeight) * gridHeight;
- ty += padding.top;
- calcHeight += ty;
- }
-
- calcWidth += padding.right;
- calcHeight += padding.bottom;
-
- // Make sure the resulting width and height are greater than minimum.
- calcWidth = Math.max(calcWidth, opt.minWidth || 0);
- calcHeight = Math.max(calcHeight, opt.minHeight || 0);
-
- var dimensionChange = calcWidth != this.options.width || calcHeight != this.options.height;
- var originChange = tx != this.options.origin.x || ty != this.options.origin.y;
-
- // Change the dimensions only if there is a size discrepency or an origin change
- if (originChange) {
- this.setOrigin(tx, ty);
- }
- if (dimensionChange) {
- this.setDimensions(calcWidth, calcHeight);
- }
- },
-
- scaleContentToFit: function(opt) {
-
- var contentBBox = this.getContentBBox();
-
- if (!contentBBox.width || !contentBBox.height) return;
-
- opt = opt || {};
-
- _.defaults(opt, {
- padding: 0,
- preserveAspectRatio: true,
- scaleGrid: null,
- minScale: 0,
- maxScale: Number.MAX_VALUE
- //minScaleX
- //minScaleY
- //maxScaleX
- //maxScaleY
- //fittingBBox
- });
-
- var padding = opt.padding;
-
- var minScaleX = opt.minScaleX || opt.minScale;
- var maxScaleX = opt.maxScaleX || opt.maxScale;
- var minScaleY = opt.minScaleY || opt.minScale;
- var maxScaleY = opt.maxScaleY || opt.maxScale;
-
- var fittingBBox = opt.fittingBBox || ({
- x: this.options.origin.x,
- y: this.options.origin.y,
- width: this.options.width,
- height: this.options.height
- });
-
- fittingBBox = g.rect(fittingBBox).moveAndExpand({
- x: padding,
- y: padding,
- width: -2 * padding,
- height: -2 * padding
- });
-
- var currentScale = V(this.viewport).scale();
-
- var newSx = fittingBBox.width / contentBBox.width * currentScale.sx;
- var newSy = fittingBBox.height / contentBBox.height * currentScale.sy;
-
- if (opt.preserveAspectRatio) {
- newSx = newSy = Math.min(newSx, newSy);
- }
-
- // snap scale to a grid
- if (opt.scaleGrid) {
-
- var gridSize = opt.scaleGrid;
-
- newSx = gridSize * Math.floor(newSx / gridSize);
- newSy = gridSize * Math.floor(newSy / gridSize);
- }
-
- // scale min/max boundaries
- newSx = Math.min(maxScaleX, Math.max(minScaleX, newSx));
- newSy = Math.min(maxScaleY, Math.max(minScaleY, newSy));
-
- this.scale(newSx, newSy);
-
- var contentTranslation = this.getContentBBox();
-
- var newOx = fittingBBox.x - contentTranslation.x;
- var newOy = fittingBBox.y - contentTranslation.y;
-
- this.setOrigin(newOx, newOy);
- },
-
- getContentBBox: function() {
-
- var crect = this.viewport.getBoundingClientRect();
-
- // Using Screen CTM was the only way to get the real viewport bounding box working in both
- // Google Chrome and Firefox.
- var screenCTM = this.viewport.getScreenCTM();
-
- // for non-default origin we need to take the viewport translation into account
- var viewportCTM = this.viewport.getCTM();
-
- var bbox = g.rect({
- x: crect.left - screenCTM.e + viewportCTM.e,
- y: crect.top - screenCTM.f + viewportCTM.f,
- width: crect.width,
- height: crect.height
- });
-
- return bbox;
- },
-
- createViewForModel: function(cell) {
-
- var view;
-
- var type = cell.get('type');
- var module = type.split('.')[0];
- var entity = type.split('.')[1];
-
- // If there is a special view defined for this model, use that one instead of the default `elementView`/`linkView`.
- if (joint.shapes[module] && joint.shapes[module][entity + 'View']) {
-
- view = new joint.shapes[module][entity + 'View']({ model: cell, interactive: this.options.interactive });
-
- } else if (cell instanceof joint.dia.Element) {
-
- view = new this.options.elementView({ model: cell, interactive: this.options.interactive });
-
- } else {
-
- view = new this.options.linkView({ model: cell, interactive: this.options.interactive });
- }
-
- return view;
- },
-
- onAddCell: function(cell, graph, options) {
-
- if (this.options.async && options.async !== false && _.isNumber(options.position)) {
-
- this._asyncCells = this._asyncCells || [];
- this._asyncCells.push(cell);
-
- if (options.position == 0) {
-
- if (this._frameId) throw 'another asynchronous rendering in progress';
-
- this.asyncRenderCells(this._asyncCells);
- delete this._asyncCells;
- }
-
- } else {
-
- this.addCell(cell);
- }
- },
-
- addCell: function(cell) {
-
- var view = this.createViewForModel(cell);
-
- V(this.viewport).append(view.el);
- view.paper = this;
- view.render();
-
- // This is the only way to prevent image dragging in Firefox that works.
- // Setting -moz-user-select: none, draggable="false" attribute or user-drag: none didn't help.
- $(view.el).find('image').on('dragstart', function() { return false; });
- },
-
- beforeRenderCells: function(cells) {
-
- // Make sure links are always added AFTER elements.
- // They wouldn't find their sources/targets in the DOM otherwise.
- cells.sort(function(a, b) { return a instanceof joint.dia.Link ? 1 : -1; });
-
- return cells;
- },
-
- afterRenderCells: function() {
-
- this.sortCells();
- },
-
- resetCells: function(cellsCollection, opt) {
-
- $(this.viewport).empty();
-
- var cells = cellsCollection.models.slice();
-
- cells = this.beforeRenderCells(cells, opt);
-
- if (this._frameId) {
-
- joint.util.cancelFrame(this._frameId);
- delete this._frameId;
- }
-
- if (this.options.async) {
-
- this.asyncRenderCells(cells, opt);
- // Sort the cells once all elements rendered (see asyncRenderCells()).
-
- } else {
-
- _.each(cells, this.addCell, this);
-
- // Sort the cells in the DOM manually as we might have changed the order they
- // were added to the DOM (see above).
- this.sortCells();
- }
- },
-
- removeCells: function() {
-
- this.model.get('cells').each(function(cell) {
- var view = this.findViewByModel(cell);
- view && view.remove();
- }, this);
- },
-
- asyncBatchAdded: _.identity,
-
- asyncRenderCells: function(cells, opt) {
-
- var done = false;
-
- if (this._frameId) {
-
- _.each(_.range(this.options.async && this.options.async.batchSize || 50), function() {
-
- var cell = cells.shift();
- done = !cell;
- if (!done) this.addCell(cell);
-
- }, this);
-
- this.asyncBatchAdded();
- }
-
- if (done) {
-
- delete this._frameId;
- this.afterRenderCells(opt);
- this.trigger('render:done', opt);
-
- } else {
-
- this._frameId = joint.util.nextFrame(_.bind(function() {
- this.asyncRenderCells(cells, opt);
- }, this));
- }
- },
-
- sortCells: function() {
-
- // Run insertion sort algorithm in order to efficiently sort DOM elements according to their
- // associated model `z` attribute.
-
- var $cells = $(this.viewport).children('[model-id]');
- var cells = this.model.get('cells');
-
- this.sortElements($cells, function(a, b) {
-
- var cellA = cells.get($(a).attr('model-id'));
- var cellB = cells.get($(b).attr('model-id'));
-
- return (cellA.get('z') || 0) > (cellB.get('z') || 0) ? 1 : -1;
- });
- },
-
- // Highly inspired by the jquery.sortElements plugin by Padolsey.
- // See http://james.padolsey.com/javascript/sorting-elements-with-jquery/.
- sortElements: function(elements, comparator) {
-
- var $elements = $(elements);
-
- var placements = $elements.map(function() {
-
- var sortElement = this;
- var parentNode = sortElement.parentNode;
-
- // Since the element itself will change position, we have
- // to have some way of storing it's original position in
- // the DOM. The easiest way is to have a 'flag' node:
- var nextSibling = parentNode.insertBefore(
- document.createTextNode(''),
- sortElement.nextSibling
- );
-
- return function() {
-
- if (parentNode === this) {
- throw new Error(
- "You can't sort elements if any one is a descendant of another."
- );
- }
-
- // Insert before flag:
- parentNode.insertBefore(this, nextSibling);
- // Remove flag:
- parentNode.removeChild(nextSibling);
-
- };
- });
-
- return Array.prototype.sort.call($elements, comparator).each(function(i) {
- placements[i].call(this);
- });
- },
-
- scale: function(sx, sy, ox, oy) {
-
- sy = sy || sx;
-
- if (_.isUndefined(ox)) {
-
- ox = 0;
- oy = 0;
- }
-
- // Remove previous transform so that the new scale is not affected by previous scales, especially
- // the old translate() does not affect the new translate if an origin is specified.
- V(this.viewport).attr('transform', '');
-
- var oldTx = this.options.origin.x;
- var oldTy = this.options.origin.y;
-
- // TODO: V.scale() doesn't support setting scale origin. #Fix
- if (ox || oy || oldTx || oldTy) {
-
- var newTx = oldTx - ox * (sx - 1);
- var newTy = oldTy - oy * (sy - 1);
- this.setOrigin(newTx, newTy);
- }
-
- V(this.viewport).scale(sx, sy);
-
- this.trigger('scale', sx, sy, ox, oy);
-
- return this;
- },
-
- rotate: function(deg, ox, oy) {
-
- // If the origin is not set explicitely, rotate around the center. Note that
- // we must use the plain bounding box (`this.el.getBBox()` instead of the one that gives us
- // the real bounding box (`bbox()`) including transformations).
- if (_.isUndefined(ox)) {
-
- var bbox = this.viewport.getBBox();
- ox = bbox.width / 2;
- oy = bbox.height / 2;
- }
-
- V(this.viewport).rotate(deg, ox, oy);
- },
-
- // Find the first view climbing up the DOM tree starting at element `el`. Note that `el` can also
- // be a selector or a jQuery object.
- findView: function(el) {
-
- var $el = this.$(el);
-
- if ($el.length === 0 || $el[0] === this.el) {
-
- return undefined;
- }
-
- return $el.data('view') || this.findView($el.parent());
- },
-
- // Find a view for a model `cell`. `cell` can also be a string representing a model `id`.
- findViewByModel: function(cell) {
-
- var id = _.isString(cell) ? cell : cell.id;
- var $view = this.$('[model-id="' + id + '"]');
-
- return $view.length ? $view.data('view') : undefined;
- },
-
- // Find all views at given point
- findViewsFromPoint: function(p) {
-
- p = g.point(p);
-
- var views = _.map(this.model.getElements(), this.findViewByModel);
-
- return _.filter(views, function(view) {
- return view && g.rect(V(view.el).bbox(false, this.viewport)).containsPoint(p);
- }, this);
- },
-
- // Find all views in given area
- findViewsInArea: function(r) {
-
- r = g.rect(r);
-
- var views = _.map(this.model.getElements(), this.findViewByModel);
-
- return _.filter(views, function(view) {
- return view && r.intersect(g.rect(V(view.el).bbox(false, this.viewport)));
- }, this);
- },
-
- getModelById: function(id) {
-
- return this.model.getCell(id);
- },
-
- snapToGrid: function(p) {
-
- // Convert global coordinates to the local ones of the `viewport`. Otherwise,
- // improper transformation would be applied when the viewport gets transformed (scaled/rotated).
- var localPoint = V(this.viewport).toLocalPoint(p.x, p.y);
-
- return {
- x: g.snapToGrid(localPoint.x, this.options.gridSize),
- y: g.snapToGrid(localPoint.y, this.options.gridSize)
- };
- },
-
- // Transform client coordinates to the paper local coordinates.
- // Useful when you have a mouse event object and you'd like to get coordinates
- // inside the paper that correspond to `evt.clientX` and `evt.clientY` point.
- // Exmaple: var paperPoint = paper.clientToLocalPoint({ x: evt.clientX, y: evt.clientY });
- clientToLocalPoint: function(p) {
-
- var svgPoint = this.svg.createSVGPoint();
- svgPoint.x = p.x;
- svgPoint.y = p.y;
-
- // This is a hack for Firefox! If there wasn't a fake (non-visible) rectangle covering the
- // whole SVG area, `$(paper.svg).offset()` used below won't work.
- var fakeRect = V('rect', { width: this.options.width, height: this.options.height, x: 0, y: 0, opacity: 0 });
- V(this.svg).prepend(fakeRect);
-
- var paperOffset = $(this.svg).offset();
-
- // Clean up the fake rectangle once we have the offset of the SVG document.
- fakeRect.remove();
-
- var scrollTop = document.body.scrollTop || document.documentElement.scrollTop;
- var scrollLeft = document.body.scrollLeft || document.documentElement.scrollLeft;
-
- svgPoint.x += scrollLeft - paperOffset.left;
- svgPoint.y += scrollTop - paperOffset.top;
-
- // Transform point into the viewport coordinate system.
- var pointTransformed = svgPoint.matrixTransform(this.viewport.getCTM().inverse());
-
- return pointTransformed;
- },
-
- getDefaultLink: function(cellView, magnet) {
-
- return _.isFunction(this.options.defaultLink)
- // default link is a function producing link model
- ? this.options.defaultLink.call(this, cellView, magnet)
- // default link is the Backbone model
- : this.options.defaultLink.clone();
- },
-
- // Cell highlighting
- // -----------------
-
- onCellHighlight: function(cellView, el) {
- V(el).addClass('highlighted');
- },
-
- onCellUnhighlight: function(cellView, el) {
- V(el).removeClass('highlighted');
- },
-
- // Interaction.
- // ------------
-
- mousedblclick: function(evt) {
-
- evt.preventDefault();
- evt = joint.util.normalizeEvent(evt);
-
- var view = this.findView(evt.target);
- var localPoint = this.snapToGrid({ x: evt.clientX, y: evt.clientY });
-
- if (view) {
-
- view.pointerdblclick(evt, localPoint.x, localPoint.y);
-
- } else {
-
- this.trigger('blank:pointerdblclick', evt, localPoint.x, localPoint.y);
- }
- },
-
- mouseclick: function(evt) {
-
- // Trigger event when mouse not moved.
- if (!this._mousemoved) {
-
- evt = joint.util.normalizeEvent(evt);
-
- var view = this.findView(evt.target);
- var localPoint = this.snapToGrid({ x: evt.clientX, y: evt.clientY });
-
- if (view) {
-
- view.pointerclick(evt, localPoint.x, localPoint.y);
-
- } else {
-
- this.trigger('blank:pointerclick', evt, localPoint.x, localPoint.y);
- }
- }
-
- this._mousemoved = false;
- },
-
- pointerdown: function(evt) {
-
- evt = joint.util.normalizeEvent(evt);
-
- var view = this.findView(evt.target);
-
- var localPoint = this.snapToGrid({ x: evt.clientX, y: evt.clientY });
-
- if (view) {
-
- this.sourceView = view;
-
- view.pointerdown(evt, localPoint.x, localPoint.y);
-
- } else {
-
- this.trigger('blank:pointerdown', evt, localPoint.x, localPoint.y);
- }
- },
-
- pointermove: function(evt) {
-
- evt.preventDefault();
- evt = joint.util.normalizeEvent(evt);
-
- if (this.sourceView) {
-
- // Mouse moved.
- this._mousemoved = true;
-
- var localPoint = this.snapToGrid({ x: evt.clientX, y: evt.clientY });
-
- this.sourceView.pointermove(evt, localPoint.x, localPoint.y);
- }
- },
-
- pointerup: function(evt) {
-
- evt = joint.util.normalizeEvent(evt);
-
- var localPoint = this.snapToGrid({ x: evt.clientX, y: evt.clientY });
-
- if (this.sourceView) {
-
- this.sourceView.pointerup(evt, localPoint.x, localPoint.y);
-
- //"delete sourceView" occasionally throws an error in chrome (illegal access exception)
- this.sourceView = null;
-
- } else {
-
- this.trigger('blank:pointerup', evt, localPoint.x, localPoint.y);
- }
- },
-
- cellMouseover: function(evt) {
-
- evt = joint.util.normalizeEvent(evt);
- var view = this.findView(evt.target);
- if (view) {
-
- view.mouseover(evt);
- }
- },
-
- cellMouseout: function(evt) {
-
- evt = joint.util.normalizeEvent(evt);
- var view = this.findView(evt.target);
- if (view) {
-
- view.mouseout(evt);
- }
- }
-});
-
-// JointJS library.
-// (c) 2011-2013 client IO
-
-joint.shapes.basic = {};
-
-joint.shapes.basic.Generic = joint.dia.Element.extend({
-
- defaults: joint.util.deepSupplement({
-
- type: 'basic.Generic',
- attrs: {
- '.': { fill: '#FFFFFF', stroke: 'none' }
- }
-
- }, joint.dia.Element.prototype.defaults)
-});
-
-joint.shapes.basic.Rect = joint.shapes.basic.Generic.extend({
-
- markup: '<g class="rotatable"><g class="scalable"><rect/></g><text/></g>',
-
- defaults: joint.util.deepSupplement({
-
- type: 'basic.Rect',
- attrs: {
- 'rect': { fill: '#FFFFFF', stroke: 'black', width: 100, height: 60 },
- 'text': { 'font-size': 14, text: '', 'ref-x': .5, 'ref-y': .5, ref: 'rect', 'y-alignment': 'middle', 'x-alignment': 'middle', fill: 'black', 'font-family': 'Arial, helvetica, sans-serif' }
- }
-
- }, joint.shapes.basic.Generic.prototype.defaults)
-});
-
-joint.shapes.basic.TextView = joint.dia.ElementView.extend({
-
- initialize: function() {
- joint.dia.ElementView.prototype.initialize.apply(this, arguments);
- // The element view is not automatically rescaled to fit the model size
- // when the attribute 'attrs' is changed.
- this.listenTo(this.model, 'change:attrs', this.resize);
- }
-});
-
-joint.shapes.basic.Text = joint.shapes.basic.Generic.extend({
-
- markup: '<g class="rotatable"><g class="scalable"><text/></g></g>',
-
- defaults: joint.util.deepSupplement({
-
- type: 'basic.Text',
- attrs: {
- 'text': { 'font-size': 18, fill: 'black' }
- }
-
- }, joint.shapes.basic.Generic.prototype.defaults)
-});
-
-joint.shapes.basic.Circle = joint.shapes.basic.Generic.extend({
-
- markup: '<g class="rotatable"><g class="scalable"><circle/></g><text/></g>',
-
- defaults: joint.util.deepSupplement({
-
- type: 'basic.Circle',
- size: { width: 60, height: 60 },
- attrs: {
- 'circle': { fill: '#FFFFFF', stroke: 'black', r: 30, transform: 'translate(30, 30)' },
- 'text': { 'font-size': 14, text: '', 'text-anchor': 'middle', 'ref-x': .5, 'ref-y': .5, ref: 'circle', 'y-alignment': 'middle', fill: 'black', 'font-family': 'Arial, helvetica, sans-serif' }
- }
- }, joint.shapes.basic.Generic.prototype.defaults)
-});
-
-joint.shapes.basic.Ellipse = joint.shapes.basic.Generic.extend({
-
- markup: '<g class="rotatable"><g class="scalable"><ellipse/></g><text/></g>',
-
- defaults: joint.util.deepSupplement({
-
- type: 'basic.Ellipse',
- size: { width: 60, height: 40 },
- attrs: {
- 'ellipse': { fill: '#FFFFFF', stroke: 'black', rx: 30, ry: 20, transform: 'translate(30, 20)' },
- 'text': { 'font-size': 14, text: '', 'text-anchor': 'middle', 'ref-x': .5, 'ref-y': .5, ref: 'ellipse', 'y-alignment': 'middle', fill: 'black', 'font-family': 'Arial, helvetica, sans-serif' }
- }
- }, joint.shapes.basic.Generic.prototype.defaults)
-});
-
-joint.shapes.basic.Polygon = joint.shapes.basic.Generic.extend({
-
- markup: '<g class="rotatable"><g class="scalable"><polygon/></g><text/></g>',
-
- defaults: joint.util.deepSupplement({
-
- type: 'basic.Polygon',
- size: { width: 60, height: 40 },
- attrs: {
- 'polygon': { fill: '#FFFFFF', stroke: 'black' },
- 'text': { 'font-size': 14, text: '', 'text-anchor': 'middle', 'ref-x': .5, 'ref-dy': 20, ref: 'polygon', 'y-alignment': 'middle', fill: 'black', 'font-family': 'Arial, helvetica, sans-serif' }
- }
- }, joint.shapes.basic.Generic.prototype.defaults)
-});
-
-joint.shapes.basic.Polyline = joint.shapes.basic.Generic.extend({
-
- markup: '<g class="rotatable"><g class="scalable"><polyline/></g><text/></g>',
-
- defaults: joint.util.deepSupplement({
-
- type: 'basic.Polyline',
- size: { width: 60, height: 40 },
- attrs: {
- 'polyline': { fill: '#FFFFFF', stroke: 'black' },
- 'text': { 'font-size': 14, text: '', 'text-anchor': 'middle', 'ref-x': .5, 'ref-dy': 20, ref: 'polyline', 'y-alignment': 'middle', fill: 'black', 'font-family': 'Arial, helvetica, sans-serif' }
- }
- }, joint.shapes.basic.Generic.prototype.defaults)
-});
-
-joint.shapes.basic.Image = joint.shapes.basic.Generic.extend({
-
- markup: '<g class="rotatable"><g class="scalable"><image/></g><text/></g>',
-
- defaults: joint.util.deepSupplement({
-
- type: 'basic.Image',
- attrs: {
- 'text': { 'font-size': 14, text: '', 'text-anchor': 'middle', 'ref-x': .5, 'ref-dy': 20, ref: 'image', 'y-alignment': 'middle', fill: 'black', 'font-family': 'Arial, helvetica, sans-serif' }
- }
- }, joint.shapes.basic.Generic.prototype.defaults)
-});
-
-joint.shapes.basic.Path = joint.shapes.basic.Generic.extend({
-
- markup: '<g class="rotatable"><g class="scalable"><path/></g><text/></g>',
-
- defaults: joint.util.deepSupplement({
-
- type: 'basic.Path',
- size: { width: 60, height: 60 },
- attrs: {
- 'path': { fill: '#FFFFFF', stroke: 'black' },
- 'text': { 'font-size': 14, text: '', 'text-anchor': 'middle', 'ref-x': .5, 'ref-dy': 20, ref: 'path', 'y-alignment': 'middle', fill: 'black', 'font-family': 'Arial, helvetica, sans-serif' }
- }
- }, joint.shapes.basic.Generic.prototype.defaults)
-});
-
-joint.shapes.basic.Rhombus = joint.shapes.basic.Path.extend({
-
- defaults: joint.util.deepSupplement({
-
- type: 'basic.Rhombus',
- attrs: {
- 'path': { d: 'M 30 0 L 60 30 30 60 0 30 z' },
- 'text': { 'ref-y': .5 }
- }
-
- }, joint.shapes.basic.Path.prototype.defaults)
-});
-
-
-// PortsModelInterface is a common interface for shapes that have ports. This interface makes it easy
-// to create new shapes with ports functionality. It is assumed that the new shapes have
-// `inPorts` and `outPorts` array properties. Only these properties should be used to set ports.
-// In other words, using this interface, it is no longer recommended to set ports directly through the
-// `attrs` object.
-
-// Usage:
-// joint.shapes.custom.MyElementWithPorts = joint.shapes.basic.Path.extend(_.extend({}, joint.shapes.basic.PortsModelInterface, {
-// getPortAttrs: function(portName, index, total, selector, type) {
-// var attrs = {};
-// var portClass = 'port' + index;
-// var portSelector = selector + '>.' + portClass;
-// var portTextSelector = portSelector + '>text';
-// var portCircleSelector = portSelector + '>circle';
-//
-// attrs[portTextSelector] = { text: portName };
-// attrs[portCircleSelector] = { port: { id: portName || _.uniqueId(type) , type: type } };
-// attrs[portSelector] = { ref: 'rect', 'ref-y': (index + 0.5) * (1 / total) };
-//
-// if (selector === '.outPorts') { attrs[portSelector]['ref-dx'] = 0; }
-//
-// return attrs;
-// }
-//}));
-joint.shapes.basic.PortsModelInterface = {
-
- initialize: function() {
-
- this.updatePortsAttrs();
- this.on('change:inPorts change:outPorts', this.updatePortsAttrs, this);
-
- // Call the `initialize()` of the parent.
- this.constructor.__super__.constructor.__super__.initialize.apply(this, arguments);
- },
-
- updatePortsAttrs: function(eventName) {
-
- // Delete previously set attributes for ports.
- var currAttrs = this.get('attrs');
- _.each(this._portSelectors, function(selector) {
- if (currAttrs[selector]) delete currAttrs[selector];
- });
-
- // This holds keys to the `attrs` object for all the port specific attribute that
- // we set in this method. This is necessary in order to remove previously set
- // attributes for previous ports.
- this._portSelectors = [];
-
- var attrs = {};
-
- _.each(this.get('inPorts'), function(portName, index, ports) {
- var portAttributes = this.getPortAttrs(portName, index, ports.length, '.inPorts', 'in');
- this._portSelectors = this._portSelectors.concat(_.keys(portAttributes));
- _.extend(attrs, portAttributes);
- }, this);
-
- _.each(this.get('outPorts'), function(portName, index, ports) {
- var portAttributes = this.getPortAttrs(portName, index, ports.length, '.outPorts', 'out');
- this._portSelectors = this._portSelectors.concat(_.keys(portAttributes));
- _.extend(attrs, portAttributes);
- }, this);
-
- // Silently set `attrs` on the cell so that noone knows the attrs have changed. This makes sure
- // that, for example, command manager does not register `change:attrs` command but only
- // the important `change:inPorts`/`change:outPorts` command.
- this.attr(attrs, { silent: true });
- // Manually call the `processPorts()` method that is normally called on `change:attrs` (that we just made silent).
- this.processPorts();
- // Let the outside world (mainly the `ModelView`) know that we're done configuring the `attrs` object.
- this.trigger('process:ports');
- },
-
- getPortSelector: function(name) {
-
- var selector = '.inPorts';
- var index = this.get('inPorts').indexOf(name);
-
- if (index < 0) {
- selector = '.outPorts';
- index = this.get('outPorts').indexOf(name);
-
- if (index < 0) throw new Error("getPortSelector(): Port doesn't exist.");
- }
-
- return selector + '>g:nth-child(' + (index + 1) + ')>circle';
- }
-};
-
-joint.shapes.basic.PortsViewInterface = {
-
- initialize: function() {
-
- // `Model` emits the `process:ports` whenever it's done configuring the `attrs` object for ports.
- this.listenTo(this.model, 'process:ports', this.update);
-
- joint.dia.ElementView.prototype.initialize.apply(this, arguments);
- },
-
- update: function() {
-
- // First render ports so that `attrs` can be applied to those newly created DOM elements
- // in `ElementView.prototype.update()`.
- this.renderPorts();
- joint.dia.ElementView.prototype.update.apply(this, arguments);
- },
-
- renderPorts: function() {
-
- var $inPorts = this.$('.inPorts').empty();
- var $outPorts = this.$('.outPorts').empty();
-
- var portTemplate = _.template(this.model.portMarkup);
-
- _.each(_.filter(this.model.ports, function(p) { return p.type === 'in'; }), function(port, index) {
-
- $inPorts.append(V(portTemplate({ id: index, port: port })).node);
- });
- _.each(_.filter(this.model.ports, function(p) { return p.type === 'out'; }), function(port, index) {
-
- $outPorts.append(V(portTemplate({ id: index, port: port })).node);
- });
- }
-};
-
-joint.shapes.basic.TextBlock = joint.shapes.basic.Generic.extend({
-
- markup: ['<g class="rotatable"><g class="scalable"><rect/></g><switch>',
-
- // if foreignObject supported
-
- '<foreignObject requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" class="fobj">',
- '<body xmlns="http://www.w3.org/1999/xhtml"><div/></body>',
- '</foreignObject>',
-
- // else foreignObject is not supported (fallback for IE)
- '<text class="content"/>',
-
- '</switch></g>'].join(''),
-
- defaults: joint.util.deepSupplement({
-
- type: 'basic.TextBlock',
-
- // see joint.css for more element styles
- attrs: {
- rect: {
- fill: '#ffffff',
- stroke: '#000000',
- width: 80,
- height: 100
- },
- text: {
- fill: '#000000',
- 'font-size': 14,
- 'font-family': 'Arial, helvetica, sans-serif'
- },
- '.content': {
- text: '',
- ref: 'rect',
- 'ref-x': .5,
- 'ref-y': .5,
- 'y-alignment': 'middle',
- 'x-alignment': 'middle'
- }
- },
-
- content: ''
-
- }, joint.shapes.basic.Generic.prototype.defaults),
-
- initialize: function() {
-
- if (typeof SVGForeignObjectElement !== 'undefined') {
-
- // foreignObject supported
- this.setForeignObjectSize(this, this.get('size'));
- this.setDivContent(this, this.get('content'));
- this.listenTo(this, 'change:size', this.setForeignObjectSize);
- this.listenTo(this, 'change:content', this.setDivContent);
-
- }
-
- joint.shapes.basic.Generic.prototype.initialize.apply(this, arguments);
- },
-
- setForeignObjectSize: function(cell, size) {
-
- // Selector `foreignObject' doesn't work accross all browsers, we'r using class selector instead.
- // We have to clone size as we don't want attributes.div.style to be same object as attributes.size.
- cell.attr({
- '.fobj': _.clone(size),
- div: { style: _.clone(size) }
- });
- },
-
- setDivContent: function(cell, content) {
-
- // Append the content to div as html.
- cell.attr({ div : {
- html: content
- }});
- }
-
-});
-
-// TextBlockView implements the fallback for IE when no foreignObject exists and
-// the text needs to be manually broken.
-joint.shapes.basic.TextBlockView = joint.dia.ElementView.extend({
-
- initialize: function() {
-
- joint.dia.ElementView.prototype.initialize.apply(this, arguments);
-
- if (typeof SVGForeignObjectElement === 'undefined') {
-
- this.noSVGForeignObjectElement = true;
-
- this.listenTo(this.model, 'change:content', function(cell) {
- // avoiding pass of extra paramters
- this.updateContent(cell);
- });
- }
- },
-
- update: function(cell, renderingOnlyAttrs) {
-
- if (this.noSVGForeignObjectElement) {
-
- var model = this.model;
-
- // Update everything but the content first.
- var noTextAttrs = _.omit(renderingOnlyAttrs || model.get('attrs'), '.content');
- joint.dia.ElementView.prototype.update.call(this, model, noTextAttrs);
-
- if (!renderingOnlyAttrs || _.has(renderingOnlyAttrs, '.content')) {
- // Update the content itself.
- this.updateContent(model, renderingOnlyAttrs);
- }
-
- } else {
-
- joint.dia.ElementView.prototype.update.call(this, model, renderingOnlyAttrs);
- }
- },
-
- updateContent: function(cell, renderingOnlyAttrs) {
-
- // Create copy of the text attributes
- var textAttrs = _.merge({}, (renderingOnlyAttrs || cell.get('attrs'))['.content']);
-
- delete textAttrs.text;
-
- // Break the content to fit the element size taking into account the attributes
- // set on the model.
- var text = joint.util.breakText(cell.get('content'), cell.get('size'), textAttrs, {
- // measuring sandbox svg document
- svgDocument: this.paper.svg
- });
-
- // Create a new attrs with same structure as the model attrs { text: { *textAttributes* }}
- var attrs = joint.util.setByPath({}, '.content', textAttrs, '/');
-
- // Replace text attribute with the one we just processed.
- attrs['.content'].text = text;
-
- // Update the view using renderingOnlyAttributes parameter.
- joint.dia.ElementView.prototype.update.call(this, cell, attrs);
- }
-});
-
-joint.routers.orthogonal = (function() {
-
- // bearing -> opposite bearing
- var opposite = {
- N: 'S',
- S: 'N',
- E: 'W',
- W: 'E'
- };
-
- // bearing -> radians
- var radians = {
- N: -Math.PI / 2 * 3,
- S: -Math.PI / 2,
- E: 0,
- W: Math.PI
- };
-
- // HELPERS //
-
- // simple bearing method (calculates only orthogonal cardinals)
- function bearing(from, to) {
- if (from.x == to.x) return from.y > to.y ? 'N' : 'S';
- if (from.y == to.y) return from.x > to.x ? 'W' : 'E';
- return null;
- }
-
- // returns either width or height of a bbox based on the given bearing
- function boxSize(bbox, brng) {
- return bbox[brng == 'W' || brng == 'E' ? 'width' : 'height'];
- }
-
- // expands a box by specific value
- function expand(bbox, val) {
- return g.rect(bbox).moveAndExpand({ x: -val, y: -val, width: 2 * val, height: 2 * val });
- }
-
- // transform point to a rect
- function pointBox(p) {
- return g.rect(p.x, p.y, 0, 0);
- }
-
- // returns a minimal rect which covers the given boxes
- function boundary(bbox1, bbox2) {
-
- var x1 = Math.min(bbox1.x, bbox2.x);
- var y1 = Math.min(bbox1.y, bbox2.y);
- var x2 = Math.max(bbox1.x + bbox1.width, bbox2.x + bbox2.width);
- var y2 = Math.max(bbox1.y + bbox1.height, bbox2.y + bbox2.height);
-
- return g.rect(x1, y1, x2 - x1, y2 - y1);
- }
-
- // returns a point `p` where lines p,p1 and p,p2 are perpendicular and p is not contained
- // in the given box
- function freeJoin(p1, p2, bbox) {
-
- var p = g.point(p1.x, p2.y);
- if (bbox.containsPoint(p)) p = g.point(p2.x, p1.y);
- // kept for reference
- // if (bbox.containsPoint(p)) p = null;
- return p;
- }
-
- // PARTIAL ROUTERS //
-
- function vertexVertex(from, to, brng) {
-
- var p1 = g.point(from.x, to.y);
- var p2 = g.point(to.x, from.y);
- var d1 = bearing(from, p1);
- var d2 = bearing(from, p2);
- var xBrng = opposite[brng];
-
- var p = (d1 == brng || (d1 != xBrng && (d2 == xBrng || d2 != brng))) ? p1 : p2;
-
- return { points: [p], direction: bearing(p, to) };
- }
-
- function elementVertex(from, to, fromBBox) {
-
- var p = freeJoin(from, to, fromBBox);
-
- return { points: [p], direction: bearing(p, to) };
- }
-
- function vertexElement(from, to, toBBox, brng) {
-
- var route = {};
-
- var pts = [g.point(from.x, to.y), g.point(to.x, from.y)];
- var freePts = _.filter(pts, function(pt) { return !toBBox.containsPoint(pt); });
- var freeBrngPts = _.filter(freePts, function(pt) { return bearing(pt, from) != brng; });
-
- var p;
-
- if (freeBrngPts.length > 0) {
-
- // try to pick a point which bears the same direction as the previous segment
- p = _.filter(freeBrngPts, function(pt) { return bearing(from, pt) == brng; }).pop();
- p = p || freeBrngPts[0];
-
- route.points = [p];
- route.direction = bearing(p, to);
-
- } else {
-
- // Here we found only points which are either contained in the element or they would create
- // a link segment going in opposite direction from the previous one.
- // We take the point inside element and move it outside the element in the direction the
- // route is going. Now we can join this point with the current end (using freeJoin).
-
- p = _.difference(pts, freePts)[0];
-
- var p2 = g.point(to).move(p, -boxSize(toBBox, brng) / 2);
- var p1 = freeJoin(p2, from, toBBox);
-
- route.points = [p1, p2];
- route.direction = bearing(p2, to);
- }
-
- return route;
- }
-
- function elementElement(from, to, fromBBox, toBBox) {
-
- var route = elementVertex(to, from, toBBox);
- var p1 = route.points[0];
-
- if (fromBBox.containsPoint(p1)) {
-
- route = elementVertex(from, to, fromBBox);
- var p2 = route.points[0];
-
- if (toBBox.containsPoint(p2)) {
-
- var fromBorder = g.point(from).move(p2, -boxSize(fromBBox, bearing(from, p2)) / 2);
- var toBorder = g.point(to).move(p1, -boxSize(toBBox, bearing(to, p1)) / 2);
- var mid = g.line(fromBorder, toBorder).midpoint();
-
- var startRoute = elementVertex(from, mid, fromBBox);
- var endRoute = vertexVertex(mid, to, startRoute.direction);
-
- route.points = [startRoute.points[0], endRoute.points[0]];
- route.direction = endRoute.direction;
- }
- }
-
- return route;
- }
-
- // Finds route for situations where one of end is inside the other.
- // Typically the route is conduct outside the outer element first and
- // let go back to the inner element.
- function insideElement(from, to, fromBBox, toBBox, brng) {
-
- var route = {};
- var bndry = expand(boundary(fromBBox, toBBox), 1);
-
- // start from the point which is closer to the boundary
- var reversed = bndry.center().distance(to) > bndry.center().distance(from);
- var start = reversed ? to : from;
- var end = reversed ? from : to;
-
- var p1, p2, p3;
-
- if (brng) {
- // Points on circle with radius equals 'W + H` are always outside the rectangle
- // with width W and height H if the center of that circle is the center of that rectangle.
- p1 = g.point.fromPolar(bndry.width + bndry.height, radians[brng], start);
- p1 = bndry.pointNearestToPoint(p1).move(p1, -1);
- } else {
- p1 = bndry.pointNearestToPoint(start).move(start, 1);
- }
-
- p2 = freeJoin(p1, end, bndry);
-
- if (p1.round().equals(p2.round())) {
- p2 = g.point.fromPolar(bndry.width + bndry.height, g.toRad(p1.theta(start)) + Math.PI / 2, end);
- p2 = bndry.pointNearestToPoint(p2).move(end, 1).round();
- p3 = freeJoin(p1, p2, bndry);
- route.points = reversed ? [p2, p3, p1] : [p1, p3, p2];
- } else {
- route.points = reversed ? [p2, p1] : [p1, p2];
- }
-
- route.direction = reversed ? bearing(p1, to) : bearing(p2, to);
-
- return route;
- }
-
- // MAIN ROUTER //
-
- // Return points that one needs to draw a connection through in order to have a orthogonal link
- // routing from source to target going through `vertices`.
- function findOrthogonalRoute(vertices, opt, linkView) {
-
- var padding = opt.elementPadding || 20;
-
- var orthogonalVertices = [];
- var sourceBBox = expand(linkView.sourceBBox, padding);
- var targetBBox = expand(linkView.targetBBox, padding);
-
- vertices = _.map(vertices, g.point);
- vertices.unshift(sourceBBox.center());
- vertices.push(targetBBox.center());
-
- var brng;
-
- for (var i = 0, max = vertices.length - 1; i < max; i++) {
-
- var route = null;
- var from = vertices[i];
- var to = vertices[i + 1];
- var isOrthogonal = !!bearing(from, to);
-
- if (i == 0) {
-
- if (i + 1 == max) { // route source -> target
-
- // Expand one of elements by 1px so we detect also situations when they
- // are positioned one next other with no gap between.
- if (sourceBBox.intersect(expand(targetBBox, 1))) {
- route = insideElement(from, to, sourceBBox, targetBBox);
- } else if (!isOrthogonal) {
- route = elementElement(from, to, sourceBBox, targetBBox);
- }
-
- } else { // route source -> vertex
-
- if (sourceBBox.containsPoint(to)) {
- route = insideElement(from, to, sourceBBox, expand(pointBox(to), padding));
- } else if (!isOrthogonal) {
- route = elementVertex(from, to, sourceBBox);
- }
- }
-
- } else if (i + 1 == max) { // route vertex -> target
-
- var orthogonalLoop = isOrthogonal && bearing(to, from) == brng;
-
- if (targetBBox.containsPoint(from) || orthogonalLoop) {
- route = insideElement(from, to, expand(pointBox(from), padding), targetBBox, brng);
- } else if (!isOrthogonal) {
- route = vertexElement(from, to, targetBBox, brng);
- }
-
- } else if (!isOrthogonal) { // route vertex -> vertex
- route = vertexVertex(from, to, brng);
- }
-
- if (route) {
- Array.prototype.push.apply(orthogonalVertices, route.points);
- brng = route.direction;
- } else {
- // orthogonal route and not looped
- brng = bearing(from, to);
- }
-
- if (i + 1 < max) {
- orthogonalVertices.push(to);
- }
- }
-
- return orthogonalVertices;
- };
-
- return findOrthogonalRoute;
-
-})();
-
-joint.routers.manhattan = (function() {
-
- 'use strict';
-
- var config = {
-
- // size of the step to find a route
- step: 10,
-
- // use of the perpendicular linkView option to connect center of element with first vertex
- perpendicular: true,
-
- // tells how to divide the paper when creating the elements map
- mapGridSize: 100,
-
- // should be source or target not to be consider as an obstacle
- excludeEnds: [], // 'source', 'target'
-
- // should be any element with a certain type not to be consider as an obstacle
- excludeTypes: ['basic.Text'],
-
- // if number of route finding loops exceed the maximum, stops searching and returns
- // fallback route
- maximumLoops: 500,
-
- // possible starting directions from an element
- startDirections: ['left', 'right', 'top', 'bottom'],
-
- // possible ending directions to an element
- endDirections: ['left', 'right', 'top', 'bottom'],
-
- // specify directions above
- directionMap: {
- right: { x: 1, y: 0 },
- bottom: { x: 0, y: 1 },
- left: { x: -1, y: 0 },
- top: { x: 0, y: -1 }
- },
-
- // maximum change of the direction
- maxAllowedDirectionChange: 1,
-
- // padding applied on the element bounding boxes
- paddingBox: function() {
-
- var step = this.step;
-
- return {
- x: -step,
- y: -step,
- width: 2 * step,
- height: 2 * step
- };
- },
-
- // an array of directions to find next points on the route
- directions: function() {
-
- var step = this.step;
-
- return [
- { offsetX: step , offsetY: 0 , cost: step },
- { offsetX: 0 , offsetY: step , cost: step },
- { offsetX: -step , offsetY: 0 , cost: step },
- { offsetX: 0 , offsetY: -step , cost: step }
- ];
- },
-
- // a penalty received for direction change
- penalties: function() {
-
- return [0, this.step / 2, this.step];
- },
-
- // heurestic method to determine the distance between two points
- estimateCost: function(from, to) {
-
- return from.manhattanDistance(to);
- },
-
- // a simple route used in situations, when main routing method fails
- // (exceed loops, inaccessible).
- fallbackRoute: function(from, to, opts) {
-
- // Find an orthogonal route ignoring obstacles.
-
- var prevDirIndexes = opts.prevDirIndexes || {};
-
- var point = (prevDirIndexes[from] || 0) % 2
- ? g.point(from.x, to.y)
- : g.point(to.x, from.y);
-
- return [point, to];
- },
-
- // if a function is provided, it's used to route the link while dragging an end
- // i.e. function(from, to, opts) { return []; }
- draggingRoute: null
- };
-
- // reconstructs a route by concating points with their parents
- function reconstructRoute(parents, point) {
-
- var route = [];
- var prevDiff = { x: 0, y: 0 };
- var current = point;
- var parent;
-
- while ((parent = parents[current])) {
-
- var diff = parent.difference(current);
-
- if (!diff.equals(prevDiff)) {
-
- route.unshift(current);
- prevDiff = diff;
- }
-
- current = parent;
- }
-
- route.unshift(current);
-
- return route;
- };
-
- // find points around the rectangle taking given directions in the account
- function getRectPoints(bbox, directionList, opts) {
-
- var step = opts.step;
-
- var center = bbox.center();
-
- var startPoints = _.chain(opts.directionMap).pick(directionList).map(function(direction) {
-
- var x = direction.x * bbox.width / 2;
- var y = direction.y * bbox.height / 2;
-
- var point = g.point(center).offset(x, y).snapToGrid(step);
-
- if (bbox.containsPoint(point)) {
-
- point.offset(direction.x * step, direction.y * step);
- }
-
- return point;
-
- }).value();
-
- return startPoints;
- };
-
- // returns a direction index from start point to end point
- function getDirection(start, end, dirLen) {
-
- var dirAngle = 360 / dirLen;
-
- var q = Math.floor(start.theta(end) / dirAngle);
-
- return dirLen - q;
- }
-
- // finds the route between to points/rectangles implementing A* alghoritm
- function findRoute(start, end, map, opt) {
-
- var startDirections = opt.reversed ? opt.endDirections : opt.startDirections;
- var endDirections = opt.reversed ? opt.startDirections : opt.endDirections;
-
- // set of points we start pathfinding from
- var startSet = start instanceof g.rect
- ? getRectPoints(start, startDirections, opt)
- : [start];
-
- // set of points we want the pathfinding to finish at
- var endSet = end instanceof g.rect
- ? getRectPoints(end, endDirections, opt)
- : [end];
-
- var startCenter = startSet.length > 1 ? start.center() : startSet[0];
- var endCenter = endSet.length > 1 ? end.center() : endSet[0];
-
- // take into account only accessible end points
- var endPoints = _.filter(endSet, function(point) {
-
- var mapKey = g.point(point).snapToGrid(opt.mapGridSize).toString();
-
- var accesible = _.every(map[mapKey], function(obstacle) {
- return !obstacle.containsPoint(point);
- });
-
- return accesible;
- });
-
-
- if (endPoints.length) {
-
- var step = opt.step;
- var penalties = opt.penalties;
-
- // choose the end point with the shortest estimated path cost
- var endPoint = _.chain(endPoints).invoke('snapToGrid', step).min(function(point) {
-
- return opt.estimateCost(startCenter, point);
-
- }).value();
-
- var parents = {};
- var costFromStart = {};
- var totalCost = {};
-
- // directions
- var dirs = opt.directions;
- var dirLen = dirs.length;
- var dirHalfLen = dirLen / 2;
- var dirIndexes = opt.previousDirIndexes || {};
-
- // The set of point already evaluated.
- var closeHash = {}; // keeps only information whether a point was evaluated'
-
- // The set of tentative points to be evaluated, initially containing the start points
- var openHash = {}; // keeps only information whether a point is to be evaluated'
- var openSet = _.chain(startSet).invoke('snapToGrid', step).each(function(point) {
-
- var key = point.toString();
-
- costFromStart[key] = 0; // Cost from start along best known path.
- totalCost[key] = opt.estimateCost(point, endPoint);
- dirIndexes[key] = dirIndexes[key] || getDirection(startCenter, point, dirLen);
- openHash[key] = true;
-
- }).map(function(point) {
-
- return point.toString();
-
- }).sortBy(function(pointKey) {
-
- return totalCost[pointKey];
-
- }).value();
-
- var loopCounter = opt.maximumLoops;
-
- var maxAllowedDirectionChange = opt.maxAllowedDirectionChange;
-
- // main route finding loop
- while (openSet.length && loopCounter--) {
-
- var currentKey = openSet[0];
- var currentPoint = g.point(currentKey);
-
- if (endPoint.equals(currentPoint)) {
-
- opt.previousDirIndexes = _.pick(dirIndexes, currentKey);
- return reconstructRoute(parents, currentPoint);
- }
-
- // remove current from the open list
- openSet.splice(0, 1);
- openHash[neighborKey] = null;
-
- // add current to the close list
- closeHash[neighborKey] = true;
-
- var currentDirIndex = dirIndexes[currentKey];
- var currentDist = costFromStart[currentKey];
-
- for (var dirIndex = 0; dirIndex < dirLen; dirIndex++) {
-
- var dirChange = Math.abs(dirIndex - currentDirIndex);
-
- if (dirChange > dirHalfLen) {
-
- dirChange = dirLen - dirChange;
- }
-
- // if the direction changed rapidly don't use this point
- if (dirChange > maxAllowedDirectionChange) {
-
- continue;
- }
-
- var dir = dirs[dirIndex];
-
- var neighborPoint = g.point(currentPoint).offset(dir.offsetX, dir.offsetY);
- var neighborKey = neighborPoint.toString();
-
- if (closeHash[neighborKey]) {
-
- continue;
- }
-
- // is point accesible - no obstacle in the way
-
- var mapKey = g.point(neighborPoint).snapToGrid(opt.mapGridSize).toString();
-
- var isAccesible = _.every(map[mapKey], function(obstacle) {
- return !obstacle.containsPoint(neighborPoint);
- });
-
- if (!isAccesible) {
-
- continue;
- }
-
- var inOpenSet = _.has(openHash, neighborKey);
-
- var costToNeighbor = currentDist + dir.cost;
-
- if (!inOpenSet || costToNeighbor < costFromStart[neighborKey]) {
-
- parents[neighborKey] = currentPoint;
- dirIndexes[neighborKey] = dirIndex;
- costFromStart[neighborKey] = costToNeighbor;
-
- totalCost[neighborKey] = costToNeighbor +
- opt.estimateCost(neighborPoint, endPoint) +
- penalties[dirChange];
-
- if (!inOpenSet) {
-
- var openIndex = _.sortedIndex(openSet, neighborKey, function(openKey) {
-
- return totalCost[openKey];
- });
-
- openSet.splice(openIndex, 0, neighborKey);
- openHash[neighborKey] = true;
- }
- };
- };
- }
- }
-
- // no route found ('to' point wasn't either accessible or finding route took
- // way to much calculations)
- return opt.fallbackRoute(startCenter, endCenter, opt);
- };
-
- // initiation of the route finding
- function router(oldVertices, opt) {
-
- // resolve some of the options
- opt.directions = _.result(opt, 'directions');
- opt.penalties = _.result(opt, 'penalties');
- opt.paddingBox = _.result(opt, 'paddingBox');
-
- // enable/disable linkView perpendicular option
- this.options.perpendicular = !!opt.perpendicular;
-
- // As route changes its shape rapidly when we start finding route from different point
- // it's necessary to start from the element that was not interacted with
- // (the position was changed) at very last.
- var reverseRouting = opt.reversed = (this.lastEndChange === 'source');
-
- var sourceBBox = reverseRouting ? g.rect(this.targetBBox) : g.rect(this.sourceBBox);
- var targetBBox = reverseRouting ? g.rect(this.sourceBBox) : g.rect(this.targetBBox);
-
- // expand boxes by specific padding
- sourceBBox.moveAndExpand(opt.paddingBox);
- targetBBox.moveAndExpand(opt.paddingBox);
-
- // building an elements map
-
- var link = this.model;
- var graph = this.paper.model;
-
- // source or target element could be excluded from set of obstacles
- var excludedEnds = _.chain(opt.excludeEnds)
- .map(link.get, link)
- .pluck('id')
- .map(graph.getCell, graph).value();
-
- var mapGridSize = opt.mapGridSize;
-
- var excludeAncestors = [];
-
- var sourceId = link.get('source').id;
- if (sourceId !== undefined) {
- var source = graph.getCell(sourceId);
- if (source !== undefined) {
- excludeAncestors = _.union(excludeAncestors, _.map(source.getAncestors(), 'id'));
- };
- }
-
- var targetId = link.get('target').id;
- if (targetId !== undefined) {
- var target = graph.getCell(targetId);
- if (target !== undefined) {
- excludeAncestors = _.union(excludeAncestors, _.map(target.getAncestors(), 'id'));
- }
- }
-
- // builds a map of all elements for quicker obstacle queries (i.e. is a point contained
- // in any obstacle?) (a simplified grid search)
- // The paper is divided to smaller cells, where each of them holds an information which
- // elements belong to it. When we query whether a point is in an obstacle we don't need
- // to go through all obstacles, we check only those in a particular cell.
- var map = _.chain(graph.getElements())
- // remove source and target element if required
- .difference(excludedEnds)
- // remove all elements whose type is listed in excludedTypes array
- .reject(function(element) {
- // reject any element which is an ancestor of either source or target
- return _.contains(opt.excludeTypes, element.get('type')) || _.contains(excludeAncestors, element.id);
- })
- // change elements (models) to their bounding boxes
- .invoke('getBBox')
- // expand their boxes by specific padding
- .invoke('moveAndExpand', opt.paddingBox)
- // build the map
- .foldl(function(res, bbox) {
-
- var origin = bbox.origin().snapToGrid(mapGridSize);
- var corner = bbox.corner().snapToGrid(mapGridSize);
-
- for (var x = origin.x; x <= corner.x; x += mapGridSize) {
- for (var y = origin.y; y <= corner.y; y += mapGridSize) {
-
- var gridKey = x + '@' + y;
-
- res[gridKey] = res[gridKey] || [];
- res[gridKey].push(bbox);
- }
- }
-
- return res;
-
- }, {}).value();
-
- // pathfinding
-
- var newVertices = [];
-
- var points = _.map(oldVertices, g.point);
-
- var tailPoint = sourceBBox.center();
-
- // find a route by concating all partial routes (routes need to go through the vertices)
- // startElement -> vertex[1] -> ... -> vertex[n] -> endElement
- for (var i = 0, len = points.length; i <= len; i++) {
-
- var partialRoute = null;
-
- var from = to || sourceBBox;
- var to = points[i];
-
- if (!to) {
-
- to = targetBBox;
-
- // 'to' is not a vertex. If the target is a point (i.e. it's not an element), we
- // might use dragging route instead of main routing method if that is enabled.
- var endingAtPoint = !this.model.get('source').id || !this.model.get('target').id;
-
- if (endingAtPoint && _.isFunction(opt.draggingRoute)) {
- // Make sure we passing points only (not rects).
- var dragFrom = from instanceof g.rect ? from.center() : from;
- partialRoute = opt.draggingRoute(dragFrom, to.origin(), opt);
- }
- }
-
- // if partial route has not been calculated yet use the main routing method to find one
- partialRoute = partialRoute || findRoute(from, to, map, opt);
-
- var leadPoint = _.first(partialRoute);
-
- if (leadPoint && leadPoint.equals(tailPoint)) {
-
- // remove the first point if the previous partial route had the same point as last
- partialRoute.shift();
- }
-
- tailPoint = _.last(partialRoute) || tailPoint;
-
- newVertices = newVertices.concat(partialRoute);
- };
-
- // we might have to reverse the result if we swapped source and target at the beginning
- return reverseRouting ? newVertices.reverse() : newVertices;
- };
-
- // public function
- return function(vertices, opt, linkView) {
-
- return router.call(linkView, vertices, _.extend({}, config, opt));
- };
-
-})();
-
-joint.routers.metro = (function() {
-
- if (!_.isFunction(joint.routers.manhattan)) {
-
- throw('Metro requires the manhattan router.');
- }
-
- var config = {
-
- // cost of a diagonal step (calculated if not defined).
- diagonalCost: null,
-
- // an array of directions to find next points on the route
- directions: function() {
-
- var step = this.step;
- var diagonalCost = this.diagonalCost || Math.ceil(Math.sqrt(step * step << 1));
-
- return [
- { offsetX: step , offsetY: 0 , cost: step },
- { offsetX: step , offsetY: step , cost: diagonalCost },
- { offsetX: 0 , offsetY: step , cost: step },
- { offsetX: -step , offsetY: step , cost: diagonalCost },
- { offsetX: -step , offsetY: 0 , cost: step },
- { offsetX: -step , offsetY: -step , cost: diagonalCost },
- { offsetX: 0 , offsetY: -step , cost: step },
- { offsetX: step , offsetY: -step , cost: diagonalCost }
- ];
- },
-
- // a simple route used in situations, when main routing method fails
- // (exceed loops, inaccessible).
- fallbackRoute: function(from, to, opts) {
-
- // Find a route which breaks by 45 degrees ignoring all obstacles.
-
- var theta = from.theta(to);
-
- var a = { x: to.x, y: from.y };
- var b = { x: from.x, y: to.y };
-
- if (theta % 180 > 90) {
- var t = a;
- a = b;
- b = t;
- }
-
- var p1 = (theta % 90) < 45 ? a : b;
-
- var l1 = g.line(from, p1);
-
- var alpha = 90 * Math.ceil(theta / 90);
-
- var p2 = g.point.fromPolar(l1.squaredLength(), g.toRad(alpha + 135), p1);
-
- var l2 = g.line(to, p2);
-
- var point = l1.intersection(l2);
-
- return point ? [point.round(), to] : [to];
- }
- };
-
- // public function
- return function(vertices, opts, linkView) {
-
- return joint.routers.manhattan(vertices, _.extend({}, config, opts), linkView);
- };
-
-})();
-
-joint.connectors.normal = function(sourcePoint, targetPoint, vertices) {
-
- // Construct the `d` attribute of the `<path>` element.
- var d = ['M', sourcePoint.x, sourcePoint.y];
-
- _.each(vertices, function(vertex) {
-
- d.push(vertex.x, vertex.y);
- });
-
- d.push(targetPoint.x, targetPoint.y);
-
- return d.join(' ');
-};
-
-joint.connectors.rounded = function(sourcePoint, targetPoint, vertices, opts) {
-
- var offset = opts.radius || 10;
-
- var c1, c2, d1, d2, prev, next;
-
- // Construct the `d` attribute of the `<path>` element.
- var d = ['M', sourcePoint.x, sourcePoint.y];
-
- _.each(vertices, function(vertex, index) {
-
- // the closest vertices
- prev = vertices[index - 1] || sourcePoint;
- next = vertices[index + 1] || targetPoint;
-
- // a half distance to the closest vertex
- d1 = d2 || g.point(vertex).distance(prev) / 2;
- d2 = g.point(vertex).distance(next) / 2;
-
- // control points
- c1 = g.point(vertex).move(prev, -Math.min(offset, d1)).round();
- c2 = g.point(vertex).move(next, -Math.min(offset, d2)).round();
-
- d.push(c1.x, c1.y, 'S', vertex.x, vertex.y, c2.x, c2.y, 'L');
- });
-
- d.push(targetPoint.x, targetPoint.y);
-
- return d.join(' ');
-};
-
-joint.connectors.smooth = function(sourcePoint, targetPoint, vertices) {
-
- var d;
-
- if (vertices.length) {
-
- d = g.bezier.curveThroughPoints([sourcePoint].concat(vertices).concat([targetPoint]));
-
- } else {
- // if we have no vertices use a default cubic bezier curve, cubic bezier requires
- // two control points. The two control points are both defined with X as mid way
- // between the source and target points. SourceControlPoint Y is equal to sourcePoint Y
- // and targetControlPointY being equal to targetPointY. Handle situation were
- // sourcePointX is greater or less then targetPointX.
- var controlPointX = (sourcePoint.x < targetPoint.x)
- ? targetPoint.x - ((targetPoint.x - sourcePoint.x) / 2)
- : sourcePoint.x - ((sourcePoint.x - targetPoint.x) / 2);
-
- d = [
- 'M', sourcePoint.x, sourcePoint.y,
- 'C', controlPointX, sourcePoint.y, controlPointX, targetPoint.y,
- targetPoint.x, targetPoint.y
- ];
- }
-
- return d.join(' ');
-};
-
-
- return joint;
-
-}));
+++ /dev/null
-/*! JointJS v0.9.3 - JavaScript diagramming library 2015-05-22
-
-
-This Source Code Form is subject to the terms of the Mozilla Public
-License, v. 2.0. If a copy of the MPL was not distributed with this
-file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-
-/*
-A complete list of SVG properties that can be set through CSS is here:
-http://www.w3.org/TR/SVG/styling.html
-
-Important note: Presentation attributes have a lower precedence over CSS style rules.
-*/
-
-
-/* .viewport is a <g> node wrapping all diagram elements in the paper */
-.viewport {
- -webkit-user-select: none;
- -moz-user-select: none;
- user-select: none;
-}
-
-/*
-1. IE can't handle paths without the `d` attribute for bounding box calculation
-2. IE can't even handle 'd' attribute as a css selector (e.g path[d]) so the following rule will
- break the links rendering.
-
-path:not([d]) {
- display: none;
-}
-
-*/
-
-/* .magnet is an element that can be either source or a target of a link */
-/*
-.magnet {
- fill: black;
- fill-opacity: 0;
- stroke: black;
- stroke-width: 15;
- stroke-opacity: 0;
- pointer-events: visibleStroke;
- cursor: crosshair;
- vector-effect: non-scaling-stroke;
-}
-
-.magnet:hover {
- stroke-opacity: .5;
-}
-*/
-
-[magnet=true]:not(.element) {
- cursor: crosshair;
-}
-[magnet=true]:not(.element):hover {
- opacity: .7;
-}
-
-/*
-
-Elements have CSS classes named by their types. E.g. type: basic.Rect has a CSS class "element basic Rect".
-This makes it possible to easilly style elements in CSS and have generic CSS rules applying to
-the whole group of elements. Each plugin can provide its own stylesheet.
-
-*/
-
-.element {
- /* Give the user a hint that he can drag&drop the element. */
- cursor: move;
-}
-
-.element * {
- /* The default behavior when scaling an element is not to scale the stroke in order to prevent the ugly effect of stroke with different proportions. */
- vector-effect: non-scaling-stroke;
- -moz-user-select: none;
- user-drag: none;
-}
-
-
-/*
-
-connection-wrap is a <path> element of the joint.dia.Link that follows the .connection <path> of that link.
-In other words, the `d` attribute of the .connection-wrap contains the same data as the `d` attribute of the
-.connection <path>. The advantage of using .connection-wrap is to be able to catch pointer events
-in the neighborhood of the .connection <path>. This is especially handy if the .connection <path> is
-very thin.
-
-*/
-
-.connection-wrap {
- fill: none;
- stroke: black;
- stroke-width: 15;
- stroke-linecap: round;
- stroke-linejoin: round;
- opacity: 0;
- cursor: move;
-}
-.connection-wrap:hover {
- opacity: .4;
- stroke-opacity: .4;
-}
-
-
-.connection {
- /* stroke: black; */
- /* stroke width cannot be overriden by attribute? */
- /* stroke-width: 1; */
- fill: none;
- stroke-linejoin: round;
-}
-
-.marker-source, .marker-target {
-/* Cannot be in CSS otherwise it could not be overruled by attributes.
- fill: black;
- stroke: black;
-*/
- /* This makes the arrowheads point to the border of objects even though the transform: scale() is applied on them. */
- vector-effect: non-scaling-stroke;
-}
-
-/*
-
-Vertex markers are `<circle>` elements that appear at connection vertex positions.
-
-*/
-
-/* <g> element wrapping .marker-vertex-group. */
-.marker-vertices {
- opacity: 0;
- cursor: move;
-}
-.marker-arrowheads {
- opacity: 0;
- cursor: move;
- cursor: -webkit-grab;
- cursor: -moz-grab;
-/* display: none; */ /* setting `display: none` on .marker-arrowheads effectivelly switches of links reconnecting */
-}
-.link-tools {
- opacity: 0;
- cursor: pointer;
-}
-.link-tools .tool-options {
- display: none; /* by default, we don't display link options tool */
-}
-.link-tools .tool-remove circle {
- fill: red;
-}
-.link-tools .tool-remove path {
- fill: white;
-}
-.link:hover .marker-vertices,
-.link:hover .marker-arrowheads,
-.link:hover .link-tools {
- opacity: 1;
-}
-
-/* <circle> element inside .marker-vertex-group <g> element */
-.marker-vertex {
- fill: #1ABC9C;
-}
-.marker-vertex:hover {
- fill: #34495E;
- stroke: none;
-}
-
-.marker-arrowhead {
- fill: #1ABC9C;
-}
-.marker-arrowhead:hover {
- fill: #F39C12;
- stroke: none;
-}
-
-/* <circle> element used to remove a vertex */
-.marker-vertex-remove {
- cursor: pointer;
- opacity: .1;
- fill: white;
-}
-
-.marker-vertex-group:hover .marker-vertex-remove {
- opacity: 1;
-}
-
-.marker-vertex-remove-area {
- opacity: .1;
- cursor: pointer;
-}
-.marker-vertex-group:hover .marker-vertex-remove-area {
- opacity: 1;
-}
-
-/* Cell highlighting - e.g a cell underneath the dragged link get highlighted.
- See joint.dia.cell.js highlight(); */
-.highlighted {
- opacity: 0.7;
-}
-
-/* For some reason, CSS `outline` property
- does not work on `<text>` elements. */
-text.highlighted {
- fill: #FF0000;
-}
-
-/* `outline` doesn't work in Firefox, Opera and IE9+.
- The only engine supporting outlines on SVG elements is Webkit. */
-@media screen and (-webkit-min-device-pixel-ratio:0) {
- .highlighted {
- outline: 2px solid #FF0000;
- opacity: initial;
- }
-}
-
-/*
-Example of custom changes (in pure CSS only!):
-
-Do not show marker vertices at all: .marker-vertices { display: none; }
-Do not allow adding new vertices: .connection-wrap { pointer-events: none; }
-*/
-
-/* foreignObject inside the elements (i.e joint.shapes.basic.TextBlock) */
-.element .fobj body {
- background-color: transparent;
- margin: 0px;
-}
-.element .fobj div {
- text-align: center;
- vertical-align: middle;
- display: table-cell;
- padding: 0px 5px 0px 5px;
-}
-
-svg {
- border: none;
- border-radius: none;
- background-image: none;
-}
-
-text.text1, text.text2 {
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
- font-size: 14px;
-}
+++ /dev/null
-/**
- * @license
- * lodash 3.9.3 (Custom Build) lodash.com/license | Underscore.js 1.8.3 underscorejs.org/LICENSE
- * Build: `lodash modern -o ./lodash.js`
- */
-;(function(){function n(n,t){if(n!==t){var r=null===n,e=n===m,u=n===n,i=null===t,o=t===m,f=t===t;if(n>t&&!i||!u||r&&!o&&f||e&&f)return 1;if(n<t&&!r||!f||i&&!e&&u||o&&u)return-1}return 0}function t(n,t,r){for(var e=n.length,u=r?e:-1;r?u--:++u<e;)if(t(n[u],u,n))return u;return-1}function r(n,t,r){if(t!==t)return s(n,r);r-=1;for(var e=n.length;++r<e;)if(n[r]===t)return r;return-1}function e(n){return typeof n=="function"||false}function u(n){return typeof n=="string"?n:null==n?"":n+""}function i(n,t){for(var r=-1,e=n.length;++r<e&&-1<t.indexOf(n.charAt(r)););
-return r}function o(n,t){for(var r=n.length;r--&&-1<t.indexOf(n.charAt(r)););return r}function f(t,r){return n(t.a,r.a)||t.b-r.b}function l(n){return Nn[n]}function a(n){return Ln[n]}function c(n){return"\\"+Mn[n]}function s(n,t,r){var e=n.length;for(t+=r?0:-1;r?t--:++t<e;){var u=n[t];if(u!==u)return t}return-1}function p(n){return!!n&&typeof n=="object"}function h(n){return 160>=n&&9<=n&&13>=n||32==n||160==n||5760==n||6158==n||8192<=n&&(8202>=n||8232==n||8233==n||8239==n||8287==n||12288==n||65279==n);
-}function _(n,t){for(var r=-1,e=n.length,u=-1,i=[];++r<e;)n[r]===t&&(n[r]=L,i[++u]=r);return i}function v(n){for(var t=-1,r=n.length;++t<r&&h(n.charCodeAt(t)););return t}function g(n){for(var t=n.length;t--&&h(n.charCodeAt(t)););return t}function y(n){return zn[n]}function d(h){function Nn(n){if(p(n)&&!(Ti(n)||n instanceof Bn)){if(n instanceof zn)return n;if(ru.call(n,"__chain__")&&ru.call(n,"__wrapped__"))return Mr(n)}return new zn(n)}function Ln(){}function zn(n,t,r){this.__wrapped__=n,this.__actions__=r||[],
-this.__chain__=!!t}function Bn(n){this.__wrapped__=n,this.__actions__=null,this.__dir__=1,this.__filtered__=false,this.__iteratees__=null,this.__takeCount__=Su,this.__views__=null}function Mn(){this.__data__={}}function Pn(n){var t=n?n.length:0;for(this.data={hash:bu(null),set:new vu};t--;)this.push(n[t])}function qn(n,t){var r=n.data;return(typeof t=="string"||ve(t)?r.set.has(t):r.hash[t])?0:-1}function Dn(n,t){var r=-1,e=n.length;for(t||(t=Me(e));++r<e;)t[r]=n[r];return t}function Kn(n,t){for(var r=-1,e=n.length;++r<e&&false!==t(n[r],r,n););
-return n}function Vn(n,t){for(var r=-1,e=n.length;++r<e;)if(!t(n[r],r,n))return false;return true}function Gn(n,t){for(var r=-1,e=n.length,u=-1,i=[];++r<e;){var o=n[r];t(o,r,n)&&(i[++u]=o)}return i}function Jn(n,t){for(var r=-1,e=n.length,u=Me(e);++r<e;)u[r]=t(n[r],r,n);return u}function Xn(n,t,r,e){var u=-1,i=n.length;for(e&&i&&(r=n[++u]);++u<i;)r=t(r,n[u],u,n);return r}function Hn(n,t){for(var r=-1,e=n.length;++r<e;)if(t(n[r],r,n))return true;return false}function Qn(n,t){return n===m?t:n}function nt(n,t,r,e){
-return n!==m&&ru.call(e,r)?n:t}function tt(n,t,r){for(var e=-1,u=Ki(t),i=u.length;++e<i;){var o=u[e],f=n[o],l=r(f,t[o],o,n,t);(l===l?l===f:f!==f)&&(f!==m||o in n)||(n[o]=l)}return n}function rt(n,t){return null==t?n:ut(t,Ki(t),n)}function et(n,t){for(var r=-1,e=null==n,u=!e&&Ir(n),i=u?n.length:0,o=t.length,f=Me(o);++r<o;){var l=t[r];f[r]=u?Er(l,i)?n[l]:m:e?m:n[l]}return f}function ut(n,t,r){r||(r={});for(var e=-1,u=t.length;++e<u;){var i=t[e];r[i]=n[i]}return r}function it(n,t,r){var e=typeof n;return"function"==e?t===m?n:Mt(n,t,r):null==n?Fe:"object"==e?xt(n):t===m?Be(n):At(n,t);
-}function ot(n,t,r,e,u,i,o){var f;if(r&&(f=u?r(n,e,u):r(n)),f!==m)return f;if(!ve(n))return n;if(e=Ti(n)){if(f=jr(n),!t)return Dn(n,f)}else{var l=uu.call(n),a=l==D;if(l!=V&&l!=z&&(!a||u))return $n[l]?Or(n,l,t):u?n:{};if(f=kr(a?{}:n),!t)return rt(f,n)}for(i||(i=[]),o||(o=[]),u=i.length;u--;)if(i[u]==n)return o[u];return i.push(n),o.push(f),(e?Kn:vt)(n,function(e,u){f[u]=ot(e,t,r,u,n,i,o)}),f}function ft(n,t,r){if(typeof n!="function")throw new Je(N);return gu(function(){n.apply(m,r)},t)}function lt(n,t){
-var e=n?n.length:0,u=[];if(!e)return u;var i=-1,o=br(),f=o==r,l=f&&200<=t.length?Vu(t):null,a=t.length;l&&(o=qn,f=false,t=l);n:for(;++i<e;)if(l=n[i],f&&l===l){for(var c=a;c--;)if(t[c]===l)continue n;u.push(l)}else 0>o(t,l,0)&&u.push(l);return u}function at(n,t){var r=true;return Mu(n,function(n,e,u){return r=!!t(n,e,u)}),r}function ct(n,t,r,e){var u=e,i=u;return Mu(n,function(n,o,f){o=+t(n,o,f),(r(o,u)||o===e&&o===i)&&(u=o,i=n)}),i}function st(n,t){var r=[];return Mu(n,function(n,e,u){t(n,e,u)&&r.push(n);
-}),r}function pt(n,t,r,e){var u;return r(n,function(n,r,i){return t(n,r,i)?(u=e?r:n,false):void 0}),u}function ht(n,t,r){for(var e=-1,u=n.length,i=-1,o=[];++e<u;){var f=n[e];if(p(f)&&Ir(f)&&(r||Ti(f)||se(f))){t&&(f=ht(f,t,r));for(var l=-1,a=f.length;++l<a;)o[++i]=f[l]}else r||(o[++i]=f)}return o}function _t(n,t){qu(n,t,ke)}function vt(n,t){return qu(n,t,Ki)}function gt(n,t){return Du(n,t,Ki)}function yt(n,t){for(var r=-1,e=t.length,u=-1,i=[];++r<e;){var o=t[r];$i(n[o])&&(i[++u]=o)}return i}function dt(n,t,r){
-if(null!=n){r!==m&&r in zr(n)&&(t=[r]),r=0;for(var e=t.length;null!=n&&r<e;)n=n[t[r++]];return r&&r==e?n:m}}function mt(n,t,r,e,u,i){if(n===t)n=true;else if(null==n||null==t||!ve(n)&&!p(t))n=n!==n&&t!==t;else n:{var o=mt,f=Ti(n),l=Ti(t),a=B,c=B;f||(a=uu.call(n),a==z?a=V:a!=V&&(f=we(n))),l||(c=uu.call(t),c==z?c=V:c!=V&&we(t));var s=a==V,l=c==V,c=a==c;if(!c||f||s){if(!e&&(a=s&&ru.call(n,"__wrapped__"),l=l&&ru.call(t,"__wrapped__"),a||l)){n=o(a?n.value():n,l?t.value():t,r,e,u,i);break n}if(c){for(u||(u=[]),
-i||(i=[]),a=u.length;a--;)if(u[a]==n){n=i[a]==t;break n}u.push(n),i.push(t),n=(f?gr:dr)(n,t,o,r,e,u,i),u.pop(),i.pop()}else n=false}else n=yr(n,t,a)}return n}function wt(n,t,r){var e=t.length,u=e,i=!r;if(null==n)return!u;for(n=zr(n);e--;){var o=t[e];if(i&&o[2]?o[1]!==n[o[0]]:!(o[0]in n))return false}for(;++e<u;){var o=t[e],f=o[0],l=n[f],a=o[1];if(i&&o[2]){if(l===m&&!(f in n))return false}else if(o=r?r(l,a,f):m,o===m?!mt(a,l,r,true):!o)return false}return true}function bt(n,t){var r=-1,e=Ir(n)?Me(n.length):[];return Mu(n,function(n,u,i){
-e[++r]=t(n,u,i)}),e}function xt(n){var t=xr(n);if(1==t.length&&t[0][2]){var r=t[0][0],e=t[0][1];return function(n){return null==n?false:n[r]===e&&(e!==m||r in zr(n))}}return function(n){return wt(n,t)}}function At(n,t){var r=Ti(n),e=Wr(n)&&t===t&&!ve(t),u=n+"";return n=Br(n),function(i){if(null==i)return false;var o=u;if(i=zr(i),!(!r&&e||o in i)){if(i=1==n.length?i:dt(i,Ct(n,0,-1)),null==i)return false;o=Vr(n),i=zr(i)}return i[o]===t?t!==m||o in i:mt(t,i[o],m,true)}}function jt(n,t,r,e,u){if(!ve(n))return n;var i=Ir(t)&&(Ti(t)||we(t)),o=i?null:Ki(t);
-return Kn(o||t,function(f,l){if(o&&(l=f,f=t[l]),p(f)){e||(e=[]),u||(u=[]);n:{for(var a=l,c=e,s=u,h=c.length,_=t[a];h--;)if(c[h]==_){n[a]=s[h];break n}var h=n[a],v=r?r(h,_,a,n,t):m,g=v===m;g&&(v=_,Ir(_)&&(Ti(_)||we(_))?v=Ti(h)?h:Ir(h)?Dn(h):[]:Fi(_)||se(_)?v=se(h)?Ae(h):Fi(h)?h:{}:g=false),c.push(_),s.push(v),g?n[a]=jt(v,_,r,c,s):(v===v?v!==h:h===h)&&(n[a]=v)}}else a=n[l],c=r?r(a,f,l,n,t):m,(s=c===m)&&(c=f),c===m&&(!i||l in n)||!s&&(c===c?c===a:a!==a)||(n[l]=c)}),n}function kt(n){return function(t){return null==t?m:t[n];
-}}function Ot(n){var t=n+"";return n=Br(n),function(r){return dt(r,n,t)}}function Rt(n,t){for(var r=n?t.length:0;r--;){var e=t[r];if(e!=u&&Er(e)){var u=e;yu.call(n,e,1)}}}function It(n,t){return n+su(Cu()*(t-n+1))}function Et(n,t,r,e,u){return u(n,function(n,u,i){r=e?(e=false,n):t(r,n,u,i)}),r}function Ct(n,t,r){var e=-1,u=n.length;for(t=null==t?0:+t||0,0>t&&(t=-t>u?0:u+t),r=r===m||r>u?u:+r||0,0>r&&(r+=u),u=t>r?0:r-t>>>0,t>>>=0,r=Me(u);++e<u;)r[e]=n[e+t];return r}function Wt(n,t){var r;return Mu(n,function(n,e,u){
-return r=t(n,e,u),!r}),!!r}function St(n,t){var r=n.length;for(n.sort(t);r--;)n[r]=n[r].c;return n}function Tt(t,r,e){var u=mr(),i=-1;return r=Jn(r,function(n){return u(n)}),t=bt(t,function(n){return{a:Jn(r,function(t){return t(n)}),b:++i,c:n}}),St(t,function(t,r){var u;n:{u=-1;for(var i=t.a,o=r.a,f=i.length,l=e.length;++u<f;){var a=n(i[u],o[u]);if(a){u=u<l?a*(e[u]?1:-1):a;break n}}u=t.b-r.b}return u})}function Ut(n,t){var r=0;return Mu(n,function(n,e,u){r+=+t(n,e,u)||0}),r}function $t(n,t){var e=-1,u=br(),i=n.length,o=u==r,f=o&&200<=i,l=f?Vu():null,a=[];
-l?(u=qn,o=false):(f=false,l=t?[]:a);n:for(;++e<i;){var c=n[e],s=t?t(c,e,n):c;if(o&&c===c){for(var p=l.length;p--;)if(l[p]===s)continue n;t&&l.push(s),a.push(c)}else 0>u(l,s,0)&&((t||f)&&l.push(s),a.push(c))}return a}function Ft(n,t){for(var r=-1,e=t.length,u=Me(e);++r<e;)u[r]=n[t[r]];return u}function Nt(n,t,r,e){for(var u=n.length,i=e?u:-1;(e?i--:++i<u)&&t(n[i],i,n););return r?Ct(n,e?0:i,e?i+1:u):Ct(n,e?i+1:0,e?u:i)}function Lt(n,t){var r=n;r instanceof Bn&&(r=r.value());for(var e=-1,u=t.length;++e<u;){
-var r=[r],i=t[e];_u.apply(r,i.args),r=i.func.apply(i.thisArg,r)}return r}function zt(n,t,r){var e=0,u=n?n.length:e;if(typeof t=="number"&&t===t&&u<=Uu){for(;e<u;){var i=e+u>>>1,o=n[i];(r?o<=t:o<t)&&null!==o?e=i+1:u=i}return u}return Bt(n,t,Fe,r)}function Bt(n,t,r,e){t=r(t);for(var u=0,i=n?n.length:0,o=t!==t,f=null===t,l=t===m;u<i;){var a=su((u+i)/2),c=r(n[a]),s=c!==m,p=c===c;(o?p||e:f?p&&s&&(e||null!=c):l?p&&(e||s):null==c?0:e?c<=t:c<t)?u=a+1:i=a}return Ou(i,Tu)}function Mt(n,t,r){if(typeof n!="function")return Fe;
-if(t===m)return n;switch(r){case 1:return function(r){return n.call(t,r)};case 3:return function(r,e,u){return n.call(t,r,e,u)};case 4:return function(r,e,u,i){return n.call(t,r,e,u,i)};case 5:return function(r,e,u,i,o){return n.call(t,r,e,u,i,o)}}return function(){return n.apply(t,arguments)}}function Pt(n){return lu.call(n,0)}function qt(n,t,r){for(var e=r.length,u=-1,i=ku(n.length-e,0),o=-1,f=t.length,l=Me(i+f);++o<f;)l[o]=t[o];for(;++u<e;)l[r[u]]=n[u];for(;i--;)l[o++]=n[u++];return l}function Dt(n,t,r){
-for(var e=-1,u=r.length,i=-1,o=ku(n.length-u,0),f=-1,l=t.length,a=Me(o+l);++i<o;)a[i]=n[i];for(o=i;++f<l;)a[o+f]=t[f];for(;++e<u;)a[o+r[e]]=n[i++];return a}function Kt(n,t){return function(r,e,u){var i=t?t():{};if(e=mr(e,u,3),Ti(r)){u=-1;for(var o=r.length;++u<o;){var f=r[u];n(i,f,e(f,u,r),r)}}else Mu(r,function(t,r,u){n(i,t,e(t,r,u),u)});return i}}function Vt(n){return ae(function(t,r){var e=-1,u=null==t?0:r.length,i=2<u?r[u-2]:m,o=2<u?r[2]:m,f=1<u?r[u-1]:m;for(typeof i=="function"?(i=Mt(i,f,5),
-u-=2):(i=typeof f=="function"?f:m,u-=i?1:0),o&&Cr(r[0],r[1],o)&&(i=3>u?m:i,u=1);++e<u;)(o=r[e])&&n(t,o,i);return t})}function Yt(n,t){return function(r,e){var u=r?Zu(r):0;if(!Tr(u))return n(r,e);for(var i=t?u:-1,o=zr(r);(t?i--:++i<u)&&false!==e(o[i],i,o););return r}}function Zt(n){return function(t,r,e){var u=zr(t);e=e(t);for(var i=e.length,o=n?i:-1;n?o--:++o<i;){var f=e[o];if(false===r(u[f],f,u))break}return t}}function Gt(n,t){function r(){return(this&&this!==Yn&&this instanceof r?e:n).apply(t,arguments);
-}var e=Xt(n);return r}function Jt(n){return function(t){var r=-1;t=Te(Ie(t));for(var e=t.length,u="";++r<e;)u=n(u,t[r],r);return u}}function Xt(n){return function(){var t=arguments;switch(t.length){case 0:return new n;case 1:return new n(t[0]);case 2:return new n(t[0],t[1]);case 3:return new n(t[0],t[1],t[2]);case 4:return new n(t[0],t[1],t[2],t[3]);case 5:return new n(t[0],t[1],t[2],t[3],t[4])}var r=Bu(n.prototype),t=n.apply(r,t);return ve(t)?t:r}}function Ht(n){function t(r,e,u){return u&&Cr(r,e,u)&&(e=null),
-r=vr(r,n,null,null,null,null,null,e),r.placeholder=t.placeholder,r}return t}function Qt(n,t){return function(r,e,u){if(u&&Cr(r,e,u)&&(e=null),e=mr(e,u,3),1==e.length){u=r=Lr(r);for(var i=e,o=-1,f=u.length,l=t,a=l;++o<f;){var c=u[o],s=+i(c);n(s,l)&&(l=s,a=c)}if(u=a,!r.length||u!==t)return u}return ct(r,e,n,t)}}function nr(n,r){return function(e,u,i){return u=mr(u,i,3),Ti(e)?(u=t(e,u,r),-1<u?e[u]:m):pt(e,u,n)}}function tr(n){return function(r,e,u){return r&&r.length?(e=mr(e,u,3),t(r,e,n)):-1}}function rr(n){
-return function(t,r,e){return r=mr(r,e,3),pt(t,r,n,true)}}function er(n){return function(){for(var t,r=arguments.length,e=n?r:-1,u=0,i=Me(r);n?e--:++e<r;){var o=i[u++]=arguments[e];if(typeof o!="function")throw new Je(N);!t&&zn.prototype.thru&&"wrapper"==wr(o)&&(t=new zn([]))}for(e=t?-1:r;++e<r;){var o=i[e],u=wr(o),f="wrapper"==u?Yu(o):null;t=f&&Sr(f[0])&&f[1]==(I|j|O|E)&&!f[4].length&&1==f[9]?t[wr(f[0])].apply(t,f[3]):1==o.length&&Sr(o)?t[u]():t.thru(o)}return function(){var n=arguments;if(t&&1==n.length&&Ti(n[0]))return t.plant(n[0]).value();
-for(var e=0,n=r?i[e].apply(this,n):n[0];++e<r;)n=i[e].call(this,n);return n}}}function ur(n,t){return function(r,e,u){return typeof e=="function"&&u===m&&Ti(r)?n(r,e):t(r,Mt(e,u,3))}}function ir(n){return function(t,r,e){return(typeof r!="function"||e!==m)&&(r=Mt(r,e,3)),n(t,r,ke)}}function or(n){return function(t,r,e){return(typeof r!="function"||e!==m)&&(r=Mt(r,e,3)),n(t,r)}}function fr(n){return function(t,r,e){var u={};return r=mr(r,e,3),vt(t,function(t,e,i){i=r(t,e,i),e=n?i:e,t=n?t:i,u[e]=t}),
-u}}function lr(n){return function(t,r,e){return t=u(t),(n?t:"")+pr(t,r,e)+(n?"":t)}}function ar(n){var t=ae(function(r,e){var u=_(e,t.placeholder);return vr(r,n,null,e,u)});return t}function cr(n,t){return function(r,e,u,i){var o=3>arguments.length;return typeof e=="function"&&i===m&&Ti(r)?n(r,e,u,o):Et(r,mr(e,i,4),u,o,t)}}function sr(n,t,r,e,u,i,o,f,l,a){function c(){for(var w=arguments.length,A=w,j=Me(w);A--;)j[A]=arguments[A];if(e&&(j=qt(j,e,u)),i&&(j=Dt(j,i,o)),v||y){var A=c.placeholder,k=_(j,A),w=w-k.length;
-if(w<a){var I=f?Dn(f):null,w=ku(a-w,0),E=v?k:null,k=v?null:k,C=v?j:null,j=v?null:j;return t|=v?O:R,t&=~(v?R:O),g||(t&=~(b|x)),j=[n,t,r,C,E,j,k,I,l,w],I=sr.apply(m,j),Sr(n)&&Gu(I,j),I.placeholder=A,I}}if(A=p?r:this,I=h?A[n]:n,f)for(w=j.length,E=Ou(f.length,w),k=Dn(j);E--;)C=f[E],j[E]=Er(C,w)?k[C]:m;return s&&l<j.length&&(j.length=l),this&&this!==Yn&&this instanceof c&&(I=d||Xt(n)),I.apply(A,j)}var s=t&I,p=t&b,h=t&x,v=t&j,g=t&A,y=t&k,d=h?null:Xt(n);return c}function pr(n,t,r){return n=n.length,t=+t,
-n<t&&Au(t)?(t-=n,r=null==r?" ":r+"",We(r,au(t/r.length)).slice(0,t)):""}function hr(n,t,r,e){function u(){for(var t=-1,f=arguments.length,l=-1,a=e.length,c=Me(f+a);++l<a;)c[l]=e[l];for(;f--;)c[l++]=arguments[++t];return(this&&this!==Yn&&this instanceof u?o:n).apply(i?r:this,c)}var i=t&b,o=Xt(n);return u}function _r(n){return function(t,r,e,u){var i=mr(e);return null==e&&i===it?zt(t,r,n):Bt(t,r,i(e,u,1),n)}}function vr(n,t,r,e,u,i,o,f){var l=t&x;if(!l&&typeof n!="function")throw new Je(N);var a=e?e.length:0;
-if(a||(t&=~(O|R),e=u=null),a-=u?u.length:0,t&R){var c=e,s=u;e=u=null}var p=l?null:Yu(n);return r=[n,t,r,e,u,c,s,i,o,f],p&&(e=r[1],t=p[1],f=e|t,u=t==I&&e==j||t==I&&e==E&&r[7].length<=p[8]||t==(I|E)&&e==j,(f<I||u)&&(t&b&&(r[2]=p[2],f|=e&b?0:A),(e=p[3])&&(u=r[3],r[3]=u?qt(u,e,p[4]):Dn(e),r[4]=u?_(r[3],L):Dn(p[4])),(e=p[5])&&(u=r[5],r[5]=u?Dt(u,e,p[6]):Dn(e),r[6]=u?_(r[5],L):Dn(p[6])),(e=p[7])&&(r[7]=Dn(e)),t&I&&(r[8]=null==r[8]?p[8]:Ou(r[8],p[8])),null==r[9]&&(r[9]=p[9]),r[0]=p[0],r[1]=f),t=r[1],f=r[9]),
-r[9]=null==f?l?0:n.length:ku(f-a,0)||0,(p?Ku:Gu)(t==b?Gt(r[0],r[2]):t!=O&&t!=(b|O)||r[4].length?sr.apply(m,r):hr.apply(m,r),r)}function gr(n,t,r,e,u,i,o){var f=-1,l=n.length,a=t.length;if(l!=a&&(!u||a<=l))return false;for(;++f<l;){var c=n[f],a=t[f],s=e?e(u?a:c,u?c:a,f):m;if(s!==m){if(s)continue;return false}if(u){if(!Hn(t,function(n){return c===n||r(c,n,e,u,i,o)}))return false}else if(c!==a&&!r(c,a,e,u,i,o))return false}return true}function yr(n,t,r){switch(r){case M:case P:return+n==+t;case q:return n.name==t.name&&n.message==t.message;
-case K:return n!=+n?t!=+t:n==+t;case Y:case Z:return n==t+""}return false}function dr(n,t,r,e,u,i,o){var f=Ki(n),l=f.length,a=Ki(t).length;if(l!=a&&!u)return false;for(a=l;a--;){var c=f[a];if(!(u?c in t:ru.call(t,c)))return false}for(var s=u;++a<l;){var c=f[a],p=n[c],h=t[c],_=e?e(u?h:p,u?p:h,c):m;if(_===m?!r(p,h,e,u,i,o):!_)return false;s||(s="constructor"==c)}return s||(r=n.constructor,e=t.constructor,!(r!=e&&"constructor"in n&&"constructor"in t)||typeof r=="function"&&r instanceof r&&typeof e=="function"&&e instanceof e)?true:false;
-}function mr(n,t,r){var e=Nn.callback||Ue,e=e===Ue?it:e;return r?e(n,t,r):e}function wr(n){for(var t=n.name,r=Lu[t],e=r?r.length:0;e--;){var u=r[e],i=u.func;if(null==i||i==n)return u.name}return t}function br(n,t,e){var u=Nn.indexOf||Kr,u=u===Kr?r:u;return n?u(n,t,e):u}function xr(n){n=Oe(n);for(var t=n.length;t--;){var r=n[t][1];n[t][2]=r===r&&!ve(r)}return n}function Ar(n,t){var r=null==n?m:n[t];return ge(r)?r:m}function jr(n){var t=n.length,r=new n.constructor(t);return t&&"string"==typeof n[0]&&ru.call(n,"index")&&(r.index=n.index,
-r.input=n.input),r}function kr(n){return n=n.constructor,typeof n=="function"&&n instanceof n||(n=Ye),new n}function Or(n,t,r){var e=n.constructor;switch(t){case G:return Pt(n);case M:case P:return new e(+n);case J:case X:case H:case Q:case nn:case tn:case rn:case en:case un:return t=n.buffer,new e(r?Pt(t):t,n.byteOffset,n.length);case K:case Z:return new e(n);case Y:var u=new e(n.source,jn.exec(n));u.lastIndex=n.lastIndex}return u}function Rr(n,t,r){return null==n||Wr(t,n)||(t=Br(t),n=1==t.length?n:dt(n,Ct(t,0,-1)),
-t=Vr(t)),t=null==n?n:n[t],null==t?m:t.apply(n,r)}function Ir(n){return null!=n&&Tr(Zu(n))}function Er(n,t){return n=typeof n=="number"||Rn.test(n)?+n:-1,t=null==t?Fu:t,-1<n&&0==n%1&&n<t}function Cr(n,t,r){if(!ve(r))return false;var e=typeof t;return("number"==e?Ir(r)&&Er(t,r.length):"string"==e&&t in r)?(t=r[t],n===n?n===t:t!==t):false}function Wr(n,t){var r=typeof n;return"string"==r&&yn.test(n)||"number"==r?true:Ti(n)?false:!gn.test(n)||null!=t&&n in zr(t)}function Sr(n){var t=wr(n);return t in Bn.prototype?(t=Nn[t],
-n===t?true:(t=Yu(t),!!t&&n===t[0])):false}function Tr(n){return typeof n=="number"&&-1<n&&0==n%1&&n<=Fu}function Ur(n,t){n=zr(n);for(var r=-1,e=t.length,u={};++r<e;){var i=t[r];i in n&&(u[i]=n[i])}return u}function $r(n,t){var r={};return _t(n,function(n,e,u){t(n,e,u)&&(r[e]=n)}),r}function Fr(n){var t;if(!p(n)||uu.call(n)!=V||!(ru.call(n,"constructor")||(t=n.constructor,typeof t!="function"||t instanceof t)))return false;var r;return _t(n,function(n,t){r=t}),r===m||ru.call(n,r)}function Nr(n){for(var t=ke(n),r=t.length,e=r&&n.length,u=!!e&&Tr(e)&&(Ti(n)||se(n)),i=-1,o=[];++i<r;){
-var f=t[i];(u&&Er(f,e)||ru.call(n,f))&&o.push(f)}return o}function Lr(n){return null==n?[]:Ir(n)?ve(n)?n:Ye(n):Re(n)}function zr(n){return ve(n)?n:Ye(n)}function Br(n){if(Ti(n))return n;var t=[];return u(n).replace(dn,function(n,r,e,u){t.push(e?u.replace(xn,"$1"):r||n)}),t}function Mr(n){return n instanceof Bn?n.clone():new zn(n.__wrapped__,n.__chain__,Dn(n.__actions__))}function Pr(n,t,r){return n&&n.length?((r?Cr(n,t,r):null==t)&&(t=1),Ct(n,0>t?0:t)):[]}function qr(n,t,r){var e=n?n.length:0;return e?((r?Cr(n,t,r):null==t)&&(t=1),
-t=e-(+t||0),Ct(n,0,0>t?0:t)):[]}function Dr(n){return n?n[0]:m}function Kr(n,t,e){var u=n?n.length:0;if(!u)return-1;if(typeof e=="number")e=0>e?ku(u+e,0):e;else if(e)return e=zt(n,t),n=n[e],(t===t?t===n:n!==n)?e:-1;return r(n,t,e||0)}function Vr(n){var t=n?n.length:0;return t?n[t-1]:m}function Yr(n){return Pr(n,1)}function Zr(n,t,e,u){if(!n||!n.length)return[];null!=t&&typeof t!="boolean"&&(u=e,e=Cr(n,t,u)?null:t,t=false);var i=mr();if((null!=e||i!==it)&&(e=i(e,u,3)),t&&br()==r){t=e;var o;e=-1,u=n.length;
-for(var i=-1,f=[];++e<u;){var l=n[e],a=t?t(l,e,n):l;e&&o===a||(o=a,f[++i]=l)}n=f}else n=$t(n,e);return n}function Gr(n){if(!n||!n.length)return[];var t=-1,r=0;n=Gn(n,function(n){return Ir(n)?(r=ku(n.length,r),true):void 0});for(var e=Me(r);++t<r;)e[t]=Jn(n,kt(t));return e}function Jr(n,t,r){return n&&n.length?(n=Gr(n),null==t?n:(t=Mt(t,r,4),Jn(n,function(n){return Xn(n,t,m,true)}))):[]}function Xr(n,t){var r=-1,e=n?n.length:0,u={};for(!e||t||Ti(n[0])||(t=[]);++r<e;){var i=n[r];t?u[i]=t[r]:i&&(u[i[0]]=i[1]);
-}return u}function Hr(n){return n=Nn(n),n.__chain__=true,n}function Qr(n,t,r){return t.call(r,n)}function ne(n,t,r){var e=Ti(n)?Vn:at;return r&&Cr(n,t,r)&&(t=null),(typeof t!="function"||r!==m)&&(t=mr(t,r,3)),e(n,t)}function te(n,t,r){var e=Ti(n)?Gn:st;return t=mr(t,r,3),e(n,t)}function re(n,t,r,e){var u=n?Zu(n):0;return Tr(u)||(n=Re(n),u=n.length),u?(r=typeof r!="number"||e&&Cr(t,r,e)?0:0>r?ku(u+r,0):r||0,typeof n=="string"||!Ti(n)&&me(n)?r<u&&-1<n.indexOf(t,r):-1<br(n,t,r)):false}function ee(n,t,r){
-var e=Ti(n)?Jn:bt;return t=mr(t,r,3),e(n,t)}function ue(n,t,r){if(r?Cr(n,t,r):null==t){n=Lr(n);var e=n.length;return 0<e?n[It(0,e-1)]:m}r=-1,n=xe(n);var e=n.length,u=e-1;for(t=Ou(0>t?0:+t||0,e);++r<t;){var e=It(r,u),i=n[e];n[e]=n[r],n[r]=i}return n.length=t,n}function ie(n,t,r){var e=Ti(n)?Hn:Wt;return r&&Cr(n,t,r)&&(t=null),(typeof t!="function"||r!==m)&&(t=mr(t,r,3)),e(n,t)}function oe(n,t){var r;if(typeof t!="function"){if(typeof n!="function")throw new Je(N);var e=n;n=t,t=e}return function(){
-return 0<--n&&(r=t.apply(this,arguments)),1>=n&&(t=null),r}}function fe(n,t,r){function e(){var r=t-(wi()-a);0>=r||r>t?(f&&cu(f),r=p,f=s=p=m,r&&(h=wi(),l=n.apply(c,o),s||f||(o=c=null))):s=gu(e,r)}function u(){s&&cu(s),f=s=p=m,(v||_!==t)&&(h=wi(),l=n.apply(c,o),s||f||(o=c=null))}function i(){if(o=arguments,a=wi(),c=this,p=v&&(s||!g),false===_)var r=g&&!s;else{f||g||(h=a);var i=_-(a-h),y=0>=i||i>_;y?(f&&(f=cu(f)),h=a,l=n.apply(c,o)):f||(f=gu(u,i))}return y&&s?s=cu(s):s||t===_||(s=gu(e,t)),r&&(y=true,l=n.apply(c,o)),
-!y||s||f||(o=c=null),l}var o,f,l,a,c,s,p,h=0,_=false,v=true;if(typeof n!="function")throw new Je(N);if(t=0>t?0:+t||0,true===r)var g=true,v=false;else ve(r)&&(g=r.leading,_="maxWait"in r&&ku(+r.maxWait||0,t),v="trailing"in r?r.trailing:v);return i.cancel=function(){s&&cu(s),f&&cu(f),f=s=p=m},i}function le(n,t){function r(){var e=arguments,u=t?t.apply(this,e):e[0],i=r.cache;return i.has(u)?i.get(u):(e=n.apply(this,e),r.cache=i.set(u,e),e)}if(typeof n!="function"||t&&typeof t!="function")throw new Je(N);return r.cache=new le.Cache,
-r}function ae(n,t){if(typeof n!="function")throw new Je(N);return t=ku(t===m?n.length-1:+t||0,0),function(){for(var r=arguments,e=-1,u=ku(r.length-t,0),i=Me(u);++e<u;)i[e]=r[t+e];switch(t){case 0:return n.call(this,i);case 1:return n.call(this,r[0],i);case 2:return n.call(this,r[0],r[1],i)}for(u=Me(t+1),e=-1;++e<t;)u[e]=r[e];return u[t]=i,n.apply(this,u)}}function ce(n,t){return n>t}function se(n){return p(n)&&Ir(n)&&uu.call(n)==z}function pe(n){return!!n&&1===n.nodeType&&p(n)&&-1<uu.call(n).indexOf("Element");
-}function he(n,t,r,e){return e=(r=typeof r=="function"?Mt(r,e,3):m)?r(n,t):m,e===m?mt(n,t,r):!!e}function _e(n){return p(n)&&typeof n.message=="string"&&uu.call(n)==q}function ve(n){var t=typeof n;return!!n&&("object"==t||"function"==t)}function ge(n){return null==n?false:uu.call(n)==D?ou.test(tu.call(n)):p(n)&&On.test(n)}function ye(n){return typeof n=="number"||p(n)&&uu.call(n)==K}function de(n){return p(n)&&uu.call(n)==Y}function me(n){return typeof n=="string"||p(n)&&uu.call(n)==Z}function we(n){return p(n)&&Tr(n.length)&&!!Un[uu.call(n)];
-}function be(n,t){return n<t}function xe(n){var t=n?Zu(n):0;return Tr(t)?t?Dn(n):[]:Re(n)}function Ae(n){return ut(n,ke(n))}function je(n){return yt(n,ke(n))}function ke(n){if(null==n)return[];ve(n)||(n=Ye(n));for(var t=n.length,t=t&&Tr(t)&&(Ti(n)||se(n))&&t||0,r=n.constructor,e=-1,r=typeof r=="function"&&r.prototype===n,u=Me(t),i=0<t;++e<t;)u[e]=e+"";for(var o in n)i&&Er(o,t)||"constructor"==o&&(r||!ru.call(n,o))||u.push(o);return u}function Oe(n){n=zr(n);for(var t=-1,r=Ki(n),e=r.length,u=Me(e);++t<e;){
-var i=r[t];u[t]=[i,n[i]]}return u}function Re(n){return Ft(n,Ki(n))}function Ie(n){return(n=u(n))&&n.replace(In,l).replace(bn,"")}function Ee(n){return(n=u(n))&&wn.test(n)?n.replace(mn,"\\$&"):n}function Ce(n,t,r){return r&&Cr(n,t,r)&&(t=0),Eu(n,t)}function We(n,t){var r="";if(n=u(n),t=+t,1>t||!n||!Au(t))return r;do t%2&&(r+=n),t=su(t/2),n+=n;while(t);return r}function Se(n,t,r){var e=n;return(n=u(n))?(r?Cr(e,t,r):null==t)?n.slice(v(n),g(n)+1):(t+="",n.slice(i(n,t),o(n,t)+1)):n}function Te(n,t,r){
-return r&&Cr(n,t,r)&&(t=null),n=u(n),n.match(t||Wn)||[]}function Ue(n,t,r){return r&&Cr(n,t,r)&&(t=null),p(n)?Ne(n):it(n,t)}function $e(n){return function(){return n}}function Fe(n){return n}function Ne(n){return xt(ot(n,true))}function Le(n,t,r){if(null==r){var e=ve(t),u=e?Ki(t):null;((u=u&&u.length?yt(t,u):null)?u.length:e)||(u=false,r=t,t=n,n=this)}u||(u=yt(t,Ki(t)));var i=true,e=-1,o=$i(n),f=u.length;false===r?i=false:ve(r)&&"chain"in r&&(i=r.chain);for(;++e<f;){r=u[e];var l=t[r];n[r]=l,o&&(n.prototype[r]=function(t){
-return function(){var r=this.__chain__;if(i||r){var e=n(this.__wrapped__);return(e.__actions__=Dn(this.__actions__)).push({func:t,args:arguments,thisArg:n}),e.__chain__=r,e}return r=[this.value()],_u.apply(r,arguments),t.apply(n,r)}}(l))}return n}function ze(){}function Be(n){return Wr(n)?kt(n):Ot(n)}h=h?Zn.defaults(Yn.Object(),h,Zn.pick(Yn,Tn)):Yn;var Me=h.Array,Pe=h.Date,qe=h.Error,De=h.Function,Ke=h.Math,Ve=h.Number,Ye=h.Object,Ze=h.RegExp,Ge=h.String,Je=h.TypeError,Xe=Me.prototype,He=Ye.prototype,Qe=Ge.prototype,nu=(nu=h.window)?nu.document:null,tu=De.prototype.toString,ru=He.hasOwnProperty,eu=0,uu=He.toString,iu=h._,ou=Ze("^"+Ee(tu.call(ru)).replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g,"$1.*?")+"$"),fu=Ar(h,"ArrayBuffer"),lu=Ar(fu&&new fu(0),"slice"),au=Ke.ceil,cu=h.clearTimeout,su=Ke.floor,pu=Ar(Ye,"getPrototypeOf"),hu=h.parseFloat,_u=Xe.push,vu=Ar(h,"Set"),gu=h.setTimeout,yu=Xe.splice,du=Ar(h,"Uint8Array"),mu=Ar(h,"WeakMap"),wu=function(){
-try{var n=Ar(h,"Float64Array"),t=new n(new fu(10),0,1)&&n}catch(r){}return t||null}(),bu=Ar(Ye,"create"),xu=Ar(Me,"isArray"),Au=h.isFinite,ju=Ar(Ye,"keys"),ku=Ke.max,Ou=Ke.min,Ru=Ar(Pe,"now"),Iu=Ar(Ve,"isFinite"),Eu=h.parseInt,Cu=Ke.random,Wu=Ve.NEGATIVE_INFINITY,Su=Ve.POSITIVE_INFINITY,Tu=4294967294,Uu=2147483647,$u=wu?wu.BYTES_PER_ELEMENT:0,Fu=9007199254740991,Nu=mu&&new mu,Lu={},zu=Nn.support={};!function(n){function t(){this.x=n}var r=[];t.prototype={valueOf:n,y:n};for(var e in new t)r.push(e);
-try{zu.dom=11===nu.createDocumentFragment().nodeType}catch(u){zu.dom=false}}(1,0),Nn.templateSettings={escape:hn,evaluate:_n,interpolate:vn,variable:"",imports:{_:Nn}};var Bu=function(){function n(){}return function(t){if(ve(t)){n.prototype=t;var r=new n;n.prototype=null}return r||{}}}(),Mu=Yt(vt),Pu=Yt(gt,true),qu=Zt(),Du=Zt(true),Ku=Nu?function(n,t){return Nu.set(n,t),n}:Fe;lu||(Pt=fu&&du?function(n){var t=n.byteLength,r=wu?su(t/$u):0,e=r*$u,u=new fu(t);if(r){var i=new wu(u,0,r);i.set(new wu(n,0,r))}return t!=e&&(i=new du(u,e),
-i.set(new du(n,e))),u}:$e(null));var Vu=bu&&vu?function(n){return new Pn(n)}:$e(null),Yu=Nu?function(n){return Nu.get(n)}:ze,Zu=kt("length"),Gu=function(){var n=0,t=0;return function(r,e){var u=wi(),i=T-(u-t);if(t=u,0<i){if(++n>=S)return r}else n=0;return Ku(r,e)}}(),Ju=ae(function(n,t){return Ir(n)?lt(n,ht(t,false,true)):[]}),Xu=tr(),Hu=tr(true),Qu=ae(function(n){for(var t=n.length,e=t,u=Me(c),i=br(),o=i==r,f=[];e--;){var l=n[e]=Ir(l=n[e])?l:[];u[e]=o&&120<=l.length?Vu(e&&l):null}var o=n[0],a=-1,c=o?o.length:0,s=u[0];
-n:for(;++a<c;)if(l=o[a],0>(s?qn(s,l):i(f,l,0))){for(e=t;--e;){var p=u[e];if(0>(p?qn(p,l):i(n[e],l,0)))continue n}s&&s.push(l),f.push(l)}return f}),ni=ae(function(t,r){r=ht(r);var e=et(t,r);return Rt(t,r.sort(n)),e}),ti=_r(),ri=_r(true),ei=ae(function(n){return $t(ht(n,false,true))}),ui=ae(function(n,t){return Ir(n)?lt(n,t):[]}),ii=ae(Gr),oi=ae(function(n){var t=n.length,r=2<t?n[t-2]:m,e=1<t?n[t-1]:m;return 2<t&&typeof r=="function"?t-=2:(r=1<t&&typeof e=="function"?(--t,e):m,e=m),n.length=t,Jr(n,r,e)}),fi=ae(function(n,t){
-return et(n,ht(t))}),li=Kt(function(n,t,r){ru.call(n,r)?++n[r]:n[r]=1}),ai=nr(Mu),ci=nr(Pu,true),si=ur(Kn,Mu),pi=ur(function(n,t){for(var r=n.length;r--&&false!==t(n[r],r,n););return n},Pu),hi=Kt(function(n,t,r){ru.call(n,r)?n[r].push(t):n[r]=[t]}),_i=Kt(function(n,t,r){n[r]=t}),vi=ae(function(n,t,r){var e=-1,u=typeof t=="function",i=Wr(t),o=Ir(n)?Me(n.length):[];return Mu(n,function(n){var f=u?t:i&&null!=n?n[t]:null;o[++e]=f?f.apply(n,r):Rr(n,t,r)}),o}),gi=Kt(function(n,t,r){n[r?0:1].push(t)},function(){
-return[[],[]]}),yi=cr(Xn,Mu),di=cr(function(n,t,r,e){var u=n.length;for(e&&u&&(r=n[--u]);u--;)r=t(r,n[u],u,n);return r},Pu),mi=ae(function(n,t){if(null==n)return[];var r=t[2];return r&&Cr(t[0],t[1],r)&&(t.length=1),Tt(n,ht(t),[])}),wi=Ru||function(){return(new Pe).getTime()},bi=ae(function(n,t,r){var e=b;if(r.length)var u=_(r,bi.placeholder),e=e|O;return vr(n,e,t,r,u)}),xi=ae(function(n,t){t=t.length?ht(t):je(n);for(var r=-1,e=t.length;++r<e;){var u=t[r];n[u]=vr(n[u],b,n)}return n}),Ai=ae(function(n,t,r){
-var e=b|x;if(r.length)var u=_(r,Ai.placeholder),e=e|O;return vr(t,e,n,r,u)}),ji=Ht(j),ki=Ht(k),Oi=ae(function(n,t){return ft(n,1,t)}),Ri=ae(function(n,t,r){return ft(n,t,r)}),Ii=er(),Ei=er(true),Ci=ar(O),Wi=ar(R),Si=ae(function(n,t){return vr(n,E,null,null,null,ht(t))}),Ti=xu||function(n){return p(n)&&Tr(n.length)&&uu.call(n)==B};zu.dom||(pe=function(n){return!!n&&1===n.nodeType&&p(n)&&!Fi(n)});var Ui=Iu||function(n){return typeof n=="number"&&Au(n)},$i=e(/x/)||du&&!e(du)?function(n){return uu.call(n)==D;
-}:e,Fi=pu?function(n){if(!n||uu.call(n)!=V)return false;var t=Ar(n,"valueOf"),r=t&&(r=pu(t))&&pu(r);return r?n==r||pu(n)==r:Fr(n)}:Fr,Ni=Vt(function(n,t,r){return r?tt(n,t,r):rt(n,t)}),Li=ae(function(n){var t=n[0];return null==t?t:(n.push(Qn),Ni.apply(m,n))}),zi=rr(vt),Bi=rr(gt),Mi=ir(qu),Pi=ir(Du),qi=or(vt),Di=or(gt),Ki=ju?function(n){var t=null==n?null:n.constructor;return typeof t=="function"&&t.prototype===n||typeof n!="function"&&Ir(n)?Nr(n):ve(n)?ju(n):[]}:Nr,Vi=fr(true),Yi=fr(),Zi=Vt(jt),Gi=ae(function(n,t){
-if(null==n)return{};if("function"!=typeof t[0])return t=Jn(ht(t),Ge),Ur(n,lt(ke(n),t));var r=Mt(t[0],t[1],3);return $r(n,function(n,t,e){return!r(n,t,e)})}),Ji=ae(function(n,t){return null==n?{}:"function"==typeof t[0]?$r(n,Mt(t[0],t[1],3)):Ur(n,ht(t))}),Xi=Jt(function(n,t,r){return t=t.toLowerCase(),n+(r?t.charAt(0).toUpperCase()+t.slice(1):t)}),Hi=Jt(function(n,t,r){return n+(r?"-":"")+t.toLowerCase()}),Qi=lr(),no=lr(true);8!=Eu(Sn+"08")&&(Ce=function(n,t,r){return(r?Cr(n,t,r):null==t)?t=0:t&&(t=+t),
-n=Se(n),Eu(n,t||(kn.test(n)?16:10))});var to=Jt(function(n,t,r){return n+(r?"_":"")+t.toLowerCase()}),ro=Jt(function(n,t,r){return n+(r?" ":"")+(t.charAt(0).toUpperCase()+t.slice(1))}),eo=ae(function(n,t){try{return n.apply(m,t)}catch(r){return _e(r)?r:new qe(r)}}),uo=ae(function(n,t){return function(r){return Rr(r,n,t)}}),io=ae(function(n,t){return function(r){return Rr(n,r,t)}}),oo=Qt(ce,Wu),fo=Qt(be,Su);return Nn.prototype=Ln.prototype,zn.prototype=Bu(Ln.prototype),zn.prototype.constructor=zn,
-Bn.prototype=Bu(Ln.prototype),Bn.prototype.constructor=Bn,Mn.prototype["delete"]=function(n){return this.has(n)&&delete this.__data__[n]},Mn.prototype.get=function(n){return"__proto__"==n?m:this.__data__[n]},Mn.prototype.has=function(n){return"__proto__"!=n&&ru.call(this.__data__,n)},Mn.prototype.set=function(n,t){return"__proto__"!=n&&(this.__data__[n]=t),this},Pn.prototype.push=function(n){var t=this.data;typeof n=="string"||ve(n)?t.set.add(n):t.hash[n]=true},le.Cache=Mn,Nn.after=function(n,t){if(typeof t!="function"){
-if(typeof n!="function")throw new Je(N);var r=n;n=t,t=r}return n=Au(n=+n)?n:0,function(){return 1>--n?t.apply(this,arguments):void 0}},Nn.ary=function(n,t,r){return r&&Cr(n,t,r)&&(t=null),t=n&&null==t?n.length:ku(+t||0,0),vr(n,I,null,null,null,null,t)},Nn.assign=Ni,Nn.at=fi,Nn.before=oe,Nn.bind=bi,Nn.bindAll=xi,Nn.bindKey=Ai,Nn.callback=Ue,Nn.chain=Hr,Nn.chunk=function(n,t,r){t=(r?Cr(n,t,r):null==t)?1:ku(+t||1,1),r=0;for(var e=n?n.length:0,u=-1,i=Me(au(e/t));r<e;)i[++u]=Ct(n,r,r+=t);return i},Nn.compact=function(n){
-for(var t=-1,r=n?n.length:0,e=-1,u=[];++t<r;){var i=n[t];i&&(u[++e]=i)}return u},Nn.constant=$e,Nn.countBy=li,Nn.create=function(n,t,r){var e=Bu(n);return r&&Cr(n,t,r)&&(t=null),t?rt(e,t):e},Nn.curry=ji,Nn.curryRight=ki,Nn.debounce=fe,Nn.defaults=Li,Nn.defer=Oi,Nn.delay=Ri,Nn.difference=Ju,Nn.drop=Pr,Nn.dropRight=qr,Nn.dropRightWhile=function(n,t,r){return n&&n.length?Nt(n,mr(t,r,3),true,true):[]},Nn.dropWhile=function(n,t,r){return n&&n.length?Nt(n,mr(t,r,3),true):[]},Nn.fill=function(n,t,r,e){var u=n?n.length:0;
-if(!u)return[];for(r&&typeof r!="number"&&Cr(n,t,r)&&(r=0,e=u),u=n.length,r=null==r?0:+r||0,0>r&&(r=-r>u?0:u+r),e=e===m||e>u?u:+e||0,0>e&&(e+=u),u=r>e?0:e>>>0,r>>>=0;r<u;)n[r++]=t;return n},Nn.filter=te,Nn.flatten=function(n,t,r){var e=n?n.length:0;return r&&Cr(n,t,r)&&(t=false),e?ht(n,t):[]},Nn.flattenDeep=function(n){return n&&n.length?ht(n,true):[]},Nn.flow=Ii,Nn.flowRight=Ei,Nn.forEach=si,Nn.forEachRight=pi,Nn.forIn=Mi,Nn.forInRight=Pi,Nn.forOwn=qi,Nn.forOwnRight=Di,Nn.functions=je,Nn.groupBy=hi,Nn.indexBy=_i,
-Nn.initial=function(n){return qr(n,1)},Nn.intersection=Qu,Nn.invert=function(n,t,r){r&&Cr(n,t,r)&&(t=null),r=-1;for(var e=Ki(n),u=e.length,i={};++r<u;){var o=e[r],f=n[o];t?ru.call(i,f)?i[f].push(o):i[f]=[o]:i[f]=o}return i},Nn.invoke=vi,Nn.keys=Ki,Nn.keysIn=ke,Nn.map=ee,Nn.mapKeys=Vi,Nn.mapValues=Yi,Nn.matches=Ne,Nn.matchesProperty=function(n,t){return At(n,ot(t,true))},Nn.memoize=le,Nn.merge=Zi,Nn.method=uo,Nn.methodOf=io,Nn.mixin=Le,Nn.negate=function(n){if(typeof n!="function")throw new Je(N);return function(){
-return!n.apply(this,arguments)}},Nn.omit=Gi,Nn.once=function(n){return oe(2,n)},Nn.pairs=Oe,Nn.partial=Ci,Nn.partialRight=Wi,Nn.partition=gi,Nn.pick=Ji,Nn.pluck=function(n,t){return ee(n,Be(t))},Nn.property=Be,Nn.propertyOf=function(n){return function(t){return dt(n,Br(t),t+"")}},Nn.pull=function(){var n=arguments,t=n[0];if(!t||!t.length)return t;for(var r=0,e=br(),u=n.length;++r<u;)for(var i=0,o=n[r];-1<(i=e(t,o,i));)yu.call(t,i,1);return t},Nn.pullAt=ni,Nn.range=function(n,t,r){r&&Cr(n,t,r)&&(t=r=null),
-n=+n||0,r=null==r?1:+r||0,null==t?(t=n,n=0):t=+t||0;var e=-1;t=ku(au((t-n)/(r||1)),0);for(var u=Me(t);++e<t;)u[e]=n,n+=r;return u},Nn.rearg=Si,Nn.reject=function(n,t,r){var e=Ti(n)?Gn:st;return t=mr(t,r,3),e(n,function(n,r,e){return!t(n,r,e)})},Nn.remove=function(n,t,r){var e=[];if(!n||!n.length)return e;var u=-1,i=[],o=n.length;for(t=mr(t,r,3);++u<o;)r=n[u],t(r,u,n)&&(e.push(r),i.push(u));return Rt(n,i),e},Nn.rest=Yr,Nn.restParam=ae,Nn.set=function(n,t,r){if(null==n)return n;var e=t+"";t=null!=n[e]||Wr(t,n)?[e]:Br(t);
-for(var e=-1,u=t.length,i=u-1,o=n;null!=o&&++e<u;){var f=t[e];ve(o)&&(e==i?o[f]=r:null==o[f]&&(o[f]=Er(t[e+1])?[]:{})),o=o[f]}return n},Nn.shuffle=function(n){return ue(n,Su)},Nn.slice=function(n,t,r){var e=n?n.length:0;return e?(r&&typeof r!="number"&&Cr(n,t,r)&&(t=0,r=e),Ct(n,t,r)):[]},Nn.sortBy=function(n,t,r){if(null==n)return[];r&&Cr(n,t,r)&&(t=null);var e=-1;return t=mr(t,r,3),n=bt(n,function(n,r,u){return{a:t(n,r,u),b:++e,c:n}}),St(n,f)},Nn.sortByAll=mi,Nn.sortByOrder=function(n,t,r,e){return null==n?[]:(e&&Cr(t,r,e)&&(r=null),
-Ti(t)||(t=null==t?[]:[t]),Ti(r)||(r=null==r?[]:[r]),Tt(n,t,r))},Nn.spread=function(n){if(typeof n!="function")throw new Je(N);return function(t){return n.apply(this,t)}},Nn.take=function(n,t,r){return n&&n.length?((r?Cr(n,t,r):null==t)&&(t=1),Ct(n,0,0>t?0:t)):[]},Nn.takeRight=function(n,t,r){var e=n?n.length:0;return e?((r?Cr(n,t,r):null==t)&&(t=1),t=e-(+t||0),Ct(n,0>t?0:t)):[]},Nn.takeRightWhile=function(n,t,r){return n&&n.length?Nt(n,mr(t,r,3),false,true):[]},Nn.takeWhile=function(n,t,r){return n&&n.length?Nt(n,mr(t,r,3)):[];
-},Nn.tap=function(n,t,r){return t.call(r,n),n},Nn.throttle=function(n,t,r){var e=true,u=true;if(typeof n!="function")throw new Je(N);return false===r?e=false:ve(r)&&(e="leading"in r?!!r.leading:e,u="trailing"in r?!!r.trailing:u),Fn.leading=e,Fn.maxWait=+t,Fn.trailing=u,fe(n,t,Fn)},Nn.thru=Qr,Nn.times=function(n,t,r){if(n=su(n),1>n||!Au(n))return[];var e=-1,u=Me(Ou(n,4294967295));for(t=Mt(t,r,1);++e<n;)4294967295>e?u[e]=t(e):t(e);return u},Nn.toArray=xe,Nn.toPlainObject=Ae,Nn.transform=function(n,t,r,e){var u=Ti(n)||we(n);
-return t=mr(t,e,4),null==r&&(u||ve(n)?(e=n.constructor,r=u?Ti(n)?new e:[]:Bu($i(e)?e.prototype:null)):r={}),(u?Kn:vt)(n,function(n,e,u){return t(r,n,e,u)}),r},Nn.union=ei,Nn.uniq=Zr,Nn.unzip=Gr,Nn.unzipWith=Jr,Nn.values=Re,Nn.valuesIn=function(n){return Ft(n,ke(n))},Nn.where=function(n,t){return te(n,xt(t))},Nn.without=ui,Nn.wrap=function(n,t){return t=null==t?Fe:t,vr(t,O,null,[n],[])},Nn.xor=function(){for(var n=-1,t=arguments.length;++n<t;){var r=arguments[n];if(Ir(r))var e=e?lt(e,r).concat(lt(r,e)):r;
-}return e?$t(e):[]},Nn.zip=ii,Nn.zipObject=Xr,Nn.zipWith=oi,Nn.backflow=Ei,Nn.collect=ee,Nn.compose=Ei,Nn.each=si,Nn.eachRight=pi,Nn.extend=Ni,Nn.iteratee=Ue,Nn.methods=je,Nn.object=Xr,Nn.select=te,Nn.tail=Yr,Nn.unique=Zr,Le(Nn,Nn),Nn.add=function(n,t){return(+n||0)+(+t||0)},Nn.attempt=eo,Nn.camelCase=Xi,Nn.capitalize=function(n){return(n=u(n))&&n.charAt(0).toUpperCase()+n.slice(1)},Nn.clone=function(n,t,r,e){return t&&typeof t!="boolean"&&Cr(n,t,r)?t=false:typeof t=="function"&&(e=r,r=t,t=false),typeof r=="function"?ot(n,t,Mt(r,e,1)):ot(n,t);
-},Nn.cloneDeep=function(n,t,r){return typeof t=="function"?ot(n,true,Mt(t,r,1)):ot(n,true)},Nn.deburr=Ie,Nn.endsWith=function(n,t,r){n=u(n),t+="";var e=n.length;return r=r===m?e:Ou(0>r?0:+r||0,e),r-=t.length,0<=r&&n.indexOf(t,r)==r},Nn.escape=function(n){return(n=u(n))&&pn.test(n)?n.replace(cn,a):n},Nn.escapeRegExp=Ee,Nn.every=ne,Nn.find=ai,Nn.findIndex=Xu,Nn.findKey=zi,Nn.findLast=ci,Nn.findLastIndex=Hu,Nn.findLastKey=Bi,Nn.findWhere=function(n,t){return ai(n,xt(t))},Nn.first=Dr,Nn.get=function(n,t,r){
-return n=null==n?m:dt(n,Br(t),t+""),n===m?r:n},Nn.gt=ce,Nn.gte=function(n,t){return n>=t},Nn.has=function(n,t){if(null==n)return false;var r=ru.call(n,t);if(!r&&!Wr(t)){if(t=Br(t),n=1==t.length?n:dt(n,Ct(t,0,-1)),null==n)return false;t=Vr(t),r=ru.call(n,t)}return r||Tr(n.length)&&Er(t,n.length)&&(Ti(n)||se(n))},Nn.identity=Fe,Nn.includes=re,Nn.indexOf=Kr,Nn.inRange=function(n,t,r){return t=+t||0,"undefined"===typeof r?(r=t,t=0):r=+r||0,n>=Ou(t,r)&&n<ku(t,r)},Nn.isArguments=se,Nn.isArray=Ti,Nn.isBoolean=function(n){
-return true===n||false===n||p(n)&&uu.call(n)==M},Nn.isDate=function(n){return p(n)&&uu.call(n)==P},Nn.isElement=pe,Nn.isEmpty=function(n){return null==n?true:Ir(n)&&(Ti(n)||me(n)||se(n)||p(n)&&$i(n.splice))?!n.length:!Ki(n).length},Nn.isEqual=he,Nn.isError=_e,Nn.isFinite=Ui,Nn.isFunction=$i,Nn.isMatch=function(n,t,r,e){return r=typeof r=="function"?Mt(r,e,3):m,wt(n,xr(t),r)},Nn.isNaN=function(n){return ye(n)&&n!=+n},Nn.isNative=ge,Nn.isNull=function(n){return null===n},Nn.isNumber=ye,Nn.isObject=ve,Nn.isPlainObject=Fi,
-Nn.isRegExp=de,Nn.isString=me,Nn.isTypedArray=we,Nn.isUndefined=function(n){return n===m},Nn.kebabCase=Hi,Nn.last=Vr,Nn.lastIndexOf=function(n,t,r){var e=n?n.length:0;if(!e)return-1;var u=e;if(typeof r=="number")u=(0>r?ku(e+r,0):Ou(r||0,e-1))+1;else if(r)return u=zt(n,t,true)-1,n=n[u],(t===t?t===n:n!==n)?u:-1;if(t!==t)return s(n,u,true);for(;u--;)if(n[u]===t)return u;return-1},Nn.lt=be,Nn.lte=function(n,t){return n<=t},Nn.max=oo,Nn.min=fo,Nn.noConflict=function(){return h._=iu,this},Nn.noop=ze,Nn.now=wi,
-Nn.pad=function(n,t,r){n=u(n),t=+t;var e=n.length;return e<t&&Au(t)?(e=(t-e)/2,t=su(e),e=au(e),r=pr("",e,r),r.slice(0,t)+n+r):n},Nn.padLeft=Qi,Nn.padRight=no,Nn.parseInt=Ce,Nn.random=function(n,t,r){r&&Cr(n,t,r)&&(t=r=null);var e=null==n,u=null==t;return null==r&&(u&&typeof n=="boolean"?(r=n,n=1):typeof t=="boolean"&&(r=t,u=true)),e&&u&&(t=1,u=false),n=+n||0,u?(t=n,n=0):t=+t||0,r||n%1||t%1?(r=Cu(),Ou(n+r*(t-n+hu("1e-"+((r+"").length-1))),t)):It(n,t)},Nn.reduce=yi,Nn.reduceRight=di,Nn.repeat=We,Nn.result=function(n,t,r){
-var e=null==n?m:n[t];return e===m&&(null==n||Wr(t,n)||(t=Br(t),n=1==t.length?n:dt(n,Ct(t,0,-1)),e=null==n?m:n[Vr(t)]),e=e===m?r:e),$i(e)?e.call(n):e},Nn.runInContext=d,Nn.size=function(n){var t=n?Zu(n):0;return Tr(t)?t:Ki(n).length},Nn.snakeCase=to,Nn.some=ie,Nn.sortedIndex=ti,Nn.sortedLastIndex=ri,Nn.startCase=ro,Nn.startsWith=function(n,t,r){return n=u(n),r=null==r?0:Ou(0>r?0:+r||0,n.length),n.lastIndexOf(t,r)==r},Nn.sum=function(n,t,r){r&&Cr(n,t,r)&&(t=null);var e=mr(),u=null==t;if(u&&e===it||(u=false,
-t=e(t,r,3)),u){for(n=Ti(n)?n:Lr(n),t=n.length,r=0;t--;)r+=+n[t]||0;n=r}else n=Ut(n,t);return n},Nn.template=function(n,t,r){var e=Nn.templateSettings;r&&Cr(n,t,r)&&(t=r=null),n=u(n),t=tt(rt({},r||t),e,nt),r=tt(rt({},t.imports),e.imports,nt);var i,o,f=Ki(r),l=Ft(r,f),a=0;r=t.interpolate||En;var s="__p+='";r=Ze((t.escape||En).source+"|"+r.source+"|"+(r===vn?An:En).source+"|"+(t.evaluate||En).source+"|$","g");var p="sourceURL"in t?"//# sourceURL="+t.sourceURL+"\n":"";if(n.replace(r,function(t,r,e,u,f,l){
-return e||(e=u),s+=n.slice(a,l).replace(Cn,c),r&&(i=true,s+="'+__e("+r+")+'"),f&&(o=true,s+="';"+f+";\n__p+='"),e&&(s+="'+((__t=("+e+"))==null?'':__t)+'"),a=l+t.length,t}),s+="';",(t=t.variable)||(s="with(obj){"+s+"}"),s=(o?s.replace(on,""):s).replace(fn,"$1").replace(ln,"$1;"),s="function("+(t||"obj")+"){"+(t?"":"obj||(obj={});")+"var __t,__p=''"+(i?",__e=_.escape":"")+(o?",__j=Array.prototype.join;function print(){__p+=__j.call(arguments,'')}":";")+s+"return __p}",t=eo(function(){return De(f,p+"return "+s).apply(m,l);
-}),t.source=s,_e(t))throw t;return t},Nn.trim=Se,Nn.trimLeft=function(n,t,r){var e=n;return(n=u(n))?n.slice((r?Cr(e,t,r):null==t)?v(n):i(n,t+"")):n},Nn.trimRight=function(n,t,r){var e=n;return(n=u(n))?(r?Cr(e,t,r):null==t)?n.slice(0,g(n)+1):n.slice(0,o(n,t+"")+1):n},Nn.trunc=function(n,t,r){r&&Cr(n,t,r)&&(t=null);var e=C;if(r=W,null!=t)if(ve(t)){var i="separator"in t?t.separator:i,e="length"in t?+t.length||0:e;r="omission"in t?u(t.omission):r}else e=+t||0;if(n=u(n),e>=n.length)return n;if(e-=r.length,
-1>e)return r;if(t=n.slice(0,e),null==i)return t+r;if(de(i)){if(n.slice(e).search(i)){var o,f=n.slice(0,e);for(i.global||(i=Ze(i.source,(jn.exec(i)||"")+"g")),i.lastIndex=0;n=i.exec(f);)o=n.index;t=t.slice(0,null==o?e:o)}}else n.indexOf(i,e)!=e&&(i=t.lastIndexOf(i),-1<i&&(t=t.slice(0,i)));return t+r},Nn.unescape=function(n){return(n=u(n))&&sn.test(n)?n.replace(an,y):n},Nn.uniqueId=function(n){var t=++eu;return u(n)+t},Nn.words=Te,Nn.all=ne,Nn.any=ie,Nn.contains=re,Nn.eq=he,Nn.detect=ai,Nn.foldl=yi,
-Nn.foldr=di,Nn.head=Dr,Nn.include=re,Nn.inject=yi,Le(Nn,function(){var n={};return vt(Nn,function(t,r){Nn.prototype[r]||(n[r]=t)}),n}(),false),Nn.sample=ue,Nn.prototype.sample=function(n){return this.__chain__||null!=n?this.thru(function(t){return ue(t,n)}):ue(this.value())},Nn.VERSION=w,Kn("bind bindKey curry curryRight partial partialRight".split(" "),function(n){Nn[n].placeholder=Nn}),Kn(["dropWhile","filter","map","takeWhile"],function(n,t){var r=t!=F,e=t==U;Bn.prototype[n]=function(n,u){var i=this.__filtered__,o=i&&e?new Bn(this):this.clone();
-return(o.__iteratees__||(o.__iteratees__=[])).push({done:false,count:0,index:0,iteratee:mr(n,u,1),limit:-1,type:t}),o.__filtered__=i||r,o}}),Kn(["drop","take"],function(n,t){var r=n+"While";Bn.prototype[n]=function(r){var e=this.__filtered__,u=e&&!t?this.dropWhile():this.clone();return r=null==r?1:ku(su(r)||0,0),e?t?u.__takeCount__=Ou(u.__takeCount__,r):Vr(u.__iteratees__).limit=r:(u.__views__||(u.__views__=[])).push({size:r,type:n+(0>u.__dir__?"Right":"")}),u},Bn.prototype[n+"Right"]=function(t){return this.reverse()[n](t).reverse();
-},Bn.prototype[n+"RightWhile"]=function(n,t){return this.reverse()[r](n,t).reverse()}}),Kn(["first","last"],function(n,t){var r="take"+(t?"Right":"");Bn.prototype[n]=function(){return this[r](1).value()[0]}}),Kn(["initial","rest"],function(n,t){var r="drop"+(t?"":"Right");Bn.prototype[n]=function(){return this[r](1)}}),Kn(["pluck","where"],function(n,t){var r=t?"filter":"map",e=t?xt:Be;Bn.prototype[n]=function(n){return this[r](e(n))}}),Bn.prototype.compact=function(){return this.filter(Fe)},Bn.prototype.reject=function(n,t){
-return n=mr(n,t,1),this.filter(function(t){return!n(t)})},Bn.prototype.slice=function(n,t){n=null==n?0:+n||0;var r=this;return 0>n?r=this.takeRight(-n):n&&(r=this.drop(n)),t!==m&&(t=+t||0,r=0>t?r.dropRight(-t):r.take(t-n)),r},Bn.prototype.toArray=function(){return this.drop(0)},vt(Bn.prototype,function(n,t){var r=Nn[t];if(r){var e=/^(?:filter|map|reject)|While$/.test(t),u=/^(?:first|last)$/.test(t);Nn.prototype[t]=function(){function t(n){return n=[n],_u.apply(n,i),r.apply(Nn,n)}var i=arguments,o=this.__chain__,f=this.__wrapped__,l=!!this.__actions__.length,a=f instanceof Bn,c=i[0],s=a||Ti(f);
-return s&&e&&typeof c=="function"&&1!=c.length&&(a=s=false),a=a&&!l,u&&!o?a?n.call(f):r.call(Nn,this.value()):s?(f=n.apply(a?f:new Bn(this),i),u||!l&&!f.__actions__||(f.__actions__||(f.__actions__=[])).push({func:Qr,args:[t],thisArg:Nn}),new zn(f,o)):this.thru(t)}}}),Kn("concat join pop push replace shift sort splice split unshift".split(" "),function(n){var t=(/^(?:replace|split)$/.test(n)?Qe:Xe)[n],r=/^(?:push|sort|unshift)$/.test(n)?"tap":"thru",e=/^(?:join|pop|replace|shift)$/.test(n);Nn.prototype[n]=function(){
-var n=arguments;return e&&!this.__chain__?t.apply(this.value(),n):this[r](function(r){return t.apply(r,n)})}}),vt(Bn.prototype,function(n,t){var r=Nn[t];if(r){var e=r.name;(Lu[e]||(Lu[e]=[])).push({name:t,func:r})}}),Lu[sr(null,x).name]=[{name:"wrapper",func:null}],Bn.prototype.clone=function(){var n=this.__actions__,t=this.__iteratees__,r=this.__views__,e=new Bn(this.__wrapped__);return e.__actions__=n?Dn(n):null,e.__dir__=this.__dir__,e.__filtered__=this.__filtered__,e.__iteratees__=t?Dn(t):null,
-e.__takeCount__=this.__takeCount__,e.__views__=r?Dn(r):null,e},Bn.prototype.reverse=function(){if(this.__filtered__){var n=new Bn(this);n.__dir__=-1,n.__filtered__=true}else n=this.clone(),n.__dir__*=-1;return n},Bn.prototype.value=function(){var n=this.__wrapped__.value();if(!Ti(n))return Lt(n,this.__actions__);var t,r=this.__dir__,e=0>r;t=n.length;for(var u=this.__views__,i=0,o=-1,f=u?u.length:0;++o<f;){var l=u[o],a=l.size;switch(l.type){case"drop":i+=a;break;case"dropRight":t-=a;break;case"take":
-t=Ou(t,i+a);break;case"takeRight":i=ku(i,t-a)}}t={start:i,end:t},u=t.start,i=t.end,t=i-u,u=e?i:u-1,i=Ou(t,this.__takeCount__),f=(o=this.__iteratees__)?o.length:0,l=0,a=[];n:for(;t--&&l<i;){for(var u=u+r,c=-1,s=n[u];++c<f;){var p=o[c],h=p.iteratee,_=p.type;if(_==U){if(p.done&&(e?u>p.index:u<p.index)&&(p.count=0,p.done=false),p.index=u,!(p.done||(_=p.limit,p.done=-1<_?p.count++>=_:!h(s))))continue n}else if(p=h(s),_==F)s=p;else if(!p){if(_==$)continue n;break n}}a[l++]=s}return a},Nn.prototype.chain=function(){
-return Hr(this)},Nn.prototype.commit=function(){return new zn(this.value(),this.__chain__)},Nn.prototype.plant=function(n){for(var t,r=this;r instanceof Ln;){var e=Mr(r);t?u.__wrapped__=e:t=e;var u=e,r=r.__wrapped__}return u.__wrapped__=n,t},Nn.prototype.reverse=function(){var n=this.__wrapped__;return n instanceof Bn?(this.__actions__.length&&(n=new Bn(this)),new zn(n.reverse(),this.__chain__)):this.thru(function(n){return n.reverse()})},Nn.prototype.toString=function(){return this.value()+""},Nn.prototype.run=Nn.prototype.toJSON=Nn.prototype.valueOf=Nn.prototype.value=function(){
-return Lt(this.__wrapped__,this.__actions__)},Nn.prototype.collect=Nn.prototype.map,Nn.prototype.head=Nn.prototype.first,Nn.prototype.select=Nn.prototype.filter,Nn.prototype.tail=Nn.prototype.rest,Nn}var m,w="3.9.3",b=1,x=2,A=4,j=8,k=16,O=32,R=64,I=128,E=256,C=30,W="...",S=150,T=16,U=0,$=1,F=2,N="Expected a function",L="__lodash_placeholder__",z="[object Arguments]",B="[object Array]",M="[object Boolean]",P="[object Date]",q="[object Error]",D="[object Function]",K="[object Number]",V="[object Object]",Y="[object RegExp]",Z="[object String]",G="[object ArrayBuffer]",J="[object Float32Array]",X="[object Float64Array]",H="[object Int8Array]",Q="[object Int16Array]",nn="[object Int32Array]",tn="[object Uint8Array]",rn="[object Uint8ClampedArray]",en="[object Uint16Array]",un="[object Uint32Array]",on=/\b__p\+='';/g,fn=/\b(__p\+=)''\+/g,ln=/(__e\(.*?\)|\b__t\))\+'';/g,an=/&(?:amp|lt|gt|quot|#39|#96);/g,cn=/[&<>"'`]/g,sn=RegExp(an.source),pn=RegExp(cn.source),hn=/<%-([\s\S]+?)%>/g,_n=/<%([\s\S]+?)%>/g,vn=/<%=([\s\S]+?)%>/g,gn=/\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\n\\]|\\.)*?\1)\]/,yn=/^\w*$/,dn=/[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\n\\]|\\.)*?)\2)\]/g,mn=/[.*+?^${}()|[\]\/\\]/g,wn=RegExp(mn.source),bn=/[\u0300-\u036f\ufe20-\ufe23]/g,xn=/\\(\\)?/g,An=/\$\{([^\\}]*(?:\\.[^\\}]*)*)\}/g,jn=/\w*$/,kn=/^0[xX]/,On=/^\[object .+?Constructor\]$/,Rn=/^\d+$/,In=/[\xc0-\xd6\xd8-\xde\xdf-\xf6\xf8-\xff]/g,En=/($^)/,Cn=/['\n\r\u2028\u2029\\]/g,Wn=RegExp("[A-Z\\xc0-\\xd6\\xd8-\\xde]+(?=[A-Z\\xc0-\\xd6\\xd8-\\xde][a-z\\xdf-\\xf6\\xf8-\\xff]+)|[A-Z\\xc0-\\xd6\\xd8-\\xde]?[a-z\\xdf-\\xf6\\xf8-\\xff]+|[A-Z\\xc0-\\xd6\\xd8-\\xde]+|[0-9]+","g"),Sn=" \t\x0b\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000",Tn="Array ArrayBuffer Date Error Float32Array Float64Array Function Int8Array Int16Array Int32Array Math Number Object RegExp Set String _ clearTimeout document isFinite parseFloat parseInt setTimeout TypeError Uint8Array Uint8ClampedArray Uint16Array Uint32Array WeakMap window".split(" "),Un={};
-Un[J]=Un[X]=Un[H]=Un[Q]=Un[nn]=Un[tn]=Un[rn]=Un[en]=Un[un]=true,Un[z]=Un[B]=Un[G]=Un[M]=Un[P]=Un[q]=Un[D]=Un["[object Map]"]=Un[K]=Un[V]=Un[Y]=Un["[object Set]"]=Un[Z]=Un["[object WeakMap]"]=false;var $n={};$n[z]=$n[B]=$n[G]=$n[M]=$n[P]=$n[J]=$n[X]=$n[H]=$n[Q]=$n[nn]=$n[K]=$n[V]=$n[Y]=$n[Z]=$n[tn]=$n[rn]=$n[en]=$n[un]=true,$n[q]=$n[D]=$n["[object Map]"]=$n["[object Set]"]=$n["[object WeakMap]"]=false;var Fn={leading:false,maxWait:0,trailing:false},Nn={"\xc0":"A","\xc1":"A","\xc2":"A","\xc3":"A","\xc4":"A","\xc5":"A",
-"\xe0":"a","\xe1":"a","\xe2":"a","\xe3":"a","\xe4":"a","\xe5":"a","\xc7":"C","\xe7":"c","\xd0":"D","\xf0":"d","\xc8":"E","\xc9":"E","\xca":"E","\xcb":"E","\xe8":"e","\xe9":"e","\xea":"e","\xeb":"e","\xcc":"I","\xcd":"I","\xce":"I","\xcf":"I","\xec":"i","\xed":"i","\xee":"i","\xef":"i","\xd1":"N","\xf1":"n","\xd2":"O","\xd3":"O","\xd4":"O","\xd5":"O","\xd6":"O","\xd8":"O","\xf2":"o","\xf3":"o","\xf4":"o","\xf5":"o","\xf6":"o","\xf8":"o","\xd9":"U","\xda":"U","\xdb":"U","\xdc":"U","\xf9":"u","\xfa":"u",
-"\xfb":"u","\xfc":"u","\xdd":"Y","\xfd":"y","\xff":"y","\xc6":"Ae","\xe6":"ae","\xde":"Th","\xfe":"th","\xdf":"ss"},Ln={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},zn={"&":"&","<":"<",">":">",""":'"',"'":"'","`":"`"},Bn={"function":true,object:true},Mn={"\\":"\\","'":"'","\n":"n","\r":"r","\u2028":"u2028","\u2029":"u2029"},Pn=Bn[typeof exports]&&exports&&!exports.nodeType&&exports,qn=Bn[typeof module]&&module&&!module.nodeType&&module,Dn=Bn[typeof self]&&self&&self.Object&&self,Kn=Bn[typeof window]&&window&&window.Object&&window,Vn=qn&&qn.exports===Pn&&Pn,Yn=Pn&&qn&&typeof global=="object"&&global&&global.Object&&global||Kn!==(this&&this.window)&&Kn||Dn||this,Zn=d();
-typeof define=="function"&&typeof define.amd=="object"&&define.amd?(Yn._=Zn, define(function(){return Zn})):Pn&&qn?Vn?(qn.exports=Zn)._=Zn:Pn._=Zn:Yn._=Zn}).call(this);
\ No newline at end of file
+++ /dev/null
-/*! JointJS v0.9.3 - JavaScript diagramming library 2015-05-22
-
-
-This Source Code Form is subject to the terms of the Mozilla Public
-License, v. 2.0. If a copy of the MPL was not distributed with this
-file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-// Vectorizer.
-// -----------
-
-// A tiny library for making your live easier when dealing with SVG.
-// The only Vectorizer dependency is the Geometry library.
-
-// Copyright © 2012 - 2015 client IO (http://client.io)
-
-(function(root, factory) {
-
- if (typeof define === 'function' && define.amd) {
-
- // AMD. Register as an anonymous module.
- define(['app/gbp-old/js/geometry'], function(g) {
- return factory(g);
- });
-
-
- } else if (typeof exports === 'object') {
-
- // Node. Does not work with strict CommonJS, but
- // only CommonJS-like environments that support module.exports,
- // like Node.
- module.exports = factory();
-
- } else {
-
- // Browser globals.
- root.Vectorizer = root.V = factory();
-
- }
-
-}(this, function(g) {
-
- var SVGsupported = typeof window === 'object' && !!(window.SVGAngle || document.implementation.hasFeature('http://www.w3.org/TR/SVG11/feature#BasicStructure', '1.1'));
-
- // SVG support is required.
- if (!SVGsupported) return function() {};
-
- // XML namespaces.
- var ns = {
- xmlns: 'http://www.w3.org/2000/svg',
- xlink: 'http://www.w3.org/1999/xlink'
- };
- // SVG version.
- var SVGversion = '1.1';
-
- // A function returning a unique identifier for this client session with every call.
- var idCounter = 0;
- function uniqueId() {
- var id = ++idCounter + '';
- return 'v-' + id;
- }
-
- // Create an SVG document element.
- // If `content` is passed, it will be used as the SVG content of the `<svg>` root element.
- function createSvgDocument(content) {
-
- var svg = '<svg xmlns="' + ns.xmlns + '" xmlns:xlink="' + ns.xlink + '" version="' + SVGversion + '">' + (content || '') + '</svg>';
- var parser = new DOMParser();
- parser.async = false;
- return parser.parseFromString(svg, 'text/xml').documentElement;
- }
-
- // Create SVG element.
- // -------------------
-
- function createElement(el, attrs, children) {
-
- var i, len;
-
- if (!el) return undefined;
-
- // If `el` is an object, it is probably a native SVG element. Wrap it to VElement.
- if (typeof el === 'object') {
- return new VElement(el);
- }
- attrs = attrs || {};
-
- // If `el` is a `'svg'` or `'SVG'` string, create a new SVG canvas.
- if (el.toLowerCase() === 'svg') {
-
- return new VElement(createSvgDocument());
-
- } else if (el[0] === '<') {
- // Create element from an SVG string.
- // Allows constructs of type: `document.appendChild(Vectorizer('<rect></rect>').node)`.
-
- var svgDoc = createSvgDocument(el);
-
- // Note that `createElement()` might also return an array should the SVG string passed as
- // the first argument contain more then one root element.
- if (svgDoc.childNodes.length > 1) {
-
- // Map child nodes to `VElement`s.
- var ret = [];
- for (i = 0, len = svgDoc.childNodes.length; i < len; i++) {
-
- var childNode = svgDoc.childNodes[i];
- ret.push(new VElement(document.importNode(childNode, true)));
- }
- return ret;
- }
-
- return new VElement(document.importNode(svgDoc.firstChild, true));
- }
-
- el = document.createElementNS(ns.xmlns, el);
-
- // Set attributes.
- for (var key in attrs) {
-
- setAttribute(el, key, attrs[key]);
- }
-
- // Normalize `children` array.
- if (Object.prototype.toString.call(children) != '[object Array]') children = [children];
-
- // Append children if they are specified.
- for (i = 0, len = (children[0] && children.length) || 0; i < len; i++) {
- var child = children[i];
- el.appendChild(child instanceof VElement ? child.node : child);
- }
-
- return new VElement(el);
- }
-
- function setAttribute(el, name, value) {
-
- if (name.indexOf(':') > -1) {
- // Attribute names can be namespaced. E.g. `image` elements
- // have a `xlink:href` attribute to set the source of the image.
- var combinedKey = name.split(':');
- el.setAttributeNS(ns[combinedKey[0]], combinedKey[1], value);
-
- } else if (name === 'id') {
- el.id = value;
- } else {
- el.setAttribute(name, value);
- }
- }
-
- function parseTransformString(transform) {
- var translate,
- rotate,
- scale;
-
- if (transform) {
-
- var separator = /[ ,]+/;
-
- var translateMatch = transform.match(/translate\((.*)\)/);
- if (translateMatch) {
- translate = translateMatch[1].split(separator);
- }
- var rotateMatch = transform.match(/rotate\((.*)\)/);
- if (rotateMatch) {
- rotate = rotateMatch[1].split(separator);
- }
- var scaleMatch = transform.match(/scale\((.*)\)/);
- if (scaleMatch) {
- scale = scaleMatch[1].split(separator);
- }
- }
-
- var sx = (scale && scale[0]) ? parseFloat(scale[0]) : 1;
-
- return {
- translate: {
- tx: (translate && translate[0]) ? parseInt(translate[0], 10) : 0,
- ty: (translate && translate[1]) ? parseInt(translate[1], 10) : 0
- },
- rotate: {
- angle: (rotate && rotate[0]) ? parseInt(rotate[0], 10) : 0,
- cx: (rotate && rotate[1]) ? parseInt(rotate[1], 10) : undefined,
- cy: (rotate && rotate[2]) ? parseInt(rotate[2], 10) : undefined
- },
- scale: {
- sx: sx,
- sy: (scale && scale[1]) ? parseFloat(scale[1]) : sx
- }
- };
- }
-
-
- // Matrix decomposition.
- // ---------------------
-
- function deltaTransformPoint(matrix, point) {
-
- var dx = point.x * matrix.a + point.y * matrix.c + 0;
- var dy = point.x * matrix.b + point.y * matrix.d + 0;
- return { x: dx, y: dy };
- }
-
- function decomposeMatrix(matrix) {
-
- // @see https://gist.github.com/2052247
-
- // calculate delta transform point
- var px = deltaTransformPoint(matrix, { x: 0, y: 1 });
- var py = deltaTransformPoint(matrix, { x: 1, y: 0 });
-
- // calculate skew
- var skewX = ((180 / Math.PI) * Math.atan2(px.y, px.x) - 90);
- var skewY = ((180 / Math.PI) * Math.atan2(py.y, py.x));
-
- return {
-
- translateX: matrix.e,
- translateY: matrix.f,
- scaleX: Math.sqrt(matrix.a * matrix.a + matrix.b * matrix.b),
- scaleY: Math.sqrt(matrix.c * matrix.c + matrix.d * matrix.d),
- skewX: skewX,
- skewY: skewY,
- rotation: skewX // rotation is the same as skew x
- };
- }
-
- // VElement.
- // ---------
-
- function VElement(el) {
- this.node = el;
- if (!this.node.id) {
- this.node.id = uniqueId();
- }
- }
-
- // VElement public API.
- // --------------------
-
- VElement.prototype = {
-
- translate: function(tx, ty, opt) {
-
- opt = opt || {};
- ty = ty || 0;
-
- var transformAttr = this.attr('transform') || '';
- var transform = parseTransformString(transformAttr);
-
- // Is it a getter?
- if (typeof tx === 'undefined') {
- return transform.translate;
- }
-
- transformAttr = transformAttr.replace(/translate\([^\)]*\)/g, '').trim();
-
- var newTx = opt.absolute ? tx : transform.translate.tx + tx;
- var newTy = opt.absolute ? ty : transform.translate.ty + ty;
- var newTranslate = 'translate(' + newTx + ',' + newTy + ')';
-
- // Note that `translate()` is always the first transformation. This is
- // usually the desired case.
- this.attr('transform', (newTranslate + ' ' + transformAttr).trim());
- return this;
- },
-
- rotate: function(angle, cx, cy, opt) {
-
- opt = opt || {};
-
- var transformAttr = this.attr('transform') || '';
- var transform = parseTransformString(transformAttr);
-
- // Is it a getter?
- if (typeof angle === 'undefined') {
- return transform.rotate;
- }
-
- transformAttr = transformAttr.replace(/rotate\([^\)]*\)/g, '').trim();
-
- angle %= 360;
-
- var newAngle = opt.absolute ? angle : transform.rotate.angle + angle;
- var newOrigin = (cx !== undefined && cy !== undefined) ? ',' + cx + ',' + cy : '';
- var newRotate = 'rotate(' + newAngle + newOrigin + ')';
-
- this.attr('transform', (transformAttr + ' ' + newRotate).trim());
- return this;
- },
-
- // Note that `scale` as the only transformation does not combine with previous values.
- scale: function(sx, sy) {
- sy = (typeof sy === 'undefined') ? sx : sy;
-
- var transformAttr = this.attr('transform') || '';
- var transform = parseTransformString(transformAttr);
-
- // Is it a getter?
- if (typeof sx === 'undefined') {
- return transform.scale;
- }
-
- transformAttr = transformAttr.replace(/scale\([^\)]*\)/g, '').trim();
-
- var newScale = 'scale(' + sx + ',' + sy + ')';
-
- this.attr('transform', (transformAttr + ' ' + newScale).trim());
- return this;
- },
-
- // Get SVGRect that contains coordinates and dimension of the real bounding box,
- // i.e. after transformations are applied.
- // If `target` is specified, bounding box will be computed relatively to `target` element.
- bbox: function(withoutTransformations, target) {
-
- // If the element is not in the live DOM, it does not have a bounding box defined and
- // so fall back to 'zero' dimension element.
- if (!this.node.ownerSVGElement) return { x: 0, y: 0, width: 0, height: 0 };
-
- var box;
- try {
-
- box = this.node.getBBox();
-
- // Opera returns infinite values in some cases.
- // Note that Infinity | 0 produces 0 as opposed to Infinity || 0.
- // We also have to create new object as the standard says that you can't
- // modify the attributes of a bbox.
- box = { x: box.x | 0, y: box.y | 0, width: box.width | 0, height: box.height | 0 };
-
- } catch (e) {
-
- // Fallback for IE.
- box = {
- x: this.node.clientLeft,
- y: this.node.clientTop,
- width: this.node.clientWidth,
- height: this.node.clientHeight
- };
- }
-
- if (withoutTransformations) {
-
- return box;
- }
-
- var matrix = this.node.getTransformToElement(target || this.node.ownerSVGElement);
-
- return V.transformRect(box, matrix);
- },
-
- text: function(content, opt) {
-
- opt = opt || {};
- var lines = content.split('\n');
- var i = 0;
- var tspan;
-
- // `alignment-baseline` does not work in Firefox.
- // Setting `dominant-baseline` on the `<text>` element doesn't work in IE9.
- // In order to have the 0,0 coordinate of the `<text>` element (or the first `<tspan>`)
- // in the top left corner we translate the `<text>` element by `0.8em`.
- // See `http://www.w3.org/Graphics/SVG/WG/wiki/How_to_determine_dominant_baseline`.
- // See also `http://apike.ca/prog_svg_text_style.html`.
- this.attr('y', '0.8em');
-
- // An empty text gets rendered into the DOM in webkit-based browsers.
- // In order to unify this behaviour across all browsers
- // we rather hide the text element when it's empty.
- this.attr('display', content ? null : 'none');
-
- // Preserve spaces. In other words, we do not want consecutive spaces to get collapsed to one.
- this.node.setAttributeNS('http://www.w3.org/XML/1998/namespace', 'xml:space', 'preserve');
-
- // Easy way to erase all `<tspan>` children;
- this.node.textContent = '';
-
- var textNode = this.node;
-
- if (opt.textPath) {
-
- // Wrap the text in the SVG <textPath> element that points
- // to a path defined by `opt.textPath` inside the internal `<defs>` element.
- var defs = this.find('defs');
- if (defs.length === 0) {
- defs = createElement('defs');
- this.append(defs);
- }
-
- // If `opt.textPath` is a plain string, consider it to be directly the
- // SVG path data for the text to go along (this is a shortcut).
- // Otherwise if it is an object and contains the `d` property, then this is our path.
- var d = Object(opt.textPath) === opt.textPath ? opt.textPath.d : opt.textPath;
- if (d) {
- var path = createElement('path', { d: d });
- defs.append(path);
- }
-
- var textPath = createElement('textPath');
- // Set attributes on the `<textPath>`. The most important one
- // is the `xlink:href` that points to our newly created `<path/>` element in `<defs/>`.
- // Note that we also allow the following construct:
- // `t.text('my text', { textPath: { 'xlink:href': '#my-other-path' } })`.
- // In other words, one can completely skip the auto-creation of the path
- // and use any other arbitrary path that is in the document.
- if (!opt.textPath['xlink:href'] && path) {
- textPath.attr('xlink:href', '#' + path.node.id);
- }
-
- if (Object(opt.textPath) === opt.textPath) {
- textPath.attr(opt.textPath);
- }
- this.append(textPath);
- // Now all the `<tspan>`s will be inside the `<textPath>`.
- textNode = textPath.node;
- }
-
- if (lines.length === 1) {
- textNode.textContent = content;
- return this;
- }
-
- for (; i < lines.length; i++) {
-
- // Shift all the <tspan> but first by one line (`1em`)
- tspan = V('tspan', { dy: (i == 0 ? '0em' : opt.lineHeight || '1em'), x: this.attr('x') || 0 });
- tspan.addClass('v-line');
- if (!lines[i]) {
- tspan.addClass('v-empty-line');
- }
- // Make sure the textContent is never empty. If it is, add an additional
- // space (an invisible character) so that following lines are correctly
- // relatively positioned. `dy=1em` won't work with empty lines otherwise.
- tspan.node.textContent = lines[i] || ' ';
-
- V(textNode).append(tspan);
- }
- return this;
- },
-
- attr: function(name, value) {
-
- if (typeof name === 'undefined') {
- // Return all attributes.
- var attributes = this.node.attributes;
- var attrs = {};
- for (var i = 0; i < attributes.length; i++) {
- attrs[attributes[i].nodeName] = attributes[i].nodeValue;
- }
- return attrs;
- }
-
- if (typeof name === 'string' && typeof value === 'undefined') {
- return this.node.getAttribute(name);
- }
-
- if (typeof name === 'object') {
-
- for (var attrName in name) {
- if (name.hasOwnProperty(attrName)) {
- setAttribute(this.node, attrName, name[attrName]);
- }
- }
-
- } else {
-
- setAttribute(this.node, name, value);
- }
-
- return this;
- },
-
- remove: function() {
- if (this.node.parentNode) {
- this.node.parentNode.removeChild(this.node);
- }
- },
-
- append: function(el) {
-
- var els = el;
-
- if (Object.prototype.toString.call(el) !== '[object Array]') {
-
- els = [el];
- }
-
- for (var i = 0, len = els.length; i < len; i++) {
- el = els[i];
- this.node.appendChild(el instanceof VElement ? el.node : el);
- }
-
- return this;
- },
-
- prepend: function(el) {
- this.node.insertBefore(el instanceof VElement ? el.node : el, this.node.firstChild);
- },
-
- svg: function() {
-
- return this.node instanceof window.SVGSVGElement ? this : V(this.node.ownerSVGElement);
- },
-
- defs: function() {
-
- var defs = this.svg().node.getElementsByTagName('defs');
-
- return (defs && defs.length) ? V(defs[0]) : undefined;
- },
-
- clone: function() {
- var clone = V(this.node.cloneNode(true));
- // Note that clone inherits also ID. Therefore, we need to change it here.
- clone.node.id = uniqueId();
- return clone;
- },
-
- findOne: function(selector) {
-
- var found = this.node.querySelector(selector);
- return found ? V(found) : undefined;
- },
-
- find: function(selector) {
-
- var nodes = this.node.querySelectorAll(selector);
-
- // Map DOM elements to `VElement`s.
- for (var i = 0, len = nodes.length; i < len; i++) {
- nodes[i] = V(nodes[i]);
- }
- return nodes;
- },
-
- // Find an index of an element inside its container.
- index: function() {
-
- var index = 0;
- var node = this.node.previousSibling;
-
- while (node) {
- // nodeType 1 for ELEMENT_NODE
- if (node.nodeType === 1) index++;
- node = node.previousSibling;
- }
-
- return index;
- },
-
- // Convert global point into the coordinate space of this element.
- toLocalPoint: function(x, y) {
-
- var svg = this.svg().node;
-
- var p = svg.createSVGPoint();
- p.x = x;
- p.y = y;
-
- try {
-
- var globalPoint = p.matrixTransform(svg.getScreenCTM().inverse());
- var globalToLocalMatrix = this.node.getTransformToElement(svg).inverse();
-
- } catch (e) {
- // IE9 throws an exception in odd cases. (`Unexpected call to method or property access`)
- // We have to make do with the original coordianates.
- return p;
- }
-
- return globalPoint.matrixTransform(globalToLocalMatrix);
- },
-
- translateCenterToPoint: function(p) {
-
- var bbox = this.bbox();
- var center = g.rect(bbox).center();
-
- this.translate(p.x - center.x, p.y - center.y);
- },
-
- // Efficiently auto-orient an element. This basically implements the orient=auto attribute
- // of markers. The easiest way of understanding on what this does is to imagine the element is an
- // arrowhead. Calling this method on the arrowhead makes it point to the `position` point while
- // being auto-oriented (properly rotated) towards the `reference` point.
- // `target` is the element relative to which the transformations are applied. Usually a viewport.
- translateAndAutoOrient: function(position, reference, target) {
-
- // Clean-up previously set transformations except the scale. If we didn't clean up the
- // previous transformations then they'd add up with the old ones. Scale is an exception as
- // it doesn't add up, consider: `this.scale(2).scale(2).scale(2)`. The result is that the
- // element is scaled by the factor 2, not 8.
-
- var s = this.scale();
- this.attr('transform', '');
- this.scale(s.sx, s.sy);
-
- var svg = this.svg().node;
- var bbox = this.bbox(false, target);
-
- // 1. Translate to origin.
- var translateToOrigin = svg.createSVGTransform();
- translateToOrigin.setTranslate(-bbox.x - bbox.width / 2, -bbox.y - bbox.height / 2);
-
- // 2. Rotate around origin.
- var rotateAroundOrigin = svg.createSVGTransform();
- var angle = g.point(position).changeInAngle(position.x - reference.x, position.y - reference.y, reference);
- rotateAroundOrigin.setRotate(angle, 0, 0);
-
- // 3. Translate to the `position` + the offset (half my width) towards the `reference` point.
- var translateFinal = svg.createSVGTransform();
- var finalPosition = g.point(position).move(reference, bbox.width / 2);
- translateFinal.setTranslate(position.x + (position.x - finalPosition.x), position.y + (position.y - finalPosition.y));
-
- // 4. Apply transformations.
- var ctm = this.node.getTransformToElement(target);
- var transform = svg.createSVGTransform();
- transform.setMatrix(
- translateFinal.matrix.multiply(
- rotateAroundOrigin.matrix.multiply(
- translateToOrigin.matrix.multiply(
- ctm)))
- );
-
- // Instead of directly setting the `matrix()` transform on the element, first, decompose
- // the matrix into separate transforms. This allows us to use normal Vectorizer methods
- // as they don't work on matrices. An example of this is to retrieve a scale of an element.
- // this.node.transform.baseVal.initialize(transform);
-
- var decomposition = decomposeMatrix(transform.matrix);
-
- this.translate(decomposition.translateX, decomposition.translateY);
- this.rotate(decomposition.rotation);
- // Note that scale has been already applied, hence the following line stays commented. (it's here just for reference).
- //this.scale(decomposition.scaleX, decomposition.scaleY);
-
- return this;
- },
-
- animateAlongPath: function(attrs, path) {
-
- var animateMotion = V('animateMotion', attrs);
- var mpath = V('mpath', { 'xlink:href': '#' + V(path).node.id });
-
- animateMotion.append(mpath);
-
- this.append(animateMotion);
- try {
- animateMotion.node.beginElement();
- } catch (e) {
- // Fallback for IE 9.
- // Run the animation programatically if FakeSmile (`http://leunen.me/fakesmile/`) present
- if (document.documentElement.getAttribute('smiling') === 'fake') {
-
- // Register the animation. (See `https://answers.launchpad.net/smil/+question/203333`)
- var animation = animateMotion.node;
- animation.animators = [];
-
- var animationID = animation.getAttribute('id');
- if (animationID) id2anim[animationID] = animation;
-
- var targets = getTargets(animation);
- for (var i = 0, len = targets.length; i < len; i++) {
- var target = targets[i];
- var animator = new Animator(animation, target, i);
- animators.push(animator);
- animation.animators[i] = animator;
- animator.register();
- }
- }
- }
- },
-
- hasClass: function(className) {
-
- return new RegExp('(\\s|^)' + className + '(\\s|$)').test(this.node.getAttribute('class'));
- },
-
- addClass: function(className) {
-
- if (!this.hasClass(className)) {
- var prevClasses = this.node.getAttribute('class') || '';
- this.node.setAttribute('class', (prevClasses + ' ' + className).trim());
- }
-
- return this;
- },
-
- removeClass: function(className) {
-
- if (this.hasClass(className)) {
- var newClasses = this.node.getAttribute('class').replace(new RegExp('(\\s|^)' + className + '(\\s|$)', 'g'), '$2');
- this.node.setAttribute('class', newClasses);
- }
-
- return this;
- },
-
- toggleClass: function(className, toAdd) {
-
- var toRemove = typeof toAdd === 'undefined' ? this.hasClass(className) : !toAdd;
-
- if (toRemove) {
- this.removeClass(className);
- } else {
- this.addClass(className);
- }
-
- return this;
- },
-
- // Interpolate path by discrete points. The precision of the sampling
- // is controlled by `interval`. In other words, `sample()` will generate
- // a point on the path starting at the beginning of the path going to the end
- // every `interval` pixels.
- // The sampler can be very useful for e.g. finding intersection between two
- // paths (finding the two closest points from two samples).
- sample: function(interval) {
-
- interval = interval || 1;
- var node = this.node;
- var length = node.getTotalLength();
- var samples = [];
- var distance = 0;
- var sample;
- while (distance < length) {
- sample = node.getPointAtLength(distance);
- samples.push({ x: sample.x, y: sample.y, distance: distance });
- distance += interval;
- }
- return samples;
- },
-
- convertToPath: function() {
-
- var path = createElement('path');
- path.attr(this.attr());
- var d = this.convertToPathData();
- if (d) {
- path.attr('d', d);
- }
- return path;
- },
-
- convertToPathData: function() {
-
- var tagName = this.node.tagName.toUpperCase();
-
- switch (tagName) {
- case 'PATH':
- return this.attr('d');
- case 'LINE':
- return convertLineToPathData(this.node);
- case 'POLYGON':
- return convertPolygonToPathData(this.node);
- case 'POLYLINE':
- return convertPolylineToPathData(this.node);
- case 'ELLIPSE':
- return convertEllipseToPathData(this.node);
- case 'CIRCLE':
- return convertCircleToPathData(this.node);
- case 'RECT':
- return convertRectToPathData(this.node);
- }
-
- throw new Error(tagName + ' cannot be converted to PATH.');
- },
-
- // Find the intersection of a line starting in the center
- // of the SVG `node` ending in the point `ref`.
- // `target` is an SVG element to which `node`s transformations are relative to.
- // In JointJS, `target` is the `paper.viewport` SVG group element.
- // Note that `ref` point must be in the coordinate system of the `target` for this function to work properly.
- // Returns a point in the `target` coordinte system (the same system as `ref` is in) if
- // an intersection is found. Returns `undefined` otherwise.
- findIntersection: function(ref, target) {
-
- var svg = this.svg().node;
- target = target || svg;
- var bbox = g.rect(this.bbox(false, target));
- var center = bbox.center();
- var spot = bbox.intersectionWithLineFromCenterToPoint(ref);
-
- if (!spot) return undefined;
-
- var tagName = this.node.localName.toUpperCase();
-
- // Little speed up optimalization for `<rect>` element. We do not do conversion
- // to path element and sampling but directly calculate the intersection through
- // a transformed geometrical rectangle.
- if (tagName === 'RECT') {
-
- var gRect = g.rect(
- parseFloat(this.attr('x') || 0),
- parseFloat(this.attr('y') || 0),
- parseFloat(this.attr('width')),
- parseFloat(this.attr('height'))
- );
- // Get the rect transformation matrix with regards to the SVG document.
- var rectMatrix = this.node.getTransformToElement(target);
- // Decompose the matrix to find the rotation angle.
- var rectMatrixComponents = V.decomposeMatrix(rectMatrix);
- // Now we want to rotate the rectangle back so that we
- // can use `intersectionWithLineFromCenterToPoint()` passing the angle as the second argument.
- var resetRotation = svg.createSVGTransform();
- resetRotation.setRotate(-rectMatrixComponents.rotation, center.x, center.y);
- var rect = V.transformRect(gRect, resetRotation.matrix.multiply(rectMatrix));
- spot = g.rect(rect).intersectionWithLineFromCenterToPoint(ref, rectMatrixComponents.rotation);
-
- } else if (tagName === 'PATH' || tagName === 'POLYGON' || tagName === 'POLYLINE' || tagName === 'CIRCLE' || tagName === 'ELLIPSE') {
-
- var pathNode = (tagName === 'PATH') ? this : this.convertToPath();
- var samples = pathNode.sample();
- var minDistance = Infinity;
- var closestSamples = [];
-
- for (var i = 0, len = samples.length; i < len; i++) {
-
- var sample = samples[i];
- // Convert the sample point in the local coordinate system to the global coordinate system.
- var gp = V.createSVGPoint(sample.x, sample.y);
- gp = gp.matrixTransform(this.node.getTransformToElement(target));
- sample = g.point(gp);
- var centerDistance = sample.distance(center);
- // Penalize a higher distance to the reference point by 10%.
- // This gives better results. This is due to
- // inaccuracies introduced by rounding errors and getPointAtLength() returns.
- var refDistance = sample.distance(ref) * 1.1;
- var distance = centerDistance + refDistance;
- if (distance < minDistance) {
- minDistance = distance;
- closestSamples = [{ sample: sample, refDistance: refDistance }];
- } else if (distance < minDistance + 1) {
- closestSamples.push({ sample: sample, refDistance: refDistance });
- }
- }
- closestSamples.sort(function(a, b) { return a.refDistance - b.refDistance; });
- spot = closestSamples[0].sample;
- }
-
- return spot;
- }
- };
-
- function convertLineToPathData(line) {
-
- line = createElement(line);
- var d = [
- 'M', line.attr('x1'), line.attr('y1'),
- 'L', line.attr('x2'), line.attr('y2')
- ].join(' ');
- return d;
- }
-
- function convertPolygonToPathData(polygon) {
-
- polygon = createElement(polygon);
- var points = polygon.node.points;
-
- var d = [];
- var p;
- for (var i = 0; i < points.length; i++) {
- p = points[i];
- d.push(i === 0 ? 'M' : 'L', p.x, p.y);
- }
- d.push('Z');
- return d.join(' ');
- }
-
- function convertPolylineToPathData(polyline) {
-
- polyline = createElement(polyline);
- var points = polyline.node.points;
-
- var d = [];
- var p;
- for (var i = 0; i < points.length; i++) {
- p = points[i];
- d.push(i === 0 ? 'M' : 'L', p.x, p.y);
- }
- return d.join(' ');
- }
-
- var KAPPA = 0.5522847498307935;
-
- function convertCircleToPathData(circle) {
-
- circle = createElement(circle);
- var cx = parseFloat(circle.attr('cx')) || 0;
- var cy = parseFloat(circle.attr('cy')) || 0;
- var r = parseFloat(circle.attr('r'));
- var cd = r * KAPPA; // Control distance.
-
- var d = [
- 'M', cx, cy - r, // Move to the first point.
- 'C', cx + cd, cy - r, cx + r, cy - cd, cx + r, cy, // I. Quadrant.
- 'C', cx + r, cy + cd, cx + cd, cy + r, cx, cy + r, // II. Quadrant.
- 'C', cx - cd, cy + r, cx - r, cy + cd, cx - r, cy, // III. Quadrant.
- 'C', cx - r, cy - cd, cx - cd, cy - r, cx, cy - r, // IV. Quadrant.
- 'Z'
- ].join(' ');
- return d;
- }
-
- function convertEllipseToPathData(ellipse) {
-
- ellipse = createElement(ellipse);
- var cx = parseFloat(ellipse.attr('cx')) || 0;
- var cy = parseFloat(ellipse.attr('cy')) || 0;
- var rx = parseFloat(ellipse.attr('rx'));
- var ry = parseFloat(ellipse.attr('ry')) || rx;
- var cdx = rx * KAPPA; // Control distance x.
- var cdy = ry * KAPPA; // Control distance y.
-
- var d = [
- 'M', cx, cy - ry, // Move to the first point.
- 'C', cx + cdx, cy - ry, cx + rx, cy - cdy, cx + rx, cy, // I. Quadrant.
- 'C', cx + rx, cy + cdy, cx + cdx, cy + ry, cx, cy + ry, // II. Quadrant.
- 'C', cx - cdx, cy + ry, cx - rx, cy + cdy, cx - rx, cy, // III. Quadrant.
- 'C', cx - rx, cy - cdy, cx - cdx, cy - ry, cx, cy - ry, // IV. Quadrant.
- 'Z'
- ].join(' ');
- return d;
- }
-
- function convertRectToPathData(rect) {
-
- rect = createElement(rect);
- var x = parseFloat(rect.attr('x')) || 0;
- var y = parseFloat(rect.attr('y')) || 0;
- var width = parseFloat(rect.attr('width')) || 0;
- var height = parseFloat(rect.attr('height')) || 0;
- var rx = parseFloat(rect.attr('rx')) || 0;
- var ry = parseFloat(rect.attr('ry')) || 0;
- var bbox = g.rect(x, y, width, height);
-
- var d;
-
- if (!rx && !ry) {
-
- d = [
- 'M', bbox.origin().x, bbox.origin().y,
- 'H', bbox.corner().x,
- 'V', bbox.corner().y,
- 'H', bbox.origin().x,
- 'V', bbox.origin().y,
- 'Z'
- ].join(' ');
-
- } else {
-
- var r = x + width;
- var b = y + height;
- d = [
- 'M', x + rx, y,
- 'L', r - rx, y,
- 'Q', r, y, r, y + ry,
- 'L', r, y + height - ry,
- 'Q', r, b, r - rx, b,
- 'L', x + rx, b,
- 'Q', x, b, x, b - rx,
- 'L', x, y + ry,
- 'Q', x, y, x + rx, y,
- 'Z'
- ].join(' ');
- }
- return d;
- }
-
- // Convert a rectangle to SVG path commands. `r` is an object of the form:
- // `{ x: [number], y: [number], width: [number], height: [number], top-ry: [number], top-ry: [number], bottom-rx: [number], bottom-ry: [number] }`,
- // where `x, y, width, height` are the usual rectangle attributes and [top-/bottom-]rx/ry allows for
- // specifying radius of the rectangle for all its sides (as opposed to the built-in SVG rectangle
- // that has only `rx` and `ry` attributes).
- function rectToPath(r) {
-
- var topRx = r.rx || r['top-rx'] || 0;
- var bottomRx = r.rx || r['bottom-rx'] || 0;
- var topRy = r.ry || r['top-ry'] || 0;
- var bottomRy = r.ry || r['bottom-ry'] || 0;
-
- return [
- 'M', r.x, r.y + topRy,
- 'v', r.height - topRy - bottomRy,
- 'a', bottomRx, bottomRy, 0, 0, 0, bottomRx, bottomRy,
- 'h', r.width - 2 * bottomRx,
- 'a', bottomRx, bottomRy, 0, 0, 0, bottomRx, -bottomRy,
- 'v', -(r.height - bottomRy - topRy),
- 'a', topRx, topRy, 0, 0, 0, -topRx, -topRy,
- 'h', -(r.width - 2 * topRx),
- 'a', topRx, topRy, 0, 0, 0, -topRx, topRy
- ].join(' ');
- }
-
- var V = createElement;
-
- V.decomposeMatrix = decomposeMatrix;
- V.rectToPath = rectToPath;
-
- var svgDocument = V('svg').node;
-
- V.createSVGMatrix = function(m) {
-
- var svgMatrix = svgDocument.createSVGMatrix();
- for (var component in m) {
- svgMatrix[component] = m[component];
- }
-
- return svgMatrix;
- };
-
- V.createSVGTransform = function() {
-
- return svgDocument.createSVGTransform();
- };
-
- V.createSVGPoint = function(x, y) {
-
- var p = svgDocument.createSVGPoint();
- p.x = x;
- p.y = y;
- return p;
- };
-
- V.transformRect = function(r, matrix) {
-
- var p = svgDocument.createSVGPoint();
-
- p.x = r.x;
- p.y = r.y;
- var corner1 = p.matrixTransform(matrix);
-
- p.x = r.x + r.width;
- p.y = r.y;
- var corner2 = p.matrixTransform(matrix);
-
- p.x = r.x + r.width;
- p.y = r.y + r.height;
- var corner3 = p.matrixTransform(matrix);
-
- p.x = r.x;
- p.y = r.y + r.height;
- var corner4 = p.matrixTransform(matrix);
-
- var minX = Math.min(corner1.x, corner2.x, corner3.x, corner4.x);
- var maxX = Math.max(corner1.x, corner2.x, corner3.x, corner4.x);
- var minY = Math.min(corner1.y, corner2.y, corner3.y, corner4.y);
- var maxY = Math.max(corner1.y, corner2.y, corner3.y, corner4.y);
-
- return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
- };
-
- return V;
-
-}));
+++ /dev/null
-<div ng-controller="actionRefCtrl" ng-init="init()">
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <section ng-show="internalView.actionRef">
- <form name="actionRefForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
-
- <div class="rowWrapper">
- <label class="block basicLabel"><span>Name:</span>
- <i class="icon-exclamation-sign red" tooltip="Required field" ng-show="actionRefForm.name.$error.required"></i>
- </label>
- <select class="form-control" ng-model="newActionRefObj.name" ng-options="c.name as getDisplayLabel(c, actionInstanceNames.labels) for c in actionInstanceNames.options" name="name" ng-required="true" ng-disabled="internalView.edit !== 'add'">
- <option>--</option>
- </select>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newActionRefObj['order']">
- <label class="block basicLabel"><span>Order:</span>
- <i class="icon-exclamation-sign red" tooltip="Invalid pattern" ng-show="errors.int32"></i>
- </label>
- <input class="form-control" type="text" ng-model="newActionRefObj.order" ng-disabled="internalView.edit === 'view'" ng-change="validate(newActionRefObj.order, errors)"/>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-hide="internalView.edit === 'view'">Save</button>
- </form>
- </section>
-
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="actionsCtrl" ng-init="init()">
- <h2 class="text-center">Actions</h2>
-
-<div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <section class="formWrapper clearfix" ng-show="actionsView">
- <form name="actionsForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
- <label class="block">Add actions</label>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Name
- <i class="icon-exclamation-sign red" tooltip="{{actionsForm.name.$error.required ? 'Required field' : actionsForm.name.$error.pattern ? 'Value must start with letter followed by letters and digits without space' : ''}}" ng-show="actionsForm.name.$error.required || actionsForm.name.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" name="name" ng-required="true" ng-model="newActionObj.name" ng-disabled="edit !== 'add'" ng-pattern="/^[a-zA-Z]([a-zA-Z0-9\-_.])*$/"/>
- </div>
-
- <div class="rowWrapper" ng-hide="edit === 'view' && !newActionObj['action-definition-id']">
- <label class="block basicLabel">Definition</label>
- <select class="form-control" ng-model="newActionObj['action-definition-id']" ng-options="d.id as getDisplayLabel(d, actionDefinitions.labels) for d in actionDefinitions.options" ng-disabled="edit === 'view'" ng-change="reloadDefs()">
- <option value="">Select option</option>
- </select>
- </div>
-
- <div class="rowWrapper">
- <div ng-repeat="param in defs">
- <div class="row-param" ng-controller="paramCtrl" ng-init="init(param, newActionObj['parameter-value'])">
- <div ng-show="param.type !== 'range'">
- <label>{{ parameter.name + ' (' + parameter.type + ')' }}:</label>
- <input class="form-control" type="text" ng-model="value" ng-disabled="edit === 'view'"></input>
- </div>
- <div ng-show="param.type === 'range'">
- <label class="param-label">{{ parameter.name + ' (' + parameter.type + ')' }}:</label>
-
- <input class="form-control narrow-input-left" type="text" ng-model="value.min" ng-disabled="edit === 'view'"></input>
- <input class="form-control narrow-input-right" type="text" ng-model="value.max" ng-disabled="edit === 'view'"></input>
- </div>
- </div>
- </div>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-hide="edit === 'view'">Save</button>
- </form>
- </section>
-
-
- <button class="btn btn-primary bottom-buttons full-width wizard-button" ng-click="showWizard('accessModelWizard')"><i class="icon-magic"></i>Access Model Wizard</button>
- <button class="btn btn-primary col-md-12 bottom-buttons home" ng-click="toggleExpandedMM('main')">Home</button>
- <button class="btn btn-primary col-md-12 bottom-buttons back" ng-click="setViewExpand('policyRendererView', 'basic', true); setBreadcrumb('l3', null, false);">Back</button>
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="boxStaticCtrl" class="simpleBox maxHeight500">
- <h2 class="text-center">Contract</h2>
-
- <section class="formWrapper clearfix">
-
- <div class="rowWrapper">
- <label class="block mb0">Id:</label>
- <span class="block">{{selectedObj.id}}</span>
- </div>
-
- <div class="rowWrapper" ng-hide="!selectedObj.description">
- <label class="block mb0">Description:</label>
- <span class="block">{{selectedObj.description}}</span>
- </div>
-
- <div class="rowWrapper" ng-hide="!selectedObj.parent">
- <label class="block mb0">Parent:</label>
- <span class="block">{{selectedObj.parent}}</span>
- </div>
-
- </section>
-
- <section class="formWrapper clearfix" ng-show="selectedObj['clause']" ng-repeat="clause in selectedObj['clause'] track by $index">
- <label class="block">Clause</label>
-
- <div class="rowWrapper">
- <label class="block mb0">Name:</label>
- <span>{{clause.name}}</span>
- </div>
-
- <div class="rowWrapper">
- <label class="block mb0">Clause subjects:</label>
- <span class="block" ng-repeat="subj in clause['subject-refs'] track by $index">{{subj}}</span>
- </div>
- </section>
-
-
- <section class="formWrapper clearfix" ng-repeat="subject in selectedObj['subject']" ng-show="selectedObj['subject']">
- <label class="block">Subject</label>
- <div class="rowWrapper">
- <label class="block mb0">Name:</label>
- <span class="block">{{subject.name}}</span>
- <!-- <input class="form-control" type="text" ng-model="selectedObj.name" ng-disabled="true"/> -->
- </div>
-
- <div class="rowWrapper" ng-show="subject['providers']">
- <label class="block">Provider list:</label>
- <span class="block" ng-repeat="provider in subject['providers'] track by $index">
- {{provider}}
- </span>
- </div>
-
- <div class="rowWrapper" ng-show="subject['consumers']">
- <label class="block">Consumer list:</label>
- <span class="block" ng-repeat="consumer in subject['consumers'] track by $index">
- {{consumer}}
- </span>
- </div>
-
- <div class="rowWrapper" ng-show="subject['rule']" ng-repeat="rule in subject['rule'] track by $index">
- <label class="block">Rule</label>
- <section class="ml10">
- <label class="basicLabel">Name:</label>
- <span>{{rule.name}}</span>
-
-
- <section class="mb10" ng-repeat="classifier in rule['classifier-ref'] track by $index" ng-show="rule['classifier-ref']">
- <label class="block mb0"><span>Classifier ref</span></label>
-
- <div>
- <label class="basicLabel mb0">Name:</label>
- <span>{{classifier.name}}</span>
- </div>
-
- <div>
- <label class="basicLabel mb0">Instance name:</label>
- <span>{{classifier['instance-name']}}</span>
- </div>
-
- <div ng-show="classifier.direction">
- <label class="basicLabel mb0">Direction:</label>
- <span>{{classifier.direction}}</span>
- </div>
-
- <div ng-show="classifier.direction">
- <label class="basicLabel mb0">Connection tracking:</label>
- <span>{{classifier['connection-tracking']}}</span>
- </div>
-
- </section>
-
- <label class="block mb0"><span>Action ref</span> <button class="btn btn-primary" ng-click="showWizard('actionReferenceWizard', 'ACTION_RULE_WIZARD_LOAD', rule, {tenantId: selectedTenant.id, contractId: selectedObj.id, subjectId: subject.name, ruleId: rule.name})">Manage</button></label>
- <section class="mb10" ng-show="rule['action-ref']" ng-repeat="action in rule['action-ref'] track by $index">
- <div class="rowWrapper">
- <label class="basicLabel mb0">Name:</label>
- <span>{{action.name}}</span>
- </div>
-
- </section>
-
- </section>
- </div>
-
- </section>
-
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="boxStaticCtrl" class="simpleBox maxHeight500">
- <h2 class="text-center">Endpoint</h2>
-
- <section class="formWrapper clearfix">
- <div class="rowWrapper">
- <label class="block mb0">Endpoint group</label>
- <span class="block">{{selectedObj['endpoint-group']}}</span>
- </div>
-
- <div class="rowWrapper">
- <label class="block mb0">Network containment</label>
- <span class="block">{{selectedObj['network-containment']}}</span>
- </div>
-
- <div class="rowWrapper">
- <label class="block mb0">L2 Contect:</label>
- <span class="block">{{selectedObj['l2-context']}}</span>
- </div>
-
- <div class="rowWrapper">
- <label class="block mb0">MAC address</label>
- <span class="block">{{selectedObj['mac-address']}}</span>
- </div>
- </section>
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="boxStaticCtrl" class="simpleBox maxHeight500">
- <h2 class="text-center">Endpoint groups</h2>
-
- <section class="formWrapper clearfix">
-
- <div class="rowWrapper">
- <label class="block mb0">Id:</label>
- <span class="block">{{selectedObj.id}}</span>
- </div>
-
- <div class="rowWrapper" ng-hide="!selectedObj['name']">
- <label class="block mb0">Name:</label>
- <span class="block">{{selectedObj.name}}</span>
- </div>
-
- <div class="rowWrapper" ng-hide="!selectedObj['description']">
- <label class="block mb0">Description:</label>
- <span class="block">{{selectedObj.description}}</span>
- </div>
-
- <div class="rowWrapper" ng-hide="!selectedObj['intra-group-policy']">
- <label class="block mb0">Intra group policy:</label>
- <span class="block">{{selectedObj['intra-group-policy']}}</span>
- </div>
-
- <div class="rowWrapper" ng-hide="!selectedObj['network-domain']">
- <label class="block mb0">Network domain:</label>
- <span class="block">{{selectedObj['network-domain']}}</span>
- </div>
-
- <div class="rowWrapper" ng-hide="!selectedObj['parent']">
- <label class="block mb0">Parent:</label>
- <span class="block">{{selectedObj.parent}}</span>
- </div>
-
- <div class="rowWrapper mt20" ng-hide="!selectedObj['consumer-named-selector']">
- <label class="block"><span>Consumer named selectors list</span></label>
-
- <div class="ml10" ng-repeat="cns in selectedObj['consumer-named-selector']">
-
- <div class="rowWrapper">
- <label class="block">Name:</label>
- <span class="block">{{cns.name}}</span>
- </div>
-
- <div class="rowWrapper">
- <label class="block">Contracts:</label>
- <span class="block" ng-repeat="con in cns.contract track by $index">{{con}}</span>
- </div>
-
- </div>
- </div>
-
- <div class="rowWrapper mt20" ng-hide="!selectedObj['provider-named-selector']">
- <label class="block"><span>Provider named selectors list</span></label>
-
- <div class="ml10" ng-repeat="pns in selectedObj['provider-named-selector']">
-
- <div class="rowWrapper">
- <label class="block">Name:</label>
- <span class="block">{{pns.name}}</span>
- </div>
-
- <div class="rowWrapper">
- <label class="block">Contracts:</label>
- <span class="block" ng-repeat="con in pns.contract track by $index">{{con}}</span>
- </div>
-
- </div>
- </div>
- </section>
-
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="boxStaticCtrl" class="simpleBox maxHeight500">
- <h2 class="text-center">Rule</h2>
-
- <section class="formWrapper clearfix">
- <section>
- <label class="block">Name:</label>
- <span>{{selectedObj.name}}</span>
-
-
- <section class="formWrapper" ng-repeat="classifier in selectedObj['classifier-ref'] track by $index" ng-show="selectedObj['classifier-ref']">
- <label class="block mb0"><span>Classifier ref</span></label>
-
- <div>
- <label class="basicLabel mb0">Name:</label>
- <span>{{classifier.name}}</span>
- </div>
-
- <div ng-show="classifier.direction">
- <label class="basicLabel mb0">Direction:</label>
- <span>{{classifier.direction}}</span>
- </div>
- </section>
-
- <section class="formWrapper" ng-show="selectedObj['action-ref']" ng-repeat="action in selectedObj['action-ref'] track by $index">
-
- <label class="block mb0"><span>Action ref</span></label>
-
- <div class="rowWrapper">
- <label class="basicLabel mb0">Name:</label>
- <span>{{action.name}}</span>
- </div>
-
- </section>
-
- </section>
- </section>
-
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="boxStaticCtrl" class="simpleBox maxHeight500">
- <h2 class="text-center">Subject</h2>
-
- <section class="formWrapper clearfix">
- <div class="rowWrapper">
- <label class="block mb0">Name:</label>
- <span class="block">{{selectedObj.name}}</span>
- <!-- <input class="form-control" type="text" ng-model="selectedObj.name" ng-disabled="true"/> -->
- </div>
-
- <div class="rowWrapper" ng-show="selectedObj['providers']">
- <label class="block">Provider list (Endpoint groups):</label>
- <ul>
- <li ng-repeat="provider in selectedObj['providers'] track by $index">
- {{getLabel(provider, 'providerItems')}}
- </li>
- </ul>
- </div>
-
- <div class="rowWrapper" ng-show="selectedObj['consumers']">
- <label class="block">Consumer list (Endpoint groups):</label>
- <ul>
- <li ng-repeat="consumer in selectedObj['consumers'] track by $index">
- {{getLabel(consumer, 'consumerItems')}}
- </li>
- </ul>
- </div>
-
- </section>
-
- <h2 class="text-center" ng-show="selectedObj['rules']">Rules</h2>
-
- <section class="formWrapper clearfix" ng-show="selectedObj['rules']" ng-repeat="rule in selectedObj['rules'] track by $index">
- <!-- <label class="block">Rule</label> -->
- <section class="ml10">
- <label class="block">Rule:</label>
- <span>{{rule.name}}</span>
-
- <label class="block mb0 ml20"><span>Classifier instances:</span></label>
- <section class="mb10 ml20" ng-repeat="classifier in rule['classifier-ref'] track by $index" ng-show="rule['classifier-ref']">
-
- <div>
- <label class="basicLabel mb0">Name:</label>
- <span>{{classifier.name}}</span>
- </div>
-
- <div>
- <label class="basicLabel mb0">Instance name:</label>
- <span>{{classifier['instance-name']}}</span>
- </div>
-
- <div ng-show="classifier.direction">
- <label class="basicLabel mb0">Direction:</label>
- <span>{{classifier.direction}}</span>
- </div>
- <div ng-show="classifier.direction">
- <label class="basicLabel mb0">Connection tracking:</label>
- <span>{{classifier['connection-tracking']}}</span>
- </div>
-
- <label class="block ml30">Parameters:</label>
-
- <section class="mb10 ml30" ng-repeat="param in classifier.parameters track by $index" ng-show="classifier.parameters">
- <div>
- <label class="basicLabel mb0">{{param.name}}:</label>
- <span>{{param['int-value']}}</span>
- </div>
- </section>
- </section>
-
- <section class="mb10 ml20" ng-show="rule['action-ref']" ng-repeat="action in rule['action-ref'] track by $index">
-
- <label class="block mb0"><span>Action ref</span></label>
-
- <div class="rowWrapper">
- <label class="basicLabel mb0">Name:</label>
- <span>{{action.name}}</span>
- </div>
-
- </section>
-
- </section>
- </section>
-
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="classifierRefCtrl" ng-init="init()">
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <section ng-show="internalView.classifierRef">
- <form name="classifierRefForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
-
- <div class="rowWrapper">
- <label class="block basicLabel"><span>Name:</span>
- <i class="icon-exclamation-sign red" tooltip="{{classifierRefForm.name.$error.required ? 'Required field' : classifierRefForm.name.$error.pattern ? 'Value must start with letter followed by letters and digits without space' : ''}}" ng-show="classifierRefForm.name.$error.required || classifierRefForm.name.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" ng-model="newClassifierRefObj.name" name="name" ng-required="true" ng-disabled="internalView.edit !== 'add'" ng-pattern="/^[a-zA-Z]([a-zA-Z0-9\-_.])*$/"/>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newClassifierRefObj['instance-name']">
- <label class="block basicLabel"><span>Instance name:</span></label>
- <select class="form-control" ng-model="newClassifierRefObj['instance-name']" ng-options="c.name as getDisplayLabel(c, instanceNames.labels) for c in instanceNames.options" ng-disabled="internalView.edit === 'view'">
- <option>--</option>
- </select>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newClassifierRefObj['direction']">
- <label class="block basicLabel"><span>Direction:</span></label>
- <select class="form-control" ng-model="newClassifierRefObj.direction" ng-options="c for c in formDirections" ng-disabled="internalView.edit === 'view'">
- <option>--</option>
- </select>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newClassifierRefObj['connection-tracking']">
- <label class="block basicLabel"><span>Connection tracking:</span></label>
- <select class="form-control" ng-model="newClassifierRefObj['connection-tracking']" ng-options="c for c in formConnectionTracking" ng-disabled="internalView.edit === 'view'">
- <option>--</option>
- </select>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-hide="internalView.edit === 'view'">Save</button>
- </form>
- </section>
-
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="classifiersCtrl" ng-init="init()">
- <h2 class="text-center">Classifiers</h2>
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <section class="formWrapper clearfix" ng-show="classifiersView">
- <form name="classifierForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
- <label class="block">Add classifiers</label>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Name
- <i class="icon-exclamation-sign red" tooltip="{{classifierForm.name.$error.required ? 'Required field' : classifierForm.name.$error.pattern ? 'Value must start with letter followed by letters and digits without space' : ''}}" ng-show="classifierForm.name.$error.required || classifierForm.name.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" name="name" ng-required="true" ng-model="newClassifierObj.name" ng-disabled="edit !== 'add'" ng-pattern="/^[a-zA-Z]([a-zA-Z0-9\-_.])*$/"/>
- </div>
-
- <div class="rowWrapper" ng-hide="edit === 'view' && !newClassifierObj['classifier-definition-id']">
- <label class="block basicLabel">Definition</label>
- <select class="form-control" ng-model="newClassifierObj['classifier-definition-id']" ng-options="d.id as getDisplayLabel(d, classifierDefinitions.labels) for d in classifierDefinitions.options" ng-change="reloadDefs()" ng-disabled="edit === 'view'">
- <option value="">Select option</option>
- </select>
- </div>
-
- <div class="rowWrapper clearfix">
- <div ng-repeat="param in defs">
- <div class="rowWrapper" ng-controller="paramCtrl" ng-init="init(param, newClassifierObj['parameter-value'])">
- <div ng-show="param.type !== 'range'">
- <label class="block basicLabel">{{ parameter.name + ' (' + parameter.type + ')' }}:</label>
- <input class="form-control" type="text" ng-model="value" ng-disabled="edit === 'view'"></input>
- </div>
- <div ng-show="param.type === 'range'">
- <label class="block basicLabel">{{ parameter.name + ' (' + parameter.type + ')' }}:</label>
-
- <div class="col-md-6 inputWrapper leftInput">
- <input class="form-control" type="text" ng-model="value.min" ng-disabled="edit === 'view'"></input>
- </div>
- <div class="col-md-6 inputWrapper rightInput">
- <input class="form-control col-md-6" type="text" ng-model="value.max" ng-disabled="edit === 'view'"></input>
- </div>
-
- </div>
- </div>
- </div>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-hide="edit === 'view'">Save</button>
- </form>
- </section>
-
- <button class="btn btn-primary bottom-buttons full-width wizard-button" ng-click="showWizard('accessModelWizard')"><i class="icon-magic"></i>Access Model Wizard</button>
- <button class="btn btn-primary col-md-12 bottom-buttons home" ng-click="toggleExpandedMM('main')">Home</button>
- <button class="btn btn-primary col-md-12 bottom-buttons back" ng-click="setViewExpand('policyRendererView', 'basic', true); setBreadcrumb('l3', null, false);">Back</button>
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="clauseCtrl" ng-init="init()">
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <section class="formWrapper clearfix" ng-show="internalView.clause">
- <form name="clauseForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
-
- <div class="rowWrapper">
- <label class="block basicLabel"><span>Name:</span>
- <i class="icon-exclamation-sign red" tooltip="{{clauseForm.name.$error.required ? 'Required field' : clauseForm.name.$error.pattern ? 'Value must start with letter followed by letters and digits without space' : ''}}" ng-show="clauseForm.name.$error.required || clauseForm.name.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" ng-model="newClauseObj.name" name="name" ng-required="true" ng-disabled="internalView.edit !== 'add'" ng-pattern="/^[a-zA-Z]([a-zA-Z0-9\-_.])*$/"/>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newClauseObj['subject-refs']">
- <label class="basicLabel"><span>Clause subjects:</span></label>
- <button class="btn btn-primary btn-slim" ng-click="addNewElem()" ng-hide="internalView.edit === 'view'"><i class="icon-plus"></i></button>
-
- <div ng-repeat="subjectRef in newClauseObj['subject-refs'] track by $index">
- <div class="selectWrapper col-md-10">
- <select class="form-control" ng-model="subjectRef" ng-change="updateAt($index, subjectRef)" ng-options="s.name as getDisplayLabel(s, subjects.labels) for s in subjects.options" ng-disabled="internalView.edit === 'view'">
- <option>--</option>
- </select>
- </div>
- <button class="btn btn-danger col-md-2" ng-click="deleteElemAt($index)" ng-hide="internalView.edit === 'view'"><i class="icon-remove"></i></button>
- </div>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-hide="internalView.edit === 'view'">Save</button>
- </form>
- </section>
-
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="cnsCtrl" ng-init="init()">
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <section class="formWrapper clearfix" ng-show="internalView.cns">
- <form name="cnsForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Name:
- <i class="icon-exclamation-sign red" tooltip="Required field" ng-show="cnsForm.name.$error.required"></i>
- </label>
- <input class="form-control" type="text" name="name" ng-model="newCNSObj.name" ng-disabled="internalView.edit !== 'add'" ng-required="true" />
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newCNSObj['contract']">
- <label class="basicLabel">Contracts:</label>
- <button class="btn btn-primary btn-slim" ng-click="addNewElem()" ng-hide="internalView.edit === 'view'"><i class="icon-plus"></i></button>
-
- <div ng-repeat="contractRef in newCNSObj.contract track by $index">
- <div class="selectWrapper col-md-10">
- <select class="form-control" ng-model="contractRef" ng-change="updateAt($index, contractRef)" ng-options="c.id as getDisplayLabel(c, contracts.labels) for c in contracts.options" ng-disabled="internalView.edit === 'view'">
- <option>--</option>
- </select>
- </div>
- <button class="btn btn-danger col-md-2" ng-click="deleteElemAt($index)" ng-hide="internalView.edit === 'view'"><i class="icon-remove"></i></button>
- </div>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-hide="internalView.edit === 'view'">Save</button>
- </form>
- </section>
-
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="contractCtrl" ng-init="init()">
-
- <h2 class="text-center">Contracts</h2>
-
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <section class="formWrapper clearfix" ng-show="internalView.contract">
- <i class="icon-remove align-right" ng-click="close()"></i>
- <label class="block">Add contract</label>
-
- <div class="rowWrapper">
- <label class="block basicLabel"><span>Id:</span></label>
- <input class="form-control" type="text" ng-model="newContractObj.id" disabled/>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newContractObj['description']">
- <label class="block basicLabel"><span>Description:</span></label>
- <input class="form-control" type="text" ng-model="newContractObj.description" ng-disabled="internalView.edit === 'view'"/>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newContractObj['parent']">
- <label class="block basicLabel"><span>Parent:</span></label>
- <select class="form-control" ng-model="newContractObj.parent" ng-options="d.id as getDisplayLabel(d, displayLabel) for d in list" ng-disabled="internalView.edit === 'view'">
- <option>--</option>
- </select>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-hide="internalView.edit === 'view'">Save</button>
- </section>
-
- <section class="formWrapper clearfix" ng-show="selectedContract">
- <div ng-include src="view_path+'clause.tpl.html'"></div>
- </section>
-
- <section class="formWrapper clearfix" ng-show="selectedContract">
- <div ng-include src="view_path+'subjects.tpl.html'"></div>
- </section>
-
- <button class="btn btn-primary bottom-buttons full-width wizard-button" ng-click="showWizard('accessModelWizard')"><i class="icon-magic"></i>Access Model Wizard</button>
- <button class="btn btn-primary col-md-12 bottom-buttons home" ng-click="toggleExpandedMM('main')">Home</button>
- <button class="btn btn-primary col-md-12 bottom-buttons back" ng-click="setViewExpand('policyRendererView', 'basic', true); setBreadcrumb('l3', null, false);">Back</button>
-
-</div>
-
-
+++ /dev/null
-<div>
- <h2 class="text-center">Docs</h2>
- <button class="btn btn-primary col-md-12 bottom-buttons home" ng-click="toggleExpanded('basic')">Home</button>
- <button class="btn btn-primary col-md-12 bottom-buttons back" ng-click="toggleExpanded('policy')">Up</button>
-</div>
+++ /dev/null
-<div ng-controller="endpointCtrl" ng-init="init()">
-
- <h2 class="text-center">Endpoint</h2>
-
- <div ng-include src="view_path+'parts/crud-endpoint.tpl.html'"></div>
-
- <section class="formWrapper clearfix" ng-show="view.endpoint">
- <form name="endpointForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
-
- <div class="rowWrapper" ng-hide="view.edit === 'view' && !newEndpointObj['network-containment']">
- <label class="block basicLabel">Network containment:</label>
- <select class="form-control" ng-model="newEndpointObj['network-containment']" ng-options="c.id as getDisplayLabel(c, networkContainment.labels) for c in networkContainment.options | orderBy:'name'" ng-disabled="view.edit === 'view'">
- <option value="">Select option</option>
- </select>
- </div>
-
- <div class="rowWrapper clearfix" ng-hide="view.edit === 'view' && !newEndpointObj['endpoint-group']">
- <label class="block basicLabel">Endpoint group:</label>
- <select class="form-control" ng-model="newEndpointObj['endpoint-group']" ng-options="c.id as getDisplayLabel(c, epg.labels) for c in epg.options" ng-disabled="view.edit === 'view'">
- <option value="">Select option</option>
- </select>
- </div>
-
- <div class="rowWrapper clearfix" ng-hide="view.edit === 'view' && !newEndpointObj['endpoint-groups']">
- <label class="basicLabel">Endpoint groups:</label>
- <button class="btn btn-primary btn-slim" ng-click="addNewLeafListEl('endpoint-groups')" ng-hide="view.edit === 'view'"><i class="icon-plus"></i></button>
-
- <div ng-repeat="epGroups in newEndpointObj['endpoint-groups'] track by $index">
- <div class="selectWrapper col-md-10">
- <div class="rowWrapper">
- <select class="form-control" ng-model="epGroups" ng-change="updateLeafListEl($index, epGroups, 'endpoint-groups')" ng-options="c.id as getDisplayLabel(c, epg.labels) for c in epg.options" ng-disabled="view.edit === 'view'">
- <option value="">Select option</option>
- </select>
- </div>
- </div>
- <button class="btn btn-danger col-md-2" ng-click="deleteNewLeafListEl($index,'endpoint-groups')" ng-hide="view.edit === 'view'"><i class="icon-remove"></i></button>
- </div>
- </div>
-
- <div class="rowWrapper clearfix" ng-hide="view.edit === 'view' && !newEndpointObj['condition']">
- <label class="basicLabel">Condition:</label>
- <button class="btn btn-primary btn-slim" ng-click="addNewLeafListEl('condition')" ng-hide="view.edit === 'view'"><i class="icon-plus"></i></button>
-
- <div ng-repeat="condition in newEndpointObj['condition'] track by $index">
- <div class="selectWrapper col-md-10">
- <div class="rowWrapper">
- <input class="form-control" type="text" ng-model="condition" ng-change="updateLeafListEl($index, condition, 'condition')" ng-disabled="view.edit === 'view'"/>
- </div>
- </div>
- <button class="btn btn-danger col-md-2" ng-click="deleteNewLeafListEl($index,'condition')" ng-hide="view.edit === 'view'"><i class="icon-remove"></i></button>
- </div>
- </div>
-
- <div class="rowWrapper clearfix">
- <label class="block basicLabel">L2 context:
- <i class="icon-exclamation-sign red" tooltip="Required field" ng-show="endpointForm.l2context.$error.required"></i>
- </label>
- <select class="form-control" ng-model="newEndpointObj['l2-context']" name="l2context" ng-required="true" ng-options="c.id as getDisplayLabel(c, l2context.labels) for c in l2context.options" ng-disabled="view.edit !== 'add'">
- <option>--</option>
- </select>
- </div>
-
- <div class="rowWrapper clearfix">
- <label class="block basicLabel">MAC Address:
- <i class="icon-exclamation-sign red" tooltip="Invalid pattern" ng-show="endpointForm.macAddress.$error.pattern"></i>
- <i class="icon-exclamation-sign red" tooltip="Required field" ng-show="endpointForm.macAddress.$error.required"></i>
- </label>
- <input class="form-control" type="text" name="macAddress" ng-model="newEndpointObj['mac-address']" ng-pattern="/^([0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5})$/" ng-required="true" ng-disabled="view.edit !== 'add'"/>
- </div>
-
- <div class="rowWrapper" ng-hide="view.edit === 'view' && !newEndpointObj['l3-address']">
- <label class="basicLabel">L3 Address:</label>
- <button class="btn btn-primary btn-slim" ng-click="addNewL3address()" ng-hide="view.edit === 'view'"><i class="icon-plus"></i></button>
-
- <div ng-repeat="l3address in newEndpointObj['l3-address'] track by $index">
- <div class="separator col-md-11">
- <div class="inner-separator"></div>
- </div>
- <div class="selectWrapper col-md-10">
- <div class="rowWrapper">
- <label class="block basicLabel">L3 Context:</label>
- <select class="form-control" ng-model="l3address['l3-context']" ng-options="c.id as getDisplayLabel(c, l3context.labels) for c in l3context.options" ng-disabled="view.edit === 'view'">
- <option value="">Select option</option>
- </select>
- </div>
-
- <div class="rowWrapper">
- <label class="block basicLabel">IP Address:
- <i class="icon-exclamation-sign red" tooltip="Invalid pattern" ng-show="endpointForm.ipAddress.$error.pattern"></i>
- <i class="icon-exclamation-sign red" tooltip="Required field" ng-show="endpointForm.ipAddress.$error.required"></i>
- </label>
- <input class="form-control" type="text" ng-model="l3address['ip-address']" name="ipAddress" ng-pattern="/^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$/" ng-required="l3address['l3-context']" ng-disabled="view.edit === 'view'"/>
- </div>
- </div>
- <button class="btn btn-danger col-md-2 btn-list" ng-click="deleteNewL3address($index)" ng-hide="view.edit === 'view'"><i class="icon-remove"></i></button>
- </div>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-hide="view.edit === 'view'">Save</button>
- </form>
- </section>
-
- <button class="btn btn-primary bottom-buttons full-width wizard-button" ng-click="showWizard('accessModelWizard')"><i class="icon-magic"></i>Access Model Wizard</button>
- <button class="btn btn-primary col-md-12 bottom-buttons home" ng-click="toggleExpandedMM('main')">Home</button>
- <button class="btn btn-primary col-md-12 bottom-buttons back" ng-click="setViewExpand('policyRendererView', 'basic', true); setBreadcrumb('l3', null, false);">Back</button>
-
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="epgCtrl" ng-init="init()">
- <h2 class="text-center">Endpoint groups</h2>
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <section class="formWrapper clearfix" ng-show="internalView.epg">
- <form name="epgForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Id:</label>
- <input class="form-control" type="text" ng-model="newEpgObj.id" ng-disabled="internalView.edit !== 'add'"/>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newEpgObj['name']">
- <label class="block basicLabel">Name:
- <i class="icon-exclamation-sign red" tooltip="{{epgForm.name.$error.required ? 'Required field' : epgForm.name.$error.pattern ? 'Value must start with letter followed by letters and digits without space' : ''}}" ng-show="epgForm.name.$error.required || epgForm.name.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" name="name" ng-model="newEpgObj.name" ng-required="true" ng-disabled="internalView.edit === 'view'" ng-pattern="/^[a-zA-Z]([a-zA-Z0-9\-_.])*$/"/>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newEpgObj['description']">
- <label class="block basicLabel">Description:</label>
- <input class="form-control" type="text" ng-model="newEpgObj.description" ng-disabled="internalView.edit === 'view'"/>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newEpgObj['intra-group-policy']">
- <label class="block basicLabel">Intra group policy:</label>
- <select class="form-control" ng-model="newEpgObj['intra-group-policy']" ng-options="opt for opt in igpOpts" ng-disabled="internalView.edit === 'view'">
- <option>--</option>
- </select>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newEpgObj['network-domain']">
- <label class="block basicLabel">Network domain:
- <i class="icon-exclamation-sign red" tooltip="Invalid pattern" ng-show="epgForm.netDomain.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" ng-model="newEpgObj['network-domain']" name="netDomain" ng-pattern="/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/" ng-disabled="internalView.edit === 'view'"/>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newEpgObj['parent']">
- <label class="block basicLabel">Parent:</label>
- <select class="form-control" ng-model="newEpgObj.parent" ng-options="d.id as getDisplayLabel(d, displayLabel) for d in list">
- <option>--</option>
- </select>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-hide="internalView.edit === 'view'">Save</button>
- </form>
- </section>
-
- <section class="formWrapper clearfix" ng-show="selectedEpg">
- <div ng-include src="view_path+'cns.tpl.html'"></div>
- </section>
-
- <section class="formWrapper clearfix" ng-show="selectedEpg">
- <div ng-include src="view_path+'pns.tpl.html'"></div>
- </section>
-
- <button class="btn btn-primary bottom-buttons full-width wizard-button" ng-click="showWizard('accessModelWizard')"><i class="icon-magic"></i>Access Model Wizard</button>
- <button class="btn btn-primary col-md-12 bottom-buttons home" ng-click="toggleExpandedMM('main')">Home</button>
- <button class="btn btn-primary col-md-12 bottom-buttons back" ng-click="setViewExpand('policyRendererView', 'basic', true); setBreadcrumb('l3', null, false);">Back</button>
-
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="gatewayCtrl" ng-init="init()">
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <section class="formWrapper clearfix" ng-show="internalView.gateway">
- <form name="gatewayForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Gateway:
- <i class="icon-exclamation-sign red" tooltip="Invalid pattern" ng-show="gatewayForm.gateway.$error.pattern"></i>
- <i class="icon-exclamation-sign red" tooltip="Required field" ng-show="gatewayForm.gateway.$error.required"></i>
- </label>
- <input class="form-control" type="text" ng-model="newGatewayObj.gateway" name="gateway" ng-pattern="/^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(%[\p{N}\p{L}]+)?$/" ng-required="true" ng-disabled="internalView.edit !== 'add'"/>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-hide="internalView.edit === 'view'">Save</button>
- </form>
- </section>
-
- <section class="formWrapper clearfix" ng-show="selectedGateway">
- <div ng-include src="view_path+'prefix.tpl.html'"></div>
- </section>
-
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="deliveredPolicyCtrl">
- <section class="simpleBox col-md-3">
- <label class="block"><span>Tenants list</span></label>
- <div class="selectWrapper col-md-12">
- <select class="form-control" ng-model="selectedTenant" ng-change="setTenant(selectedTenant)" ng-options="getDisplayLabel(d, tenantDisplayLabel) for d in tenantList">
- <option value="">Select option</option>
- </select>
- </div>
- </section>
- <section class="sectionTitle col-md-3">
- <label class="block"><span>Delivered policy</span></label>
- </section>
-
- <!-- Legend -->
- <section class="simpleBox col-md-2 legendBox" ng-show="selectedTenant">
- <ul>
- <li class="item"><span class="line green"></span>consumes</li>
- <li class="item"><span class="line blue"></span>provides</li>
- </ul>
- </section>
-
- <!-- Graph -->
- <div class="clear"></div>
- <section class="graphWrapper" ng-controller="graphCtrl" ng-init="init(getPaperObj())">
-
- <section class="controlPanelButtons">
- <button class="btn btn-primary btn-slim" ng-click="zoom()"><i class="icon-zoom-in"></i></button>
- <div class="line"></div>
- <button class="btn btn-primary btn-slim" ng-click="zoom(true)"><i class="icon-zoom-out"></i></button>
- </section>
-
- <div graph="graph" id="graph" grid-size="1" />
- </section>
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="epgDetailCtrl">
- <section class="simpleBox col-md-3">
- <label class="block"><span>Epg list</span></label>
- <div class="selectWrapper col-md-12">
- <select class="form-control" ng-model="selectedEpg" ng-change="setEpg(selectedEpg)" ng-options="getDisplayLabel(d, epgDisplayLabel) for d in epgList">
- <option value="">Select option</option>
- </select>
- </div>
- </section>
- <section class="sectionTitle col-md-3">
- <label class="block"><span>Endpoint group detail</span></label>
- </section>
-
- <!-- Graph -->
- <div class="clear"></div>
- <section class="graphWrapper" ng-controller="graphCtrl" ng-init="init(getPaperObj())">
-
- <section class="controlPanelButtons">
- <button class="btn btn-primary btn-slim" ng-click="zoom()"><i class="icon-zoom-in"></i></button>
- <div class="line"></div>
- <button class="btn btn-primary btn-slim" ng-click="zoom(true)"><i class="icon-zoom-out"></i></button>
- </section>
-
- <div graph="graph" id="graph" grid-size="1" />
- </section>
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="expressedPolicyCtrl">
- <section class="simpleBox col-md-3">
- <label class="block"><span>Tenants list</span></label>
- <div class="selectWrapper col-md-12">
- <select class="form-control" ng-model="selectedTenant" ng-change="setTenant(selectedTenant)" ng-options="getDisplayLabel(d, tenantDisplayLabel) for d in tenantList">
- <option value="">Select option</option>
- </select>
- </div>
- </section>
- <section class="sectionTitle col-md-3">
- <label class="block"><span>Expressed policy</span></label>
- </section>
-
- <!-- Legend -->
- <section class="simpleBox col-md-2 legendBox" ng-show="selectedTenant">
- <ul>
- <li class="item"><span class="line green"></span>consumes</li>
- <li class="item"><span class="line blue"></span>provides</li>
- </ul>
- </section>
-
- <!-- Graph -->
- <div class="clear"></div>
- <section class="graphWrapper" ng-controller="graphCtrl" ng-init="init(getPaperObj())">
-
- <section class="controlPanelButtons">
- <button class="btn btn-primary btn-slim" ng-click="zoom()"><i class="icon-zoom-in"></i></button>
- <div class="line"></div>
- <button class="btn btn-primary btn-slim" ng-click="zoom(true)"><i class="icon-zoom-out"></i></button>
- </section>
-
- <div graph="graph" id="graph" grid-size="1" />
- </section>
-</div>
\ No newline at end of file
+++ /dev/null
-<section class="col-md-3 simpleBox mt30">
- <h3 class="text-center">Health</h3>
- <div class="panelWrapper clearfix">
- <button class="btn btn-primary col-md-12 btn-lg">Exception</button>
- <button class="btn btn-primary col-md-12 btn-lg">Conflict</button>
- </div>
-</section>
-
-<section class="col-md-4 col-md-offset-2 simpleBox mt30">
- <div class="panelWrapper clearfix">
- <!-- Tenants list -->
- <div class="rowWrapper clearfix">
- <label class="block"><span>Tenants list</span></label>
- <div class="selectWrapper col-md-12">
- <select class="form-control" ng-model="selectedTenant" ng-change="setTenant(selectedTenant)" ng-options="getDisplayLabel(d, tenantDisplayLabel) for d in tenantList">
- <option value="">Select option</option>
- </select>
- </div>
-
- <div class="clear"></div>
-
- <div class="mt10 clearfix">
- <div class="col-md-6 pl0">
- <button class="btn btn-primary col-md-12 btn-big" ng-click="toggleExpanded('expressed-policy'); setViewExpand('subMenuView','governance', true); setBreadcrumb('l2', 'Expressed policy', true);" >Expressed<br />policy</button>
- </div>
- <div class="col-md-6 pr0">
- <button class="btn btn-primary col-md-12 btn-big" ng-click="toggleExpanded('delivered-policy'); setViewExpand('subMenuView','governance', true); setBreadcrumb('l2', 'Delivered policy', true);">Delivered<br />policy</button>
- </div>
- </div>
-
- </div>
- </div>
-
-
- <div class="panelWrapper clearfix">
- <!-- Tenants list -->
- <div class="rowWrapper clearfix">
- <label class="block"><span>Renderers list</span></label>
- <div class="selectWrapper col-md-12">
- <select class="form-control" ng-model="selectedRenderer" ng-change="setRenderer()" ng-options="getDisplayLabel(d, tenantDisplayLabel) for d in rendererList">
- <option value="">Select option</option>
- </select>
- </div>
-
- <div class="clear"></div>
-
- <div class="mt10 clearfix">
- <div class="col-md-6 pl0">
- <button class="btn btn-primary col-md-12 btn-big" ng-click="toggleExpandedMM('policy-renderer'); setViewExpand('policyRendererView', 'basic', true); setViewExpand('subMenuView', 'renderers', true); setBreadcrumb('l1', 'Policy expression', true); setBreadcrumb('l2', 'Renderers', true);" >Renderer<br />configuration</button>
- </div>
- <div class="col-md-6 pr0">
- <button class="btn btn-primary col-md-12 btn-big" ng-click="toggleExpanded('renderer-state'); setBreadcrumb('l1', 'Governance', true); setBreadcrumb('l2', 'Renderer state', true);">Renderer<br />state</button>
- </div>
- </div>
-
- </div>
- </div>
-</section>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="layerCtrl" ng-init="init(key,value)" class="{{ checkData(value, 'Object') ? 'customContainer' : '' }}">
-
- <div ng-if="checkData(value, 'Object')" class="topContainerPart">
- <span class="treeBullet containerBullet" ng-if="key !== 'subject-feature-definitions'">•</span>
- <button class="yangButton {{ expanded ? 'iconArrowDown' : 'iconArrowRight' }} inlineBlock" tooltip="Show / Hide container" ng-click='toggleExpanded()'></button>
- <button class="btn-name btn-slim">
- {{key}}
- </button>
-
- <div ng-if="checkData(data, 'Array')" class="listPagination inlineBlock" ng-show="data.length > 0">
- <button ng-click="shiftDisplayPrev()" ng-show="showPrevButton()" tooltip="Show previous item" class="yangButton iconPrev"></button>
- <div class="paginationItemWrapper">
- <button ng-repeat="offset in displayOffsets track by $index" ng-if="currentDisplayIndex + offset > -1 && data.length > currentDisplayIndex + offset" class="btn btn-like-tab {{ (data[currentDisplayIndex + offset] === actSelected ? 'btn-selected':'') }}" ng-click="setActData(data[currentDisplayIndex + offset])" tooltip="Select this node">
- {{ data[currentDisplayIndex + offset].name }}
- </button>
- </div>
- <button ng-click="shiftDisplayNext()" ng-show="showNextButton('listData')" tooltip="Show next item" class="yangButton iconNext"></button>
- </div>
- </div>
-
- <div class="leaf" ng-if="!checkData(value, 'Object') && !checkData(value, 'Array')">
- <span class="treeBullet" ng-if="key !== 'subject-feature-definitions'">•</span>
- <span class="leaf-label col-md-2">
- {{ key }}
- </span>
- <span class="leaf-label col-md-9"><strong>{{value}}</strong></span>
- <div class="clear"></div>
- </div>
-
- <div ng-if="checkData(data, 'Array')" ng-repeat="(key, value) in actSelected track by $index" ng-include src="view_path+'/node-structure.tpl.html'" ng-show="expanded">
- </div>
-
- <div ng-if="!checkData(data, 'Array') && checkData(data, 'Object')" ng-repeat="(key, value) in data track by $index" ng-include src="view_path+'/node-structure.tpl.html'" ng-show="expanded">
- </div>
-
- <i class="icon-caret-down borderArrow"></i>
-</div>
\ No newline at end of file
+++ /dev/null
-renderer-configuration
\ No newline at end of file
+++ /dev/null
-<section class="col-md-9 col-md-offset-2 simpleBox mt30">
- <div ng-controller="rendererStateCtrl">
- <div ng-if="!checkData(data, 'Array')" ng-repeat="(key, value) in data" ng-include src="view_path+'/node-structure.tpl.html'">
- </div>
- </div>
-</section>
-
+++ /dev/null
-<div ng-controller="subjectDetailCtrl">
- <section class="simpleBox col-md-3">
- <div class="selectWrapper col-md-12">
- <select class="form-control" ng-model="selectedSubject" ng-change="setSubject(selectedSubject)" ng-options="d.name for d in subjectList">
- <option value="">Select option</option>
- </select>
- </div>
- </section>
- <section class="sectionTitle col-md-3">
- <label class="block"><span>Subject detail</span></label>
- </section>
-
- <!-- Graph -->
- <div class="clear"></div>
- <section class="graphWrapper" ng-controller="graphCtrl" ng-init="init(getPaperObj())">
-
- <section class="controlPanelButtons">
- <button class="btn btn-primary btn-slim" ng-click="zoom()"><i class="icon-zoom-in"></i></button>
- <div class="line"></div>
- <button class="btn btn-primary btn-slim" ng-click="zoom(true)"><i class="icon-zoom-out"></i></button>
- </section>
-
- <div graph="graph" id="graph" grid-size="1" />
- </section>
-</div>
\ No newline at end of file
+++ /dev/null
-<section class="gbpWrapper clearfix">
-
- <section class="mainNavigationWrapper" ng-show="mainView.main" ng-include src="view_path+'main/main.tpl.html'"></section>
- <section ng-show="mainView.governance" ng-include src="view_path+'main/governance.tpl.html'"></section>
- <section ng-show="mainView['policy-renderer']" ng-include src="view_path+'main/policy-renderer.tpl.html'"></section>
-</section>
-
-
-
-
+++ /dev/null
-<div ng-controller="l3ContextCtrl" ng-init="init()">
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <section class="formWrapper clearfix" ng-show="view.l3context">
- <form name="l3ContextForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
- <label class="block">Add L3 Context</label>
-
-
- <div class="rowWrapper">
- <label class="block basicLabel">Id:</label>
- <input class="form-control" type="text" ng-model="newL3ContextObj.id" disabled />
- </div>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Name:
- <i class="icon-exclamation-sign red" tooltip="{{l3ContextForm.name.$error.required ? 'Required field' : l3ContextForm.name.$error.pattern ? 'Value must start with letter followed by letters and digits without space' : ''}}" ng-show="l3ContextForm.name.$error.required || l3ContextForm.name.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" ng-model="newL3ContextObj.name" name="name" ng-required="true" ng-disabled="view.edit === 'view'" ng-pattern="/^[a-zA-Z]([a-zA-Z0-9\-_.])*$/"/>
- </div>
-
- <div class="rowWrapper" ng-hide="view.edit === 'view' && !newL3ContextObj.description">
- <label class="block basicLabel">Description:</label>
- <input class="form-control" type="text" ng-model="newL3ContextObj.description" ng-disabled="view.edit === 'view'" />
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-hide="view.edit === 'view'">Save</button>
- </form>
- </section>
-</div>
-
-<br/><br/>
-
-<div ng-controller="l2BridgeCtrl" ng-init="init()">
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <section class="formWrapper clearfix" ng-show="view.l2bridge">
- <form name="l2BridgeForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
- <label class="block">Add L2 Bridge Domain</label>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Id:</label>
- <input class="form-control" type="text" ng-model="newL2BridgeObj.id" disabled />
- </div>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Name:
- <i class="icon-exclamation-sign red" tooltip="{{l2BridgeForm.name.$error.required ? 'Required field' : l2BridgeForm.name.$error.pattern ? 'Value must start with letter followed by letters and digits without space' : ''}}" ng-show="l2BridgeForm.name.$error.required || l2BridgeForm.name.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" ng-model="newL2BridgeObj.name" name="name" ng-required="true" ng-disabled="view.edit === 'view'" ng-pattern="/^[a-zA-Z]([a-zA-Z0-9\-_.])*$/"/>
- </div>
-
- <div class="rowWrapper" ng-hide="view.edit === 'view' && !newL2BridgeObj.description">
- <label class="block basicLabel">Description:</label>
- <input class="form-control" type="text" ng-model="newL2BridgeObj.description" ng-disabled="view.edit === 'view'" />
- </div>
-
- <div class="rowWrapper" ng-hide="view.edit === 'view' && !newL2BridgeObj.parent">
- <label class="block basicLabel">Parent:</label>
- <select class="form-control" ng-model="newL2BridgeObj.parent" ng-options="d.id as getDisplayLabel(d, l3context.labels) for d in l3context.options" ng-disabled="view.edit === 'view'">
- <option value="">Select option</option>
- </select>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-hide="view.edit === 'view'">Save</button>
- </form>
- </section>
-</div>
-
-<br/><br/>
-
-<div ng-controller="l2FloodCtrl" ng-init="init()">
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <section class="formWrapper clearfix" ng-show="view.l2flood">
- <form name="l2FloodForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
- <label class="block">Add L2 Flood Domain</label>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Id:</label>
- <input class="form-control" type="text" ng-model="newL2FloodObj.id" disabled />
- </div>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Name:
- <i class="icon-exclamation-sign red" tooltip="{{l2FloodForm.name.$error.required ? 'Required field' : l2FloodForm.name.$error.pattern ? 'Value must start with letter followed by letters and digits without space' : ''}}" ng-show="l2FloodForm.name.$error.required || l2FloodForm.name.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" ng-model="newL2FloodObj.name" name="name" ng-required="true" ng-disabled="view.edit === 'view'" ng-pattern="/^[a-zA-Z]([a-zA-Z0-9\-_.])*$/"/>
- </div>
-
- <div class="rowWrapper" ng-hide="view.edit === 'view' && !newL2FloodObj.description">
- <label class="block basicLabel">Description:</label>
- <input class="form-control" type="text" ng-model="newL2FloodObj.description" ng-disabled="view.edit === 'view'" />
- </div>
-
- <div class="rowWrapper" ng-hide="view.edit === 'view' && !newL2FloodObj.parent">
- <label class="block basicLabel">Parent:</label>
- <select class="form-control" ng-model="newL2FloodObj.parent" ng-options="d.id as getDisplayLabel(d, l2bridge.labels) for d in l2bridge.options" ng-disabled="view.edit === 'view'">
- <option value="">Select option</option>
- </select>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-hide="view.edit === 'view'">Save</button>
- </form>
- </section>
-</div>
-
-<br/><br/>
-
-<div ng-controller="subnetCtrl" ng-init="init()">
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <section class="formWrapper clearfix" ng-show="view.subnet">
- <form name="subnetForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
- <label class="block">Add Subnet</label>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Id:</label>
- <input class="form-control" type="text" ng-model="newSubnetObj.id" disabled />
- </div>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Name:
- <i class="icon-exclamation-sign red" tooltip="{{subnetForm.name.$error.required ? 'Required field' : subnetForm.name.$error.pattern ? 'Value must start with letter followed by letters and digits without space' : ''}}" ng-show="subnetForm.name.$error.required || subnetForm.name.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" ng-model="newSubnetObj.name" name="name" ng-required="true" ng-disabled="view.edit === 'view'" ng-pattern="/^[a-zA-Z]([a-zA-Z0-9\-_.])*$/"/>
- </div>
-
- <div class="rowWrapper" ng-hide="view.edit === 'view' && !newSubnetObj.description">
- <label class="block basicLabel">Description:</label>
- <input class="form-control" type="text" ng-model="newSubnetObj.description" ng-disabled="view.edit === 'view'"/>
- </div>
-
- <div class="rowWrapper" ng-hide="view.edit === 'view' && !newSubnetObj.parent">
- <label class="block basicLabel">Parent:</label>
- <select class="form-control" ng-model="newSubnetObj.parent" ng-options="d.id as getDisplayLabel(d, l2L3List.labels) for d in l2L3List.options" ng-disabled="view.edit === 'view'">
- <option value="">Select option</option>
- </select>
- </div>
-
- <div class="rowWrapper" ng-hide="view.edit === 'view' && !newSubnetObj['ip-prefix']">
- <label class="block basicLabel">IP prefix:
- <i class="icon-exclamation-sign red" tooltip="Invalid pattern" ng-show="subnetForm.ipPrefix.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" ng-model="newSubnetObj['ip-prefix']" name="ipPrefix" ng-pattern="/^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))$/" ng-disabled="view.edit === 'view'" />
- </div>
-
- <div class="rowWrapper" ng-hide="view.edit === 'view' && !newSubnetObj['virtual-router-ip']">
- <label class="block basicLabel">Virtual router:
- <i class="icon-exclamation-sign red" tooltip="Invalid pattern" ng-show="subnetForm.virtualRouter.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" ng-model="newSubnetObj['virtual-router-ip']" name="virtualRouter" ng-pattern="/^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])(%[\p{N}\p{L}]+)?$/"
- ng-model="newSubnetObj['virtual-router-ip']" ng-disabled="view.edit === 'view'" />
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-hide="view.edit === 'view'">Save</button>
- </form>
- </section>
-
- <section class="formWrapper clearfix" ng-show="selectedSubnet">
- <div ng-include src="view_path+'gateway.tpl.html'"></div>
- </section>
-
- <div class="formWrapper clearfix">
- <button class="btn btn-primary bottom-buttons full-width wizard-button" ng-click="showWizard('accessModelWizard')"><i class="icon-magic"></i>Access Model Wizard</button>
- <button class="btn btn-primary col-md-12 bottom-buttons home" ng-click="toggleExpandedMM('main')">Home</button>
- <button class="btn btn-primary col-md-12 bottom-buttons back" ng-click="setViewExpand('policyRendererView', 'basic', true); setBreadcrumb('l3', null, false);">Back</button>
- </div>
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="l3EndpointCtrl" ng-init="init()">
-
- <h2 class="text-center">L3 Prefix Endpoint</h2>
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <section class="formWrapper clearfix" ng-show="view.endpoint">
- <form name="l3EndpointForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
-
- <div class="rowWrapper" ng-hide="view.edit === 'view' && !newEndpointObj['endpoint-group']">
- <label class="block basicLabel">Endpoint group:</label>
- <select class="form-control" ng-model="newEndpointObj['endpoint-group']" ng-options="c.id as getDisplayLabel(c, epg.labels) for c in epg.options" ng-disabled="view.edit === 'view'">
- <option value="">Select option</option>
- </select>
- </div>
-
- <div class="rowWrapper clearfix" ng-hide="view.edit === 'view' && !newEndpointObj['endpoint-groups']">
- <label class="basicLabel">Endpoint groups:</label>
- <button class="btn btn-primary btn-slim" ng-click="addNewLeafListEl('endpoint-groups')" ng-hide="view.edit === 'view'"><i class="icon-plus"></i></button>
-
- <div ng-repeat="epGroups in newEndpointObj['endpoint-groups'] track by $index">
- <div class="selectWrapper col-md-10">
- <div class="rowWrapper">
- <select class="form-control" ng-model="epGroups" ng-change="updateLeafListEl($index, epGroups, 'endpoint-groups')" ng-options="c.id as getDisplayLabel(c, epg.labels) for c in epg.options" ng-disabled="view.edit === 'view'">
- <option value="">Select option</option>
- </select>
- </div>
- </div>
- <button class="btn btn-danger col-md-2" ng-click="deleteNewLeafListEl($index,'endpoint-groups')" ng-hide="view.edit === 'view'"><i class="icon-remove"></i></button>
- </div>
- </div>
-
- <div class="rowWrapper" ng-hide="view.edit === 'view' && !newEndpointObj['condition']">
- <label class="basicLabel">Condition:</label>
- <button class="btn btn-primary btn-slim" ng-click="addNewLeafListEl('condition')" ng-disabled="view.edit === 'view'"><i class="icon-plus"></i></button>
-
- <div ng-repeat="condition in newEndpointObj['condition'] track by $index">
- <div class="selectWrapper col-md-10">
- <div class="rowWrapper">
- <input class="form-control" type="text" ng-model="condition" ng-change="updateLeafListEl($index, condition, 'condition')" ng-disabled="view.edit === 'view'"/>
- </div>
- </div>
- <button class="btn btn-danger col-md-2" ng-click="deleteNewLeafListEl($index,'condition')" ng-disabled="view.edit === 'view'"><i class="icon-remove"></i></button>
- </div>
- </div>
-
- <div class="rowWrapper">
- <label class="block basicLabel">L3 Context:
- <i class="icon-exclamation-sign red" tooltip="Required field" ng-show="l3EndpointForm.l3context.$error.required"></i>
- </label>
- <select class="form-control" ng-model="newEndpointObj['l3-context']" name="l3context" ng-required="true" ng-options="c.id as getDisplayLabel(c, l3context.labels) for c in l3context.options" ng-disabled="view.edit !== 'add'">
- <option>--</option>
- </select>
- </div>
-
- <div class="rowWrapper" ng-hide="view.edit === 'view' && !newEndpointObj['endpoint-l2-gateways']">
- <label class="basicLabel">L2 gateways:</label>
- <button class="btn btn-primary btn-slim" ng-click="addNewL2gateways()" ng-hide="view.edit === 'view'"><i class="icon-plus"></i></button>
-
- <div ng-repeat="l2gateways in newEndpointObj['endpoint-l2-gateways'] track by $index">
- <div class="separator col-md-11">
- <div class="inner-separator"></div>
- </div>
- <div class="selectWrapper col-md-10">
- <div class="rowWrapper">
- <label class="block basicLabel">L2 context:</label>
- <select class="form-control" ng-model="l2gateways['l2-context']" ng-options="c.id as getDisplayLabel(c, l2context.labels) for c in l2context.options" ng-disabled="view.edit === 'view'">
- <option value="">Select option</option>
- </select>
- </div>
-
- <div class="rowWrapper">
- <label class="block basicLabel">MAC Address:
- <i class="icon-exclamation-sign red" tooltip="Invalid pattern" ng-show="l3EndpointForm.macAddress.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" name="macAddress" ng-pattern="/^([0-9a-fA-F]{2}(:[0-9a-fA-F]{2}){5})$/" ng-model="l2gateways['mac-address']"/ ng-disabled="view.edit === 'view'">
- </div>
- </div>
- <button class="btn btn-danger col-md-2 btn-list" ng-click="deleteNewL2gateways($index)" ng-hide="view.edit === 'view'"><i class="icon-remove"></i></button>
- </div>
- </div>
-
- <div class="rowWrapper" ng-hide="view.edit === 'view' && !newEndpointObj['endpoint-l3-gateways']">
- <label class="basicLabel">L3 gateways:</label>
- <button class="btn btn-primary btn-slim" ng-click="addNewL3gateways()" ng-hide="view.edit === 'view'"><i class="icon-plus"></i></button>
-
- <div ng-repeat="l3gateways in newEndpointObj['endpoint-l3-gateways'] track by $index">
- <div class="separator col-md-11">
- <div class="inner-separator"></div>
- </div>
- <div class="selectWrapper col-md-10">
- <div class="rowWrapper">
- <label class="block basicLabel">L3 Context:</label>
- <select class="form-control" ng-model="l3gateways['l3-context']" ng-options="c.id as getDisplayLabel(c, l3context.labels) for c in l3context.options" ng-disabled="view.edit === 'view'">
- <option value="">Select option</option>
- </select>
- </div>
-
- <div class="rowWrapper">
- <label class="block basicLabel">IP Address:
- <i class="icon-exclamation-sign red" tooltip="Invalid pattern" ng-show="l3EndpointForm.ipAddress.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" name="ipAddress" ng-pattern="/^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])$/" ng-model="l3gateways['ip-address']"
- ng-disabled="view.edit === 'view'"/>
- </div>
- </div>
- <button class="btn btn-danger col-md-2 btn-list" ng-click="deleteNewL3gateways($index)" ng-hide="view.edit === 'view'"><i class="icon-remove"></i></button>
- </div>
- </div>
-
- <div class="clearfix"></div>
-
- <div class="rowWrapper">
- <label class="basicLabel">IP prefix:
- <i class="icon-exclamation-sign red" tooltip="Invalid pattern" ng-show="l3EndpointForm.ipprefix.$error.pattern"></i>
- <i class="icon-exclamation-sign red" tooltip="Required field" ng-show="l3EndpointForm.ipprefix.$error.required"></i>
- </label>
- <input class="form-control" type="text" name="ipprefix" ng-model="newEndpointObj['ip-prefix']" ng-pattern="/^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))$/" ng-required="true" ng-disabled="view.edit !== 'add'" />
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-show="view.edit === 'edit' || view.edit === 'add'">Save</button>
- </form>
- </section>
-
- <button class="btn btn-primary bottom-buttons full-width wizard-button" ng-click="showWizard('accessModelWizard')"><i class="icon-magic"></i>Access Model Wizard</button>
- <button class="btn btn-primary col-md-12 bottom-buttons home" ng-click="toggleExpandedMM('main')">Home</button>
- <button class="btn btn-primary col-md-12 bottom-buttons back" ng-click="setViewExpand('policyRendererView', 'basic', true); setBreadcrumb('l3', null, false);">Back</button>
-
-</div>
\ No newline at end of file
+++ /dev/null
-<section ng-controller="governanceCtrl">
- <section class="col-md-9">
-
- <section ng-if="contentTpl" ng-include src="view_path + 'governance/' + contentTpl + '.tpl.html'" onload="checkBroadcastCalling(contentTpl)"></section>
-
- </section>
-
- <!-- RIGHT PANEL -->
- <aside class="col-md-3">
- <section class="inWrapper">
-
- <!-- Menu including -->
- <section ng-if="menuTpl" ng-include src="view_path + 'menu/' + menuTpl + '.tpl.html'"></section>
- <section class="mb50" ng-if="menuBox" ng-include src="view_path + 'box/' + menuBox + '.tpl.html'" onload="broadcastCalling('menuBox')"></section>
- </section>
- </aside>
-
- <section ng-show="wizards.actionReferenceWizard">
- <div ng-include src="view_path+'wizards/actionReferenceWizard.tpl.html'"></div>
- </section>
-</section>
-
+++ /dev/null
-<h1 class="text-center">GBP</h1>
-
-<nav class="mainNavigation">
-
- <div class="topButtonsWrapper">
- <div class="buttonWrapper">
- <button class="btn btn-primary btn-large" ng-click="toggleExpandedMM('policy-renderer'); setViewExpand('policyRendererView', 'basic', true); setViewExpand('subMenuView','policySub', true); setBreadcrumb('l1', 'Policy expression', true); setBreadcrumb('l2', 'Policy', true);"></i>Policy expression</button>
- <i class="icon-large icon-circle-arrow-down"></i>
- </div>
- </div>
-
- <div class="middleButtonsWrapper">
- <div class="buttonWrapper">
- <button class="btn btn-primary btn-large" ng-click="toggleExpandedMM('governance', null, 'GOV_INIT'); setViewExpand('subMenuView','governance', true); setBreadcrumb('l1', 'Governance', true);">Governance</button>
- <div class="iconWrapper">
- <i class="icon-large icon-circle-arrow-right"></i>
- </div>
- </div>
-
- <div class="middleBox">
- <div class="infinityIcon" ng-click="toggleExpandedMM('governance', null, 'GOV_INIT'); setBreadcrumb('l1', 'Governance', true);"></div>
- </div>
-
- <div class="buttonWrapper">
- <div class="iconWrapper">
- <i class="icon-large icon-circle-arrow-left"></i>
- </div>
- <button class="btn btn-primary btn-large" ></i>Operational constraints</button>
- </div>
- </div>
-
- <div class="bottomButtonsWrapper">
- <div class="buttonWrapper">
- <i class="icon-large icon-circle-arrow-up"></i>
- <button class="btn btn-primary btn-large" ng-click="toggleExpandedMM('policy-renderer'); setViewExpand('policyRendererView', 'basic', true); setViewExpand('subMenuView', 'renderers', true); setBreadcrumb('l1', 'Policy expression', true); setBreadcrumb('l2', 'Renderers', true);"></i>Renderer configuration</button>
- </div>
- </div>
-
-</nav>
\ No newline at end of file
+++ /dev/null
-<section ng-controller="policyRendererCtrl">
- <!-- TOPOLOGY -->
- <section class="sigmaWrapper col-md-9">
- <section class="sigmaModalWrapper simpleBox" ng-controller="linkDataCtrl" ng-show="showTable">
- <div class="tableWrapper">
- <i class="icon-remove" ng-click="close()"></i>
-
- <div class="dataWrapper">
- <section ng-repeat="subject in linkData">
- <section class="header">
- <span class="block">{{ 'Subject: ' + subject.name }}</span>
- </section>
-
- <section class="ml10" ng-repeat="rule in subject['ui-rule']">
- <label class="block">Rule:{{rule.name}}</label>
- <section class="ml10" ng-repeat="classifier in rule['classifier-ref']">
- <span class="block">Classifier:</span>
- <ul>
- <li ng-repeat="(key, value) in classifier">{{key}}: {{value}}</li>
- </ul>
- </section>
- <section ng-repeat="classifier in rule['action-ref']">
- <span class="block">Action:</span>
- <ul>
- <li ng-repeat="(key, value) in classifier">{{key}}: {{value}}</li>
- </ul>
- </section>
- </section>
- </section>
- </div>
- </div>
- </section>
-
-
- <section class="policyGraphWrapper">
- <div graph="graph" id="graph" grid-size="1" />
- </section>
-
- <div class="topoNav">
- <label class="block"><span>Topology type:</span></label>
- <div class="btn-group" role="group">
- <button type="button" class="btn btn-primary" ng-click="loadTopology('CONFIG', { tenantId: selectedTenant.id })">Config</button>
- <button type="button" class="btn btn-primary" ng-click="loadTopology('OPERATIONAL', { tenantId: selectedTenant.id })">Operational</button>
- <button type="button" class="btn btn-primary" ng-click="loadTopology('L2L3', { tenantId: selectedTenant.id, storage: 'config' })">L2/L3</button>
- </div>
- </div>
-
- </section>
-
- <!-- RIGHT PANEL -->
- <aside class="col-md-3">
- <section class="inWrapper">
-
- <div ng-include src="view_path+'parts/breadcrumbs.tpl.html'" class="breadcrumbs clearfix"></div>
-
- <div class="block clearfix" style="height: 109px;">
- <!-- Tenants list -->
- <div class="rowWrapper clearfix">
- <label class="block"><span>Tenants list</span></label>
- <div class="selectWrapper col-md-12">
- <select class="form-control" ng-model="selectedTenant" ng-change="setTenant(selectedTenant); reloadTopo();" ng-options="getDisplayLabel(d, tenantDisplayLabel) for d in tenantList">
- <option value="">Select option</option>
- </select>
- </div>
- </div>
- </div>
-
- <div class="panelWrapper clearfix" ng-show="policyRendererView.basic">
- <button class="btn btn-primary col-md-12 btn-lg" ng-click="setViewExpand('subMenuView','policySub'); setBreadcrumb('l2', 'Policy', subMenuView.policySub);" tooltip="Show/Hide policy submenu" >Policy</button>
- <section ng-show="subMenuView.policySub">
- <button class="btn btn-default col-md-12" ng-click="toggleExpanded('tenants'); setBreadcrumb('l3', 'Tenants', policyRendererView.tenants);" tooltip="CRUD for tenants" >Tenants</button>
- <button class="btn btn-default col-md-12" ng-click="toggleExpanded('epg'); setBreadcrumb('l3', 'Endpoint groups', policyRendererView.epg);" tooltip="CRUD for endpoint groups">Endpoint groups</button>
- <button class="btn btn-default col-md-12" ng-click="toggleExpanded('contracts'); setBreadcrumb('l3', 'Contracts', policyRendererView.contracts);" tooltip="CRUD for contracts">Contracts</button>
- <button class="btn btn-default col-md-12" ng-click="toggleExpanded('l2l3'); setBreadcrumb('l3', 'L2/L3', policyRendererView.l2l3);" tooltip="CRUD for l2/l3">L2/L3</button>
- </section>
-
- <button class="btn btn-primary col-md-12 btn-lg" ng-click="setViewExpand('subMenuView','renderers'); setBreadcrumb('l2', 'Renderers', subMenuView.renderers);" tooltip="Show/Hide renderers submenu" >Renderers</button>
-
- <section ng-show="subMenuView.renderers">
- <button class="btn btn-default col-md-12" ng-click="toggleExpanded('classifiers'); setBreadcrumb('l3', 'Classifiers', policyRendererView.classifiers);" tooltip="CRUD for classifiers">Classifiers</button>
- <button class="btn btn-default col-md-12" ng-click="toggleExpanded('actions'); setBreadcrumb('l3', 'Actions', policyRendererView.actions);" tooltip="CRUD for actions">Actions</button>
- </section>
-
- <button class="btn btn-primary col-md-12 btn-lg" ng-click="setViewExpand('subMenuView','endpoints'); setBreadcrumb('l2', 'Endpoints', subMenuView.endpoints);" tooltip="Show/Hide endpoints submenu">Endpoints</button>
- <section ng-show="subMenuView.endpoints">
- <button class="btn btn-default col-md-12" ng-click="toggleExpanded('registerEndpoint'); setBreadcrumb('l3', 'Endpoint', policyRendererView.registerEndpoint);" tooltip="CRUD for endpoint">Endpoint</button>
- <button class="btn btn-default col-md-12" ng-click="toggleExpanded('registerL3PrefixEndpoint'); setBreadcrumb('l3', 'L3 prefix endpoint', policyRendererView.registerL3PrefixEndpoint);" tooltip="CRUD for L3 prefix endpoint">L3 prefix endpoint</button>
- </section>
- <!-- <button class="btn btn-primary col-md-12" ng-click="toggleExpanded('docs')" >Docs</button> -->
-
- <button class="btn btn-primary bottom-buttons full-width wizard-button" ng-click="showWizard('accessModelWizard')"><i class="icon-magic"></i>Access Model Wizard</button>
- <button class="btn btn-primary bottom-buttons full-width" ng-click="toggleExpandedMM('main')" >Home</button>
- </div>
-
- <div class="panelWrapper clearfix" ng-show="policyRendererView.tenants">
- <div ng-include src="view_path+'tenants.tpl.html'"></div>
- </div>
-
- <div class="panelWrapper clearfix" ng-show="policyRendererView.l2l3">
- <div ng-include src="view_path+'l2l3.tpl.html'"></div>
- </div>
-
- <div class="panelWrapper clearfix" ng-show="policyRendererView.epg" ng-controller="epgCtrl">
- <div ng-include src="view_path+'epg.tpl.html'"></div>
- </div>
-
- <div class="panelWrapper clearfix" ng-show="policyRendererView.contracts">
- <div ng-include src="view_path+'contracts.tpl.html'"></div>
- </div>
-
- <div class="panelWrapper clearfix" ng-show="policyRendererView.docs">
- <div ng-include src="view_path+'docs.tpl.html'"></div>
- </div>
-
- <div ng-controller="renderersCtrl">
- <div class="panelWrapper clearfix" ng-show="policyRendererView.classifiers" ng-controller="classifiersCtrl">
- <div ng-include src="view_path+'classifiers.tpl.html'"></div>
- </div>
-
- <div class="panelWrapper clearfix" ng-show="policyRendererView.actions" ng-controller="actionsCtrl">
- <div ng-include src="view_path+'actions.tpl.html'"></div>
- </div>
- </div>
-
- <div class="panelWrapper clearfix" ng-show="policyRendererView.registerEndpoint">
- <div ng-include src="view_path+'endpoint.tpl.html'"></div>
- </div>
-
- <div class="panelWrapper clearfix" ng-show="policyRendererView.registerL3PrefixEndpoint">
- <div ng-include src="view_path+'l3-endpoint.tpl.html'"></div>
- </div>
-
-
-
- </section>
- </aside>
-
- <div ng-if="wizards.accessModelWizard">
- <div ng-include src="view_path+'wizards/accessModelWizard.tpl.html'"></div>
- </div>
-</section>
+++ /dev/null
-<div ng-include src="view_path+'parts/breadcrumbs.tpl.html'" class="breadcrumbs clearfix"></div>
-
-<div class="panelWrapper clearfix no-padd-top">
- <button class="btn btn-primary col-md-12 btn-lg" ng-click="setViewExpand('subMenuView','policy');" tooltip="Show/Hide policy submenu"></i>Policy expression</button>
- <section ng-show="subMenuView.policy">
- <button class="btn btn-default col-md-12" ng-click="toggleExpandedMM('policy-renderer'); setViewExpand('policyRendererView', 'basic', true); setViewExpand('subMenuView','policySub', true); setBreadcrumb('l1', 'Policy expression', true); setBreadcrumb('l2', 'Policy', true);" >Policy</button>
- <button class="btn btn-default col-md-12" ng-click="toggleExpandedMM('policy-renderer'); setViewExpand('policyRendererView', 'basic', true); setViewExpand('subMenuView','renderers', true); setBreadcrumb('l1', 'Policy expression', true); setBreadcrumb('l2', 'Renderers', true);">Renderers</button>
- <button class="btn btn-default col-md-12" ng-click="toggleExpandedMM('policy-renderer'); setViewExpand('policyRendererView', 'basic', true); setViewExpand('subMenuView','endpoints', true); setBreadcrumb('l1', 'Policy expression', true); setBreadcrumb('l2', 'Endpoints', true);">Endpoints</button>
- </section>
-
-
-
- <button class="btn btn-primary col-md-12 btn-lg" ng-click="toggleExpandedMM('policy-renderer'); setViewExpand('policyRendererView', 'basic', true); setBreadcrumb('l1', 'Policy expression', true); setBreadcrumb('l2', 'Renderers', true);"></i>Renderer configuration</button>
-
- <button class="btn btn-primary col-md-12 btn-lg" ng-click="setViewExpand('subMenuView','governance')" tooltip="Show/Hide governance submenu">Governance</button>
-
- <section ng-show="subMenuView.governance">
- <button class="btn btn-default col-md-12" ng-class="contentTpl === 'main' && mainView.governance ? 'activated' : ''" ng-click="toggleExpandedMM('governance', true, 'GOV_INIT'); setBreadcrumb('l1', 'Governance', true);" >Governance</button>
- <button class="btn btn-default col-md-12" ng-class="contentTpl === 'expressed-policy' ? 'activated' : ''" ng-click="toggleExpanded('expressed-policy'); setBreadcrumb('l2', 'Expressed policy', true);" tooltip="Show expressed policy diagram">Expressed policy</button>
- <button class="btn btn-default col-md-12" ng-class="contentTpl === 'delivered-policy' || contentTpl === 'epg-detail' || contentTpl === 'subject-detail' ? 'activated' : ''" ng-click="toggleExpanded('delivered-policy'); setBreadcrumb('l2', 'Delivered policy', true);" tooltip="Show delivered policy diagram">Delivered policy</button>
-
- <!-- <button class="btn btn-default col-md-12" ng-click="toggleExpandedMM('policy-renderer'); setViewExpand('policyRendererView', 'basic', true);" >Renderer configuration</button> -->
-
- <button class="btn btn-default col-md-12" ng-class="contentTpl === 'renderer-state' ? 'activated' : ''" ng-click="toggleExpanded('renderer-state'); setBreadcrumb('l1', 'Governance', true); setBreadcrumb('l2', 'Renderer state', true);">Renderer state</button>
- </section>
-
- <button class="btn btn-primary col-md-12 btn-lg" ></i>Operational constraints</button>
-
- <button class="btn btn-primary bottom-buttons full-width" ng-click="toggleExpandedMM('main')" >Home</button>
-</div>
-
+++ /dev/null
-<span ng-repeat="(key, value) in breadcrumbs" ng-if="value">{{ key !== 'l1' ? ' > ' : ''}}{{value}}</span>
\ No newline at end of file
+++ /dev/null
-<section class="rowWrapper clearfix" ng-controller="crudCtrl">
- <div class="inline-block full-width">
- <label class="block float-left"><span>{{ crudLabel }}</span></label>
-
- <button type="button" class="btn btn-primary col-md-4 float-right" ng-click="filter = !filter"><i class="icon-filter"></i></button>
- </div>
-
- <div ng-init="filter = false" class="ep-filter" ng-show="filter">
- <div class="inline-block">
- <label class="block"><span>Endpoint group</span></label>
- <input type="text" class="form-control" ng-model="q['endpoint-group']" placeholder="Filter by Endpoint groups"/>
- </div>
-
- <div class="inline-block">
- <label class="block"><span>Network containment</span></label>
- <input type="text" class="form-control" ng-model="q['network-containment']" placeholder="Filter by netw. containment"/>
- </div>
- </div>
-
- <div class="selectWrapper col-md-6">
- <select class="form-control" ng-model="selectedObj" ng-change="reload(selectedObj)" ng-options="getDisplayLabel(d, displayLabel) for d in list | filter:q">
- <option value="">Select option</option>
- </select>
-
- </div>
-
- <div class="btn-group col-md-6" role="group">
- <button type="button" class="btn btn-primary col-md-4" ng-click="add()">Add</button>
- <button type="button" class="btn btn-primary col-md-4" ng-click="modify()">Edit</button>
- <button type="button" class="btn btn-primary col-md-4" ng-click="delete()">Delete</button>
- </div>
-</section>
\ No newline at end of file
+++ /dev/null
-<section class="rowWrapper clearfix" ng-controller="crudCtrl">
- <label class="block"><span>{{ crudLabel }}</span></label>
-
- <div class="selectWrapper col-md-6">
- <select class="form-control" ng-model="selectedObj" ng-change="reload(selectedObj)" ng-options="getDisplayLabel(d, displayLabel) for d in list">
- <option value="">Select option</option>
- </select>
- </div>
-
- <div class="btn-group col-md-6" role="group">
- <button type="button" class="btn btn-primary col-md-4" ng-click="add()">Add</button>
- <button type="button" class="btn btn-primary col-md-4" ng-click="modify()">Edit</button>
- <button type="button" class="btn btn-primary col-md-4" ng-click="delete()">Delete</button>
- </div>
-</section>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="paramCtrl">
- <label class="block basicLabel">{{ param.name }} :</label>
- <input type="text" style="width:50px;" ng-model="param.string" ng-change="changeParam(param.string)"></input>
- <input type="text" style="width:50px;" ng-model="param.int" ng-change="changeParam(param.int)"></input>
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="pnsCtrl" ng-init="init()">
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <section class="formWrapper clearfix" ng-show="internalView.pns">
- <form name="pnsForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Name:
- <i class="icon-exclamation-sign red" tooltip="Required field" ng-show="pnsForm.name.$error.required"></i>
- </label>
- <input class="form-control" type="text" ng-model="newPNSObj.name" ng-disabled="internalView.edit !== 'add'" name="name" ng-required="true" />
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newPNSObj['contract']">
- <label class="basicLabel">Contracts:</label>
- <button class="btn btn-primary btn-slim" ng-click="addNewElem()" ng-hide="internalView.edit === 'view'"><i class="icon-plus"></i></button>
-
-
- <div ng-repeat="contractRef in newPNSObj.contract track by $index">
-
- <div class="selectWrapper col-md-10">
- <select class="form-control" ng-model="contractRef" ng-change="updateAt($index, contractRef)" ng-options="c.id as getDisplayLabel(c, contracts.labels) for c in contracts.options" ng-disabled="internalView.edit === 'view'">
- <option>--</option>
- </select>
- </div>
- <button class="btn btn-danger col-md-2" ng-click="deleteElemAt($index)" ng-hide="internalView.edit === 'view'"><i class="icon-remove"></i></button>
-
- </div>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-hide="internalView.edit === 'view'">Save</button>
- </form>
- </section>
-
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="prefixCtrl" ng-init="init()">
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <section class="formWrapper clearfix" ng-show="internalView.prefix">
- <form name="prefixForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Prefix:
- <i class="icon-exclamation-sign red" tooltip="Invalid pattern" ng-show="prefixForm.prefix.$error.pattern"></i>
- <i class="icon-exclamation-sign red" tooltip="Required field" ng-show="prefixForm.prefix.$error.required"></i>
- </label>
- <input class="form-control" type="text" ng-model="newPrefixObj.prefix" name="prefix" ng-pattern="/^(([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9][0-9]|2[0-4][0-9]|25[0-5])/(([0-9])|([1-2][0-9])|(3[0-2]))$/" ng-required="true" ng-disabled="internalView.edit !== 'add'"/>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-hide="internalView.edit === 'view'">Save</button>
- </form>
- </section>
-
-</div>
\ No newline at end of file
+++ /dev/null
-<div class="main" ui-view></div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="ruleCtrl" ng-init="init()">
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <section ng-show="internalView.rule">
- <form name="rulesForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
-
- <div class="rowWrapper">
- <label class="block basicLabel"><span>Name:</span>
- <i class="icon-exclamation-sign red" tooltip="{{rulesForm.name.$error.required ? 'Required field' : rulesForm.name.$error.pattern ? 'Value must start with letter followed by letters and digits without space' : ''}}" ng-show="rulesForm.name.$error.required || rulesForm.name.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" ng-model="newRuleObj.name" name="name" ng-required="true" ng-disabled="internalView.edit !== 'add'" ng-pattern="/^[a-zA-Z]([a-zA-Z0-9\-_.])*$/"/>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newRuleObj['order']">
- <label class="block basicLabel"><span>Order:</span>
- <i class="icon-exclamation-sign red" tooltip="Required field" ng-show="rulesForm.order.$error.required"></i>
- <i class="icon-exclamation-sign red" tooltip="Invalid pattern" ng-show="errors.int32 && !rulesForm.order.$error.required"></i>
- </label>
- <input class="form-control" type="text" name="order" ng-required="true" ng-model="newRuleObj.order" ng-disabled="internalView.edit === 'view'" ng-change="validate(newRuleObj.order, errors)"/>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-hide="internalView.edit === 'view'">Save</button>
- </form>
- </section>
-
- <section class="formWrapper clearfix" ng-show="selectedRule">
- <div ng-include src="view_path+'action-ref.tpl.html'"></div>
- </section>
-
- <section class="formWrapper clearfix" ng-show="selectedRule">
- <div ng-include src="view_path+'classifier-ref.tpl.html'"></div>
- </section>
-
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="subjectCtrl" ng-init="init()">
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <section ng-show="internalView.subject">
- <form name="subjectForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
-
- <div class="rowWrapper">
- <label class="block basicLabel"><span>Name:</span>
- <i class="icon-exclamation-sign red" tooltip="{{subjectForm.name.$error.required ? 'Required field' : subjectForm.name.$error.pattern ? 'Value must start with letter followed by letters and digits without space' : ''}}" ng-show="subjectForm.name.$error.required || subjectForm.name.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" ng-model="newSubjectObj.name" name="name" ng-required="true" ng-disabled="internalView.edit !== 'add'" ng-pattern="/^[a-zA-Z]([a-zA-Z0-9\-_.])*$/"/>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newSubjectObj['order']">
- <label class="block basicLabel"><span>Order:</span>
- <i class="icon-exclamation-sign red" tooltip="Required field" ng-show="subjectForm.order.$error.required"></i>
- <i class="icon-exclamation-sign red" tooltip="Invalid pattern" ng-show="errors.int32 && !subjectForm.order.$error.required"></i>
- </label>
- <input class="form-control" type="text" name="order" ng-required="true" name="order" ng-model="newSubjectObj.order" ng-disabled="internalView.edit === 'view'" ng-change="validate(newSubjectObj.order, errors)"/>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-hide="internalView.edit === 'view'">Save</button>
- </form>
- </section>
-
- <section class="formWrapper clearfix" ng-show="selectedSubject">
- <div ng-include src="view_path+'rules.tpl.html'"></div>
- </section>
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="tenantCtrl" ng-init="init()">
-
- <h2 class="text-center">Tenants</h2>
-
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <section class="formWrapper clearfix" ng-show="view.tenant">
- <form name="tenantForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
- <label class="block">Add Tenant</label>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Id:</label>
- <input class="form-control" type="text" ng-model="newTenantObj.id" disabled/>
- </div>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Name:
- <i class="icon-exclamation-sign red" tooltip="{{tenantForm.name.$error.required ? 'Required field' : tenantForm.name.$error.pattern ? 'Value must start with letter followed by letters and digits without space' : ''}}" ng-show="tenantForm.name.$error.required || tenantForm.name.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" name="name" ng-model="newTenantObj.name" ng-required="true" ng-disabled="view.edit === 'view'" ng-pattern="/^[a-zA-Z]([a-zA-Z0-9\-_.])*$/"/>
- </div>
-
- <div class="rowWrapper" ng-hide="view.edit === 'view' && !newTenantObj.description">
- <label class="block basicLabel">Description:</label>
- <input class="form-control" type="text" ng-model="newTenantObj.description" ng-disabled="view.edit === 'view'"/>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-hide="view.edit === 'view'">Save</button>
- </form>
- </section>
-
- <button class="btn btn-primary bottom-buttons full-width wizard-button" ng-click="showWizard('accessModelWizard')"><i class="icon-magic"></i>Access Model Wizard</button>
- <button class="btn btn-primary col-md-12 bottom-buttons home" ng-click="toggleExpandedMM('main')">Home</button>
- <button class="btn btn-primary col-md-12 bottom-buttons back" ng-click="setViewExpand('policyRendererView', 'basic', true); setBreadcrumb('l3', null, false);">Back</button>
-
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="accessModelWizardCtrl">
- <div class="modal-canvas"></div>
- <div class="modal-dialog">
- <div class="modal-header">
- <i class="icon-remove align-right padding" ng-click="closeWizard('accessModelWizard')"></i>
- <h2>Access model wizard</h2>
- </div>
- <aside class="modal-navigation">
- <ul>
- <li class="navigation-item {{wizardPage === 'tenants' ? 'selected' : ''}}">Tenants</li>
- <li class="navigation-item {{wizardPage === 'contracts' ? 'selected' : ''}}">Contracts</li>
- <li class="navigation-item {{wizardPage === 'epgs' ? 'selected' : ''}}">Endpoint groups</li>
- </ul>
- </aside>
- <section class="modal-content-container">
- <div ng-show="wizardPage === 'tenants'" ng-controller="wizardTenantCtrl" ng-init="init()">
- <div class="content">
- <h2>Tenant</h2>
- <div class="clearfix">
- <div class="rowWrapper">
- <label class="block basicLabel">Select tenant</label>
- <select class="form-control" ng-model="selectedTenant" ng-options="getDisplayLabel(c, displayLabel) for c in tenantList" ng-change="reloadTenants(selectedTenant)">
- <option value="">Select option</option>
- </select>
- </div>
- </div>
- <div class="formWrapper clearfix">OR Add New</div>
- <div class="clearfix">
- <form name="tenantForm" novalidate="novalidate">
- <div class="rowWrapper">
- <label class="block basicLabel">Id:</label>
- <input class="form-control" type="text" ng-model="newTenantObj.id" disabled/>
- </div>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Name:
- <i class="icon-exclamation-sign red" tooltip="{{tenantForm.name.$error.required ? 'Required field' : tenantForm.name.$error.pattern ? 'Value must start with letter followed by letters and digits without space' : ''}}" ng-show="tenantForm.name.$error.required || tenantForm.name.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" name="name" ng-model="newTenantObj.name" ng-required="true" ng-disabled="view.tenantEdit" ng-pattern="/^[a-zA-Z]([a-zA-Z0-9\-_.])*$/"/>
- </div>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Description:</label>
- <input class="form-control" type="text" ng-model="newTenantObj.description" ng-disabled="view.tenantEdit"/>
- </div>
- </form>
- </div>
- </div>
- <div class="bottom-navigation clearfix">
- <button class="btn btn-primary" ng-click="setPage('contracts', newTenantObj)" ng-disabled="!tenantForm.$valid">Next</button>
- </div>
- </div>
-
- <div ng-show="wizardPage === 'contracts'" ng-controller="wizardContractCtrl" ng-init="init()">
- <div class="content">
- <h2 class="text-center">Contracts</h2>
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <div class="formWrapper clearfix" ng-show="contractFormView">
- <form name="contractForm" novalidate="novalidate">
- <label class="block">Add contract</label>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Id:</label>
- <input class="form-control" type="text" ng-model="newContractObj.id" disabled />
- </div>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Description:</label>
- <input class="form-control" type="text" ng-model="newContractObj.description" />
- </div>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Parent:</label>
- <select class="form-control" ng-model="newContractObj.parent" ng-options="d.id as getDisplayLabel(d, displayLabel) for d in list">
- <option value="">Select option</option>
- </select>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-disabled="!contractForm.$valid">Save contract</button>
- </form>
- </div>
-
- <fieldset ng-disabled="!selectedContract">
- <div class="formWrapper clearfix">
- <div ng-controller="wizardSubjectCtrl" ng-init="init()">
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <div ng-show="internalView.subject">
- <form name="subjectForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
-
- <div class="rowWrapper">
- <label class="block basicLabel"><span>Name:</span>
- <i class="icon-exclamation-sign red" tooltip="Required field" ng-show="subjectForm.name.$error.required"></i>
- </label>
- <input class="form-control" type="text" ng-model="newSubjectObj.name" name="name" ng-required="true" />
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newSubjectObj['order']">
- <label class="block basicLabel"><span>Order:</span>
- <i class="icon-exclamation-sign red" tooltip="Required field" ng-show="subjectForm.order.$error.required"></i>
- <i class="icon-exclamation-sign red" tooltip="Invalid pattern" ng-show="errors.int32 && !subjectForm.order.$error.required"></i>
- </label>
- <input class="form-control" type="text" name="order" ng-required="true" ng-model="newSubjectObj.order" ng-change="validate(newSubjectObj.order, errors)"/>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-disabled="!subjectForm.$valid">Save subject</button>
- </form>
- </div>
-
- <fieldset ng-disabled="!selectedSubject">
- <div class="formWrapper clearfix">
- <div ng-controller="wizardRuleCtrl" ng-init="init()">
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <div ng-show="internalView.rule">
- <form name="rulesForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
-
- <div class="rowWrapper">
- <label class="block basicLabel"><span>Name:</span>
- <i class="icon-exclamation-sign red" tooltip="{{rulesForm.name.$error.required ? 'Required field' : rulesForm.name.$error.pattern ? 'Value must start with letter followed by letters and digits without space' : ''}}" ng-show="rulesForm.name.$error.required || rulesForm.name.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" ng-model="newRuleObj.name" name="name" ng-required="true" ng-pattern="/^[a-zA-Z]([a-zA-Z0-9\-_.])*$/"/>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newRuleObj['order']">
- <label class="block basicLabel"><span>Order:</span>
- <i class="icon-exclamation-sign red" tooltip="Required field" ng-show="rulesForm.order.$error.required"></i>
- <i class="icon-exclamation-sign red" tooltip="Invalid pattern" ng-show="errors.int32 && !rulesForm.order.$error.required"></i>
- </label>
- <input class="form-control" type="text" name="order" ng-required="true" ng-model="newRuleObj.order" ng-change="validate(newRuleObj.order, errors)"/>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-disabled="!rulesForm.$valid">Save rule</button>
- </form>
- </div>
-
- <fieldset ng-disabled="!selectedRule">
- <div class="formWrapper clearfix">
- <div ng-controller="wizardActionRefCtrl" ng-init="init()">
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <div ng-show="internalView.actionRef">
- <form name="actionRefForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
-
- <div class="rowWrapper">
- <label class="block basicLabel"><span>Name:</span>
- <i class="icon-exclamation-sign red" tooltip="Required field" ng-show="actionRefForm.name.$error.required"></i>
- </label>
- <select class="form-control" ng-model="newActionRefObj.name" ng-options="c.name as getDisplayLabel(c, actionInstanceNames.labels) for c in actionInstanceNames.options" name="name" ng-required="true">
- <option>--</option>
- </select>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newActionRefObj['order']">
- <label class="block basicLabel"><span>Order:</span>
- <i class="icon-exclamation-sign red" tooltip="Invalid pattern" ng-show="errors.int32"></i>
- </label>
- <input class="form-control" type="text" ng-model="newActionRefObj.order" ng-change="validate(newActionRefObj.order, errors)"/>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" >Save</button>
- </form>
- </div>
- </div>
-
- <div ng-controller="wizardClassifierRefCtrl" ng-init="init()">
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <div ng-show="internalView.classifierRef">
- <form name="classifierRefForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
-
- <div class="rowWrapper">
- <label class="block basicLabel"><span>Name:</span>
- <i class="icon-exclamation-sign red" tooltip="{{classifierRefForm.name.$error.required ? 'Required field' : classifierRefForm.name.$error.pattern ? 'Value must start with letter followed by letters and digits without space' : ''}}" ng-show="classifierRefForm.name.$error.required || classifierRefForm.name.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" ng-model="newClassifierRefObj.name" name="name" ng-required="true" ng-pattern="/^[a-zA-Z]([a-zA-Z0-9\-_.])*$/"/>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newClassifierRefObj['instance-name']">
- <label class="block basicLabel"><span>Instance name:</span></label>
- <select class="form-control" ng-model="newClassifierRefObj['instance-name']" ng-options="c.name as getDisplayLabel(c, instanceNames.labels) for c in instanceNames.options" >
- <option>--</option>
- </select>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newClassifierRefObj['direction']">
- <label class="block basicLabel"><span>Direction:</span></label>
- <select class="form-control" ng-model="newClassifierRefObj.direction" ng-options="c for c in formDirections" >
- <option>--</option>
- </select>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newClassifierRefObj['connection-tracking']">
- <label class="block basicLabel"><span>Connection tracking:</span></label>
- <select class="form-control" ng-model="newClassifierRefObj['connection-tracking']" ng-options="c for c in formConnectionTracking" >
- <option>--</option>
- </select>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" >Save</button>
- </form>
- </div>
- </div>
- </div>
- </fieldset>
- </div>
- </div>
- </fieldset>
- </div>
-
- <div ng-controller="wizardClauseCtrl" ng-init="init()">
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <div class="formWrapper clearfix" ng-show="internalView.clause">
- <form name="clauseForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
-
- <div class="rowWrapper">
- <label class="block basicLabel"><span>Name:</span>
- <i class="icon-exclamation-sign red" tooltip="{{clauseForm.name.$error.required ? 'Required field' : clauseForm.name.$error.pattern ? 'Value must start with letter followed by letters and digits without space' : ''}}" ng-show="clauseForm.name.$error.required || clauseForm.name.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" ng-model="newClauseObj.name" name="name" ng-required="true" ng-pattern="/^[a-zA-Z]([a-zA-Z0-9\-_.])*$/"/>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newClauseObj['subject-refs']">
- <label class="basicLabel"><span>Clause subjects:</span></label>
- <button class="btn btn-primary btn-slim" ng-click="addNewElem()"><i class="icon-plus"></i></button>
-
- <div ng-repeat="subjectRef in newClauseObj['subject-refs'] track by $index">
- <div class="selectWrapper col-md-10">
- <select class="form-control" ng-model="subjectRef" ng-change="updateAt($index, subjectRef)" ng-options="s.name as getDisplayLabel(s, subjects.labels) for s in subjects.options">
- <option>--</option>
- </select>
- </div>
- <button class="btn btn-danger col-md-2" ng-click="deleteElemAt($index)" ><i class="icon-remove"></i></button>
- </div>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-disabled="!clauseForm.$valid">Save</button>
- </form>
- </div>
- </div>
- </div>
- </fieldset>
-
- </div>
-
- <div class="bottom-navigation clearfix">
- <button class="btn" ng-click="setPage('tenants')">Previous</button>
- <button class="btn btn-primary" ng-click="setPage('epgs', list)">Next</button>
- </div>
- </div>
-
- <div ng-show="wizardPage === 'epgs'" ng-controller="wizardEpgCtrl" ng-init="init()">
- <div class="content">
- <h2 class="text-center">Endpoint groups</h2>
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <div class=" clearfix" ng-show="epgFormView">
- <form name="epgForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
- <div class="rowWrapper">
- <label class="block basicLabel">Id:</label>
- <input class="form-control" type="text" ng-model="newEpgObj.id" disabled />
- </div>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Name:
- <i class="icon-exclamation-sign red" tooltip="{{epgForm.name.$error.required ? 'Required field' : epgForm.name.$error.pattern ? 'Value must start with letter followed by letters and digits without space' : ''}}" ng-show="epgForm.name.$error.required || epgForm.name.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" name="name" ng-model="newEpgObj.name" ng-required="true" ng-pattern="/^[a-zA-Z]([a-zA-Z0-9\-_.])*$/"/>
- </div>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Description:</label>
- <input class="form-control" type="text" ng-model="newEpgObj.description" />
- </div>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Intra group policy:</label>
- <select class="form-control" ng-model="newEpgObj['intra-group-policy']" ng-options="opt for opt in igpOpts">
- <option>--</option>
- </select>
- </div>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Network domain:
- <i class="icon-exclamation-sign red" tooltip="Invalid pattern" ng-show="epgForm.netDomain.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" ng-model="newEpgObj['network-domain']" name="netDomain" ng-pattern="/^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$/"/>
- </div>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Parent:</label>
- <select class="form-control" ng-model="newEpgObj.parent" ng-options="d.id as getDisplayLabel(d, displayLabel) for d in list">
- <option>--</option>
- </select>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-disabled="!epgForm.$valid">Save</button>
- </form>
- </div>
-
- <fieldset ng-disabled="!selectedEpg">
- <div class="formWrapper clearfix">
- <div ng-controller="wizardCnsCtrl" ng-init="init()">
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <div class="formWrapper clearfix" ng-show="internalView.cns">
- <form name="cnsForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Name:
- <i class="icon-exclamation-sign red" tooltip="Required field" ng-show="cnsForm.name.$error.required"></i>
- </label>
- <input class="form-control" type="text" name="name" ng-model="newCNSObj.name" ng-required="true" />
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newCNSObj['contract']">
- <label class="basicLabel">Contracts:</label>
- <button class="btn btn-primary btn-slim" ng-click="addNewElem()" ><i class="icon-plus"></i></button>
-
- <div ng-repeat="contractRef in newCNSObj.contract track by $index">
- <div class="selectWrapper col-md-10">
- <select class="form-control" ng-model="contractRef" ng-change="updateAt($index, contractRef)" ng-options="c.id as getDisplayLabel(c, contractList.labels) for c in contractList.options" ng->
- <option value="">Select option</option>
- </select>
- </div>
- <button class="btn btn-danger col-md-2" ng-click="deleteElemAt($index)" ><i class="icon-remove"></i></button>
- </div>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-disabled="!cnsForm.$valid">Save</button>
- </form>
- </div>
-
- </div>
- </div>
-
- <div class="clearfix">
- <div ng-controller="wizardPnsCtrl" ng-init="init()">
-
- <div ng-include src="view_path+'parts/crud.tpl.html'"></div>
-
- <section class="formWrapper clearfix" ng-show="internalView.pns">
- <form name="pnsForm" novalidate="novalidate">
- <i class="icon-remove align-right" ng-click="close()"></i>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Name:
- <i class="icon-exclamation-sign red" tooltip="Required field" ng-show="pnsForm.name.$error.required"></i>
- </label>
- <input class="form-control" type="text" ng-model="newPNSObj.name" name="name" ng-required="true" />
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newPNSObj['contract']">
- <label class="basicLabel">Contracts:</label>
- <button class="btn btn-primary btn-slim" ng-click="addNewElem()" ><i class="icon-plus"></i></button>
-
-
- <div ng-repeat="contractRef in newPNSObj.contract track by $index">
-
- <div class="selectWrapper col-md-10">
- <select class="form-control" ng-model="contractRef" ng-change="updateAt($index, contractRef)" ng-options="c.id as getDisplayLabel(c, contractList.labels) for c in contractList.options" >
- <option>--</option>
- </select>
- </div>
- <button class="btn btn-danger col-md-2" ng-click="deleteElemAt($index)" ><i class="icon-remove"></i></button>
-
- </div>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-disabled="!pnsForm.$valid">Save</button>
- </form>
- </section>
-
- </div>
- </div>
- </fieldset>
- </div>
-
- <div class="bottom-navigation clearfix">
- <button class="btn" ng-click="setPage('contracts')">Previous</button>
- <!-- <button class="btn btn-primary" ng-click="setPage('summary', list)">Next</button> -->
- <button class="btn btn-primary"ng-click="submit(list)">Submit</button>
- </div>
- </div>
- </section>
- </div>
-</div>
\ No newline at end of file
+++ /dev/null
-<div ng-controller="actionReferenceWizardCtrl" ng-init="init()">
- <div class="modal-canvas"></div>
- <div class="modal-dialog">
- <div class="modal-header">
- <i class="icon-remove align-right padding" ng-click="closeWizard('actionReferenceWizard')"></i>
- <h2>Action reference wizard</h2>
- </div>
- <aside class="modal-navigation">
- <ul>
- <li class="navigation-item {{wizardPage === 'reference' ? 'selected' : ''}}">References</li>
- <li class="navigation-item {{wizardPage === 'instance' ? 'selected' : ''}}">Instances</li>
- </ul>
- </aside>
- <section class="modal-content-container">
- <div ng-show="wizardPage === 'reference'" ng-controller="actionsRefListCtrl">
- <div class="content">
- <label class="basicLabel mb0">Action references list:</label>
- <table class="table table-hover">
- <thead>
- <tr>
- <th>Order</th>
- <th>Name</th>
- <th><button class="btn btn-primary" tooltip="Add Action reference" ng-click="showForm()"><i class="icon-plus"></i></button></th>
- </tr>
- </thead>
- <tbody>
- <tr ng-repeat="action in rule['action-ref'] track by $index | orderBy:'order'">
- <th>{{action.order}}</th>
- <td>{{action.name}}</td>
- <td>
- <button class="btn btn-primary" ng-click="showForm(action)" tooltil="Edit Action reference" >
- <i class="icon-pencil"></i>
- </button>
- <button class="btn btn-danger" ng-click="deleteElemAt($index)" tooltip="Remove Action reference">
- <i class="icon-remove"></i>
- </button>
- </td>
- </tr>
- </tbody>
- </table>
- <div ng-show="actionReferenceForm">
- <form name="actionRefForm" novalidate="novalidate">
- <i class="icon-remove align-right padding" ng-click="closeForm()"></i>
- <div class="rowWrapper">
- <label class="block basicLabel"><span>Instance name:</span>
- <i class="icon-exclamation-sign red" tooltip="Required field" ng-show="actionRefForm.name.$error.required"></i>
- </label>
- <select class="form-control" ng-model="newActionRefObj.name" ng-options="c.name as getDisplayLabel(c, actionInstanceNames.labels) for c in actionInstanceNames.options" name="name" ng-required="true" >
- <option>--</option>
- </select>
- <button class="btn btn-primary" tooltip="Add Action instance" ng-click="setPage('instance')"><i class="icon-plus"></i></button>
- </div>
-
- <div class="rowWrapper" ng-hide="internalView.edit === 'view' && !newActionRefObj['order']">
- <label class="block basicLabel"><span>Order:</span>
- <i class="icon-exclamation-sign red" tooltip="Invalid pattern" ng-show="errors.int32"></i>
- </label>
- <input class="form-control" type="text" ng-model="newActionRefObj.order" ng-change="validate(newActionRefObj.order, errors)"/>
- </div>
-
- <div class="rowWrapper">
- <button ng-click="save()" class="btn btn-primary col-md-12" ng-disabled="!actionRefForm.$valid">Save</button>
- </div>
- </form>
- </div>
-
- </div>
- <div class="bottom-navigation clearfix">
- <button class="btn btn-primary" ng-click="submit()">Submit</button>
- </div>
- </div>
-
- <div ng-show="wizardPage === 'instance'" ng-controller="actionInstanceWizardCtrl" ng-init="init()">
- <div class="content">
- <section class="formWrapper clearfix">
- <form name="actionsForm" novalidate="novalidate">
- <label class="block">Add actions</label>
-
- <div class="rowWrapper">
- <label class="block basicLabel">Name
- <i class="icon-exclamation-sign red" tooltip="{{actionsForm.name.$error.required ? 'Required field' : actionsForm.name.$error.pattern ? 'Value must start with letter followed by letters and digits without space' : ''}}" ng-show="actionsForm.name.$error.required || actionsForm.name.$error.pattern"></i>
- </label>
- <input class="form-control" type="text" name="name" ng-required="true" ng-model="newActionObj.name" ng-pattern="/^[a-zA-Z]([a-zA-Z0-9\-_.])*$/"/>
- </div>
-
- <div class="rowWrapper" ng-hide="edit === 'view' && !newActionObj['action-definition-id']">
- <label class="block basicLabel">Definition</label>
- <select class="form-control" ng-model="newActionObj['action-definition-id']" ng-options="d.id as getDisplayLabel(d, actionDefinitions.labels) for d in actionDefinitions.options" ng-change="reloadDefs()">
- <option value="">Select option</option>
- </select>
- </div>
-
- <div class="rowWrapper">
- <div ng-repeat="param in defs">
- <div class="row-param" ng-controller="paramCtrl" ng-init="init(param, newActionObj['parameter-value'])">
- <div ng-show="param.type !== 'range' && param.name !== 'sfc-chain-name'">
- <label class="block basicLabel">{{ parameter.name + ' (' + parameter.type + ')' }}:</label>
- <input class="form-control" type="text" ng-model="value" ng-disabled="edit === 'view'"></input>
- </div>
- <div ng-show="param.name === 'sfc-chain-name'">
- <label class="block basicLabel">Pick SFC:</label>
- <input class="form-control" type="text" ng-model="value" disabled></input>
- <table class="table table-hover">
- <thead>
- <tr>
- <th>Symmetric</th>
- <th>Name</th>
- <th>Functions</th>
- <th>Action</th>
- </tr>
- </thead>
- <tbody>
- <tr ng-repeat="chain in serviceFunctionChains">
- <th>{{chain.symmetric}}</th>
- <td>{{chain.name}}</td>
- <td>
- <ul>
- <li ng-repeat="function in chain['sfc-service-function']">
- {{function.name + ' - ' + function.type}}
- </li>
- </ul>
- </td>
- <td>
- <button class="btn btn-primary" ng-click="$parent.value = chain.name" ng-disabled="value === chain.name">
- {{value === chain.name ? 'picked' : 'pick'}}
- </button>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- <div ng-show="param.type === 'range'">
- <label class="param-label">{{ parameter.name + ' (' + parameter.type + ')' }}:</label>
-
- <input class="form-control narrow-input-left" type="text" ng-model="value.min" ng-disabled="edit === 'view'"></input>
- <input class="form-control narrow-input-right" type="text" ng-model="value.max" ng-disabled="edit === 'view'"></input>
- </div>
- </div>
- </div>
- </div>
-
- <button class="btn btn-primary col-md-12" ng-click="save()" ng-hide="edit === 'view'" ng-disabled="!actionsForm.$valid">Save</button>
- </form>
- </section>
- </div>
-
- <div class="bottom-navigation clearfix">
- <button class="btn btn-primary" ng-click="setPage('reference')">Back</button>
- </div>
- </div>
- </section>
- </div>
-</div>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- Copyright (c) 2014 Inocybe Technologies, and others. All rights reserved.
-
- This program and the accompanying materials are made available under the
- terms of the Eclipse Public License v1.0 which accompanies this distribution,
- and is available at http://www.eclipse.org/legal/epl-v10.html
--->
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
- <groupId>org.opendaylight.groupbasedpolicy</groupId>
- <artifactId>groupbasedpolicy-old-ui</artifactId>
- <name>groupbasedpolicy-old-ui</name>
- <description>Resources</description>
- <version>0.4.0-SNAPSHOT</version>
- <packaging>pom</packaging>
-
- <prerequisites>
- <maven>3.0</maven>
- </prerequisites>
-
- <modules>
- <module>module</module>
- <module>bundle</module>
- </modules>
-
-</project>
<module>neutron-mapper</module>
<module>neutron-vpp-mapper</module>
<module>neutron-ovsdb</module>
- <module>ui-backend</module>
<module>groupbasedpolicy-ui</module>
- <module>groupbasedpolicy-old-ui</module>
<module>distribution-karaf</module>
<module>features</module>
<module>sxp-mapper</module>
+++ /dev/null
-<?xml version="1.0"?>
-<project
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
- xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <modelVersion>4.0.0</modelVersion>
-
- <parent>
- <groupId>org.opendaylight.controller</groupId>
- <artifactId>config-parent</artifactId>
- <version>0.5.0-SNAPSHOT</version>
- <relativePath/>
- </parent>
-
- <groupId>org.opendaylight.groupbasedpolicy</groupId>
- <artifactId>ui-backend</artifactId>
- <version>0.4.0-SNAPSHOT</version>
- <packaging>bundle</packaging>
-
- <dependencies>
- <dependency>
- <groupId>org.opendaylight.groupbasedpolicy</groupId>
- <artifactId>groupbasedpolicy</artifactId>
- <version>${project.version}</version>
- </dependency>
- </dependencies>
-
- <!-- project build -->
- <build>
- <plugins>
- <plugin>
- <groupId>org.apache.felix</groupId>
- <artifactId>maven-bundle-plugin</artifactId>
- <extensions>true</extensions>
- <configuration>
- <instructions>
- <Export-Package>
- </Export-Package>
- </instructions>
- <manifestLocation>${project.basedir}/META-INF</manifestLocation>
- </configuration>
- </plugin>
- </plugins>
- </build>
-</project>
\ No newline at end of file
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>\r
-<!--\r
- Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.\r
-\r
- This program and the accompanying materials are made available under the\r
- terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- and is available at http://www.eclipse.org/legal/epl-v10.html\r
--->\r
-<snapshot>\r
- <configuration>\r
- <data xmlns="urn:ietf:params:xml:ns:netconf:base:1.0">\r
- <modules xmlns="urn:opendaylight:params:xml:ns:yang:controller:config">\r
- <module>\r
- <type xmlns:binding-impl="urn:opendaylight:params:xml:ns:yang:controller:config:ui-backend:impl">\r
- binding-impl:ui-backend-impl\r
- </type>\r
- <name>ui-backend-impl</name>\r
-\r
- <data-broker>\r
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">\r
- binding:binding-async-data-broker\r
- </type>\r
- <name>binding-data-broker</name>\r
- </data-broker>\r
-\r
- <rpc-registry>\r
- <type xmlns:binding="urn:opendaylight:params:xml:ns:yang:controller:md:sal:binding">\r
- binding:binding-rpc-registry\r
- </type>\r
- <name>binding-rpc-broker</name>\r
- </rpc-registry>\r
- </module>\r
- </modules>\r
- </data>\r
- </configuration>\r
-\r
- <required-capabilities>\r
- <capability>urn:opendaylight:params:xml:ns:yang:controller:config:ui-backend:impl?module=ui-backend-impl&revision=2015-05-11\r
- </capability>\r
- </required-capabilities>\r
-</snapshot>\r
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-package org.opendaylight.controller.config.yang.config.ui_backend.impl;
-
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.groupbasedpolicy.ui.backend.UiBackendServiceImpl;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import com.google.common.base.Preconditions;
-
-public class UiBackendModule extends org.opendaylight.controller.config.yang.config.ui_backend.impl.AbstractUiBackendModule {
-
- private static final Logger LOG = LoggerFactory.getLogger(UiBackendModule.class);
-
- public UiBackendModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver) {
- super(identifier, dependencyResolver);
- }
-
- public UiBackendModule(org.opendaylight.controller.config.api.ModuleIdentifier identifier, org.opendaylight.controller.config.api.DependencyResolver dependencyResolver, org.opendaylight.controller.config.yang.config.ui_backend.impl.UiBackendModule oldModule, java.lang.AutoCloseable oldInstance) {
- super(identifier, dependencyResolver, oldModule, oldInstance);
- }
-
- @Override
- public void customValidation() {
- // add custom validation form module attributes here.
- }
-
- @Override
- public java.lang.AutoCloseable createInstance() {
- DataBroker dataProvider = Preconditions.checkNotNull(getDataBrokerDependency());
- final UiBackendServiceImpl pgnApplicationService = new UiBackendServiceImpl(dataProvider,
- getRpcRegistryDependency());
- LOG.info("ui-backend started.");
-
- return new AutoCloseable() {
-
- @Override
- public void close() throws Exception {
- pgnApplicationService.close();
- }
- };
- }
-
-}
+++ /dev/null
-/*
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
- *
- * This program and the accompanying materials are made available under the
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,
- * and is available at http://www.eclipse.org/legal/epl-v10.html
- */
-
-/*
-* Generated file
-*
-* Generated from: yang module name: ui-backend-impl yang module local name: ui-backend-impl
-* Generated by: org.opendaylight.controller.config.yangjmxgenerator.plugin.JMXGenerator
-* Generated at: Mon May 11 01:23:43 CEST 2015
-*
-* Do not modify this file unless it is present under src/main directory
-*/
-package org.opendaylight.controller.config.yang.config.ui_backend.impl;
-public class UiBackendModuleFactory extends org.opendaylight.controller.config.yang.config.ui_backend.impl.AbstractUiBackendModuleFactory {
-
-}
+++ /dev/null
-/*\r
- * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.\r
- *\r
- * This program and the accompanying materials are made available under the\r
- * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
- * and is available at http://www.eclipse.org/legal/epl-v10.html\r
- */\r
-\r
-package org.opendaylight.groupbasedpolicy.ui.backend;\r
-\r
-import java.util.ArrayList;\r
-import java.util.Collections;\r
-import java.util.HashSet;\r
-import java.util.List;\r
-import java.util.Set;\r
-import java.util.concurrent.Future;\r
-\r
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;\r
-import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;\r
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;\r
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;\r
-import org.opendaylight.controller.sal.binding.api.BindingAwareBroker;\r
-import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry;\r
-import org.opendaylight.groupbasedpolicy.dto.EgKey;\r
-import org.opendaylight.groupbasedpolicy.dto.IndexedTenant;\r
-import org.opendaylight.groupbasedpolicy.dto.Policy;\r
-import org.opendaylight.groupbasedpolicy.dto.RuleGroup;\r
-import org.opendaylight.groupbasedpolicy.util.PolicyResolverUtils;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.Endpoints;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.endpoints.Endpoint;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Tenants;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.Tenant;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.TenantKey;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.Rule;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.GetEndpointsFromEndpointGroupInput;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.GetEndpointsFromEndpointGroupOutput;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.GetEndpointsFromEndpointGroupOutputBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.GetSubjectsBetweenEndpointGroupsInput;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.GetSubjectsBetweenEndpointGroupsOutput;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.GetSubjectsBetweenEndpointGroupsOutputBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.UiBackendService;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.get.endpoints.from.endpoint.group.output.UiEndpoint;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.get.endpoints.from.endpoint.group.output.UiEndpointBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.get.subjects.between.endpoint.groups.input.FromOperData;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.get.subjects.between.endpoint.groups.output.EndpointGroupPairWithSubject;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.get.subjects.between.endpoint.groups.output.EndpointGroupPairWithSubjectBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.get.subjects.between.endpoint.groups.output.endpoint.group.pair.with.subject.UiSubject;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.get.subjects.between.endpoint.groups.output.endpoint.group.pair.with.subject.UiSubjectBuilder;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.get.subjects.between.endpoint.groups.output.endpoint.group.pair.with.subject.ui.subject.UiRule;\r
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ui.backend.rev150511.get.subjects.between.endpoint.groups.output.endpoint.group.pair.with.subject.ui.subject.UiRuleBuilder;\r
-import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;\r
-import org.opendaylight.yangtools.yang.common.RpcResult;\r
-import org.opendaylight.yangtools.yang.common.RpcResultBuilder;\r
-import org.slf4j.Logger;\r
-import org.slf4j.LoggerFactory;\r
-\r
-import com.google.common.base.Function;\r
-import com.google.common.base.Optional;\r
-import com.google.common.base.Preconditions;\r
-import com.google.common.collect.ImmutableSet;\r
-import com.google.common.collect.Table;\r
-import com.google.common.collect.Table.Cell;\r
-import com.google.common.util.concurrent.CheckedFuture;\r
-import com.google.common.util.concurrent.Futures;\r
-\r
-public class UiBackendServiceImpl implements UiBackendService, AutoCloseable {\r
-\r
- private static final Logger LOG = LoggerFactory.getLogger(UiBackendServiceImpl.class);\r
-\r
- private final DataBroker dataProvider;\r
- private final BindingAwareBroker.RpcRegistration<UiBackendService> rpcRegistration;\r
- private final InstanceIdentifier<Endpoints> ENDPOINTS_IID = InstanceIdentifier.builder(Endpoints.class).build();\r
-\r
- public UiBackendServiceImpl(DataBroker dataBroker, RpcProviderRegistry rpcRegistry) {\r
- Preconditions.checkNotNull(dataBroker);\r
- Preconditions.checkNotNull(rpcRegistry);\r
- this.dataProvider = dataBroker;\r
- rpcRegistration = rpcRegistry.addRpcImplementation(UiBackendService.class, this);\r
- }\r
-\r
- @Override\r
- public Future<RpcResult<GetEndpointsFromEndpointGroupOutput>> getEndpointsFromEndpointGroup(\r
- GetEndpointsFromEndpointGroupInput input) {\r
- LOG.trace("getEndpointsFromEndpointGroup: {}", input);\r
- final TenantId tenantId = input.getTenantId();\r
- if (tenantId == null) {\r
- throw new IllegalArgumentException("Missing tenant-Id in RPC input.");\r
- }\r
- final EndpointGroupId epgId = input.getEndpointGroupId();\r
- if (epgId == null) {\r
- throw new IllegalArgumentException("Missing endpoint-group-id in RPC input.");\r
- }\r
- ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction();\r
- CheckedFuture<Optional<Endpoints>, ReadFailedException> futureEndpoints = rTx.read(\r
- LogicalDatastoreType.OPERATIONAL, ENDPOINTS_IID);\r
- return Futures.transform(futureEndpoints,\r
- new Function<Optional<Endpoints>, RpcResult<GetEndpointsFromEndpointGroupOutput>>() {\r
-\r
- @Override\r
- public RpcResult<GetEndpointsFromEndpointGroupOutput> apply(Optional<Endpoints> potentialEndpoints) {\r
- GetEndpointsFromEndpointGroupOutputBuilder outputBuilder = new GetEndpointsFromEndpointGroupOutputBuilder();\r
- if (!potentialEndpoints.isPresent() || potentialEndpoints.get().getEndpoint() == null) {\r
- LOG.trace("No endpoint in datastore.");\r
- return RpcResultBuilder.success(outputBuilder.build()).build();\r
- }\r
-\r
- List<Endpoint> endpoints = potentialEndpoints.get().getEndpoint();\r
- List<UiEndpoint> uiEndpoints = new ArrayList<>();\r
- for (Endpoint ep : endpoints) {\r
- if (tenantId.equals(ep.getTenant()) && isEpInEpg(ep, epgId)) {\r
- uiEndpoints.add(new UiEndpointBuilder(ep).build());\r
- }\r
- }\r
- outputBuilder.setUiEndpoint(uiEndpoints);\r
- return RpcResultBuilder.success(outputBuilder.build()).build();\r
- }\r
- });\r
- }\r
-\r
- private boolean isEpInEpg(Endpoint ep, EndpointGroupId epgId) {\r
- if (epgId.equals(ep.getEndpointGroup())) {\r
- return true;\r
- }\r
- if (ep.getEndpointGroups() != null) {\r
- for (EndpointGroupId epgFromEp : ep.getEndpointGroups()) {\r
- if (epgId.equals(epgFromEp)) {\r
- return true;\r
- }\r
- }\r
- }\r
- return false;\r
- }\r
-\r
- @Override\r
- public Future<RpcResult<GetSubjectsBetweenEndpointGroupsOutput>> getSubjectsBetweenEndpointGroups(\r
- GetSubjectsBetweenEndpointGroupsInput input) {\r
- LOG.trace("getSubjectsBetweenEndpointGroups: {}", input);\r
- final TenantId tenantId = input.getTenantId();\r
- if (tenantId == null) {\r
- throw new IllegalArgumentException("Missing tenant-Id in RPC input.");\r
- }\r
- final FromOperData fromOperData = input.getFromOperData();\r
- InstanceIdentifier<Tenant> tenantIid = InstanceIdentifier.builder(Tenants.class)\r
- .child(Tenant.class, new TenantKey(tenantId))\r
- .build();\r
- CheckedFuture<Optional<Tenant>, ReadFailedException> futureTenant;\r
- try (ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction()) {\r
- if (fromOperData == null) {\r
- futureTenant = rTx.read(LogicalDatastoreType.CONFIGURATION, tenantIid);\r
- } else {\r
- futureTenant = rTx.read(LogicalDatastoreType.OPERATIONAL, tenantIid);\r
- }\r
- }\r
- return Futures.transform(futureTenant,\r
- new Function<Optional<Tenant>, RpcResult<GetSubjectsBetweenEndpointGroupsOutput>>() {\r
-\r
- @Override\r
- public RpcResult<GetSubjectsBetweenEndpointGroupsOutput> apply(Optional<Tenant> potentialTenant) {\r
- GetSubjectsBetweenEndpointGroupsOutputBuilder outputBuilder = new GetSubjectsBetweenEndpointGroupsOutputBuilder();\r
- if (!potentialTenant.isPresent()) {\r
- LOG.trace(\r
- "No tenant with id {} in {} datastore",\r
- tenantId.getValue(),\r
- fromOperData == null ? LogicalDatastoreType.CONFIGURATION : LogicalDatastoreType.OPERATIONAL);\r
- return RpcResultBuilder.success(outputBuilder.build()).build();\r
- }\r
-\r
- Tenant tenant = potentialTenant.get();\r
- Table<EgKey, EgKey, Policy> resolvedPolicy = PolicyResolverUtils.resolvePolicy(ImmutableSet.of(new IndexedTenant(\r
- tenant)));\r
- List<EndpointGroupPairWithSubject> epgPairsWithSubjects = new ArrayList<>();\r
- for (Cell<EgKey, EgKey, Policy> policyByConsProvEpg : resolvedPolicy.cellSet()) {\r
- Policy policy = policyByConsProvEpg.getValue();\r
- List<RuleGroup> subjects = getUniqueSortedSubjects(policy);\r
- List<UiSubject> uiSubjects = new ArrayList<>();\r
- for (RuleGroup subject : subjects) {\r
- UiSubject uiSubject = new UiSubjectBuilder().setName(subject.getRelatedSubject())\r
- .setOrder(subject.getOrder())\r
- .setUiRule(getUiRules(subject.getRules()))\r
- .build();\r
- uiSubjects.add(uiSubject);\r
- }\r
- EgKey consEgKey = policyByConsProvEpg.getRowKey();\r
- EgKey provEgKey = policyByConsProvEpg.getColumnKey();\r
- LOG.trace(\r
- "Resolved policies from {} datastore: \nConsumer EPG: {}\nProvider EPG: {}\nPolicy: {}",\r
- fromOperData == null ? LogicalDatastoreType.CONFIGURATION : LogicalDatastoreType.OPERATIONAL,\r
- consEgKey, provEgKey, policy);\r
- EndpointGroupPairWithSubject epgPairWithSubject = new EndpointGroupPairWithSubjectBuilder().setConsumerEndpointGroupId(\r
- consEgKey.getEgId())\r
- .setConsumerTenantId(consEgKey.getTenantId())\r
- .setProviderEndpointGroupId(provEgKey.getEgId())\r
- .setProviderTenantId(provEgKey.getTenantId())\r
- .setUiSubject(uiSubjects)\r
- .build();\r
- epgPairsWithSubjects.add(epgPairWithSubject);\r
- }\r
- GetSubjectsBetweenEndpointGroupsOutput result = outputBuilder.setEndpointGroupPairWithSubject(\r
- epgPairsWithSubjects).build();\r
- return RpcResultBuilder.success(result).build();\r
- }\r
- });\r
- }\r
-\r
- private List<RuleGroup> getUniqueSortedSubjects(Policy policy) {\r
- Set<RuleGroup> uniqueSubjects = new HashSet<>();\r
- for (List<RuleGroup> subjects : policy.getRuleMap().values()) {\r
- for (RuleGroup subject : subjects) {\r
- uniqueSubjects.add(subject);\r
- }\r
- }\r
- ArrayList<RuleGroup> sortedSubjects = new ArrayList<>(uniqueSubjects);\r
- Collections.sort(sortedSubjects);\r
- return sortedSubjects;\r
- }\r
-\r
- private List<UiRule> getUiRules(List<Rule> rules) {\r
- if (rules == null) {\r
- return Collections.emptyList();\r
- }\r
- List<UiRule> uiRules = new ArrayList<>();\r
- for (Rule rule : rules) {\r
- UiRule uiRule = new UiRuleBuilder().setName(rule.getName())\r
- .setOrder(rule.getOrder())\r
- .setClassifierRef(rule.getClassifierRef())\r
- .setActionRef(rule.getActionRef())\r
- .build();\r
- uiRules.add(uiRule);\r
- }\r
- return uiRules;\r
- }\r
-\r
- /**\r
- * @see java.lang.AutoCloseable#close()\r
- */\r
- @Override\r
- public void close() throws Exception {\r
- rpcRegistration.close();\r
- }\r
-\r
-}\r
+++ /dev/null
-module ui-backend-impl {
-
- yang-version 1;
- namespace "urn:opendaylight:params:xml:ns:yang:controller:config:ui-backend:impl";
- prefix "ui-backend-impl";
-
- import config { prefix config; revision-date 2013-04-05; }
- import opendaylight-md-sal-binding { prefix mdsal; revision-date 2013-10-28; }
-
- description
- "This module contains the base YANG definitions for
- ui-backend implementation.";
-
- revision "2015-05-11" {
- description
- "Initial revision.";
- }
-
- // This is the definition of the service implementation as a module identity.
- identity ui-backend-impl {
- base config:module-type;
-
- // Specifies the prefix for generated java classes.
- config:java-name-prefix UiBackend;
- }
-
- // Augments the 'configuration' choice node under modules/module.
- augment "/config:modules/config:module/config:configuration" {
- case ui-backend-impl {
- when "/config:modules/config:module/config:type = 'ui-backend-impl'";
-
- container data-broker {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity mdsal:binding-async-data-broker;
- }
- }
- }
-
- container rpc-registry {
- uses config:service-ref {
- refine type {
- mandatory true;
- config:required-identity mdsal:binding-rpc-registry;
- }
- }
- }
-
- }
- }
-}
\ No newline at end of file
+++ /dev/null
-module ui-backend {\r
- namespace "urn:opendaylight:params:xml:ns:yang:controller:config:ui-backend";\r
- prefix "ui-backend";\r
-\r
- import policy {prefix gbp-policy;}\r
- import gbp-common {prefix gbp-common;}\r
- import endpoint {prefix endpoint;}\r
-\r
- description\r
- "Module contains RPC definitions for more easier interaction of the GUI with the GBP APIs.";\r
-\r
- revision "2015-05-11" {\r
- description "Initial revision of ui-backend model";\r
- }\r
-\r
- grouping endpoint-group-identifier-fields {\r
- leaf tenant-id {\r
- type gbp-common:tenant-id;\r
- }\r
- leaf endpoint-group-id {\r
- type gbp-common:endpoint-group-id;\r
- }\r
- }\r
-\r
- grouping consumer-endpoint-group-ref {\r
- leaf consumer-tenant-id {\r
- type leafref {\r
- path "/gbp-policy:tenants/gbp-policy:tenant/gbp-policy:id";\r
- }\r
- }\r
- leaf consumer-endpoint-group-id {\r
- type leafref {\r
- path "/gbp-policy:tenants/gbp-policy:tenant/gbp-policy:policy/gbp-policy:endpoint-group/gbp-policy:id";\r
- }\r
- }\r
- }\r
-\r
- grouping provider-endpoint-group-ref {\r
- leaf provider-tenant-id {\r
- type leafref {\r
- path "/gbp-policy:tenants/gbp-policy:tenant/gbp-policy:id";\r
- }\r
- }\r
- leaf provider-endpoint-group-id {\r
- type leafref {\r
- path "/gbp-policy:tenants/gbp-policy:tenant/gbp-policy:policy/gbp-policy:endpoint-group/gbp-policy:id";\r
- }\r
- }\r
- }\r
-\r
- rpc get-endpoints-from-endpoint-group {\r
- description "Returns endpoints which are in the given endpoint group.";\r
- input {\r
- uses endpoint-group-identifier-fields;\r
- }\r
- output {\r
- list ui-endpoint {\r
- description\r
- "Endpoints indexed by layer 2 addreses.";\r
- key "l2-context mac-address";\r
- uses endpoint:endpoint-fields;\r
- }\r
- }\r
- }\r
-\r
- rpc get-subjects-between-endpoint-groups {\r
- description "Returns subjects between endpoint group pairs where endpoint groups are from the given tenant.";\r
- input {\r
- leaf tenant-id {\r
- description "Tenant ID of the tenant.";\r
- type gbp-common:tenant-id;\r
- mandatory true;\r
- }\r
- container from-oper-data {\r
- presence "Resolve subjects for endpoint gorup pairs based on operational data.";\r
- }\r
- }\r
- output {\r
- list endpoint-group-pair-with-subject {\r
- key "consumer-endpoint-group-id consumer-tenant-id provider-endpoint-group-id provider-tenant-id";\r
- uses consumer-endpoint-group-ref;\r
- uses provider-endpoint-group-ref;\r
- list ui-subject {\r
- key "name";\r
- leaf name {\r
- description "A name for the subject";\r
- type gbp-common:subject-name;\r
- }\r
- list ui-rule {\r
- key "name";\r
- leaf name {\r
- description "A name for the rule";\r
- type gbp-common:rule-name;\r
- }\r
- uses gbp-policy:has-classifier-refs;\r
- uses gbp-policy:has-action-refs;\r
- uses gbp-policy:has-order;\r
- }\r
- uses gbp-policy:has-order;\r
- }\r
- }\r
- }\r
- }\r
-\r
-}\r