This commit is contained in:
nik
2025-10-03 22:27:28 +03:00
parent 829fad0e17
commit 871cf7e792
16520 changed files with 2967597 additions and 3 deletions

3
node_modules/cytoscape-cose-bilkent/.babelrc generated vendored Normal file
View File

@@ -0,0 +1,3 @@
{
"presets": ["env"]
}

1
node_modules/cytoscape-cose-bilkent/.eslintignore generated vendored Normal file
View File

@@ -0,0 +1 @@
node_modules/**/*

13
node_modules/cytoscape-cose-bilkent/.eslintrc generated vendored Normal file
View File

@@ -0,0 +1,13 @@
{
"env": {
"browser": true,
"commonjs": true,
"node": true,
"amd": true,
"es6": true
},
"extends": "eslint:recommended",
"rules": {
"semi": "error"
}
}

21
node_modules/cytoscape-cose-bilkent/LICENSE generated vendored Normal file
View File

@@ -0,0 +1,21 @@
Copyright (c) 2016-2018, The Cytoscape Consortium.
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the “Software”), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

145
node_modules/cytoscape-cose-bilkent/README.md generated vendored Normal file
View File

@@ -0,0 +1,145 @@
cytoscape-cose-bilkent
================================================================================
[![DOI](https://zenodo.org/badge/42200589.svg)](https://zenodo.org/badge/latestdoi/42200589)
## Description
The CoSE (Compound Spring Embedder) layout for Cytoscape.js developed by [i-Vis Lab](http://cs.bilkent.edu.tr/~ivis/) in Bilkent University is a spring embedder layout with support for compound graphs (nested structures) and varying (non-uniform) node dimensions.
([demo](https://raw.githack.com/cytoscape/cytoscape.js-cose-bilkent/master/demo.html), [compound demo](https://raw.githack.com/cytoscape/cytoscape.js-cose-bilkent/master/demo-compound.html))
Please cite the following when using this layout:
U. Dogrusoz, E. Giral, A. Cetintas, A. Civril, and E. Demir, "[A Layout Algorithm For Undirected Compound Graphs](http://www.sciencedirect.com/science/article/pii/S0020025508004799)", Information Sciences, 179, pp. 980-994, 2009.
## Dependencies
* Cytoscape.js ^3.2.0
* cose-base ^1.0.0
## Usage instructions
Download the library:
* via npm: `npm install cytoscape-cose-bilkent`,
* via bower: `bower install cytoscape-cose-bilkent`, or
* via direct download in the repository (probably from a tag).
Import the library as appropriate for your project:
ES import:
```js
import cytoscape from 'cytoscape';
import coseBilkent from 'cytoscape-cose-bilkent';
cytoscape.use( coseBilkent );
```
CommonJS require:
```js
let cytoscape = require('cytoscape');
let coseBilkent = require('cytoscape-cose-bilkent');
cytoscape.use( coseBilkent ); // register extension
```
AMD:
```js
require(['cytoscape', 'cytoscape-cose-bilkent'], function( cytoscape, coseBilkent ){
coseBilkent( cytoscape ); // register extension
});
```
Plain HTML/JS has the extension registered for you automatically, because no `require()` is needed.
## API
When calling the layout, e.g. `cy.layout({ name: 'cose-bilkent', ... })`, the following options are supported:
```js
var defaultOptions = {
// Called on `layoutready`
ready: function () {
},
// Called on `layoutstop`
stop: function () {
},
// 'draft', 'default' or 'proof"
// - 'draft' fast cooling rate
// - 'default' moderate cooling rate
// - "proof" slow cooling rate
quality: 'default',
// Whether to include labels in node dimensions. Useful for avoiding label overlap
nodeDimensionsIncludeLabels: false,
// number of ticks per frame; higher is faster but more jerky
refresh: 30,
// Whether to fit the network view after when done
fit: true,
// Padding on fit
padding: 10,
// Whether to enable incremental mode
randomize: true,
// Node repulsion (non overlapping) multiplier
nodeRepulsion: 4500,
// Ideal (intra-graph) edge length
idealEdgeLength: 50,
// Divisor to compute edge forces
edgeElasticity: 0.45,
// Nesting factor (multiplier) to compute ideal edge length for inter-graph edges
nestingFactor: 0.1,
// Gravity force (constant)
gravity: 0.25,
// Maximum number of iterations to perform
numIter: 2500,
// Whether to tile disconnected nodes
tile: true,
// Type of layout animation. The option set is {'during', 'end', false}
animate: 'end',
// Duration for animate:end
animationDuration: 500,
// Amount of vertical space to put between degree zero nodes during tiling (can also be a function)
tilingPaddingVertical: 10,
// Amount of horizontal space to put between degree zero nodes during tiling (can also be a function)
tilingPaddingHorizontal: 10,
// Gravity range (constant) for compounds
gravityRangeCompound: 1.5,
// Gravity force (constant) for compounds
gravityCompound: 1.0,
// Gravity range (constant)
gravityRange: 3.8,
// Initial cooling factor for incremental layout
initialEnergyOnIncremental: 0.5
};
```
*Note that this extension supports only relatively modern browsers. Browsers like IE require significant shimming, for example with [core-js](https://www.npmjs.com/package/core-js).*
*Note that while running Cytoscape.js in headless mode, stylingEnabled option of Cytoscape.js should be set as true because this extension considers node dimensions and some other styling properties.*
## Build targets
* `npm run test` : Run Mocha tests in `./test`
* `npm run build` : Build `./src/**` into `cytoscape-cose-bilkent.js`
* `npm run watch` : Automatically build on changes with live reloading (N.b. you must already have an HTTP server running)
* `npm run dev` : Automatically build on changes with live reloading with webpack dev server
* `npm run lint` : Run eslint on the source
N.b. all builds use babel, so modern ES features can be used in the `src`.
## Publishing instructions
This project is set up to automatically be published to npm and bower. To publish:
1. Build the extension : `npm run build:release`
1. Commit the build : `git commit -am "Build for release"`
1. Bump the version number and tag: `npm version major|minor|patch`
1. Push to origin: `git push && git push --tags`
1. Publish to npm: `npm publish .`
1. If publishing to bower for the first time, you'll need to run `bower register cytoscape-cose-bilkent https://github.com/cytoscape/cytoscape.js-cose-bilkent.git`
1. [Make a new release](https://github.com/cytoscape/cytoscape.js-cose-bilkent/releases/new) for Zenodo.

25
node_modules/cytoscape-cose-bilkent/bower.json generated vendored Normal file
View File

@@ -0,0 +1,25 @@
{
"name": "cytoscape-cose-bilkent",
"description": "The CoSE layout for Cytoscape.js by Bilkent with enhanced compound node placement",
"main": "cytoscape-cose-bilkent.js",
"dependencies": {
"cytoscape": "^3.2.0",
"cose-base": "^1.0.0"
},
"repository": {
"type": "git",
"url": "https://github.com/cytoscape/cytoscape.js-cose-bilkent.git"
},
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"test",
"tests"
],
"keywords": [
"cytoscape",
"cytoscape-extension"
],
"license": "MIT"
}

View File

@@ -0,0 +1,458 @@
(function webpackUniversalModuleDefinition(root, factory) {
if(typeof exports === 'object' && typeof module === 'object')
module.exports = factory(require("cose-base"));
else if(typeof define === 'function' && define.amd)
define(["cose-base"], factory);
else if(typeof exports === 'object')
exports["cytoscapeCoseBilkent"] = factory(require("cose-base"));
else
root["cytoscapeCoseBilkent"] = factory(root["coseBase"]);
})(this, function(__WEBPACK_EXTERNAL_MODULE_0__) {
return /******/ (function(modules) { // webpackBootstrap
/******/ // The module cache
/******/ var installedModules = {};
/******/
/******/ // The require function
/******/ function __webpack_require__(moduleId) {
/******/
/******/ // Check if module is in cache
/******/ if(installedModules[moduleId]) {
/******/ return installedModules[moduleId].exports;
/******/ }
/******/ // Create a new module (and put it into the cache)
/******/ var module = installedModules[moduleId] = {
/******/ i: moduleId,
/******/ l: false,
/******/ exports: {}
/******/ };
/******/
/******/ // Execute the module function
/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/ // Flag the module as loaded
/******/ module.l = true;
/******/
/******/ // Return the exports of the module
/******/ return module.exports;
/******/ }
/******/
/******/
/******/ // expose the modules object (__webpack_modules__)
/******/ __webpack_require__.m = modules;
/******/
/******/ // expose the module cache
/******/ __webpack_require__.c = installedModules;
/******/
/******/ // identity function for calling harmony imports with the correct context
/******/ __webpack_require__.i = function(value) { return value; };
/******/
/******/ // define getter function for harmony exports
/******/ __webpack_require__.d = function(exports, name, getter) {
/******/ if(!__webpack_require__.o(exports, name)) {
/******/ Object.defineProperty(exports, name, {
/******/ configurable: false,
/******/ enumerable: true,
/******/ get: getter
/******/ });
/******/ }
/******/ };
/******/
/******/ // getDefaultExport function for compatibility with non-harmony modules
/******/ __webpack_require__.n = function(module) {
/******/ var getter = module && module.__esModule ?
/******/ function getDefault() { return module['default']; } :
/******/ function getModuleExports() { return module; };
/******/ __webpack_require__.d(getter, 'a', getter);
/******/ return getter;
/******/ };
/******/
/******/ // Object.prototype.hasOwnProperty.call
/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/ // __webpack_public_path__
/******/ __webpack_require__.p = "";
/******/
/******/ // Load entry module and return exports
/******/ return __webpack_require__(__webpack_require__.s = 1);
/******/ })
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, exports) {
module.exports = __WEBPACK_EXTERNAL_MODULE_0__;
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
var LayoutConstants = __webpack_require__(0).layoutBase.LayoutConstants;
var FDLayoutConstants = __webpack_require__(0).layoutBase.FDLayoutConstants;
var CoSEConstants = __webpack_require__(0).CoSEConstants;
var CoSELayout = __webpack_require__(0).CoSELayout;
var CoSENode = __webpack_require__(0).CoSENode;
var PointD = __webpack_require__(0).layoutBase.PointD;
var DimensionD = __webpack_require__(0).layoutBase.DimensionD;
var defaults = {
// Called on `layoutready`
ready: function ready() {},
// Called on `layoutstop`
stop: function stop() {},
// 'draft', 'default' or 'proof"
// - 'draft' fast cooling rate
// - 'default' moderate cooling rate
// - "proof" slow cooling rate
quality: 'default',
// include labels in node dimensions
nodeDimensionsIncludeLabels: false,
// number of ticks per frame; higher is faster but more jerky
refresh: 30,
// Whether to fit the network view after when done
fit: true,
// Padding on fit
padding: 10,
// Whether to enable incremental mode
randomize: true,
// Node repulsion (non overlapping) multiplier
nodeRepulsion: 4500,
// Ideal edge (non nested) length
idealEdgeLength: 50,
// Divisor to compute edge forces
edgeElasticity: 0.45,
// Nesting factor (multiplier) to compute ideal edge length for nested edges
nestingFactor: 0.1,
// Gravity force (constant)
gravity: 0.25,
// Maximum number of iterations to perform
numIter: 2500,
// For enabling tiling
tile: true,
// Type of layout animation. The option set is {'during', 'end', false}
animate: 'end',
// Duration for animate:end
animationDuration: 500,
// Represents the amount of the vertical space to put between the zero degree members during the tiling operation(can also be a function)
tilingPaddingVertical: 10,
// Represents the amount of the horizontal space to put between the zero degree members during the tiling operation(can also be a function)
tilingPaddingHorizontal: 10,
// Gravity range (constant) for compounds
gravityRangeCompound: 1.5,
// Gravity force (constant) for compounds
gravityCompound: 1.0,
// Gravity range (constant)
gravityRange: 3.8,
// Initial cooling factor for incremental layout
initialEnergyOnIncremental: 0.5
};
function extend(defaults, options) {
var obj = {};
for (var i in defaults) {
obj[i] = defaults[i];
}
for (var i in options) {
obj[i] = options[i];
}
return obj;
};
function _CoSELayout(_options) {
this.options = extend(defaults, _options);
getUserOptions(this.options);
}
var getUserOptions = function getUserOptions(options) {
if (options.nodeRepulsion != null) CoSEConstants.DEFAULT_REPULSION_STRENGTH = FDLayoutConstants.DEFAULT_REPULSION_STRENGTH = options.nodeRepulsion;
if (options.idealEdgeLength != null) CoSEConstants.DEFAULT_EDGE_LENGTH = FDLayoutConstants.DEFAULT_EDGE_LENGTH = options.idealEdgeLength;
if (options.edgeElasticity != null) CoSEConstants.DEFAULT_SPRING_STRENGTH = FDLayoutConstants.DEFAULT_SPRING_STRENGTH = options.edgeElasticity;
if (options.nestingFactor != null) CoSEConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = options.nestingFactor;
if (options.gravity != null) CoSEConstants.DEFAULT_GRAVITY_STRENGTH = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH = options.gravity;
if (options.numIter != null) CoSEConstants.MAX_ITERATIONS = FDLayoutConstants.MAX_ITERATIONS = options.numIter;
if (options.gravityRange != null) CoSEConstants.DEFAULT_GRAVITY_RANGE_FACTOR = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR = options.gravityRange;
if (options.gravityCompound != null) CoSEConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = options.gravityCompound;
if (options.gravityRangeCompound != null) CoSEConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = options.gravityRangeCompound;
if (options.initialEnergyOnIncremental != null) CoSEConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = options.initialEnergyOnIncremental;
if (options.quality == 'draft') LayoutConstants.QUALITY = 0;else if (options.quality == 'proof') LayoutConstants.QUALITY = 2;else LayoutConstants.QUALITY = 1;
CoSEConstants.NODE_DIMENSIONS_INCLUDE_LABELS = FDLayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = options.nodeDimensionsIncludeLabels;
CoSEConstants.DEFAULT_INCREMENTAL = FDLayoutConstants.DEFAULT_INCREMENTAL = LayoutConstants.DEFAULT_INCREMENTAL = !options.randomize;
CoSEConstants.ANIMATE = FDLayoutConstants.ANIMATE = LayoutConstants.ANIMATE = options.animate;
CoSEConstants.TILE = options.tile;
CoSEConstants.TILING_PADDING_VERTICAL = typeof options.tilingPaddingVertical === 'function' ? options.tilingPaddingVertical.call() : options.tilingPaddingVertical;
CoSEConstants.TILING_PADDING_HORIZONTAL = typeof options.tilingPaddingHorizontal === 'function' ? options.tilingPaddingHorizontal.call() : options.tilingPaddingHorizontal;
};
_CoSELayout.prototype.run = function () {
var ready;
var frameId;
var options = this.options;
var idToLNode = this.idToLNode = {};
var layout = this.layout = new CoSELayout();
var self = this;
self.stopped = false;
this.cy = this.options.cy;
this.cy.trigger({ type: 'layoutstart', layout: this });
var gm = layout.newGraphManager();
this.gm = gm;
var nodes = this.options.eles.nodes();
var edges = this.options.eles.edges();
this.root = gm.addRoot();
this.processChildrenList(this.root, this.getTopMostNodes(nodes), layout);
for (var i = 0; i < edges.length; i++) {
var edge = edges[i];
var sourceNode = this.idToLNode[edge.data("source")];
var targetNode = this.idToLNode[edge.data("target")];
if (sourceNode !== targetNode && sourceNode.getEdgesBetween(targetNode).length == 0) {
var e1 = gm.add(layout.newEdge(), sourceNode, targetNode);
e1.id = edge.id();
}
}
var getPositions = function getPositions(ele, i) {
if (typeof ele === "number") {
ele = i;
}
var theId = ele.data('id');
var lNode = self.idToLNode[theId];
return {
x: lNode.getRect().getCenterX(),
y: lNode.getRect().getCenterY()
};
};
/*
* Reposition nodes in iterations animatedly
*/
var iterateAnimated = function iterateAnimated() {
// Thigs to perform after nodes are repositioned on screen
var afterReposition = function afterReposition() {
if (options.fit) {
options.cy.fit(options.eles, options.padding);
}
if (!ready) {
ready = true;
self.cy.one('layoutready', options.ready);
self.cy.trigger({ type: 'layoutready', layout: self });
}
};
var ticksPerFrame = self.options.refresh;
var isDone;
for (var i = 0; i < ticksPerFrame && !isDone; i++) {
isDone = self.stopped || self.layout.tick();
}
// If layout is done
if (isDone) {
// If the layout is not a sublayout and it is successful perform post layout.
if (layout.checkLayoutSuccess() && !layout.isSubLayout) {
layout.doPostLayout();
}
// If layout has a tilingPostLayout function property call it.
if (layout.tilingPostLayout) {
layout.tilingPostLayout();
}
layout.isLayoutFinished = true;
self.options.eles.nodes().positions(getPositions);
afterReposition();
// trigger layoutstop when the layout stops (e.g. finishes)
self.cy.one('layoutstop', self.options.stop);
self.cy.trigger({ type: 'layoutstop', layout: self });
if (frameId) {
cancelAnimationFrame(frameId);
}
ready = false;
return;
}
var animationData = self.layout.getPositionsData(); // Get positions of layout nodes note that all nodes may not be layout nodes because of tiling
// Position nodes, for the nodes whose id does not included in data (because they are removed from their parents and included in dummy compounds)
// use position of their ancestors or dummy ancestors
options.eles.nodes().positions(function (ele, i) {
if (typeof ele === "number") {
ele = i;
}
// If ele is a compound node, then its position will be defined by its children
if (!ele.isParent()) {
var theId = ele.id();
var pNode = animationData[theId];
var temp = ele;
// If pNode is undefined search until finding position data of its first ancestor (It may be dummy as well)
while (pNode == null) {
pNode = animationData[temp.data('parent')] || animationData['DummyCompound_' + temp.data('parent')];
animationData[theId] = pNode;
temp = temp.parent()[0];
if (temp == undefined) {
break;
}
}
if (pNode != null) {
return {
x: pNode.x,
y: pNode.y
};
} else {
return {
x: ele.position('x'),
y: ele.position('y')
};
}
}
});
afterReposition();
frameId = requestAnimationFrame(iterateAnimated);
};
/*
* Listen 'layoutstarted' event and start animated iteration if animate option is 'during'
*/
layout.addListener('layoutstarted', function () {
if (self.options.animate === 'during') {
frameId = requestAnimationFrame(iterateAnimated);
}
});
layout.runLayout(); // Run cose layout
/*
* If animate option is not 'during' ('end' or false) perform these here (If it is 'during' similar things are already performed)
*/
if (this.options.animate !== "during") {
self.options.eles.nodes().not(":parent").layoutPositions(self, self.options, getPositions); // Use layout positions to reposition the nodes it considers the options parameter
ready = false;
}
return this; // chaining
};
//Get the top most ones of a list of nodes
_CoSELayout.prototype.getTopMostNodes = function (nodes) {
var nodesMap = {};
for (var i = 0; i < nodes.length; i++) {
nodesMap[nodes[i].id()] = true;
}
var roots = nodes.filter(function (ele, i) {
if (typeof ele === "number") {
ele = i;
}
var parent = ele.parent()[0];
while (parent != null) {
if (nodesMap[parent.id()]) {
return false;
}
parent = parent.parent()[0];
}
return true;
});
return roots;
};
_CoSELayout.prototype.processChildrenList = function (parent, children, layout) {
var size = children.length;
for (var i = 0; i < size; i++) {
var theChild = children[i];
var children_of_children = theChild.children();
var theNode;
var dimensions = theChild.layoutDimensions({
nodeDimensionsIncludeLabels: this.options.nodeDimensionsIncludeLabels
});
if (theChild.outerWidth() != null && theChild.outerHeight() != null) {
theNode = parent.add(new CoSENode(layout.graphManager, new PointD(theChild.position('x') - dimensions.w / 2, theChild.position('y') - dimensions.h / 2), new DimensionD(parseFloat(dimensions.w), parseFloat(dimensions.h))));
} else {
theNode = parent.add(new CoSENode(this.graphManager));
}
// Attach id to the layout node
theNode.id = theChild.data("id");
// Attach the paddings of cy node to layout node
theNode.paddingLeft = parseInt(theChild.css('padding'));
theNode.paddingTop = parseInt(theChild.css('padding'));
theNode.paddingRight = parseInt(theChild.css('padding'));
theNode.paddingBottom = parseInt(theChild.css('padding'));
//Attach the label properties to compound if labels will be included in node dimensions
if (this.options.nodeDimensionsIncludeLabels) {
if (theChild.isParent()) {
var labelWidth = theChild.boundingBox({ includeLabels: true, includeNodes: false }).w;
var labelHeight = theChild.boundingBox({ includeLabels: true, includeNodes: false }).h;
var labelPos = theChild.css("text-halign");
theNode.labelWidth = labelWidth;
theNode.labelHeight = labelHeight;
theNode.labelPos = labelPos;
}
}
// Map the layout node
this.idToLNode[theChild.data("id")] = theNode;
if (isNaN(theNode.rect.x)) {
theNode.rect.x = 0;
}
if (isNaN(theNode.rect.y)) {
theNode.rect.y = 0;
}
if (children_of_children != null && children_of_children.length > 0) {
var theNewGraph;
theNewGraph = layout.getGraphManager().add(layout.newGraph(), theNode);
this.processChildrenList(theNewGraph, children_of_children, layout);
}
}
};
/**
* @brief : called on continuous layouts to stop them before they finish
*/
_CoSELayout.prototype.stop = function () {
this.stopped = true;
return this; // chaining
};
var register = function register(cytoscape) {
// var Layout = getLayout( cytoscape );
cytoscape('layout', 'cose-bilkent', _CoSELayout);
};
// auto reg for globals
if (typeof cytoscape !== 'undefined') {
register(cytoscape);
}
module.exports = register;
/***/ })
/******/ ]);
});

199
node_modules/cytoscape-cose-bilkent/demo-compound.html generated vendored Normal file
View File

@@ -0,0 +1,199 @@
<!DOCTYPE>
<html>
<head>
<title>cytoscape-cose-bilkent.js demo (compound)</title>
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1, maximum-scale=1">
<script src="https://unpkg.com/cytoscape/dist/cytoscape.min.js"></script>
<!-- for testing with local version of cytoscape.js -->
<!--<script src="../cytoscape.js/build/cytoscape.js"></script>-->
<!--polyfills are needed for this extension for old browsers like IE -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/core-js/2.5.7/shim.min.js"></script>
<script src="https://unpkg.com/layout-base/layout-base.js"></script>
<script src="https://unpkg.com/cose-base/cose-base.js"></script>
<script src="cytoscape-cose-bilkent.js"></script>
<style>
body {
font-family: helvetica;
font-size: 14px;
}
#cy {
width: 100%;
height: 90%;
z-index: 999;
}
h1 {
opacity: 0.5;
font-size: 1em;
}
button {
margin-right: 10px;
}
</style>
<script>
document.addEventListener('DOMContentLoaded', function(){
var cy = window.cy = cytoscape({
container: document.getElementById('cy'),
ready: function(){
this.nodes().forEach(function(node){
let width = [30, 70, 110];
let size = width[Math.floor(Math.random()*3)];
node.css("width", size);
node.css("height", size);
});
this.layout({name: 'cose-bilkent', animationDuration: 1000}).run();
},
style: [
{
selector: 'node',
style: {
'background-color': '#ad1a66'
}
},
{
selector: ':parent',
style: {
'background-opacity': 0.333
}
},
{
selector: 'edge',
style: {
'width': 3,
'line-color': '#ad1a66'
}
}
],
elements: [{ group:'nodes', data:{ id: 'n0'}},
{ group:'nodes', data:{ id: 'n1'}},
{ group:'nodes', data:{ id: 'n2'}},
{ group:'nodes', data:{ id: 'n3'}},
{ group:'nodes', data:{ id: 'n4', parent: 'n37'}},
{ group:'nodes', data:{ id: 'n5'}},
{ group:'nodes', data:{ id: 'n6'}},
{ group:'nodes', data:{ id: 'n7', parent: 'n37'}},
{ group:'nodes', data:{ id: 'n8', parent: 'n37'}},
{ group:'nodes', data:{ id: 'n9', parent: 'n37'}},
{ group:'nodes', data:{ id: 'n10', parent: 'n38'}},
{ group:'nodes', data:{ id: 'n12'}},
{ group:'nodes', data:{ id: 'n13'}},
{ group:'nodes', data:{ id: 'n14'}},
{ group:'nodes', data:{ id: 'n15'}},
{ group:'nodes', data:{ id: 'n16'}},
{ group:'nodes', data:{ id: 'n17'}},
{ group:'nodes', data:{ id: 'n18'}},
{ group:'nodes', data:{ id: 'n19'}},
{ group:'nodes', data:{ id: 'n20'}},
{ group:'nodes', data:{ id: 'n21'}},
{ group:'nodes', data:{ id: 'n22'}},
{ group:'nodes', data:{ id: 'n23'}},
{ group:'nodes', data:{ id: 'n24', parent: 'n39'}},
{ group:'nodes', data:{ id: 'n25', parent: 'n39'}},
{ group:'nodes', data:{ id: 'n26', parent: 'n42'}},
{ group:'nodes', data:{ id: 'n27', parent: 'n42'}},
{ group:'nodes', data:{ id: 'n28', parent: 'n42'}},
{ group:'nodes', data:{ id: 'n29', parent: 'n40'}},
{ group:'nodes', data:{ id: 'n31', parent: 'n41'}},
{ group:'nodes', data:{ id: 'n32', parent: 'n41'}},
{ group:'nodes', data:{ id: 'n33', parent: 'n41'}},
{ group:'nodes', data:{ id: 'n34', parent: 'n41'}},
{ group:'nodes', data:{ id: 'n35', parent: 'n41'}},
{ group:'nodes', data:{ id: 'n36', parent: 'n41'}},
{ group:'nodes', data:{ id: 'n37'}},
{ group:'nodes', data:{ id: 'n38'}},
{ group:'nodes', data:{ id: 'n39', parent: 'n43'}},
{ group:'nodes', data:{ id: 'n40', parent: 'n42'}},
{ group:'nodes', data:{ id: 'n41', parent: 'n42'}},
{ group:'nodes', data:{ id: 'n42', parent: 'n43'}},
{ group:'nodes', data:{ id: 'n43'}},
{ group:'edges', data:{ id: 'e0', source: 'n0', target: 'n1'} },
{ group:'edges', data:{ id: 'e1', source: 'n1', target: 'n2'} },
{ group:'edges', data:{ id: 'e2', source: 'n2', target: 'n3'} },
{ group:'edges', data:{ id: 'e3', source: 'n0', target: 'n3'} },
{ group:'edges', data:{ id: 'e4', source: 'n1', target: 'n4'} },
{ group:'edges', data:{ id: 'e5', source: 'n2', target: 'n4'} },
{ group:'edges', data:{ id: 'e6', source: 'n4', target: 'n5'} },
{ group:'edges', data:{ id: 'e7', source: 'n5', target: 'n6'} },
{ group:'edges', data:{ id: 'e8', source: 'n4', target: 'n6'} },
{ group:'edges', data:{ id: 'e9', source: 'n4', target: 'n7'} },
{ group:'edges', data:{ id: 'e10', source: 'n7', target: 'n8'} },
{ group:'edges', data:{ id: 'e11', source: 'n8', target: 'n9'} },
{ group:'edges', data:{ id: 'e12', source: 'n7', target: 'n9'} },
{ group:'edges', data:{ id: 'e13', source: 'n13', target: 'n14'} },
{ group:'edges', data:{ id: 'e14', source: 'n12', target: 'n14'} },
{ group:'edges', data:{ id: 'e15', source: 'n14', target: 'n15'} },
{ group:'edges', data:{ id: 'e16', source: 'n14', target: 'n16'} },
{ group:'edges', data:{ id: 'e17', source: 'n15', target: 'n17'} },
{ group:'edges', data:{ id: 'e18', source: 'n17', target: 'n18'} },
{ group:'edges', data:{ id: 'e19', source: 'n18', target: 'n19'} },
{ group:'edges', data:{ id: 'e20', source: 'n17', target: 'n20'} },
{ group:'edges', data:{ id: 'e21', source: 'n19', target: 'n20'} },
{ group:'edges', data:{ id: 'e22', source: 'n16', target: 'n20'} },
{ group:'edges', data:{ id: 'e23', source: 'n20', target: 'n21'} },
{ group:'edges', data:{ id: 'e25', source: 'n23', target: 'n24'} },
{ group:'edges', data:{ id: 'e26', source: 'n24', target: 'n25'} },
{ group:'edges', data:{ id: 'e27', source: 'n26', target: 'n38'} },
{ group:'edges', data:{ id: 'e29', source: 'n26', target: 'n39'} },
{ group:'edges', data:{ id: 'e30', source: 'n26', target: 'n27'} },
{ group:'edges', data:{ id: 'e31', source: 'n26', target: 'n28'} },
{ group:'edges', data:{ id: 'e33', source: 'n21', target: 'n31'} },
{ group:'edges', data:{ id: 'e35', source: 'n31', target: 'n33'} },
{ group:'edges', data:{ id: 'e36', source: 'n31', target: 'n34'} },
{ group:'edges', data:{ id: 'e37', source: 'n33', target: 'n34'} },
{ group:'edges', data:{ id: 'e38', source: 'n32', target: 'n35'} },
{ group:'edges', data:{ id: 'e39', source: 'n32', target: 'n36'} },
{ group:'edges', data:{ id: 'e40', source: 'n16', target: 'n40'} }
]
});
document.getElementById("layoutButton").addEventListener("click", function(){
var layout = cy.layout({
name: 'cose-bilkent',
animate: 'end',
animationEasing: 'ease-out',
animationDuration: 1000,
randomize: true
});
layout.run();
});
document.getElementById("randomize").addEventListener("click", function(){
var layout = cy.layout({
name: 'random',
animate: true,
animationDuration: 1000,
animationEasing: 'ease-out'
});
layout.run();
});
});
</script>
</head>
<body>
<h1>cytoscape-cose-bilkent demo (compound)</h1>
<button id="randomize" type="button">Randomize</button>
<button id="layoutButton" type="button">CoSE-Bilkent</button>
<div id="cy"></div>
</body>
</html>

117
node_modules/cytoscape-cose-bilkent/demo.html generated vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
browser=Chrome.INTEGRATED

View File

@@ -0,0 +1,3 @@
files.encoding=UTF-8
site.root.folder=
source.folder=

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://www.netbeans.org/ns/project/1">
<type>org.netbeans.modules.web.clientproject</type>
<configuration>
<data xmlns="http://www.netbeans.org/ns/clientside-project/1">
<name>cytoscape-cose-bilkent</name>
</data>
</configuration>
</project>

55
node_modules/cytoscape-cose-bilkent/package.json generated vendored Normal file
View File

@@ -0,0 +1,55 @@
{
"name": "cytoscape-cose-bilkent",
"version": "4.1.0",
"description": "The CoSE layout for Cytoscape.js by Bilkent with enhanced compound node placement",
"main": "cytoscape-cose-bilkent.js",
"scripts": {
"postpublish": "run-s gh-pages",
"gh-pages": "gh-pages -d pages",
"copyright": "update license",
"lint": "eslint src",
"build": "cross-env NODE_ENV=production webpack",
"build:min": "cross-env NODE_ENV=production MIN=true webpack",
"build:release": "run-s build copyright",
"watch": "webpack --progress --watch",
"dev": "webpack-dev-server --open",
"test": "mocha"
},
"repository": {
"type": "git",
"url": "https://github.com/cytoscape/cytoscape.js-cose-bilkent.git"
},
"keywords": [
"cytoscape",
"cytoscape-extension"
],
"license": "MIT",
"bugs": {
"url": "https://github.com/cytoscape/cytoscape.js-cose-bilkent/issues"
},
"homepage": "https://github.com/cytoscape/cytoscape.js-cose-bilkent",
"devDependencies": {
"babel-core": "^6.24.1",
"babel-loader": "^7.0.0",
"babel-preset-env": "^1.5.1",
"camelcase": "^4.1.0",
"chai": "4.0.2",
"cpy-cli": "^1.0.1",
"cross-env": "^5.0.0",
"eslint": "^3.9.1",
"gh-pages": "^1.0.0",
"mocha": "3.4.2",
"npm-run-all": "^4.1.2",
"rimraf": "^2.6.2",
"update": "^0.7.4",
"updater-license": "^1.0.0",
"webpack": "^2.6.1",
"webpack-dev-server": "^2.4.5"
},
"peerDependencies": {
"cytoscape": "^3.2.0"
},
"dependencies": {
"cose-base": "^1.0.0"
}
}

390
node_modules/cytoscape-cose-bilkent/src/index.js generated vendored Normal file
View File

@@ -0,0 +1,390 @@
'use strict';
var LayoutConstants = require('cose-base').layoutBase.LayoutConstants;
var FDLayoutConstants = require('cose-base').layoutBase.FDLayoutConstants;
var CoSEConstants = require('cose-base').CoSEConstants;
var CoSELayout = require('cose-base').CoSELayout;
var CoSENode = require('cose-base').CoSENode;
var PointD = require('cose-base').layoutBase.PointD;
var DimensionD = require('cose-base').layoutBase.DimensionD;
var defaults = {
// Called on `layoutready`
ready: function () {
},
// Called on `layoutstop`
stop: function () {
},
// 'draft', 'default' or 'proof"
// - 'draft' fast cooling rate
// - 'default' moderate cooling rate
// - "proof" slow cooling rate
quality: 'default',
// include labels in node dimensions
nodeDimensionsIncludeLabels: false,
// number of ticks per frame; higher is faster but more jerky
refresh: 30,
// Whether to fit the network view after when done
fit: true,
// Padding on fit
padding: 10,
// Whether to enable incremental mode
randomize: true,
// Node repulsion (non overlapping) multiplier
nodeRepulsion: 4500,
// Ideal edge (non nested) length
idealEdgeLength: 50,
// Divisor to compute edge forces
edgeElasticity: 0.45,
// Nesting factor (multiplier) to compute ideal edge length for nested edges
nestingFactor: 0.1,
// Gravity force (constant)
gravity: 0.25,
// Maximum number of iterations to perform
numIter: 2500,
// For enabling tiling
tile: true,
// Type of layout animation. The option set is {'during', 'end', false}
animate: 'end',
// Duration for animate:end
animationDuration: 500,
// Represents the amount of the vertical space to put between the zero degree members during the tiling operation(can also be a function)
tilingPaddingVertical: 10,
// Represents the amount of the horizontal space to put between the zero degree members during the tiling operation(can also be a function)
tilingPaddingHorizontal: 10,
// Gravity range (constant) for compounds
gravityRangeCompound: 1.5,
// Gravity force (constant) for compounds
gravityCompound: 1.0,
// Gravity range (constant)
gravityRange: 3.8,
// Initial cooling factor for incremental layout
initialEnergyOnIncremental: 0.5
};
function extend(defaults, options) {
var obj = {};
for (var i in defaults) {
obj[i] = defaults[i];
}
for (var i in options) {
obj[i] = options[i];
}
return obj;
};
function _CoSELayout(_options) {
this.options = extend(defaults, _options);
getUserOptions(this.options);
}
var getUserOptions = function (options) {
if (options.nodeRepulsion != null)
CoSEConstants.DEFAULT_REPULSION_STRENGTH = FDLayoutConstants.DEFAULT_REPULSION_STRENGTH = options.nodeRepulsion;
if (options.idealEdgeLength != null)
CoSEConstants.DEFAULT_EDGE_LENGTH = FDLayoutConstants.DEFAULT_EDGE_LENGTH = options.idealEdgeLength;
if (options.edgeElasticity != null)
CoSEConstants.DEFAULT_SPRING_STRENGTH = FDLayoutConstants.DEFAULT_SPRING_STRENGTH = options.edgeElasticity;
if (options.nestingFactor != null)
CoSEConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = FDLayoutConstants.PER_LEVEL_IDEAL_EDGE_LENGTH_FACTOR = options.nestingFactor;
if (options.gravity != null)
CoSEConstants.DEFAULT_GRAVITY_STRENGTH = FDLayoutConstants.DEFAULT_GRAVITY_STRENGTH = options.gravity;
if (options.numIter != null)
CoSEConstants.MAX_ITERATIONS = FDLayoutConstants.MAX_ITERATIONS = options.numIter;
if (options.gravityRange != null)
CoSEConstants.DEFAULT_GRAVITY_RANGE_FACTOR = FDLayoutConstants.DEFAULT_GRAVITY_RANGE_FACTOR = options.gravityRange;
if(options.gravityCompound != null)
CoSEConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_STRENGTH = options.gravityCompound;
if(options.gravityRangeCompound != null)
CoSEConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = FDLayoutConstants.DEFAULT_COMPOUND_GRAVITY_RANGE_FACTOR = options.gravityRangeCompound;
if (options.initialEnergyOnIncremental != null)
CoSEConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = FDLayoutConstants.DEFAULT_COOLING_FACTOR_INCREMENTAL = options.initialEnergyOnIncremental;
if (options.quality == 'draft')
LayoutConstants.QUALITY = 0;
else if(options.quality == 'proof')
LayoutConstants.QUALITY = 2;
else
LayoutConstants.QUALITY = 1;
CoSEConstants.NODE_DIMENSIONS_INCLUDE_LABELS = FDLayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = LayoutConstants.NODE_DIMENSIONS_INCLUDE_LABELS = options.nodeDimensionsIncludeLabels;
CoSEConstants.DEFAULT_INCREMENTAL = FDLayoutConstants.DEFAULT_INCREMENTAL = LayoutConstants.DEFAULT_INCREMENTAL =
!(options.randomize);
CoSEConstants.ANIMATE = FDLayoutConstants.ANIMATE = LayoutConstants.ANIMATE = options.animate;
CoSEConstants.TILE = options.tile;
CoSEConstants.TILING_PADDING_VERTICAL =
typeof options.tilingPaddingVertical === 'function' ? options.tilingPaddingVertical.call() : options.tilingPaddingVertical;
CoSEConstants.TILING_PADDING_HORIZONTAL =
typeof options.tilingPaddingHorizontal === 'function' ? options.tilingPaddingHorizontal.call() : options.tilingPaddingHorizontal;
};
_CoSELayout.prototype.run = function () {
var ready;
var frameId;
var options = this.options;
var idToLNode = this.idToLNode = {};
var layout = this.layout = new CoSELayout();
var self = this;
self.stopped = false;
this.cy = this.options.cy;
this.cy.trigger({ type: 'layoutstart', layout: this });
var gm = layout.newGraphManager();
this.gm = gm;
var nodes = this.options.eles.nodes();
var edges = this.options.eles.edges();
this.root = gm.addRoot();
this.processChildrenList(this.root, this.getTopMostNodes(nodes), layout);
for (var i = 0; i < edges.length; i++) {
var edge = edges[i];
var sourceNode = this.idToLNode[edge.data("source")];
var targetNode = this.idToLNode[edge.data("target")];
if(sourceNode !== targetNode && sourceNode.getEdgesBetween(targetNode).length == 0){
var e1 = gm.add(layout.newEdge(), sourceNode, targetNode);
e1.id = edge.id();
}
}
var getPositions = function(ele, i){
if(typeof ele === "number") {
ele = i;
}
var theId = ele.data('id');
var lNode = self.idToLNode[theId];
return {
x: lNode.getRect().getCenterX(),
y: lNode.getRect().getCenterY()
};
};
/*
* Reposition nodes in iterations animatedly
*/
var iterateAnimated = function () {
// Thigs to perform after nodes are repositioned on screen
var afterReposition = function() {
if (options.fit) {
options.cy.fit(options.eles, options.padding);
}
if (!ready) {
ready = true;
self.cy.one('layoutready', options.ready);
self.cy.trigger({type: 'layoutready', layout: self});
}
};
var ticksPerFrame = self.options.refresh;
var isDone;
for( var i = 0; i < ticksPerFrame && !isDone; i++ ){
isDone = self.stopped || self.layout.tick();
}
// If layout is done
if (isDone) {
// If the layout is not a sublayout and it is successful perform post layout.
if (layout.checkLayoutSuccess() && !layout.isSubLayout) {
layout.doPostLayout();
}
// If layout has a tilingPostLayout function property call it.
if (layout.tilingPostLayout) {
layout.tilingPostLayout();
}
layout.isLayoutFinished = true;
self.options.eles.nodes().positions(getPositions);
afterReposition();
// trigger layoutstop when the layout stops (e.g. finishes)
self.cy.one('layoutstop', self.options.stop);
self.cy.trigger({ type: 'layoutstop', layout: self });
if (frameId) {
cancelAnimationFrame(frameId);
}
ready = false;
return;
}
var animationData = self.layout.getPositionsData(); // Get positions of layout nodes note that all nodes may not be layout nodes because of tiling
// Position nodes, for the nodes whose id does not included in data (because they are removed from their parents and included in dummy compounds)
// use position of their ancestors or dummy ancestors
options.eles.nodes().positions(function (ele, i) {
if (typeof ele === "number") {
ele = i;
}
// If ele is a compound node, then its position will be defined by its children
if(!ele.isParent()){
var theId = ele.id();
var pNode = animationData[theId];
var temp = ele;
// If pNode is undefined search until finding position data of its first ancestor (It may be dummy as well)
while (pNode == null) {
pNode = animationData[temp.data('parent')] || animationData['DummyCompound_' + temp.data('parent')];
animationData[theId] = pNode;
temp = temp.parent()[0];
if(temp == undefined){
break;
}
}
if(pNode != null){
return {
x: pNode.x,
y: pNode.y
};
} else{
return {
x: ele.position('x'),
y: ele.position('y')
};
}
}
});
afterReposition();
frameId = requestAnimationFrame(iterateAnimated);
};
/*
* Listen 'layoutstarted' event and start animated iteration if animate option is 'during'
*/
layout.addListener('layoutstarted', function () {
if (self.options.animate === 'during') {
frameId = requestAnimationFrame(iterateAnimated);
}
});
layout.runLayout(); // Run cose layout
/*
* If animate option is not 'during' ('end' or false) perform these here (If it is 'during' similar things are already performed)
*/
if(this.options.animate !== "during"){
self.options.eles.nodes().not(":parent").layoutPositions(self, self.options, getPositions); // Use layout positions to reposition the nodes it considers the options parameter
ready = false;
}
return this; // chaining
};
//Get the top most ones of a list of nodes
_CoSELayout.prototype.getTopMostNodes = function(nodes) {
var nodesMap = {};
for (var i = 0; i < nodes.length; i++) {
nodesMap[nodes[i].id()] = true;
}
var roots = nodes.filter(function (ele, i) {
if(typeof ele === "number") {
ele = i;
}
var parent = ele.parent()[0];
while(parent != null){
if(nodesMap[parent.id()]){
return false;
}
parent = parent.parent()[0];
}
return true;
});
return roots;
};
_CoSELayout.prototype.processChildrenList = function (parent, children, layout) {
var size = children.length;
for (var i = 0; i < size; i++) {
var theChild = children[i];
var children_of_children = theChild.children();
var theNode;
var dimensions = theChild.layoutDimensions({
nodeDimensionsIncludeLabels: this.options.nodeDimensionsIncludeLabels
});
if (theChild.outerWidth() != null
&& theChild.outerHeight() != null) {
theNode = parent.add(new CoSENode(layout.graphManager,
new PointD(theChild.position('x') - dimensions.w / 2, theChild.position('y') - dimensions.h / 2),
new DimensionD(parseFloat(dimensions.w), parseFloat(dimensions.h))));
}
else {
theNode = parent.add(new CoSENode(this.graphManager));
}
// Attach id to the layout node
theNode.id = theChild.data("id");
// Attach the paddings of cy node to layout node
theNode.paddingLeft = parseInt( theChild.css('padding') );
theNode.paddingTop = parseInt( theChild.css('padding') );
theNode.paddingRight = parseInt( theChild.css('padding') );
theNode.paddingBottom = parseInt( theChild.css('padding') );
//Attach the label properties to compound if labels will be included in node dimensions
if(this.options.nodeDimensionsIncludeLabels){
if(theChild.isParent()){
var labelWidth = theChild.boundingBox({ includeLabels: true, includeNodes: false }).w;
var labelHeight = theChild.boundingBox({ includeLabels: true, includeNodes: false }).h;
var labelPos = theChild.css("text-halign");
theNode.labelWidth = labelWidth;
theNode.labelHeight = labelHeight;
theNode.labelPos = labelPos;
}
}
// Map the layout node
this.idToLNode[theChild.data("id")] = theNode;
if (isNaN(theNode.rect.x)) {
theNode.rect.x = 0;
}
if (isNaN(theNode.rect.y)) {
theNode.rect.y = 0;
}
if (children_of_children != null && children_of_children.length > 0) {
var theNewGraph;
theNewGraph = layout.getGraphManager().add(layout.newGraph(), theNode);
this.processChildrenList(theNewGraph, children_of_children, layout);
}
}
};
/**
* @brief : called on continuous layouts to stop them before they finish
*/
_CoSELayout.prototype.stop = function () {
this.stopped = true;
return this; // chaining
};
var register = function( cytoscape ){
// var Layout = getLayout( cytoscape );
cytoscape('layout', 'cose-bilkent', _CoSELayout);
};
// auto reg for globals
if( typeof cytoscape !== 'undefined' ){
register( cytoscape );
}
module.exports = register;

7
node_modules/cytoscape-cose-bilkent/test/example.js generated vendored Normal file
View File

@@ -0,0 +1,7 @@
const chai = require('chai');
describe('This', function(){
it('does that', function(){
expect( true ).to.be.true;
});
});

43
node_modules/cytoscape-cose-bilkent/webpack.config.js generated vendored Normal file
View File

@@ -0,0 +1,43 @@
const path = require('path');
const pkg = require('./package.json');
const camelcase = require('camelcase');
const process = require('process');
const webpack = require('webpack');
const env = process.env;
const NODE_ENV = env.NODE_ENV;
const MIN = env.MIN;
const PROD = NODE_ENV === 'production';
let config = {
devtool: PROD ? false : 'inline-source-map',
entry: './src/index.js',
output: {
path: path.join( __dirname ),
filename: pkg.name + '.js',
library: camelcase( pkg.name ),
libraryTarget: 'umd'
},
module: {
rules: [
{ test: /\.js$/, exclude: /node_modules/, use: 'babel-loader' }
]
},
externals: PROD ? {
'cose-base': {
commonjs2: 'cose-base',
commonjs: 'cose-base',
amd: 'cose-base',
root: 'coseBase'
}
} : {},
plugins: MIN ? [
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
drop_console: false,
}
})
] : []
};
module.exports = config;