From 3428df6dcd740cc9810d9b17164dcb15697c3c59 Mon Sep 17 00:00:00 2001 From: Michael Behrisch <m.behrisch@uu.nl> Date: Fri, 11 Mar 2022 10:33:27 +0100 Subject: [PATCH] chore: :bug: deletes old graph-layouts testing library Was only used for trying nx's publishable library functionalities. --- .../graph-layout/src/lib/cytoscape-layouts.ts | 66 +- .../src/lib/layout-creator-usecase.spec.ts | 38 +- libs/shared/graph-layouts/.eslintrc.json | 18 - libs/shared/graph-layouts/README.md | 11 - libs/shared/graph-layouts/dist/README.md | 11 - libs/shared/graph-layouts/jest.config.js | 14 - .../node_modules/.yarn-integrity | 18 - .../node_modules/events/.airtap.yml | 15 - .../node_modules/events/.github/FUNDING.yml | 12 - .../node_modules/events/.travis.yml | 18 - .../node_modules/events/History.md | 118 - .../graph-layouts/node_modules/events/LICENSE | 22 - .../node_modules/events/Readme.md | 50 - .../node_modules/events/events.js | 497 -- .../node_modules/events/package.json | 37 - .../node_modules/events/security.md | 10 - .../events/tests/add-listeners.js | 111 - .../events/tests/check-listener-leaks.js | 101 - .../node_modules/events/tests/common.js | 104 - .../node_modules/events/tests/errors.js | 13 - .../node_modules/events/tests/events-list.js | 28 - .../node_modules/events/tests/events-once.js | 234 - .../node_modules/events/tests/index.js | 64 - .../events/tests/legacy-compat.js | 16 - .../events/tests/listener-count.js | 37 - .../events/tests/listeners-side-effects.js | 56 - .../node_modules/events/tests/listeners.js | 168 - .../events/tests/max-listeners.js | 47 - .../node_modules/events/tests/method-names.js | 35 - .../events/tests/modify-in-emit.js | 90 - .../node_modules/events/tests/num-args.js | 60 - .../node_modules/events/tests/once.js | 83 - .../node_modules/events/tests/prepend.js | 31 - .../events/tests/remove-all-listeners.js | 133 - .../events/tests/remove-listeners.js | 212 - .../tests/set-max-listeners-side-effects.js | 31 - .../events/tests/special-event-names.js | 45 - .../node_modules/events/tests/subclass.js | 66 - .../node_modules/events/tests/symbols.js | 25 - .../node_modules/graphology/LICENSE.txt | 21 - .../node_modules/graphology/README.md | 9 - .../graphology/dist/graphology.cjs.js | 5463 -------------- .../graphology/dist/graphology.d.ts | 36 - .../graphology/dist/graphology.esm.js | 6671 ----------------- .../graphology/dist/graphology.umd.js | 6125 --------------- .../graphology/dist/graphology.umd.min.js | 2 - .../node_modules/graphology/package.json | 84 - .../graphology/specs/attributes.js | 992 --- .../node_modules/graphology/specs/events.js | 426 -- .../node_modules/graphology/specs/helpers.js | 101 - .../node_modules/graphology/specs/index.js | 78 - .../graphology/specs/instantiation.js | 211 - .../graphology/specs/iteration/edges.js | 894 --- .../graphology/specs/iteration/index.js | 161 - .../graphology/specs/iteration/neighbors.js | 284 - .../graphology/specs/iteration/nodes.js | 248 - .../node_modules/graphology/specs/known.js | 50 - .../node_modules/graphology/specs/misc.js | 112 - .../node_modules/graphology/specs/mutation.js | 883 --- .../graphology/specs/properties.js | 214 - .../node_modules/graphology/specs/read.js | 909 --- .../graphology/specs/serialization.js | 171 - .../node_modules/graphology/specs/utils.js | 249 - .../node_modules/obliterator/LICENSE.txt | 21 - .../node_modules/obliterator/README.md | 415 - .../node_modules/obliterator/chain.d.ts | 5 - .../node_modules/obliterator/chain.js | 46 - .../obliterator/combinations.d.ts | 4 - .../node_modules/obliterator/combinations.js | 76 - .../node_modules/obliterator/consume.d.ts | 1 - .../node_modules/obliterator/consume.js | 29 - .../node_modules/obliterator/every.d.ts | 8 - .../node_modules/obliterator/every.js | 27 - .../node_modules/obliterator/filter.d.ts | 8 - .../node_modules/obliterator/filter.js | 28 - .../node_modules/obliterator/find.d.ts | 8 - .../node_modules/obliterator/find.js | 27 - .../obliterator/foreach-with-null-keys.d.ts | 29 - .../obliterator/foreach-with-null-keys.js | 83 - .../node_modules/obliterator/foreach.d.ts | 24 - .../node_modules/obliterator/foreach.js | 73 - .../node_modules/obliterator/includes.d.ts | 6 - .../node_modules/obliterator/includes.js | 27 - .../node_modules/obliterator/index.d.ts | 20 - .../node_modules/obliterator/index.js | 26 - .../node_modules/obliterator/iter.d.ts | 1 - .../node_modules/obliterator/iter.js | 46 - .../node_modules/obliterator/iterator.d.ts | 18 - .../node_modules/obliterator/iterator.js | 96 - .../node_modules/obliterator/map.d.ts | 8 - .../node_modules/obliterator/map.js | 29 - .../node_modules/obliterator/match.d.ts | 4 - .../node_modules/obliterator/match.js | 43 - .../node_modules/obliterator/package.json | 46 - .../obliterator/permutations.d.ts | 4 - .../node_modules/obliterator/permutations.js | 94 - .../node_modules/obliterator/power-set.d.ts | 3 - .../node_modules/obliterator/power-set.js | 27 - .../node_modules/obliterator/range.d.ts | 10 - .../node_modules/obliterator/range.js | 44 - .../node_modules/obliterator/some.d.ts | 8 - .../node_modules/obliterator/some.js | 27 - .../node_modules/obliterator/split.d.ts | 4 - .../node_modules/obliterator/split.js | 68 - .../node_modules/obliterator/support.js | 2 - .../node_modules/obliterator/take-into.d.ts | 9 - .../node_modules/obliterator/take-into.js | 39 - .../node_modules/obliterator/take.d.ts | 6 - .../node_modules/obliterator/take.js | 39 - .../node_modules/obliterator/types.d.ts | 7 - libs/shared/graph-layouts/package.json | 8 - libs/shared/graph-layouts/project.json | 33 - libs/shared/graph-layouts/src/index.ts | 1 - .../src/lib/cytoscape-layouts.ts | 54 - .../src/lib/graphology-layouts.ts | 170 - .../src/lib/layout-creator-usecase.spec.ts | 140 - .../src/lib/layout-creator-usecase.ts | 77 - libs/shared/graph-layouts/src/lib/layout.ts | 21 - libs/shared/graph-layouts/tsconfig.json | 23 - libs/shared/graph-layouts/tsconfig.lib.json | 10 - libs/shared/graph-layouts/tsconfig.spec.json | 10 - libs/shared/graph-layouts/yarn.lock | 21 - 122 files changed, 94 insertions(+), 29286 deletions(-) delete mode 100644 libs/shared/graph-layouts/.eslintrc.json delete mode 100644 libs/shared/graph-layouts/README.md delete mode 100644 libs/shared/graph-layouts/dist/README.md delete mode 100644 libs/shared/graph-layouts/jest.config.js delete mode 100644 libs/shared/graph-layouts/node_modules/.yarn-integrity delete mode 100644 libs/shared/graph-layouts/node_modules/events/.airtap.yml delete mode 100644 libs/shared/graph-layouts/node_modules/events/.github/FUNDING.yml delete mode 100644 libs/shared/graph-layouts/node_modules/events/.travis.yml delete mode 100644 libs/shared/graph-layouts/node_modules/events/History.md delete mode 100644 libs/shared/graph-layouts/node_modules/events/LICENSE delete mode 100644 libs/shared/graph-layouts/node_modules/events/Readme.md delete mode 100644 libs/shared/graph-layouts/node_modules/events/events.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/package.json delete mode 100644 libs/shared/graph-layouts/node_modules/events/security.md delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/add-listeners.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/check-listener-leaks.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/common.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/errors.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/events-list.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/events-once.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/index.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/legacy-compat.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/listener-count.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/listeners-side-effects.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/listeners.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/max-listeners.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/method-names.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/modify-in-emit.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/num-args.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/once.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/prepend.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/remove-all-listeners.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/remove-listeners.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/set-max-listeners-side-effects.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/special-event-names.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/subclass.js delete mode 100644 libs/shared/graph-layouts/node_modules/events/tests/symbols.js delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/LICENSE.txt delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/README.md delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/dist/graphology.cjs.js delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/dist/graphology.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/dist/graphology.esm.js delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/dist/graphology.umd.js delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/dist/graphology.umd.min.js delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/package.json delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/specs/attributes.js delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/specs/events.js delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/specs/helpers.js delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/specs/index.js delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/specs/instantiation.js delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/specs/iteration/edges.js delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/specs/iteration/index.js delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/specs/iteration/neighbors.js delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/specs/iteration/nodes.js delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/specs/known.js delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/specs/misc.js delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/specs/mutation.js delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/specs/properties.js delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/specs/read.js delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/specs/serialization.js delete mode 100644 libs/shared/graph-layouts/node_modules/graphology/specs/utils.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/LICENSE.txt delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/README.md delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/chain.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/chain.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/combinations.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/combinations.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/consume.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/consume.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/every.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/every.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/filter.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/filter.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/find.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/find.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/foreach-with-null-keys.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/foreach-with-null-keys.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/foreach.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/foreach.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/includes.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/includes.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/index.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/index.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/iter.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/iter.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/iterator.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/iterator.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/map.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/map.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/match.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/match.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/package.json delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/permutations.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/permutations.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/power-set.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/power-set.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/range.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/range.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/some.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/some.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/split.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/split.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/support.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/take-into.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/take-into.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/take.d.ts delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/take.js delete mode 100644 libs/shared/graph-layouts/node_modules/obliterator/types.d.ts delete mode 100644 libs/shared/graph-layouts/package.json delete mode 100644 libs/shared/graph-layouts/project.json delete mode 100644 libs/shared/graph-layouts/src/index.ts delete mode 100644 libs/shared/graph-layouts/src/lib/cytoscape-layouts.ts delete mode 100644 libs/shared/graph-layouts/src/lib/graphology-layouts.ts delete mode 100644 libs/shared/graph-layouts/src/lib/layout-creator-usecase.spec.ts delete mode 100644 libs/shared/graph-layouts/src/lib/layout-creator-usecase.ts delete mode 100644 libs/shared/graph-layouts/src/lib/layout.ts delete mode 100644 libs/shared/graph-layouts/tsconfig.json delete mode 100644 libs/shared/graph-layouts/tsconfig.lib.json delete mode 100644 libs/shared/graph-layouts/tsconfig.spec.json delete mode 100644 libs/shared/graph-layouts/yarn.lock diff --git a/libs/shared/graph-layout/src/lib/cytoscape-layouts.ts b/libs/shared/graph-layout/src/lib/cytoscape-layouts.ts index 325377b8f..c188ae5a3 100644 --- a/libs/shared/graph-layout/src/lib/cytoscape-layouts.ts +++ b/libs/shared/graph-layout/src/lib/cytoscape-layouts.ts @@ -1,24 +1,66 @@ +import Graph from 'graphology'; +import { Attributes } from 'graphology-types'; import { Layout } from './layout'; import { ILayoutFactory, LayoutAlgorithm } from './layout-creator-usecase'; +import cytoscape from 'cytoscape'; +import klay from 'cytoscape-klay'; + +cytoscape.use( klay ); + export type CytoscapeProvider = 'Cytoscape'; export type CytoscapeLayoutAlgorithms = - | `${CytoscapeProvider}_coupe` - | `${CytoscapeProvider}_i4`; + | `${CytoscapeProvider}_klay` + | `${CytoscapeProvider}_dagre` + | `${CytoscapeProvider}_elk` + | `${CytoscapeProvider}_fcose` + | `${CytoscapeProvider}_cose-bilkent` + | `${CytoscapeProvider}_cise`; + + +type CytoNode = { + data: { + id: string; + type: string; + source?: string; + target?: string; + position?: { + x: number; + y: number; + }; + }; +}; /** - * This is a ConcreteCreator + * This is the Cytoscape Factory */ export class CytoscapeFactory implements ILayoutFactory<CytoscapeLayoutAlgorithms> { createLayout(LayoutAlgorithm: CytoscapeLayoutAlgorithms): Cytoscape | null { switch (LayoutAlgorithm) { - case 'Cytoscape_coupe': - return new CytoscapeCoupe(); - case 'Cytoscape_i4': - return new CytoscapeI4(); + case 'Cytoscape_klay': + //https://github.com/cytoscape/cytoscape.js-klay + return new CytoscapeKlay(); + // case 'Cytoscape_dagre': + // //https://github.com/cytoscape/cytoscape.js-dagre + // return new CytoscapeCoupe(); + // case 'Cytoscape_elk': + // //https://github.com/cytoscape/cytoscape.js-elk + // return new CytoscapeI4(); + + // case 'Cytoscape_fcose': + // //https://github.com/iVis-at-Bilkent/cytoscape.js-fcose + // return new CytoscapeI4(); + + // case 'Cytoscape_cose-bilkent': + // //https://github.com/cytoscape/cytoscape.js-cose-bilkent + // return new CytoscapeI4(); + + // case 'Cytoscape_cise': + // //https://github.com/iVis-at-Bilkent/cytoscape.js-cise + // return new CytoscapeI4(); default: return null; } @@ -38,9 +80,15 @@ export abstract class Cytoscape extends Layout<CytoscapeProvider> { /** * This is a ConcreteProduct */ -class CytoscapeI4 extends Cytoscape { +class CytoscapeKlay extends Cytoscape { constructor() { - super('Cytoscape_i4'); + super('Cytoscape_klay'); + } + + public override layout( + graph: Graph<Attributes, Attributes, Attributes> + ): void { + } } diff --git a/libs/shared/graph-layout/src/lib/layout-creator-usecase.spec.ts b/libs/shared/graph-layout/src/lib/layout-creator-usecase.spec.ts index 903a079dc..d6ff588a2 100644 --- a/libs/shared/graph-layout/src/lib/layout-creator-usecase.spec.ts +++ b/libs/shared/graph-layout/src/lib/layout-creator-usecase.spec.ts @@ -16,7 +16,7 @@ const TIMEOUT = 10; /** * @jest-environment jsdom */ -describe('LayoutFactory', () => { +describe('LayoutFactory Graphology Libries', () => { /** * @jest-environment jsdom */ @@ -154,3 +154,39 @@ describe('LayoutFactory', () => { }); }, TIMEOUT); }); + + +describe('LayoutFactory Cytoscape Libraries', () => { + /** + * @jest-environment jsdom + */ + it('should work with noverlap from graphology ', () => { + const graph = new MultiGraph(); + + // Adding some nodes + // graph.addNode('John', { x: 0, y: 0, width: 200, height: 200 }); + // graph.addNode('Martha', { x: 0, y: 0 }); + graph.addNode('John'); + graph.addNode('Martha'); + + // Adding an edge + graph.addEdge('John', 'Martha'); + + const layoutFactory = new LayoutFactory(); + const layoutAlgorithm = layoutFactory.createLayout( + 'Cytoscape_dagre' + ); + layoutAlgorithm?.layout(graph); + + // const positionMap = new Set<string>(); + graph.forEachNode((node, attr) => { + expect(graph.getNodeAttribute(node, 'x')).toBeDefined(); + expect(graph.getNodeAttribute(node, 'y')).toBeDefined(); + + // const pos = '' + attr['x'] + '' + attr['y']; + // expect(positionMap.has(pos)).toBeFalsy(); + // positionMap.add(pos); + }); + }, TIMEOUT); + +}); \ No newline at end of file diff --git a/libs/shared/graph-layouts/.eslintrc.json b/libs/shared/graph-layouts/.eslintrc.json deleted file mode 100644 index 3456be9b9..000000000 --- a/libs/shared/graph-layouts/.eslintrc.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "extends": ["../../../.eslintrc.json"], - "ignorePatterns": ["!**/*"], - "overrides": [ - { - "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], - "rules": {} - }, - { - "files": ["*.ts", "*.tsx"], - "rules": {} - }, - { - "files": ["*.js", "*.jsx"], - "rules": {} - } - ] -} diff --git a/libs/shared/graph-layouts/README.md b/libs/shared/graph-layouts/README.md deleted file mode 100644 index b30ee66b0..000000000 --- a/libs/shared/graph-layouts/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# shared-graph-layouts - -This library was generated with [Nx](https://nx.dev). - -## Building - -Run `nx build shared-graph-layouts` to build the library. - -## Running unit tests - -Run `nx test shared-graph-layouts` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/shared/graph-layouts/dist/README.md b/libs/shared/graph-layouts/dist/README.md deleted file mode 100644 index b30ee66b0..000000000 --- a/libs/shared/graph-layouts/dist/README.md +++ /dev/null @@ -1,11 +0,0 @@ -# shared-graph-layouts - -This library was generated with [Nx](https://nx.dev). - -## Building - -Run `nx build shared-graph-layouts` to build the library. - -## Running unit tests - -Run `nx test shared-graph-layouts` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/shared/graph-layouts/jest.config.js b/libs/shared/graph-layouts/jest.config.js deleted file mode 100644 index 89ea43d51..000000000 --- a/libs/shared/graph-layouts/jest.config.js +++ /dev/null @@ -1,14 +0,0 @@ -module.exports = { - displayName: 'shared-graph-layouts', - preset: '../../../jest.preset.js', - globals: { - 'ts-jest': { - tsconfig: '<rootDir>/tsconfig.spec.json', - }, - }, - transform: { - '^.+\\.[tj]s$': 'ts-jest', - }, - moduleFileExtensions: ['ts', 'js', 'html'], - coverageDirectory: '../../../coverage/libs/shared/graph-layouts', -}; diff --git a/libs/shared/graph-layouts/node_modules/.yarn-integrity b/libs/shared/graph-layouts/node_modules/.yarn-integrity deleted file mode 100644 index f5558a47e..000000000 --- a/libs/shared/graph-layouts/node_modules/.yarn-integrity +++ /dev/null @@ -1,18 +0,0 @@ -{ - "systemParams": "win32-x64-83", - "modulesFolders": [ - "node_modules" - ], - "flags": [], - "linkedModules": [], - "topLevelPatterns": [ - "graphology@^0.24.1" - ], - "lockfileEntries": { - "events@^3.3.0": "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400", - "graphology@^0.24.1": "https://registry.yarnpkg.com/graphology/-/graphology-0.24.1.tgz#035e452e294b01168cf5c85d5dd0a4b7e4837d87", - "obliterator@^2.0.2": "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.2.tgz#25f50dc92e1181371b9d8209d11890f1a3c2fc21" - }, - "files": [], - "artifacts": {} -} \ No newline at end of file diff --git a/libs/shared/graph-layouts/node_modules/events/.airtap.yml b/libs/shared/graph-layouts/node_modules/events/.airtap.yml deleted file mode 100644 index c7a8a87d5..000000000 --- a/libs/shared/graph-layouts/node_modules/events/.airtap.yml +++ /dev/null @@ -1,15 +0,0 @@ -sauce_connect: true -loopback: airtap.local -browsers: - - name: chrome - version: latest - - name: firefox - version: latest - - name: safari - version: 9..latest - - name: iphone - version: latest - - name: ie - version: 9..latest - - name: microsoftedge - version: 13..latest diff --git a/libs/shared/graph-layouts/node_modules/events/.github/FUNDING.yml b/libs/shared/graph-layouts/node_modules/events/.github/FUNDING.yml deleted file mode 100644 index 8b8cb78ba..000000000 --- a/libs/shared/graph-layouts/node_modules/events/.github/FUNDING.yml +++ /dev/null @@ -1,12 +0,0 @@ -# These are supported funding model platforms - -github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] -patreon: # Replace with a single Patreon username -open_collective: # Replace with a single Open Collective username -ko_fi: # Replace with a single Ko-fi username -tidelift: npm/events -community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry -liberapay: # Replace with a single Liberapay username -issuehunt: # Replace with a single IssueHunt username -otechie: # Replace with a single Otechie username -custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] diff --git a/libs/shared/graph-layouts/node_modules/events/.travis.yml b/libs/shared/graph-layouts/node_modules/events/.travis.yml deleted file mode 100644 index 486dc3c4c..000000000 --- a/libs/shared/graph-layouts/node_modules/events/.travis.yml +++ /dev/null @@ -1,18 +0,0 @@ -dist: xenial -os: linux -language: node_js -node_js: - - 'stable' - - 'lts/*' - - '0.12' -script: - - npm test - - if [ "${TRAVIS_PULL_REQUEST}" = "false" ] && [ "${TRAVIS_NODE_VERSION}" = "stable" ]; then npm run test:browsers; fi -addons: - sauce_connect: true - hosts: - - airtap.local -env: - global: - - secure: XcBiD8yReflut9q7leKsigDZ0mI3qTKH+QrNVY8DaqlomJOZw8aOrVuX9Jz12l86ZJ41nbxmKnRNkFzcVr9mbP9YaeTb3DpeOBWmvaoSfud9Wnc16VfXtc1FCcwDhSVcSiM3UtnrmFU5cH+Dw1LPh5PbfylYOS/nJxUvG0FFLqI= - - secure: jNWtEbqhUdQ0xXDHvCYfUbKYeJCi6a7B4LsrcxYCyWWn4NIgncE5x2YbB+FSUUFVYfz0dsn5RKP1oHB99f0laUEo18HBNkrAS/rtyOdVzcpJjbQ6kgSILGjnJD/Ty1B57Rcz3iyev5Y7bLZ6Y1FbDnk/i9/l0faOGz8vTC3Vdkc= diff --git a/libs/shared/graph-layouts/node_modules/events/History.md b/libs/shared/graph-layouts/node_modules/events/History.md deleted file mode 100644 index f48bf210d..000000000 --- a/libs/shared/graph-layouts/node_modules/events/History.md +++ /dev/null @@ -1,118 +0,0 @@ -# 3.3.0 - - - Support EventTarget emitters in `events.once` from Node.js 12.11.0. - - Now you can use the `events.once` function with objects that implement the EventTarget interface. This interface is used widely in - the DOM and other web APIs. - - ```js - var events = require('events'); - var assert = require('assert'); - - async function connect() { - var ws = new WebSocket('wss://example.com'); - await events.once(ws, 'open'); - assert(ws.readyState === WebSocket.OPEN); - } - - async function onClick() { - await events.once(document.body, 'click'); - alert('you clicked the page!'); - } - ``` - -# 3.2.0 - - - Add `events.once` from Node.js 11.13.0. - - To use this function, Promises must be supported in the environment. Use a polyfill like `es6-promise` if you support older browsers. - -# 3.1.0 (2020-01-08) - -`events` now matches the Node.js 11.12.0 API. - - - pass through return value in wrapped `emitter.once()` listeners - - Now, this works: - ```js - emitter.once('myevent', function () { return 1; }); - var listener = emitter.rawListeners('myevent')[0] - assert(listener() === 1); - ``` - Previously, `listener()` would return undefined regardless of the implementation. - - Ported from https://github.com/nodejs/node/commit/acc506c2d2771dab8d7bba6d3452bc5180dff7cf - - - Reduce code duplication in listener type check ([#67](https://github.com/Gozala/events/pull/67) by [@friederbluemle](https://github.com/friederbluemle)). - - Improve `emitter.once()` performance in some engines - -# 3.0.0 (2018-05-25) - -**This version drops support for IE8.** `events` no longer includes polyfills -for ES5 features. If you need to support older environments, use an ES5 shim -like [es5-shim](https://npmjs.com/package/es5-shim). Both the shim and sham -versions of es5-shim are necessary. - - - Update to events code from Node.js 10.x - - (semver major) Adds `off()` method - - Port more tests from Node.js - - Switch browser tests to airtap, making things more reliable - -# 2.1.0 (2018-05-25) - - - add Emitter#rawListeners from Node.js v9.4 - -# 2.0.0 (2018-02-02) - - - Update to events code from node.js 8.x - - Adds `prependListener()` and `prependOnceListener()` - - Adds `eventNames()` method - - (semver major) Unwrap `once()` listeners in `listeners()` - - copy tests from node.js - -Note that this version doubles the gzipped size, jumping from 1.1KB to 2.1KB, -due to new methods and runtime performance improvements. Be aware of that when -upgrading. - -# 1.1.1 (2016-06-22) - - - add more context to errors if they are not instanceof Error - -# 1.1.0 (2015-09-29) - - - add Emitter#listerCount (to match node v4 api) - -# 1.0.2 (2014-08-28) - - - remove un-reachable code - - update devDeps - -## 1.0.1 / 2014-05-11 - - - check for console.trace before using it - -## 1.0.0 / 2013-12-10 - - - Update to latest events code from node.js 0.10 - - copy tests from node.js - -## 0.4.0 / 2011-07-03 ## - - - Switching to graphquire@0.8.0 - -## 0.3.0 / 2011-07-03 ## - - - Switching to URL based module require. - -## 0.2.0 / 2011-06-10 ## - - - Simplified package structure. - - Graphquire for dependency management. - -## 0.1.1 / 2011-05-16 ## - - - Unhandled errors are logged via console.error - -## 0.1.0 / 2011-04-22 ## - - - Initial release diff --git a/libs/shared/graph-layouts/node_modules/events/LICENSE b/libs/shared/graph-layouts/node_modules/events/LICENSE deleted file mode 100644 index 52ed3b0a6..000000000 --- a/libs/shared/graph-layouts/node_modules/events/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -MIT - -Copyright Joyent, Inc. and other Node contributors. - -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. diff --git a/libs/shared/graph-layouts/node_modules/events/Readme.md b/libs/shared/graph-layouts/node_modules/events/Readme.md deleted file mode 100644 index 80849c0b2..000000000 --- a/libs/shared/graph-layouts/node_modules/events/Readme.md +++ /dev/null @@ -1,50 +0,0 @@ -# events [](https://travis-ci.org/Gozala/events) - -> Node's event emitter for all engines. - -This implements the Node.js [`events`][node.js docs] module for environments that do not have it, like browsers. - -> `events` currently matches the **Node.js 11.13.0** API. - -Note that the `events` module uses ES5 features. If you need to support very old browsers like IE8, use a shim like [`es5-shim`](https://www.npmjs.com/package/es5-shim). You need both the shim and the sham versions of `es5-shim`. - -This module is maintained, but only by very few people. If you'd like to help, let us know in the [Maintainer Needed](https://github.com/Gozala/events/issues/43) issue! - -## Install - -You usually do not have to install `events` yourself! If your code runs in Node.js, `events` is built in. If your code runs in the browser, bundlers like [browserify](https://github.com/browserify/browserify) or [webpack](https://github.com/webpack/webpack) also include the `events` module. - -But if none of those apply, with npm do: - -``` -npm install events -``` - -## Usage - -```javascript -var EventEmitter = require('events') - -var ee = new EventEmitter() -ee.on('message', function (text) { - console.log(text) -}) -ee.emit('message', 'hello world') -``` - -## API - -See the [Node.js EventEmitter docs][node.js docs]. `events` currently matches the Node.js 11.13.0 API. - -## Contributing - -PRs are very welcome! The main way to contribute to `events` is by porting features, bugfixes and tests from Node.js. Ideally, code contributions to this module are copy-pasted from Node.js and transpiled to ES5, rather than reimplemented from scratch. Matching the Node.js code as closely as possible makes maintenance simpler when new changes land in Node.js. -This module intends to provide exactly the same API as Node.js, so features that are not available in the core `events` module will not be accepted. Feature requests should instead be directed at [nodejs/node](https://github.com/nodejs/node) and will be added to this module once they are implemented in Node.js. - -If there is a difference in behaviour between Node.js's `events` module and this module, please open an issue! - -## License - -[MIT](./LICENSE) - -[node.js docs]: https://nodejs.org/dist/v11.13.0/docs/api/events.html diff --git a/libs/shared/graph-layouts/node_modules/events/events.js b/libs/shared/graph-layouts/node_modules/events/events.js deleted file mode 100644 index 34b69a0b4..000000000 --- a/libs/shared/graph-layouts/node_modules/events/events.js +++ /dev/null @@ -1,497 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. - -'use strict'; - -var R = typeof Reflect === 'object' ? Reflect : null -var ReflectApply = R && typeof R.apply === 'function' - ? R.apply - : function ReflectApply(target, receiver, args) { - return Function.prototype.apply.call(target, receiver, args); - } - -var ReflectOwnKeys -if (R && typeof R.ownKeys === 'function') { - ReflectOwnKeys = R.ownKeys -} else if (Object.getOwnPropertySymbols) { - ReflectOwnKeys = function ReflectOwnKeys(target) { - return Object.getOwnPropertyNames(target) - .concat(Object.getOwnPropertySymbols(target)); - }; -} else { - ReflectOwnKeys = function ReflectOwnKeys(target) { - return Object.getOwnPropertyNames(target); - }; -} - -function ProcessEmitWarning(warning) { - if (console && console.warn) console.warn(warning); -} - -var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) { - return value !== value; -} - -function EventEmitter() { - EventEmitter.init.call(this); -} -module.exports = EventEmitter; -module.exports.once = once; - -// Backwards-compat with node 0.10.x -EventEmitter.EventEmitter = EventEmitter; - -EventEmitter.prototype._events = undefined; -EventEmitter.prototype._eventsCount = 0; -EventEmitter.prototype._maxListeners = undefined; - -// By default EventEmitters will print a warning if more than 10 listeners are -// added to it. This is a useful default which helps finding memory leaks. -var defaultMaxListeners = 10; - -function checkListener(listener) { - if (typeof listener !== 'function') { - throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener); - } -} - -Object.defineProperty(EventEmitter, 'defaultMaxListeners', { - enumerable: true, - get: function() { - return defaultMaxListeners; - }, - set: function(arg) { - if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) { - throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.'); - } - defaultMaxListeners = arg; - } -}); - -EventEmitter.init = function() { - - if (this._events === undefined || - this._events === Object.getPrototypeOf(this)._events) { - this._events = Object.create(null); - this._eventsCount = 0; - } - - this._maxListeners = this._maxListeners || undefined; -}; - -// Obviously not all Emitters should be limited to 10. This function allows -// that to be increased. Set to zero for unlimited. -EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) { - if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) { - throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.'); - } - this._maxListeners = n; - return this; -}; - -function _getMaxListeners(that) { - if (that._maxListeners === undefined) - return EventEmitter.defaultMaxListeners; - return that._maxListeners; -} - -EventEmitter.prototype.getMaxListeners = function getMaxListeners() { - return _getMaxListeners(this); -}; - -EventEmitter.prototype.emit = function emit(type) { - var args = []; - for (var i = 1; i < arguments.length; i++) args.push(arguments[i]); - var doError = (type === 'error'); - - var events = this._events; - if (events !== undefined) - doError = (doError && events.error === undefined); - else if (!doError) - return false; - - // If there is no 'error' event listener then throw. - if (doError) { - var er; - if (args.length > 0) - er = args[0]; - if (er instanceof Error) { - // Note: The comments on the `throw` lines are intentional, they show - // up in Node's output if this results in an unhandled exception. - throw er; // Unhandled 'error' event - } - // At least give some kind of context to the user - var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : '')); - err.context = er; - throw err; // Unhandled 'error' event - } - - var handler = events[type]; - - if (handler === undefined) - return false; - - if (typeof handler === 'function') { - ReflectApply(handler, this, args); - } else { - var len = handler.length; - var listeners = arrayClone(handler, len); - for (var i = 0; i < len; ++i) - ReflectApply(listeners[i], this, args); - } - - return true; -}; - -function _addListener(target, type, listener, prepend) { - var m; - var events; - var existing; - - checkListener(listener); - - events = target._events; - if (events === undefined) { - events = target._events = Object.create(null); - target._eventsCount = 0; - } else { - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (events.newListener !== undefined) { - target.emit('newListener', type, - listener.listener ? listener.listener : listener); - - // Re-assign `events` because a newListener handler could have caused the - // this._events to be assigned to a new object - events = target._events; - } - existing = events[type]; - } - - if (existing === undefined) { - // Optimize the case of one listener. Don't need the extra array object. - existing = events[type] = listener; - ++target._eventsCount; - } else { - if (typeof existing === 'function') { - // Adding the second element, need to change to array. - existing = events[type] = - prepend ? [listener, existing] : [existing, listener]; - // If we've already got an array, just append. - } else if (prepend) { - existing.unshift(listener); - } else { - existing.push(listener); - } - - // Check for listener leak - m = _getMaxListeners(target); - if (m > 0 && existing.length > m && !existing.warned) { - existing.warned = true; - // No error code for this since it is a Warning - // eslint-disable-next-line no-restricted-syntax - var w = new Error('Possible EventEmitter memory leak detected. ' + - existing.length + ' ' + String(type) + ' listeners ' + - 'added. Use emitter.setMaxListeners() to ' + - 'increase limit'); - w.name = 'MaxListenersExceededWarning'; - w.emitter = target; - w.type = type; - w.count = existing.length; - ProcessEmitWarning(w); - } - } - - return target; -} - -EventEmitter.prototype.addListener = function addListener(type, listener) { - return _addListener(this, type, listener, false); -}; - -EventEmitter.prototype.on = EventEmitter.prototype.addListener; - -EventEmitter.prototype.prependListener = - function prependListener(type, listener) { - return _addListener(this, type, listener, true); - }; - -function onceWrapper() { - if (!this.fired) { - this.target.removeListener(this.type, this.wrapFn); - this.fired = true; - if (arguments.length === 0) - return this.listener.call(this.target); - return this.listener.apply(this.target, arguments); - } -} - -function _onceWrap(target, type, listener) { - var state = { fired: false, wrapFn: undefined, target: target, type: type, listener: listener }; - var wrapped = onceWrapper.bind(state); - wrapped.listener = listener; - state.wrapFn = wrapped; - return wrapped; -} - -EventEmitter.prototype.once = function once(type, listener) { - checkListener(listener); - this.on(type, _onceWrap(this, type, listener)); - return this; -}; - -EventEmitter.prototype.prependOnceListener = - function prependOnceListener(type, listener) { - checkListener(listener); - this.prependListener(type, _onceWrap(this, type, listener)); - return this; - }; - -// Emits a 'removeListener' event if and only if the listener was removed. -EventEmitter.prototype.removeListener = - function removeListener(type, listener) { - var list, events, position, i, originalListener; - - checkListener(listener); - - events = this._events; - if (events === undefined) - return this; - - list = events[type]; - if (list === undefined) - return this; - - if (list === listener || list.listener === listener) { - if (--this._eventsCount === 0) - this._events = Object.create(null); - else { - delete events[type]; - if (events.removeListener) - this.emit('removeListener', type, list.listener || listener); - } - } else if (typeof list !== 'function') { - position = -1; - - for (i = list.length - 1; i >= 0; i--) { - if (list[i] === listener || list[i].listener === listener) { - originalListener = list[i].listener; - position = i; - break; - } - } - - if (position < 0) - return this; - - if (position === 0) - list.shift(); - else { - spliceOne(list, position); - } - - if (list.length === 1) - events[type] = list[0]; - - if (events.removeListener !== undefined) - this.emit('removeListener', type, originalListener || listener); - } - - return this; - }; - -EventEmitter.prototype.off = EventEmitter.prototype.removeListener; - -EventEmitter.prototype.removeAllListeners = - function removeAllListeners(type) { - var listeners, events, i; - - events = this._events; - if (events === undefined) - return this; - - // not listening for removeListener, no need to emit - if (events.removeListener === undefined) { - if (arguments.length === 0) { - this._events = Object.create(null); - this._eventsCount = 0; - } else if (events[type] !== undefined) { - if (--this._eventsCount === 0) - this._events = Object.create(null); - else - delete events[type]; - } - return this; - } - - // emit removeListener for all listeners on all events - if (arguments.length === 0) { - var keys = Object.keys(events); - var key; - for (i = 0; i < keys.length; ++i) { - key = keys[i]; - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - this.removeAllListeners('removeListener'); - this._events = Object.create(null); - this._eventsCount = 0; - return this; - } - - listeners = events[type]; - - if (typeof listeners === 'function') { - this.removeListener(type, listeners); - } else if (listeners !== undefined) { - // LIFO order - for (i = listeners.length - 1; i >= 0; i--) { - this.removeListener(type, listeners[i]); - } - } - - return this; - }; - -function _listeners(target, type, unwrap) { - var events = target._events; - - if (events === undefined) - return []; - - var evlistener = events[type]; - if (evlistener === undefined) - return []; - - if (typeof evlistener === 'function') - return unwrap ? [evlistener.listener || evlistener] : [evlistener]; - - return unwrap ? - unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); -} - -EventEmitter.prototype.listeners = function listeners(type) { - return _listeners(this, type, true); -}; - -EventEmitter.prototype.rawListeners = function rawListeners(type) { - return _listeners(this, type, false); -}; - -EventEmitter.listenerCount = function(emitter, type) { - if (typeof emitter.listenerCount === 'function') { - return emitter.listenerCount(type); - } else { - return listenerCount.call(emitter, type); - } -}; - -EventEmitter.prototype.listenerCount = listenerCount; -function listenerCount(type) { - var events = this._events; - - if (events !== undefined) { - var evlistener = events[type]; - - if (typeof evlistener === 'function') { - return 1; - } else if (evlistener !== undefined) { - return evlistener.length; - } - } - - return 0; -} - -EventEmitter.prototype.eventNames = function eventNames() { - return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : []; -}; - -function arrayClone(arr, n) { - var copy = new Array(n); - for (var i = 0; i < n; ++i) - copy[i] = arr[i]; - return copy; -} - -function spliceOne(list, index) { - for (; index + 1 < list.length; index++) - list[index] = list[index + 1]; - list.pop(); -} - -function unwrapListeners(arr) { - var ret = new Array(arr.length); - for (var i = 0; i < ret.length; ++i) { - ret[i] = arr[i].listener || arr[i]; - } - return ret; -} - -function once(emitter, name) { - return new Promise(function (resolve, reject) { - function errorListener(err) { - emitter.removeListener(name, resolver); - reject(err); - } - - function resolver() { - if (typeof emitter.removeListener === 'function') { - emitter.removeListener('error', errorListener); - } - resolve([].slice.call(arguments)); - }; - - eventTargetAgnosticAddListener(emitter, name, resolver, { once: true }); - if (name !== 'error') { - addErrorHandlerIfEventEmitter(emitter, errorListener, { once: true }); - } - }); -} - -function addErrorHandlerIfEventEmitter(emitter, handler, flags) { - if (typeof emitter.on === 'function') { - eventTargetAgnosticAddListener(emitter, 'error', handler, flags); - } -} - -function eventTargetAgnosticAddListener(emitter, name, listener, flags) { - if (typeof emitter.on === 'function') { - if (flags.once) { - emitter.once(name, listener); - } else { - emitter.on(name, listener); - } - } else if (typeof emitter.addEventListener === 'function') { - // EventTarget does not have `error` event semantics like Node - // EventEmitters, we do not listen for `error` events here. - emitter.addEventListener(name, function wrapListener(arg) { - // IE does not have builtin `{ once: true }` support so we - // have to do it manually. - if (flags.once) { - emitter.removeEventListener(name, wrapListener); - } - listener(arg); - }); - } else { - throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter); - } -} diff --git a/libs/shared/graph-layouts/node_modules/events/package.json b/libs/shared/graph-layouts/node_modules/events/package.json deleted file mode 100644 index b9580d881..000000000 --- a/libs/shared/graph-layouts/node_modules/events/package.json +++ /dev/null @@ -1,37 +0,0 @@ -{ - "name": "events", - "version": "3.3.0", - "description": "Node's event emitter for all engines.", - "keywords": [ - "events", - "eventEmitter", - "eventDispatcher", - "listeners" - ], - "author": "Irakli Gozalishvili <rfobic@gmail.com> (http://jeditoolkit.com)", - "repository": { - "type": "git", - "url": "git://github.com/Gozala/events.git", - "web": "https://github.com/Gozala/events" - }, - "bugs": { - "url": "http://github.com/Gozala/events/issues/" - }, - "main": "./events.js", - "engines": { - "node": ">=0.8.x" - }, - "devDependencies": { - "airtap": "^1.0.0", - "functions-have-names": "^1.2.1", - "has": "^1.0.3", - "has-symbols": "^1.0.1", - "isarray": "^2.0.5", - "tape": "^5.0.0" - }, - "scripts": { - "test": "node tests/index.js", - "test:browsers": "airtap -- tests/index.js" - }, - "license": "MIT" -} diff --git a/libs/shared/graph-layouts/node_modules/events/security.md b/libs/shared/graph-layouts/node_modules/events/security.md deleted file mode 100644 index a14ace6a5..000000000 --- a/libs/shared/graph-layouts/node_modules/events/security.md +++ /dev/null @@ -1,10 +0,0 @@ -# Security Policy - -## Supported Versions -Only the latest major version is supported at any given time. - -## Reporting a Vulnerability - -To report a security vulnerability, please use the -[Tidelift security contact](https://tidelift.com/security). -Tidelift will coordinate the fix and disclosure. diff --git a/libs/shared/graph-layouts/node_modules/events/tests/add-listeners.js b/libs/shared/graph-layouts/node_modules/events/tests/add-listeners.js deleted file mode 100644 index 9b578272b..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/add-listeners.js +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. - -var common = require('./common'); -var assert = require('assert'); -var EventEmitter = require('../'); - -{ - var ee = new EventEmitter(); - var events_new_listener_emitted = []; - var listeners_new_listener_emitted = []; - - // Sanity check - assert.strictEqual(ee.addListener, ee.on); - - ee.on('newListener', function(event, listener) { - // Don't track newListener listeners. - if (event === 'newListener') - return; - - events_new_listener_emitted.push(event); - listeners_new_listener_emitted.push(listener); - }); - - var hello = common.mustCall(function(a, b) { - assert.strictEqual('a', a); - assert.strictEqual('b', b); - }); - - ee.once('newListener', function(name, listener) { - assert.strictEqual(name, 'hello'); - assert.strictEqual(listener, hello); - - var listeners = this.listeners('hello'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 0); - }); - - ee.on('hello', hello); - ee.once('foo', assert.fail); - - assert.ok(Array.isArray(events_new_listener_emitted)); - assert.strictEqual(events_new_listener_emitted.length, 2); - assert.strictEqual(events_new_listener_emitted[0], 'hello'); - assert.strictEqual(events_new_listener_emitted[1], 'foo'); - - assert.ok(Array.isArray(listeners_new_listener_emitted)); - assert.strictEqual(listeners_new_listener_emitted.length, 2); - assert.strictEqual(listeners_new_listener_emitted[0], hello); - assert.strictEqual(listeners_new_listener_emitted[1], assert.fail); - - ee.emit('hello', 'a', 'b'); -} - -// just make sure that this doesn't throw: -{ - var f = new EventEmitter(); - - f.setMaxListeners(0); -} - -{ - var listen1 = function() {}; - var listen2 = function() {}; - var ee = new EventEmitter(); - - ee.once('newListener', function() { - var listeners = ee.listeners('hello'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 0); - ee.once('newListener', function() { - var listeners = ee.listeners('hello'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 0); - }); - ee.on('hello', listen2); - }); - ee.on('hello', listen1); - // The order of listeners on an event is not always the order in which the - // listeners were added. - var listeners = ee.listeners('hello'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 2); - assert.strictEqual(listeners[0], listen2); - assert.strictEqual(listeners[1], listen1); -} - -// Verify that the listener must be a function -assert.throws(function() { - var ee = new EventEmitter(); - - ee.on('foo', null); -}, /^TypeError: The "listener" argument must be of type Function. Received type object$/); diff --git a/libs/shared/graph-layouts/node_modules/events/tests/check-listener-leaks.js b/libs/shared/graph-layouts/node_modules/events/tests/check-listener-leaks.js deleted file mode 100644 index 7fce48f37..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/check-listener-leaks.js +++ /dev/null @@ -1,101 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. - -var common = require('./common'); -var assert = require('assert'); -var events = require('../'); - -// Redirect warning output to tape. -var consoleWarn = console.warn; -console.warn = common.test.comment; - -common.test.on('end', function () { - console.warn = consoleWarn; -}); - -// default -{ - var e = new events.EventEmitter(); - - for (var i = 0; i < 10; i++) { - e.on('default', common.mustNotCall()); - } - assert.ok(!e._events['default'].hasOwnProperty('warned')); - e.on('default', common.mustNotCall()); - assert.ok(e._events['default'].warned); - - // specific - e.setMaxListeners(5); - for (var i = 0; i < 5; i++) { - e.on('specific', common.mustNotCall()); - } - assert.ok(!e._events['specific'].hasOwnProperty('warned')); - e.on('specific', common.mustNotCall()); - assert.ok(e._events['specific'].warned); - - // only one - e.setMaxListeners(1); - e.on('only one', common.mustNotCall()); - assert.ok(!e._events['only one'].hasOwnProperty('warned')); - e.on('only one', common.mustNotCall()); - assert.ok(e._events['only one'].hasOwnProperty('warned')); - - // unlimited - e.setMaxListeners(0); - for (var i = 0; i < 1000; i++) { - e.on('unlimited', common.mustNotCall()); - } - assert.ok(!e._events['unlimited'].hasOwnProperty('warned')); -} - -// process-wide -{ - events.EventEmitter.defaultMaxListeners = 42; - var e = new events.EventEmitter(); - - for (var i = 0; i < 42; ++i) { - e.on('fortytwo', common.mustNotCall()); - } - assert.ok(!e._events['fortytwo'].hasOwnProperty('warned')); - e.on('fortytwo', common.mustNotCall()); - assert.ok(e._events['fortytwo'].hasOwnProperty('warned')); - delete e._events['fortytwo'].warned; - - events.EventEmitter.defaultMaxListeners = 44; - e.on('fortytwo', common.mustNotCall()); - assert.ok(!e._events['fortytwo'].hasOwnProperty('warned')); - e.on('fortytwo', common.mustNotCall()); - assert.ok(e._events['fortytwo'].hasOwnProperty('warned')); -} - -// but _maxListeners still has precedence over defaultMaxListeners -{ - events.EventEmitter.defaultMaxListeners = 42; - var e = new events.EventEmitter(); - e.setMaxListeners(1); - e.on('uno', common.mustNotCall()); - assert.ok(!e._events['uno'].hasOwnProperty('warned')); - e.on('uno', common.mustNotCall()); - assert.ok(e._events['uno'].hasOwnProperty('warned')); - - // chainable - assert.strictEqual(e, e.setMaxListeners(1)); -} diff --git a/libs/shared/graph-layouts/node_modules/events/tests/common.js b/libs/shared/graph-layouts/node_modules/events/tests/common.js deleted file mode 100644 index 49569b05f..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/common.js +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. - -var test = require('tape'); -var assert = require('assert'); - -var noop = function() {}; - -var mustCallChecks = []; - -function runCallChecks(exitCode) { - if (exitCode !== 0) return; - - var failed = filter(mustCallChecks, function(context) { - if ('minimum' in context) { - context.messageSegment = 'at least ' + context.minimum; - return context.actual < context.minimum; - } else { - context.messageSegment = 'exactly ' + context.exact; - return context.actual !== context.exact; - } - }); - - for (var i = 0; i < failed.length; i++) { - var context = failed[i]; - console.log('Mismatched %s function calls. Expected %s, actual %d.', - context.name, - context.messageSegment, - context.actual); - // IE8 has no .stack - if (context.stack) console.log(context.stack.split('\n').slice(2).join('\n')); - } - - assert.strictEqual(failed.length, 0); -} - -exports.mustCall = function(fn, exact) { - return _mustCallInner(fn, exact, 'exact'); -}; - -function _mustCallInner(fn, criteria, field) { - if (typeof criteria == 'undefined') criteria = 1; - - if (typeof fn === 'number') { - criteria = fn; - fn = noop; - } else if (fn === undefined) { - fn = noop; - } - - if (typeof criteria !== 'number') - throw new TypeError('Invalid ' + field + ' value: ' + criteria); - - var context = { - actual: 0, - stack: (new Error()).stack, - name: fn.name || '<anonymous>' - }; - - context[field] = criteria; - - // add the exit listener only once to avoid listener leak warnings - if (mustCallChecks.length === 0) test.onFinish(function() { runCallChecks(0); }); - - mustCallChecks.push(context); - - return function() { - context.actual++; - return fn.apply(this, arguments); - }; -} - -exports.mustNotCall = function(msg) { - return function mustNotCall() { - assert.fail(msg || 'function should not have been called'); - }; -}; - -function filter(arr, fn) { - if (arr.filter) return arr.filter(fn); - var filtered = []; - for (var i = 0; i < arr.length; i++) { - if (fn(arr[i], i, arr)) filtered.push(arr[i]); - } - return filtered -} diff --git a/libs/shared/graph-layouts/node_modules/events/tests/errors.js b/libs/shared/graph-layouts/node_modules/events/tests/errors.js deleted file mode 100644 index a23df437f..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/errors.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict'; -var assert = require('assert'); -var EventEmitter = require('../'); - -var EE = new EventEmitter(); - -assert.throws(function () { - EE.emit('error', 'Accepts a string'); -}, 'Error: Unhandled error. (Accepts a string)'); - -assert.throws(function () { - EE.emit('error', { message: 'Error!' }); -}, 'Unhandled error. ([object Object])'); diff --git a/libs/shared/graph-layouts/node_modules/events/tests/events-list.js b/libs/shared/graph-layouts/node_modules/events/tests/events-list.js deleted file mode 100644 index 08aa62177..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/events-list.js +++ /dev/null @@ -1,28 +0,0 @@ -'use strict'; - -var EventEmitter = require('../'); -var assert = require('assert'); - -var EE = new EventEmitter(); -var m = function() {}; -EE.on('foo', function() {}); -assert.equal(1, EE.eventNames().length); -assert.equal('foo', EE.eventNames()[0]); -EE.on('bar', m); -assert.equal(2, EE.eventNames().length); -assert.equal('foo', EE.eventNames()[0]); -assert.equal('bar', EE.eventNames()[1]); -EE.removeListener('bar', m); -assert.equal(1, EE.eventNames().length); -assert.equal('foo', EE.eventNames()[0]); - -if (typeof Symbol !== 'undefined') { - var s = Symbol('s'); - EE.on(s, m); - assert.equal(2, EE.eventNames().length); - assert.equal('foo', EE.eventNames()[0]); - assert.equal(s, EE.eventNames()[1]); - EE.removeListener(s, m); - assert.equal(1, EE.eventNames().length); - assert.equal('foo', EE.eventNames()[0]); -} diff --git a/libs/shared/graph-layouts/node_modules/events/tests/events-once.js b/libs/shared/graph-layouts/node_modules/events/tests/events-once.js deleted file mode 100644 index dae864963..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/events-once.js +++ /dev/null @@ -1,234 +0,0 @@ -'use strict'; - -var common = require('./common'); -var EventEmitter = require('../').EventEmitter; -var once = require('../').once; -var has = require('has'); -var assert = require('assert'); - -function Event(type) { - this.type = type; -} - -function EventTargetMock() { - this.events = {}; - - this.addEventListener = common.mustCall(this.addEventListener); - this.removeEventListener = common.mustCall(this.removeEventListener); -} - -EventTargetMock.prototype.addEventListener = function addEventListener(name, listener, options) { - if (!(name in this.events)) { - this.events[name] = { listeners: [], options: options || {} } - } - this.events[name].listeners.push(listener); -}; - -EventTargetMock.prototype.removeEventListener = function removeEventListener(name, callback) { - if (!(name in this.events)) { - return; - } - var event = this.events[name]; - var stack = event.listeners; - - for (var i = 0, l = stack.length; i < l; i++) { - if (stack[i] === callback) { - stack.splice(i, 1); - if (stack.length === 0) { - delete this.events[name]; - } - return; - } - } -}; - -EventTargetMock.prototype.dispatchEvent = function dispatchEvent(arg) { - if (!(arg.type in this.events)) { - return true; - } - - var event = this.events[arg.type]; - var stack = event.listeners.slice(); - - for (var i = 0, l = stack.length; i < l; i++) { - stack[i].call(null, arg); - if (event.options.once) { - this.removeEventListener(arg.type, stack[i]); - } - } - return !arg.defaultPrevented; -}; - -function onceAnEvent() { - var ee = new EventEmitter(); - - process.nextTick(function () { - ee.emit('myevent', 42); - }); - - return once(ee, 'myevent').then(function (args) { - var value = args[0] - assert.strictEqual(value, 42); - assert.strictEqual(ee.listenerCount('error'), 0); - assert.strictEqual(ee.listenerCount('myevent'), 0); - }); -} - -function onceAnEventWithTwoArgs() { - var ee = new EventEmitter(); - - process.nextTick(function () { - ee.emit('myevent', 42, 24); - }); - - return once(ee, 'myevent').then(function (value) { - assert.strictEqual(value.length, 2); - assert.strictEqual(value[0], 42); - assert.strictEqual(value[1], 24); - }); -} - -function catchesErrors() { - var ee = new EventEmitter(); - - var expected = new Error('kaboom'); - var err; - process.nextTick(function () { - ee.emit('error', expected); - }); - - return once(ee, 'myevent').then(function () { - throw new Error('should reject') - }, function (err) { - assert.strictEqual(err, expected); - assert.strictEqual(ee.listenerCount('error'), 0); - assert.strictEqual(ee.listenerCount('myevent'), 0); - }); -} - -function stopListeningAfterCatchingError() { - var ee = new EventEmitter(); - - var expected = new Error('kaboom'); - var err; - process.nextTick(function () { - ee.emit('error', expected); - ee.emit('myevent', 42, 24); - }); - - // process.on('multipleResolves', common.mustNotCall()); - - return once(ee, 'myevent').then(common.mustNotCall, function (err) { - // process.removeAllListeners('multipleResolves'); - assert.strictEqual(err, expected); - assert.strictEqual(ee.listenerCount('error'), 0); - assert.strictEqual(ee.listenerCount('myevent'), 0); - }); -} - -function onceError() { - var ee = new EventEmitter(); - - var expected = new Error('kaboom'); - process.nextTick(function () { - ee.emit('error', expected); - }); - - var promise = once(ee, 'error'); - assert.strictEqual(ee.listenerCount('error'), 1); - return promise.then(function (args) { - var err = args[0] - assert.strictEqual(err, expected); - assert.strictEqual(ee.listenerCount('error'), 0); - assert.strictEqual(ee.listenerCount('myevent'), 0); - }); -} - -function onceWithEventTarget() { - var et = new EventTargetMock(); - var event = new Event('myevent'); - process.nextTick(function () { - et.dispatchEvent(event); - }); - return once(et, 'myevent').then(function (args) { - var value = args[0]; - assert.strictEqual(value, event); - assert.strictEqual(has(et.events, 'myevent'), false); - }); -} - -function onceWithEventTargetError() { - var et = new EventTargetMock(); - var error = new Event('error'); - process.nextTick(function () { - et.dispatchEvent(error); - }); - return once(et, 'error').then(function (args) { - var err = args[0]; - assert.strictEqual(err, error); - assert.strictEqual(has(et.events, 'error'), false); - }); -} - -function prioritizesEventEmitter() { - var ee = new EventEmitter(); - ee.addEventListener = assert.fail; - ee.removeAllListeners = assert.fail; - process.nextTick(function () { - ee.emit('foo'); - }); - return once(ee, 'foo'); -} - -var allTests = [ - onceAnEvent(), - onceAnEventWithTwoArgs(), - catchesErrors(), - stopListeningAfterCatchingError(), - onceError(), - onceWithEventTarget(), - onceWithEventTargetError(), - prioritizesEventEmitter() -]; - -var hasBrowserEventTarget = false; -try { - hasBrowserEventTarget = typeof (new window.EventTarget().addEventListener) === 'function' && - new window.Event('xyz').type === 'xyz'; -} catch (err) {} - -if (hasBrowserEventTarget) { - var onceWithBrowserEventTarget = function onceWithBrowserEventTarget() { - var et = new window.EventTarget(); - var event = new window.Event('myevent'); - process.nextTick(function () { - et.dispatchEvent(event); - }); - return once(et, 'myevent').then(function (args) { - var value = args[0]; - assert.strictEqual(value, event); - assert.strictEqual(has(et.events, 'myevent'), false); - }); - } - - var onceWithBrowserEventTargetError = function onceWithBrowserEventTargetError() { - var et = new window.EventTarget(); - var error = new window.Event('error'); - process.nextTick(function () { - et.dispatchEvent(error); - }); - return once(et, 'error').then(function (args) { - var err = args[0]; - assert.strictEqual(err, error); - assert.strictEqual(has(et.events, 'error'), false); - }); - } - - common.test.comment('Testing with browser built-in EventTarget'); - allTests.push([ - onceWithBrowserEventTarget(), - onceWithBrowserEventTargetError() - ]); -} - -module.exports = Promise.all(allTests); diff --git a/libs/shared/graph-layouts/node_modules/events/tests/index.js b/libs/shared/graph-layouts/node_modules/events/tests/index.js deleted file mode 100644 index 2d739e670..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/index.js +++ /dev/null @@ -1,64 +0,0 @@ -var test = require('tape'); -var functionsHaveNames = require('functions-have-names'); -var hasSymbols = require('has-symbols'); - -require('./legacy-compat'); -var common = require('./common'); - -// we do this to easily wrap each file in a mocha test -// and also have browserify be able to statically analyze this file -var orig_require = require; -var require = function(file) { - test(file, function(t) { - // Store the tape object so tests can access it. - t.on('end', function () { delete common.test; }); - common.test = t; - - try { - var exp = orig_require(file); - if (exp && exp.then) { - exp.then(function () { t.end(); }, t.fail); - return; - } - } catch (err) { - t.fail(err); - } - t.end(); - }); -}; - -require('./add-listeners.js'); -require('./check-listener-leaks.js'); -require('./errors.js'); -require('./events-list.js'); -if (typeof Promise === 'function') { - require('./events-once.js'); -} else { - // Promise support is not available. - test('./events-once.js', { skip: true }, function () {}); -} -require('./listener-count.js'); -require('./listeners-side-effects.js'); -require('./listeners.js'); -require('./max-listeners.js'); -if (functionsHaveNames()) { - require('./method-names.js'); -} else { - // Function.name is not supported in IE - test('./method-names.js', { skip: true }, function () {}); -} -require('./modify-in-emit.js'); -require('./num-args.js'); -require('./once.js'); -require('./prepend.js'); -require('./set-max-listeners-side-effects.js'); -require('./special-event-names.js'); -require('./subclass.js'); -if (hasSymbols()) { - require('./symbols.js'); -} else { - // Symbol is not available. - test('./symbols.js', { skip: true }, function () {}); -} -require('./remove-all-listeners.js'); -require('./remove-listeners.js'); diff --git a/libs/shared/graph-layouts/node_modules/events/tests/legacy-compat.js b/libs/shared/graph-layouts/node_modules/events/tests/legacy-compat.js deleted file mode 100644 index a402be6e2..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/legacy-compat.js +++ /dev/null @@ -1,16 +0,0 @@ -// sigh... life is hard -if (!global.console) { - console = {} -} - -var fns = ['log', 'error', 'trace']; -for (var i=0 ; i<fns.length ; ++i) { - var fn = fns[i]; - if (!console[fn]) { - console[fn] = function() {}; - } -} - -if (!Array.isArray) { - Array.isArray = require('isarray'); -} diff --git a/libs/shared/graph-layouts/node_modules/events/tests/listener-count.js b/libs/shared/graph-layouts/node_modules/events/tests/listener-count.js deleted file mode 100644 index 9d422d872..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/listener-count.js +++ /dev/null @@ -1,37 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. - -require('./common'); -var assert = require('assert'); -var EventEmitter = require('../'); - -var emitter = new EventEmitter(); -emitter.on('foo', function() {}); -emitter.on('foo', function() {}); -emitter.on('baz', function() {}); -// Allow any type -emitter.on(123, function() {}); - -assert.strictEqual(EventEmitter.listenerCount(emitter, 'foo'), 2); -assert.strictEqual(emitter.listenerCount('foo'), 2); -assert.strictEqual(emitter.listenerCount('bar'), 0); -assert.strictEqual(emitter.listenerCount('baz'), 1); -assert.strictEqual(emitter.listenerCount(123), 1); diff --git a/libs/shared/graph-layouts/node_modules/events/tests/listeners-side-effects.js b/libs/shared/graph-layouts/node_modules/events/tests/listeners-side-effects.js deleted file mode 100644 index 180f83312..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/listeners-side-effects.js +++ /dev/null @@ -1,56 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. - -require('./common'); -var assert = require('assert'); - -var EventEmitter = require('../').EventEmitter; - -var e = new EventEmitter(); -var fl; // foo listeners - -fl = e.listeners('foo'); -assert.ok(Array.isArray(fl)); -assert.strictEqual(fl.length, 0); -if (Object.create) assert.ok(!(e._events instanceof Object)); -assert.strictEqual(Object.keys(e._events).length, 0); - -e.on('foo', assert.fail); -fl = e.listeners('foo'); -assert.strictEqual(e._events.foo, assert.fail); -assert.ok(Array.isArray(fl)); -assert.strictEqual(fl.length, 1); -assert.strictEqual(fl[0], assert.fail); - -e.listeners('bar'); - -e.on('foo', assert.ok); -fl = e.listeners('foo'); - -assert.ok(Array.isArray(e._events.foo)); -assert.strictEqual(e._events.foo.length, 2); -assert.strictEqual(e._events.foo[0], assert.fail); -assert.strictEqual(e._events.foo[1], assert.ok); - -assert.ok(Array.isArray(fl)); -assert.strictEqual(fl.length, 2); -assert.strictEqual(fl[0], assert.fail); -assert.strictEqual(fl[1], assert.ok); diff --git a/libs/shared/graph-layouts/node_modules/events/tests/listeners.js b/libs/shared/graph-layouts/node_modules/events/tests/listeners.js deleted file mode 100644 index 1909d2dfe..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/listeners.js +++ /dev/null @@ -1,168 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. - -require('./common'); -var assert = require('assert'); -var events = require('../'); -var util = require('util'); - -function listener() {} -function listener2() {} -function listener3() { - return 0; -} -function listener4() { - return 1; -} - -function TestStream() {} -util.inherits(TestStream, events.EventEmitter); - -{ - var ee = new events.EventEmitter(); - ee.on('foo', listener); - var fooListeners = ee.listeners('foo'); - - var listeners = ee.listeners('foo'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 1); - assert.strictEqual(listeners[0], listener); - - ee.removeAllListeners('foo'); - listeners = ee.listeners('foo'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 0); - - assert.ok(Array.isArray(fooListeners)); - assert.strictEqual(fooListeners.length, 1); - assert.strictEqual(fooListeners[0], listener); -} - -{ - var ee = new events.EventEmitter(); - ee.on('foo', listener); - - var eeListenersCopy = ee.listeners('foo'); - assert.ok(Array.isArray(eeListenersCopy)); - assert.strictEqual(eeListenersCopy.length, 1); - assert.strictEqual(eeListenersCopy[0], listener); - - var listeners = ee.listeners('foo'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 1); - assert.strictEqual(listeners[0], listener); - - eeListenersCopy.push(listener2); - listeners = ee.listeners('foo'); - - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 1); - assert.strictEqual(listeners[0], listener); - - assert.strictEqual(eeListenersCopy.length, 2); - assert.strictEqual(eeListenersCopy[0], listener); - assert.strictEqual(eeListenersCopy[1], listener2); -} - -{ - var ee = new events.EventEmitter(); - ee.on('foo', listener); - var eeListenersCopy = ee.listeners('foo'); - ee.on('foo', listener2); - - var listeners = ee.listeners('foo'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 2); - assert.strictEqual(listeners[0], listener); - assert.strictEqual(listeners[1], listener2); - - assert.ok(Array.isArray(eeListenersCopy)); - assert.strictEqual(eeListenersCopy.length, 1); - assert.strictEqual(eeListenersCopy[0], listener); -} - -{ - var ee = new events.EventEmitter(); - ee.once('foo', listener); - var listeners = ee.listeners('foo'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 1); - assert.strictEqual(listeners[0], listener); -} - -{ - var ee = new events.EventEmitter(); - ee.on('foo', listener); - ee.once('foo', listener2); - - var listeners = ee.listeners('foo'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 2); - assert.strictEqual(listeners[0], listener); - assert.strictEqual(listeners[1], listener2); -} - -{ - var ee = new events.EventEmitter(); - ee._events = undefined; - var listeners = ee.listeners('foo'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 0); -} - -{ - var s = new TestStream(); - var listeners = s.listeners('foo'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 0); -} - - -{ - var ee = new events.EventEmitter(); - ee.on('foo', listener); - var wrappedListener = ee.rawListeners('foo'); - assert.strictEqual(wrappedListener.length, 1); - assert.strictEqual(wrappedListener[0], listener); - assert.notStrictEqual(wrappedListener, ee.rawListeners('foo')); - ee.once('foo', listener); - var wrappedListeners = ee.rawListeners('foo'); - assert.strictEqual(wrappedListeners.length, 2); - assert.strictEqual(wrappedListeners[0], listener); - assert.notStrictEqual(wrappedListeners[1], listener); - assert.strictEqual(wrappedListeners[1].listener, listener); - assert.notStrictEqual(wrappedListeners, ee.rawListeners('foo')); - ee.emit('foo'); - assert.strictEqual(wrappedListeners.length, 2); - assert.strictEqual(wrappedListeners[1].listener, listener); -} - -{ - var ee = new events.EventEmitter(); - ee.once('foo', listener3); - ee.on('foo', listener4); - var rawListeners = ee.rawListeners('foo'); - assert.strictEqual(rawListeners.length, 2); - assert.strictEqual(rawListeners[0](), 0); - var rawListener = ee.rawListeners('foo'); - assert.strictEqual(rawListener.length, 1); - assert.strictEqual(rawListener[0](), 1); -} diff --git a/libs/shared/graph-layouts/node_modules/events/tests/max-listeners.js b/libs/shared/graph-layouts/node_modules/events/tests/max-listeners.js deleted file mode 100644 index 0b4395385..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/max-listeners.js +++ /dev/null @@ -1,47 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. - -var common = require('./common'); -var assert = require('assert'); -var events = require('../'); -var e = new events.EventEmitter(); - -var hasDefineProperty = !!Object.defineProperty; -try { Object.defineProperty({}, 'x', { value: 0 }); } catch (err) { hasDefineProperty = false } - -e.on('maxListeners', common.mustCall()); - -// Should not corrupt the 'maxListeners' queue. -e.setMaxListeners(42); - -var throwsObjs = [NaN, -1, 'and even this']; -var maxError = /^RangeError: The value of "n" is out of range\. It must be a non-negative number\./; -var defError = /^RangeError: The value of "defaultMaxListeners" is out of range\. It must be a non-negative number\./; - -for (var i = 0; i < throwsObjs.length; i++) { - var obj = throwsObjs[i]; - assert.throws(function() { e.setMaxListeners(obj); }, maxError); - if (hasDefineProperty) { - assert.throws(function() { events.defaultMaxListeners = obj; }, defError); - } -} - -e.emit('maxListeners'); diff --git a/libs/shared/graph-layouts/node_modules/events/tests/method-names.js b/libs/shared/graph-layouts/node_modules/events/tests/method-names.js deleted file mode 100644 index 364a161fe..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/method-names.js +++ /dev/null @@ -1,35 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. - -'use strict'; -require('./common'); -var assert = require('assert'); -var events = require('../'); - -var E = events.EventEmitter.prototype; -assert.strictEqual(E.constructor.name, 'EventEmitter'); -assert.strictEqual(E.on, E.addListener); // Same method. -assert.strictEqual(E.off, E.removeListener); // Same method. -Object.getOwnPropertyNames(E).forEach(function(name) { - if (name === 'constructor' || name === 'on' || name === 'off') return; - if (typeof E[name] !== 'function') return; - assert.strictEqual(E[name].name, name); -}); diff --git a/libs/shared/graph-layouts/node_modules/events/tests/modify-in-emit.js b/libs/shared/graph-layouts/node_modules/events/tests/modify-in-emit.js deleted file mode 100644 index 53fa63395..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/modify-in-emit.js +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. - -require('./common'); -var assert = require('assert'); -var events = require('../'); - -var callbacks_called = []; - -var e = new events.EventEmitter(); - -function callback1() { - callbacks_called.push('callback1'); - e.on('foo', callback2); - e.on('foo', callback3); - e.removeListener('foo', callback1); -} - -function callback2() { - callbacks_called.push('callback2'); - e.removeListener('foo', callback2); -} - -function callback3() { - callbacks_called.push('callback3'); - e.removeListener('foo', callback3); -} - -e.on('foo', callback1); -assert.strictEqual(e.listeners('foo').length, 1); - -e.emit('foo'); -assert.strictEqual(e.listeners('foo').length, 2); -assert.ok(Array.isArray(callbacks_called)); -assert.strictEqual(callbacks_called.length, 1); -assert.strictEqual(callbacks_called[0], 'callback1'); - -e.emit('foo'); -assert.strictEqual(e.listeners('foo').length, 0); -assert.ok(Array.isArray(callbacks_called)); -assert.strictEqual(callbacks_called.length, 3); -assert.strictEqual(callbacks_called[0], 'callback1'); -assert.strictEqual(callbacks_called[1], 'callback2'); -assert.strictEqual(callbacks_called[2], 'callback3'); - -e.emit('foo'); -assert.strictEqual(e.listeners('foo').length, 0); -assert.ok(Array.isArray(callbacks_called)); -assert.strictEqual(callbacks_called.length, 3); -assert.strictEqual(callbacks_called[0], 'callback1'); -assert.strictEqual(callbacks_called[1], 'callback2'); -assert.strictEqual(callbacks_called[2], 'callback3'); - -e.on('foo', callback1); -e.on('foo', callback2); -assert.strictEqual(e.listeners('foo').length, 2); -e.removeAllListeners('foo'); -assert.strictEqual(e.listeners('foo').length, 0); - -// Verify that removing callbacks while in emit allows emits to propagate to -// all listeners -callbacks_called = []; - -e.on('foo', callback2); -e.on('foo', callback3); -assert.strictEqual(2, e.listeners('foo').length); -e.emit('foo'); -assert.ok(Array.isArray(callbacks_called)); -assert.strictEqual(callbacks_called.length, 2); -assert.strictEqual(callbacks_called[0], 'callback2'); -assert.strictEqual(callbacks_called[1], 'callback3'); -assert.strictEqual(0, e.listeners('foo').length); diff --git a/libs/shared/graph-layouts/node_modules/events/tests/num-args.js b/libs/shared/graph-layouts/node_modules/events/tests/num-args.js deleted file mode 100644 index c9b0deb9c..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/num-args.js +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. - -require('./common'); -var assert = require('assert'); -var events = require('../'); - -var e = new events.EventEmitter(); -var num_args_emitted = []; - -e.on('numArgs', function() { - var numArgs = arguments.length; - num_args_emitted.push(numArgs); -}); - -e.on('foo', function() { - num_args_emitted.push(arguments.length); -}); - -e.on('foo', function() { - num_args_emitted.push(arguments.length); -}); - -e.emit('numArgs'); -e.emit('numArgs', null); -e.emit('numArgs', null, null); -e.emit('numArgs', null, null, null); -e.emit('numArgs', null, null, null, null); -e.emit('numArgs', null, null, null, null, null); - -e.emit('foo', null, null, null, null); - -assert.ok(Array.isArray(num_args_emitted)); -assert.strictEqual(num_args_emitted.length, 8); -assert.strictEqual(num_args_emitted[0], 0); -assert.strictEqual(num_args_emitted[1], 1); -assert.strictEqual(num_args_emitted[2], 2); -assert.strictEqual(num_args_emitted[3], 3); -assert.strictEqual(num_args_emitted[4], 4); -assert.strictEqual(num_args_emitted[5], 5); -assert.strictEqual(num_args_emitted[6], 4); -assert.strictEqual(num_args_emitted[6], 4); diff --git a/libs/shared/graph-layouts/node_modules/events/tests/once.js b/libs/shared/graph-layouts/node_modules/events/tests/once.js deleted file mode 100644 index 4b36c055e..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/once.js +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. - -var common = require('./common'); -var assert = require('assert'); -var EventEmitter = require('../'); - -var e = new EventEmitter(); - -e.once('hello', common.mustCall()); - -e.emit('hello', 'a', 'b'); -e.emit('hello', 'a', 'b'); -e.emit('hello', 'a', 'b'); -e.emit('hello', 'a', 'b'); - -function remove() { - assert.fail('once->foo should not be emitted'); -} - -e.once('foo', remove); -e.removeListener('foo', remove); -e.emit('foo'); - -e.once('e', common.mustCall(function() { - e.emit('e'); -})); - -e.once('e', common.mustCall()); - -e.emit('e'); - -// Verify that the listener must be a function -assert.throws(function() { - var ee = new EventEmitter(); - - ee.once('foo', null); -}, /^TypeError: The "listener" argument must be of type Function. Received type object$/); - -{ - // once() has different code paths based on the number of arguments being - // emitted. Verify that all of the cases are covered. - var maxArgs = 4; - - for (var i = 0; i <= maxArgs; ++i) { - var ee = new EventEmitter(); - var args = ['foo']; - - for (var j = 0; j < i; ++j) - args.push(j); - - ee.once('foo', common.mustCall(function() { - var params = Array.prototype.slice.call(arguments); - var restArgs = args.slice(1); - assert.ok(Array.isArray(params)); - assert.strictEqual(params.length, restArgs.length); - for (var index = 0; index < params.length; index++) { - var param = params[index]; - assert.strictEqual(param, restArgs[index]); - } - })); - - EventEmitter.prototype.emit.apply(ee, args); - } -} diff --git a/libs/shared/graph-layouts/node_modules/events/tests/prepend.js b/libs/shared/graph-layouts/node_modules/events/tests/prepend.js deleted file mode 100644 index 79afde0bf..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/prepend.js +++ /dev/null @@ -1,31 +0,0 @@ -'use strict'; - -var common = require('./common'); -var EventEmitter = require('../'); -var assert = require('assert'); - -var myEE = new EventEmitter(); -var m = 0; -// This one comes last. -myEE.on('foo', common.mustCall(function () { - assert.strictEqual(m, 2); -})); - -// This one comes second. -myEE.prependListener('foo', common.mustCall(function () { - assert.strictEqual(m++, 1); -})); - -// This one comes first. -myEE.prependOnceListener('foo', - common.mustCall(function () { - assert.strictEqual(m++, 0); - })); - -myEE.emit('foo'); - -// Verify that the listener must be a function -assert.throws(function () { - var ee = new EventEmitter(); - ee.prependOnceListener('foo', null); -}, 'TypeError: The "listener" argument must be of type Function. Received type object'); diff --git a/libs/shared/graph-layouts/node_modules/events/tests/remove-all-listeners.js b/libs/shared/graph-layouts/node_modules/events/tests/remove-all-listeners.js deleted file mode 100644 index 622941cfa..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/remove-all-listeners.js +++ /dev/null @@ -1,133 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. - -var common = require('./common'); -var assert = require('assert'); -var events = require('../'); -var test = require('tape'); - -function expect(expected) { - var actual = []; - test.onFinish(function() { - var sortedActual = actual.sort(); - var sortedExpected = expected.sort(); - assert.strictEqual(sortedActual.length, sortedExpected.length); - for (var index = 0; index < sortedActual.length; index++) { - var value = sortedActual[index]; - assert.strictEqual(value, sortedExpected[index]); - } - }); - function listener(name) { - actual.push(name); - } - return common.mustCall(listener, expected.length); -} - -{ - var ee = new events.EventEmitter(); - var noop = common.mustNotCall(); - ee.on('foo', noop); - ee.on('bar', noop); - ee.on('baz', noop); - ee.on('baz', noop); - var fooListeners = ee.listeners('foo'); - var barListeners = ee.listeners('bar'); - var bazListeners = ee.listeners('baz'); - ee.on('removeListener', expect(['bar', 'baz', 'baz'])); - ee.removeAllListeners('bar'); - ee.removeAllListeners('baz'); - - var listeners = ee.listeners('foo'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 1); - assert.strictEqual(listeners[0], noop); - - listeners = ee.listeners('bar'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 0); - listeners = ee.listeners('baz'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 0); - // After calling removeAllListeners(), - // the old listeners array should stay unchanged. - assert.strictEqual(fooListeners.length, 1); - assert.strictEqual(fooListeners[0], noop); - assert.strictEqual(barListeners.length, 1); - assert.strictEqual(barListeners[0], noop); - assert.strictEqual(bazListeners.length, 2); - assert.strictEqual(bazListeners[0], noop); - assert.strictEqual(bazListeners[1], noop); - // After calling removeAllListeners(), - // new listeners arrays is different from the old. - assert.notStrictEqual(ee.listeners('bar'), barListeners); - assert.notStrictEqual(ee.listeners('baz'), bazListeners); -} - -{ - var ee = new events.EventEmitter(); - ee.on('foo', common.mustNotCall()); - ee.on('bar', common.mustNotCall()); - // Expect LIFO order - ee.on('removeListener', expect(['foo', 'bar', 'removeListener'])); - ee.on('removeListener', expect(['foo', 'bar'])); - ee.removeAllListeners(); - - var listeners = ee.listeners('foo'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 0); - listeners = ee.listeners('bar'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 0); -} - -{ - var ee = new events.EventEmitter(); - ee.on('removeListener', common.mustNotCall()); - // Check for regression where removeAllListeners() throws when - // there exists a 'removeListener' listener, but there exists - // no listeners for the provided event type. - assert.doesNotThrow(function () { ee.removeAllListeners(ee, 'foo') }); -} - -{ - var ee = new events.EventEmitter(); - var expectLength = 2; - ee.on('removeListener', function() { - assert.strictEqual(expectLength--, this.listeners('baz').length); - }); - ee.on('baz', common.mustNotCall()); - ee.on('baz', common.mustNotCall()); - ee.on('baz', common.mustNotCall()); - assert.strictEqual(ee.listeners('baz').length, expectLength + 1); - ee.removeAllListeners('baz'); - assert.strictEqual(ee.listeners('baz').length, 0); -} - -{ - var ee = new events.EventEmitter(); - assert.strictEqual(ee, ee.removeAllListeners()); -} - -{ - var ee = new events.EventEmitter(); - ee._events = undefined; - assert.strictEqual(ee, ee.removeAllListeners()); -} diff --git a/libs/shared/graph-layouts/node_modules/events/tests/remove-listeners.js b/libs/shared/graph-layouts/node_modules/events/tests/remove-listeners.js deleted file mode 100644 index 18e4d1651..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/remove-listeners.js +++ /dev/null @@ -1,212 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. - -var common = require('./common'); -var assert = require('assert'); -var EventEmitter = require('../'); - -var listener1 = function listener1() {}; -var listener2 = function listener2() {}; - -{ - var ee = new EventEmitter(); - ee.on('hello', listener1); - ee.on('removeListener', common.mustCall(function(name, cb) { - assert.strictEqual(name, 'hello'); - assert.strictEqual(cb, listener1); - })); - ee.removeListener('hello', listener1); - var listeners = ee.listeners('hello'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 0); -} - -{ - var ee = new EventEmitter(); - ee.on('hello', listener1); - ee.on('removeListener', common.mustNotCall()); - ee.removeListener('hello', listener2); - - var listeners = ee.listeners('hello'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 1); - assert.strictEqual(listeners[0], listener1); -} - -{ - var ee = new EventEmitter(); - ee.on('hello', listener1); - ee.on('hello', listener2); - - var listeners; - ee.once('removeListener', common.mustCall(function(name, cb) { - assert.strictEqual(name, 'hello'); - assert.strictEqual(cb, listener1); - listeners = ee.listeners('hello'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 1); - assert.strictEqual(listeners[0], listener2); - })); - ee.removeListener('hello', listener1); - listeners = ee.listeners('hello'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 1); - assert.strictEqual(listeners[0], listener2); - ee.once('removeListener', common.mustCall(function(name, cb) { - assert.strictEqual(name, 'hello'); - assert.strictEqual(cb, listener2); - listeners = ee.listeners('hello'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 0); - })); - ee.removeListener('hello', listener2); - listeners = ee.listeners('hello'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 0); -} - -{ - var ee = new EventEmitter(); - - function remove1() { - assert.fail('remove1 should not have been called'); - } - - function remove2() { - assert.fail('remove2 should not have been called'); - } - - ee.on('removeListener', common.mustCall(function(name, cb) { - if (cb !== remove1) return; - this.removeListener('quux', remove2); - this.emit('quux'); - }, 2)); - ee.on('quux', remove1); - ee.on('quux', remove2); - ee.removeListener('quux', remove1); -} - -{ - var ee = new EventEmitter(); - ee.on('hello', listener1); - ee.on('hello', listener2); - - var listeners; - ee.once('removeListener', common.mustCall(function(name, cb) { - assert.strictEqual(name, 'hello'); - assert.strictEqual(cb, listener1); - listeners = ee.listeners('hello'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 1); - assert.strictEqual(listeners[0], listener2); - ee.once('removeListener', common.mustCall(function(name, cb) { - assert.strictEqual(name, 'hello'); - assert.strictEqual(cb, listener2); - listeners = ee.listeners('hello'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 0); - })); - ee.removeListener('hello', listener2); - listeners = ee.listeners('hello'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 0); - })); - ee.removeListener('hello', listener1); - listeners = ee.listeners('hello'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 0); -} - -{ - var ee = new EventEmitter(); - var listener3 = common.mustCall(function() { - ee.removeListener('hello', listener4); - }, 2); - var listener4 = common.mustCall(); - - ee.on('hello', listener3); - ee.on('hello', listener4); - - // listener4 will still be called although it is removed by listener 3. - ee.emit('hello'); - // This is so because the interal listener array at time of emit - // was [listener3,listener4] - - // Interal listener array [listener3] - ee.emit('hello'); -} - -{ - var ee = new EventEmitter(); - - ee.once('hello', listener1); - ee.on('removeListener', common.mustCall(function(eventName, listener) { - assert.strictEqual(eventName, 'hello'); - assert.strictEqual(listener, listener1); - })); - ee.emit('hello'); -} - -{ - var ee = new EventEmitter(); - - assert.strictEqual(ee, ee.removeListener('foo', function() {})); -} - -// Verify that the removed listener must be a function -assert.throws(function() { - var ee = new EventEmitter(); - - ee.removeListener('foo', null); -}, /^TypeError: The "listener" argument must be of type Function\. Received type object$/); - -{ - var ee = new EventEmitter(); - var listener = function() {}; - ee._events = undefined; - var e = ee.removeListener('foo', listener); - assert.strictEqual(e, ee); -} - -{ - var ee = new EventEmitter(); - - ee.on('foo', listener1); - ee.on('foo', listener2); - var listeners = ee.listeners('foo'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 2); - assert.strictEqual(listeners[0], listener1); - assert.strictEqual(listeners[1], listener2); - - ee.removeListener('foo', listener1); - assert.strictEqual(ee._events.foo, listener2); - - ee.on('foo', listener1); - listeners = ee.listeners('foo'); - assert.ok(Array.isArray(listeners)); - assert.strictEqual(listeners.length, 2); - assert.strictEqual(listeners[0], listener2); - assert.strictEqual(listeners[1], listener1); - - ee.removeListener('foo', listener1); - assert.strictEqual(ee._events.foo, listener2); -} diff --git a/libs/shared/graph-layouts/node_modules/events/tests/set-max-listeners-side-effects.js b/libs/shared/graph-layouts/node_modules/events/tests/set-max-listeners-side-effects.js deleted file mode 100644 index 13dbb671e..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/set-max-listeners-side-effects.js +++ /dev/null @@ -1,31 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. - -require('./common'); -var assert = require('assert'); -var events = require('../'); - -var e = new events.EventEmitter(); - -if (Object.create) assert.ok(!(e._events instanceof Object)); -assert.strictEqual(Object.keys(e._events).length, 0); -e.setMaxListeners(5); -assert.strictEqual(Object.keys(e._events).length, 0); diff --git a/libs/shared/graph-layouts/node_modules/events/tests/special-event-names.js b/libs/shared/graph-layouts/node_modules/events/tests/special-event-names.js deleted file mode 100644 index a2f0b744a..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/special-event-names.js +++ /dev/null @@ -1,45 +0,0 @@ -'use strict'; - -var common = require('./common'); -var EventEmitter = require('../'); -var assert = require('assert'); - -var ee = new EventEmitter(); -var handler = function() {}; - -assert.strictEqual(ee.eventNames().length, 0); - -assert.strictEqual(ee._events.hasOwnProperty, undefined); -assert.strictEqual(ee._events.toString, undefined); - -ee.on('__defineGetter__', handler); -ee.on('toString', handler); -ee.on('__proto__', handler); - -assert.strictEqual(ee.eventNames()[0], '__defineGetter__'); -assert.strictEqual(ee.eventNames()[1], 'toString'); - -assert.strictEqual(ee.listeners('__defineGetter__').length, 1); -assert.strictEqual(ee.listeners('__defineGetter__')[0], handler); -assert.strictEqual(ee.listeners('toString').length, 1); -assert.strictEqual(ee.listeners('toString')[0], handler); - -// Only run __proto__ tests if that property can actually be set -if ({ __proto__: 'ok' }.__proto__ === 'ok') { - assert.strictEqual(ee.eventNames().length, 3); - assert.strictEqual(ee.eventNames()[2], '__proto__'); - assert.strictEqual(ee.listeners('__proto__').length, 1); - assert.strictEqual(ee.listeners('__proto__')[0], handler); - - ee.on('__proto__', common.mustCall(function(val) { - assert.strictEqual(val, 1); - })); - ee.emit('__proto__', 1); - - process.on('__proto__', common.mustCall(function(val) { - assert.strictEqual(val, 1); - })); - process.emit('__proto__', 1); -} else { - console.log('# skipped __proto__') -} diff --git a/libs/shared/graph-layouts/node_modules/events/tests/subclass.js b/libs/shared/graph-layouts/node_modules/events/tests/subclass.js deleted file mode 100644 index bd033fff4..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/subclass.js +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright Joyent, Inc. and other Node contributors. -// -// 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. - -var common = require('./common'); -var test = require('tape'); -var assert = require('assert'); -var EventEmitter = require('../').EventEmitter; -var util = require('util'); - -util.inherits(MyEE, EventEmitter); - -function MyEE(cb) { - this.once(1, cb); - this.emit(1); - this.removeAllListeners(); - EventEmitter.call(this); -} - -var myee = new MyEE(common.mustCall()); - - -util.inherits(ErrorEE, EventEmitter); -function ErrorEE() { - this.emit('error', new Error('blerg')); -} - -assert.throws(function() { - new ErrorEE(); -}, /blerg/); - -test.onFinish(function() { - assert.ok(!(myee._events instanceof Object)); - assert.strictEqual(Object.keys(myee._events).length, 0); -}); - - -function MyEE2() { - EventEmitter.call(this); -} - -MyEE2.prototype = new EventEmitter(); - -var ee1 = new MyEE2(); -var ee2 = new MyEE2(); - -ee1.on('x', function() {}); - -assert.strictEqual(ee2.listenerCount('x'), 0); diff --git a/libs/shared/graph-layouts/node_modules/events/tests/symbols.js b/libs/shared/graph-layouts/node_modules/events/tests/symbols.js deleted file mode 100644 index 0721f0ec0..000000000 --- a/libs/shared/graph-layouts/node_modules/events/tests/symbols.js +++ /dev/null @@ -1,25 +0,0 @@ -'use strict'; - -var common = require('./common'); -var EventEmitter = require('../'); -var assert = require('assert'); - -var ee = new EventEmitter(); -var foo = Symbol('foo'); -var listener = common.mustCall(); - -ee.on(foo, listener); -assert.strictEqual(ee.listeners(foo).length, 1); -assert.strictEqual(ee.listeners(foo)[0], listener); - -ee.emit(foo); - -ee.removeAllListeners(); -assert.strictEqual(ee.listeners(foo).length, 0); - -ee.on(foo, listener); -assert.strictEqual(ee.listeners(foo).length, 1); -assert.strictEqual(ee.listeners(foo)[0], listener); - -ee.removeListener(foo, listener); -assert.strictEqual(ee.listeners(foo).length, 0); diff --git a/libs/shared/graph-layouts/node_modules/graphology/LICENSE.txt b/libs/shared/graph-layouts/node_modules/graphology/LICENSE.txt deleted file mode 100644 index 158967c8d..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2016-2021 Guillaume Plique (Yomguithereal) - -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. diff --git a/libs/shared/graph-layouts/node_modules/graphology/README.md b/libs/shared/graph-layouts/node_modules/graphology/README.md deleted file mode 100644 index cb1dd4452..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# Graphology - -`graphology` is a specification for a robust & multipurpose JavaScript `Graph` object and aiming at supporting various kinds of graphs under a same unified interface. - -You will also find here the source for the reference implementation of this specification. - -## Documentation - -Full documentation for the library/specs is available [here](https://graphology.github.io). diff --git a/libs/shared/graph-layouts/node_modules/graphology/dist/graphology.cjs.js b/libs/shared/graph-layouts/node_modules/graphology/dist/graphology.cjs.js deleted file mode 100644 index 9bd8ac9c7..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/dist/graphology.cjs.js +++ /dev/null @@ -1,5463 +0,0 @@ -'use strict'; - -var events = require('events'); -var Iterator = require('obliterator/iterator'); -var take = require('obliterator/take'); -var chain = require('obliterator/chain'); - -function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; } - -var Iterator__default = /*#__PURE__*/_interopDefaultLegacy(Iterator); -var take__default = /*#__PURE__*/_interopDefaultLegacy(take); -var chain__default = /*#__PURE__*/_interopDefaultLegacy(chain); - -function _typeof(obj) { - "@babel/helpers - typeof"; - - return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { - return typeof obj; - } : function (obj) { - return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; - }, _typeof(obj); -} - -function _inheritsLoose(subClass, superClass) { - subClass.prototype = Object.create(superClass.prototype); - subClass.prototype.constructor = subClass; - - _setPrototypeOf(subClass, superClass); -} - -function _getPrototypeOf(o) { - _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { - return o.__proto__ || Object.getPrototypeOf(o); - }; - return _getPrototypeOf(o); -} - -function _setPrototypeOf(o, p) { - _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { - o.__proto__ = p; - return o; - }; - - return _setPrototypeOf(o, p); -} - -function _isNativeReflectConstruct() { - if (typeof Reflect === "undefined" || !Reflect.construct) return false; - if (Reflect.construct.sham) return false; - if (typeof Proxy === "function") return true; - - try { - Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); - return true; - } catch (e) { - return false; - } -} - -function _construct(Parent, args, Class) { - if (_isNativeReflectConstruct()) { - _construct = Reflect.construct; - } else { - _construct = function _construct(Parent, args, Class) { - var a = [null]; - a.push.apply(a, args); - var Constructor = Function.bind.apply(Parent, a); - var instance = new Constructor(); - if (Class) _setPrototypeOf(instance, Class.prototype); - return instance; - }; - } - - return _construct.apply(null, arguments); -} - -function _isNativeFunction(fn) { - return Function.toString.call(fn).indexOf("[native code]") !== -1; -} - -function _wrapNativeSuper(Class) { - var _cache = typeof Map === "function" ? new Map() : undefined; - - _wrapNativeSuper = function _wrapNativeSuper(Class) { - if (Class === null || !_isNativeFunction(Class)) return Class; - - if (typeof Class !== "function") { - throw new TypeError("Super expression must either be null or a function"); - } - - if (typeof _cache !== "undefined") { - if (_cache.has(Class)) return _cache.get(Class); - - _cache.set(Class, Wrapper); - } - - function Wrapper() { - return _construct(Class, arguments, _getPrototypeOf(this).constructor); - } - - Wrapper.prototype = Object.create(Class.prototype, { - constructor: { - value: Wrapper, - enumerable: false, - writable: true, - configurable: true - } - }); - return _setPrototypeOf(Wrapper, Class); - }; - - return _wrapNativeSuper(Class); -} - -function _assertThisInitialized(self) { - if (self === void 0) { - throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); - } - - return self; -} - -/** - * Graphology Utilities - * ===================== - * - * Collection of helpful functions used by the implementation. - */ - -/** - * Object.assign-like polyfill. - * - * @param {object} target - First object. - * @param {object} [...objects] - Objects to merge. - * @return {object} - */ -function assignPolyfill() { - var target = arguments[0]; - - for (var i = 1, l = arguments.length; i < l; i++) { - if (!arguments[i]) continue; - - for (var k in arguments[i]) { - target[k] = arguments[i][k]; - } - } - - return target; -} - -var assign = assignPolyfill; -if (typeof Object.assign === 'function') assign = Object.assign; -/** - * Function returning the first matching edge for given path. - * Note: this function does not check the existence of source & target. This - * must be performed by the caller. - * - * @param {Graph} graph - Target graph. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {string} type - Type of the edge (mixed, directed or undirected). - * @return {string|null} - */ - -function getMatchingEdge(graph, source, target, type) { - var sourceData = graph._nodes.get(source); - - var edge = null; - if (!sourceData) return edge; - - if (type === 'mixed') { - edge = sourceData.out && sourceData.out[target] || sourceData.undirected && sourceData.undirected[target]; - } else if (type === 'directed') { - edge = sourceData.out && sourceData.out[target]; - } else { - edge = sourceData.undirected && sourceData.undirected[target]; - } - - return edge; -} -/** - * Checks whether the given value is a Graph implementation instance. - * - * @param {mixed} value - Target value. - * @return {boolean} - */ - -function isGraph(value) { - return value !== null && _typeof(value) === 'object' && typeof value.addUndirectedEdgeWithKey === 'function' && typeof value.dropNode === 'function'; -} -/** - * Checks whether the given value is a plain object. - * - * @param {mixed} value - Target value. - * @return {boolean} - */ - -function isPlainObject(value) { - return _typeof(value) === 'object' && value !== null && value.constructor === Object; -} -/** - * Checks whether the given object is empty. - * - * @param {object} o - Target Object. - * @return {boolean} - */ - -function isEmpty(o) { - var k; - - for (k in o) { - return false; - } - - return true; -} -/** - * Creates a "private" property for the given member name by concealing it - * using the `enumerable` option. - * - * @param {object} target - Target object. - * @param {string} name - Member name. - */ - -function privateProperty(target, name, value) { - Object.defineProperty(target, name, { - enumerable: false, - configurable: false, - writable: true, - value: value - }); -} -/** - * Creates a read-only property for the given member name & the given getter. - * - * @param {object} target - Target object. - * @param {string} name - Member name. - * @param {mixed} value - The attached getter or fixed value. - */ - -function readOnlyProperty(target, name, value) { - var descriptor = { - enumerable: true, - configurable: true - }; - - if (typeof value === 'function') { - descriptor.get = value; - } else { - descriptor.value = value; - descriptor.writable = false; - } - - Object.defineProperty(target, name, descriptor); -} -/** - * Returns whether the given object constitute valid hints. - * - * @param {object} hints - Target object. - */ - -function validateHints(hints) { - if (!isPlainObject(hints)) return false; - if (hints.attributes && !Array.isArray(hints.attributes)) return false; - return true; -} -/** - * Creates a function generating incremental ids for edges. - * - * @return {function} - */ - -function incrementalIdStartingFromRandomByte() { - var i = Math.floor(Math.random() * 256) & 0xff; - return function () { - return i++; - }; -} - -/** - * Graphology Custom Errors - * ========================= - * - * Defining custom errors for ease of use & easy unit tests across - * implementations (normalized typology rather than relying on error - * messages to check whether the correct error was found). - */ -var GraphError = /*#__PURE__*/function (_Error) { - _inheritsLoose(GraphError, _Error); - - function GraphError(message) { - var _this; - - _this = _Error.call(this) || this; - _this.name = 'GraphError'; - _this.message = message; - return _this; - } - - return GraphError; -}( /*#__PURE__*/_wrapNativeSuper(Error)); -var InvalidArgumentsGraphError = /*#__PURE__*/function (_GraphError) { - _inheritsLoose(InvalidArgumentsGraphError, _GraphError); - - function InvalidArgumentsGraphError(message) { - var _this2; - - _this2 = _GraphError.call(this, message) || this; - _this2.name = 'InvalidArgumentsGraphError'; // This is V8 specific to enhance stack readability - - if (typeof Error.captureStackTrace === 'function') Error.captureStackTrace(_assertThisInitialized(_this2), InvalidArgumentsGraphError.prototype.constructor); - return _this2; - } - - return InvalidArgumentsGraphError; -}(GraphError); -var NotFoundGraphError = /*#__PURE__*/function (_GraphError2) { - _inheritsLoose(NotFoundGraphError, _GraphError2); - - function NotFoundGraphError(message) { - var _this3; - - _this3 = _GraphError2.call(this, message) || this; - _this3.name = 'NotFoundGraphError'; // This is V8 specific to enhance stack readability - - if (typeof Error.captureStackTrace === 'function') Error.captureStackTrace(_assertThisInitialized(_this3), NotFoundGraphError.prototype.constructor); - return _this3; - } - - return NotFoundGraphError; -}(GraphError); -var UsageGraphError = /*#__PURE__*/function (_GraphError3) { - _inheritsLoose(UsageGraphError, _GraphError3); - - function UsageGraphError(message) { - var _this4; - - _this4 = _GraphError3.call(this, message) || this; - _this4.name = 'UsageGraphError'; // This is V8 specific to enhance stack readability - - if (typeof Error.captureStackTrace === 'function') Error.captureStackTrace(_assertThisInitialized(_this4), UsageGraphError.prototype.constructor); - return _this4; - } - - return UsageGraphError; -}(GraphError); - -/** - * Graphology Internal Data Classes - * ================================= - * - * Internal classes hopefully reduced to structs by engines & storing - * necessary information for nodes & edges. - * - * Note that those classes don't rely on the `class` keyword to avoid some - * cruft introduced by most of ES2015 transpilers. - */ - -/** - * MixedNodeData class. - * - * @constructor - * @param {string} string - The node's key. - * @param {object} attributes - Node's attributes. - */ -function MixedNodeData(key, attributes) { - // Attributes - this.key = key; - this.attributes = attributes; - this.clear(); -} - -MixedNodeData.prototype.clear = function () { - // Degrees - this.inDegree = 0; - this.outDegree = 0; - this.undirectedDegree = 0; // Indices - - this["in"] = {}; - this.out = {}; - this.undirected = {}; -}; -/** - * DirectedNodeData class. - * - * @constructor - * @param {string} string - The node's key. - * @param {object} attributes - Node's attributes. - */ - - -function DirectedNodeData(key, attributes) { - // Attributes - this.key = key; - this.attributes = attributes; - this.clear(); -} - -DirectedNodeData.prototype.clear = function () { - // Degrees - this.inDegree = 0; - this.outDegree = 0; // Indices - - this["in"] = {}; - this.out = {}; -}; -/** - * UndirectedNodeData class. - * - * @constructor - * @param {string} string - The node's key. - * @param {object} attributes - Node's attributes. - */ - - -function UndirectedNodeData(key, attributes) { - // Attributes - this.key = key; - this.attributes = attributes; - this.clear(); -} - -UndirectedNodeData.prototype.clear = function () { - // Degrees - this.undirectedDegree = 0; // Indices - - this.undirected = {}; -}; -/** - * EdgeData class. - * - * @constructor - * @param {boolean} undirected - Whether the edge is undirected. - * @param {string} string - The edge's key. - * @param {string} source - Source of the edge. - * @param {string} target - Target of the edge. - * @param {object} attributes - Edge's attributes. - */ - - -function EdgeData(undirected, key, source, target, attributes) { - // Attributes - this.key = key; - this.attributes = attributes; - this.undirected = undirected; // Extremities - - this.source = source; - this.target = target; -} - -EdgeData.prototype.attach = function () { - var outKey = 'out'; - var inKey = 'in'; - if (this.undirected) outKey = inKey = 'undirected'; - var source = this.source.key; - var target = this.target.key; // Handling source - - this.source[outKey][target] = this; - if (this.undirected && source === target) return; // Handling target - - this.target[inKey][source] = this; -}; - -EdgeData.prototype.attachMulti = function () { - var outKey = 'out'; - var inKey = 'in'; - var source = this.source.key; - var target = this.target.key; - if (this.undirected) outKey = inKey = 'undirected'; // Handling source - - var adj = this.source[outKey]; - var head = adj[target]; - - if (typeof head === 'undefined') { - adj[target] = this; // Self-loop optimization - - if (!(this.undirected && source === target)) { - // Handling target - this.target[inKey][source] = this; - } - - return; - } // Prepending to doubly-linked list - - - head.previous = this; - this.next = head; // Pointing to new head - // NOTE: use mutating swap later to avoid lookup? - - adj[target] = this; - this.target[inKey][source] = this; -}; - -EdgeData.prototype.detach = function () { - var source = this.source.key; - var target = this.target.key; - var outKey = 'out'; - var inKey = 'in'; - if (this.undirected) outKey = inKey = 'undirected'; - delete this.source[outKey][target]; // No-op delete in case of undirected self-loop - - delete this.target[inKey][source]; -}; - -EdgeData.prototype.detachMulti = function () { - var source = this.source.key; - var target = this.target.key; - var outKey = 'out'; - var inKey = 'in'; - if (this.undirected) outKey = inKey = 'undirected'; // Deleting from doubly-linked list - - if (this.previous === undefined) { - // We are dealing with the head - // Should we delete the adjacency entry because it is now empty? - if (this.next === undefined) { - delete this.source[outKey][target]; // No-op delete in case of undirected self-loop - - delete this.target[inKey][source]; - } else { - // Detaching - this.next.previous = undefined; // NOTE: could avoid the lookups by creating a #.become mutating method - - this.source[outKey][target] = this.next; // No-op delete in case of undirected self-loop - - this.target[inKey][source] = this.next; - } - } else { - // We are dealing with another list node - this.previous.next = this.next; // If not last - - if (this.next !== undefined) { - this.next.previous = this.previous; - } - } -}; - -/** - * Graphology Node Attributes methods - * =================================== - */ -var NODE = 0; -var SOURCE = 1; -var TARGET = 2; -var OPPOSITE = 3; - -function findRelevantNodeData(graph, method, mode, nodeOrEdge, nameOrEdge, add1, add2) { - var nodeData, edgeData, arg1, arg2; - nodeOrEdge = '' + nodeOrEdge; - - if (mode === NODE) { - nodeData = graph._nodes.get(nodeOrEdge); - if (!nodeData) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(nodeOrEdge, "\" node in the graph.")); - arg1 = nameOrEdge; - arg2 = add1; - } else if (mode === OPPOSITE) { - nameOrEdge = '' + nameOrEdge; - edgeData = graph._edges.get(nameOrEdge); - if (!edgeData) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(nameOrEdge, "\" edge in the graph.")); - var source = edgeData.source.key; - var target = edgeData.target.key; - - if (nodeOrEdge === source) { - nodeData = edgeData.target; - } else if (nodeOrEdge === target) { - nodeData = edgeData.source; - } else { - throw new NotFoundGraphError("Graph.".concat(method, ": the \"").concat(nodeOrEdge, "\" node is not attached to the \"").concat(nameOrEdge, "\" edge (").concat(source, ", ").concat(target, ").")); - } - - arg1 = add1; - arg2 = add2; - } else { - edgeData = graph._edges.get(nodeOrEdge); - if (!edgeData) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(nodeOrEdge, "\" edge in the graph.")); - - if (mode === SOURCE) { - nodeData = edgeData.source; - } else { - nodeData = edgeData.target; - } - - arg1 = nameOrEdge; - arg2 = add1; - } - - return [nodeData, arg1, arg2]; -} - -function attachNodeAttributeGetter(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) { - var _findRelevantNodeData = findRelevantNodeData(this, method, mode, nodeOrEdge, nameOrEdge, add1), - data = _findRelevantNodeData[0], - name = _findRelevantNodeData[1]; - - return data.attributes[name]; - }; -} - -function attachNodeAttributesGetter(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge) { - var _findRelevantNodeData2 = findRelevantNodeData(this, method, mode, nodeOrEdge, nameOrEdge), - data = _findRelevantNodeData2[0]; - - return data.attributes; - }; -} - -function attachNodeAttributeChecker(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) { - var _findRelevantNodeData3 = findRelevantNodeData(this, method, mode, nodeOrEdge, nameOrEdge, add1), - data = _findRelevantNodeData3[0], - name = _findRelevantNodeData3[1]; - - return data.attributes.hasOwnProperty(name); - }; -} - -function attachNodeAttributeSetter(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1, add2) { - var _findRelevantNodeData4 = findRelevantNodeData(this, method, mode, nodeOrEdge, nameOrEdge, add1, add2), - data = _findRelevantNodeData4[0], - name = _findRelevantNodeData4[1], - value = _findRelevantNodeData4[2]; - - data.attributes[name] = value; // Emitting - - this.emit('nodeAttributesUpdated', { - key: data.key, - type: 'set', - attributes: data.attributes, - name: name - }); - return this; - }; -} - -function attachNodeAttributeUpdater(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1, add2) { - var _findRelevantNodeData5 = findRelevantNodeData(this, method, mode, nodeOrEdge, nameOrEdge, add1, add2), - data = _findRelevantNodeData5[0], - name = _findRelevantNodeData5[1], - updater = _findRelevantNodeData5[2]; - - if (typeof updater !== 'function') throw new InvalidArgumentsGraphError("Graph.".concat(method, ": updater should be a function.")); - var attributes = data.attributes; - var value = updater(attributes[name]); - attributes[name] = value; // Emitting - - this.emit('nodeAttributesUpdated', { - key: data.key, - type: 'set', - attributes: data.attributes, - name: name - }); - return this; - }; -} - -function attachNodeAttributeRemover(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) { - var _findRelevantNodeData6 = findRelevantNodeData(this, method, mode, nodeOrEdge, nameOrEdge, add1), - data = _findRelevantNodeData6[0], - name = _findRelevantNodeData6[1]; - - delete data.attributes[name]; // Emitting - - this.emit('nodeAttributesUpdated', { - key: data.key, - type: 'remove', - attributes: data.attributes, - name: name - }); - return this; - }; -} - -function attachNodeAttributesReplacer(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) { - var _findRelevantNodeData7 = findRelevantNodeData(this, method, mode, nodeOrEdge, nameOrEdge, add1), - data = _findRelevantNodeData7[0], - attributes = _findRelevantNodeData7[1]; - - if (!isPlainObject(attributes)) throw new InvalidArgumentsGraphError("Graph.".concat(method, ": provided attributes are not a plain object.")); - data.attributes = attributes; // Emitting - - this.emit('nodeAttributesUpdated', { - key: data.key, - type: 'replace', - attributes: data.attributes - }); - return this; - }; -} - -function attachNodeAttributesMerger(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) { - var _findRelevantNodeData8 = findRelevantNodeData(this, method, mode, nodeOrEdge, nameOrEdge, add1), - data = _findRelevantNodeData8[0], - attributes = _findRelevantNodeData8[1]; - - if (!isPlainObject(attributes)) throw new InvalidArgumentsGraphError("Graph.".concat(method, ": provided attributes are not a plain object.")); - assign(data.attributes, attributes); // Emitting - - this.emit('nodeAttributesUpdated', { - key: data.key, - type: 'merge', - attributes: data.attributes, - data: attributes - }); - return this; - }; -} - -function attachNodeAttributesUpdater(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) { - var _findRelevantNodeData9 = findRelevantNodeData(this, method, mode, nodeOrEdge, nameOrEdge, add1), - data = _findRelevantNodeData9[0], - updater = _findRelevantNodeData9[1]; - - if (typeof updater !== 'function') throw new InvalidArgumentsGraphError("Graph.".concat(method, ": provided updater is not a function.")); - data.attributes = updater(data.attributes); // Emitting - - this.emit('nodeAttributesUpdated', { - key: data.key, - type: 'update', - attributes: data.attributes - }); - return this; - }; -} -/** - * List of methods to attach. - */ - - -var NODE_ATTRIBUTES_METHODS = [{ - name: function name(element) { - return "get".concat(element, "Attribute"); - }, - attacher: attachNodeAttributeGetter -}, { - name: function name(element) { - return "get".concat(element, "Attributes"); - }, - attacher: attachNodeAttributesGetter -}, { - name: function name(element) { - return "has".concat(element, "Attribute"); - }, - attacher: attachNodeAttributeChecker -}, { - name: function name(element) { - return "set".concat(element, "Attribute"); - }, - attacher: attachNodeAttributeSetter -}, { - name: function name(element) { - return "update".concat(element, "Attribute"); - }, - attacher: attachNodeAttributeUpdater -}, { - name: function name(element) { - return "remove".concat(element, "Attribute"); - }, - attacher: attachNodeAttributeRemover -}, { - name: function name(element) { - return "replace".concat(element, "Attributes"); - }, - attacher: attachNodeAttributesReplacer -}, { - name: function name(element) { - return "merge".concat(element, "Attributes"); - }, - attacher: attachNodeAttributesMerger -}, { - name: function name(element) { - return "update".concat(element, "Attributes"); - }, - attacher: attachNodeAttributesUpdater -}]; -/** - * Attach every attributes-related methods to a Graph class. - * - * @param {function} Graph - Target class. - */ - -function attachNodeAttributesMethods(Graph) { - NODE_ATTRIBUTES_METHODS.forEach(function (_ref) { - var name = _ref.name, - attacher = _ref.attacher; - // For nodes - attacher(Graph, name('Node'), NODE); // For sources - - attacher(Graph, name('Source'), SOURCE); // For targets - - attacher(Graph, name('Target'), TARGET); // For opposites - - attacher(Graph, name('Opposite'), OPPOSITE); - }); -} - -/** - * Graphology Edge Attributes methods - * =================================== - */ -/** - * Attach an attribute getter method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ - -function attachEdgeAttributeGetter(Class, method, type) { - /** - * Get the desired attribute for the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {string} name - Attribute's name. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {string} name - Attribute's name. - * - * @return {mixed} - The attribute's value. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, name) { - var data; - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) throw new UsageGraphError("Graph.".concat(method, ": cannot find this type of edges in your ").concat(this.type, " graph.")); - - if (arguments.length > 2) { - if (this.multi) throw new UsageGraphError("Graph.".concat(method, ": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.")); - var source = '' + element; - var target = '' + name; - name = arguments[2]; - data = getMatchingEdge(this, source, target, type); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find an edge for the given path (\"").concat(source, "\" - \"").concat(target, "\").")); - } else { - if (type !== 'mixed') throw new UsageGraphError("Graph.".concat(method, ": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.")); - element = '' + element; - data = this._edges.get(element); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(element, "\" edge in the graph.")); - } - - return data.attributes[name]; - }; -} -/** - * Attach an attributes getter method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ - - -function attachEdgeAttributesGetter(Class, method, type) { - /** - * Retrieves all the target element's attributes. - * - * Arity 2: - * @param {any} element - Target element. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * - * @return {object} - The element's attributes. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element) { - var data; - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) throw new UsageGraphError("Graph.".concat(method, ": cannot find this type of edges in your ").concat(this.type, " graph.")); - - if (arguments.length > 1) { - if (this.multi) throw new UsageGraphError("Graph.".concat(method, ": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.")); - var source = '' + element, - target = '' + arguments[1]; - data = getMatchingEdge(this, source, target, type); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find an edge for the given path (\"").concat(source, "\" - \"").concat(target, "\").")); - } else { - if (type !== 'mixed') throw new UsageGraphError("Graph.".concat(method, ": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.")); - element = '' + element; - data = this._edges.get(element); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(element, "\" edge in the graph.")); - } - - return data.attributes; - }; -} -/** - * Attach an attribute checker method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ - - -function attachEdgeAttributeChecker(Class, method, type) { - /** - * Checks whether the desired attribute is set for the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {string} name - Attribute's name. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {string} name - Attribute's name. - * - * @return {boolean} - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, name) { - var data; - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) throw new UsageGraphError("Graph.".concat(method, ": cannot find this type of edges in your ").concat(this.type, " graph.")); - - if (arguments.length > 2) { - if (this.multi) throw new UsageGraphError("Graph.".concat(method, ": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.")); - var source = '' + element; - var target = '' + name; - name = arguments[2]; - data = getMatchingEdge(this, source, target, type); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find an edge for the given path (\"").concat(source, "\" - \"").concat(target, "\").")); - } else { - if (type !== 'mixed') throw new UsageGraphError("Graph.".concat(method, ": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.")); - element = '' + element; - data = this._edges.get(element); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(element, "\" edge in the graph.")); - } - - return data.attributes.hasOwnProperty(name); - }; -} -/** - * Attach an attribute setter method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ - - -function attachEdgeAttributeSetter(Class, method, type) { - /** - * Set the desired attribute for the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {string} name - Attribute's name. - * @param {mixed} value - New attribute value. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {string} name - Attribute's name. - * @param {mixed} value - New attribute value. - * - * @return {Graph} - Returns itself for chaining. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, name, value) { - var data; - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) throw new UsageGraphError("Graph.".concat(method, ": cannot find this type of edges in your ").concat(this.type, " graph.")); - - if (arguments.length > 3) { - if (this.multi) throw new UsageGraphError("Graph.".concat(method, ": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.")); - var source = '' + element; - var target = '' + name; - name = arguments[2]; - value = arguments[3]; - data = getMatchingEdge(this, source, target, type); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find an edge for the given path (\"").concat(source, "\" - \"").concat(target, "\").")); - } else { - if (type !== 'mixed') throw new UsageGraphError("Graph.".concat(method, ": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.")); - element = '' + element; - data = this._edges.get(element); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(element, "\" edge in the graph.")); - } - - data.attributes[name] = value; // Emitting - - this.emit('edgeAttributesUpdated', { - key: data.key, - type: 'set', - attributes: data.attributes, - name: name - }); - return this; - }; -} -/** - * Attach an attribute updater method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ - - -function attachEdgeAttributeUpdater(Class, method, type) { - /** - * Update the desired attribute for the given element (node or edge) using - * the provided function. - * - * Arity 2: - * @param {any} element - Target element. - * @param {string} name - Attribute's name. - * @param {function} updater - Updater function. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {string} name - Attribute's name. - * @param {function} updater - Updater function. - * - * @return {Graph} - Returns itself for chaining. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, name, updater) { - var data; - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) throw new UsageGraphError("Graph.".concat(method, ": cannot find this type of edges in your ").concat(this.type, " graph.")); - - if (arguments.length > 3) { - if (this.multi) throw new UsageGraphError("Graph.".concat(method, ": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.")); - var source = '' + element; - var target = '' + name; - name = arguments[2]; - updater = arguments[3]; - data = getMatchingEdge(this, source, target, type); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find an edge for the given path (\"").concat(source, "\" - \"").concat(target, "\").")); - } else { - if (type !== 'mixed') throw new UsageGraphError("Graph.".concat(method, ": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.")); - element = '' + element; - data = this._edges.get(element); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(element, "\" edge in the graph.")); - } - - if (typeof updater !== 'function') throw new InvalidArgumentsGraphError("Graph.".concat(method, ": updater should be a function.")); - data.attributes[name] = updater(data.attributes[name]); // Emitting - - this.emit('edgeAttributesUpdated', { - key: data.key, - type: 'set', - attributes: data.attributes, - name: name - }); - return this; - }; -} -/** - * Attach an attribute remover method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ - - -function attachEdgeAttributeRemover(Class, method, type) { - /** - * Remove the desired attribute for the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {string} name - Attribute's name. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {string} name - Attribute's name. - * - * @return {Graph} - Returns itself for chaining. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, name) { - var data; - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) throw new UsageGraphError("Graph.".concat(method, ": cannot find this type of edges in your ").concat(this.type, " graph.")); - - if (arguments.length > 2) { - if (this.multi) throw new UsageGraphError("Graph.".concat(method, ": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.")); - var source = '' + element; - var target = '' + name; - name = arguments[2]; - data = getMatchingEdge(this, source, target, type); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find an edge for the given path (\"").concat(source, "\" - \"").concat(target, "\").")); - } else { - if (type !== 'mixed') throw new UsageGraphError("Graph.".concat(method, ": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.")); - element = '' + element; - data = this._edges.get(element); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(element, "\" edge in the graph.")); - } - - delete data.attributes[name]; // Emitting - - this.emit('edgeAttributesUpdated', { - key: data.key, - type: 'remove', - attributes: data.attributes, - name: name - }); - return this; - }; -} -/** - * Attach an attribute replacer method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ - - -function attachEdgeAttributesReplacer(Class, method, type) { - /** - * Replace the attributes for the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {object} attributes - New attributes. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {object} attributes - New attributes. - * - * @return {Graph} - Returns itself for chaining. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, attributes) { - var data; - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) throw new UsageGraphError("Graph.".concat(method, ": cannot find this type of edges in your ").concat(this.type, " graph.")); - - if (arguments.length > 2) { - if (this.multi) throw new UsageGraphError("Graph.".concat(method, ": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.")); - var source = '' + element, - target = '' + attributes; - attributes = arguments[2]; - data = getMatchingEdge(this, source, target, type); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find an edge for the given path (\"").concat(source, "\" - \"").concat(target, "\").")); - } else { - if (type !== 'mixed') throw new UsageGraphError("Graph.".concat(method, ": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.")); - element = '' + element; - data = this._edges.get(element); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(element, "\" edge in the graph.")); - } - - if (!isPlainObject(attributes)) throw new InvalidArgumentsGraphError("Graph.".concat(method, ": provided attributes are not a plain object.")); - data.attributes = attributes; // Emitting - - this.emit('edgeAttributesUpdated', { - key: data.key, - type: 'replace', - attributes: data.attributes - }); - return this; - }; -} -/** - * Attach an attribute merger method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ - - -function attachEdgeAttributesMerger(Class, method, type) { - /** - * Merge the attributes for the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {object} attributes - Attributes to merge. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {object} attributes - Attributes to merge. - * - * @return {Graph} - Returns itself for chaining. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, attributes) { - var data; - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) throw new UsageGraphError("Graph.".concat(method, ": cannot find this type of edges in your ").concat(this.type, " graph.")); - - if (arguments.length > 2) { - if (this.multi) throw new UsageGraphError("Graph.".concat(method, ": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.")); - var source = '' + element, - target = '' + attributes; - attributes = arguments[2]; - data = getMatchingEdge(this, source, target, type); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find an edge for the given path (\"").concat(source, "\" - \"").concat(target, "\").")); - } else { - if (type !== 'mixed') throw new UsageGraphError("Graph.".concat(method, ": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.")); - element = '' + element; - data = this._edges.get(element); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(element, "\" edge in the graph.")); - } - - if (!isPlainObject(attributes)) throw new InvalidArgumentsGraphError("Graph.".concat(method, ": provided attributes are not a plain object.")); - assign(data.attributes, attributes); // Emitting - - this.emit('edgeAttributesUpdated', { - key: data.key, - type: 'merge', - attributes: data.attributes, - data: attributes - }); - return this; - }; -} -/** - * Attach an attribute updater method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ - - -function attachEdgeAttributesUpdater(Class, method, type) { - /** - * Update the attributes of the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {function} updater - Updater function. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {function} updater - Updater function. - * - * @return {Graph} - Returns itself for chaining. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, updater) { - var data; - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) throw new UsageGraphError("Graph.".concat(method, ": cannot find this type of edges in your ").concat(this.type, " graph.")); - - if (arguments.length > 2) { - if (this.multi) throw new UsageGraphError("Graph.".concat(method, ": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.")); - var source = '' + element, - target = '' + updater; - updater = arguments[2]; - data = getMatchingEdge(this, source, target, type); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find an edge for the given path (\"").concat(source, "\" - \"").concat(target, "\").")); - } else { - if (type !== 'mixed') throw new UsageGraphError("Graph.".concat(method, ": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.")); - element = '' + element; - data = this._edges.get(element); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(element, "\" edge in the graph.")); - } - - if (typeof updater !== 'function') throw new InvalidArgumentsGraphError("Graph.".concat(method, ": provided updater is not a function.")); - data.attributes = updater(data.attributes); // Emitting - - this.emit('edgeAttributesUpdated', { - key: data.key, - type: 'update', - attributes: data.attributes - }); - return this; - }; -} -/** - * List of methods to attach. - */ - - -var EDGE_ATTRIBUTES_METHODS = [{ - name: function name(element) { - return "get".concat(element, "Attribute"); - }, - attacher: attachEdgeAttributeGetter -}, { - name: function name(element) { - return "get".concat(element, "Attributes"); - }, - attacher: attachEdgeAttributesGetter -}, { - name: function name(element) { - return "has".concat(element, "Attribute"); - }, - attacher: attachEdgeAttributeChecker -}, { - name: function name(element) { - return "set".concat(element, "Attribute"); - }, - attacher: attachEdgeAttributeSetter -}, { - name: function name(element) { - return "update".concat(element, "Attribute"); - }, - attacher: attachEdgeAttributeUpdater -}, { - name: function name(element) { - return "remove".concat(element, "Attribute"); - }, - attacher: attachEdgeAttributeRemover -}, { - name: function name(element) { - return "replace".concat(element, "Attributes"); - }, - attacher: attachEdgeAttributesReplacer -}, { - name: function name(element) { - return "merge".concat(element, "Attributes"); - }, - attacher: attachEdgeAttributesMerger -}, { - name: function name(element) { - return "update".concat(element, "Attributes"); - }, - attacher: attachEdgeAttributesUpdater -}]; -/** - * Attach every attributes-related methods to a Graph class. - * - * @param {function} Graph - Target class. - */ - -function attachEdgeAttributesMethods(Graph) { - EDGE_ATTRIBUTES_METHODS.forEach(function (_ref) { - var name = _ref.name, - attacher = _ref.attacher; - // For edges - attacher(Graph, name('Edge'), 'mixed'); // For directed edges - - attacher(Graph, name('DirectedEdge'), 'directed'); // For undirected edges - - attacher(Graph, name('UndirectedEdge'), 'undirected'); - }); -} - -/** - * Graphology Edge Iteration - * ========================== - * - * Attaching some methods to the Graph class to be able to iterate over a - * graph's edges. - */ -/** - * Definitions. - */ - -var EDGES_ITERATION = [{ - name: 'edges', - type: 'mixed' -}, { - name: 'inEdges', - type: 'directed', - direction: 'in' -}, { - name: 'outEdges', - type: 'directed', - direction: 'out' -}, { - name: 'inboundEdges', - type: 'mixed', - direction: 'in' -}, { - name: 'outboundEdges', - type: 'mixed', - direction: 'out' -}, { - name: 'directedEdges', - type: 'directed' -}, { - name: 'undirectedEdges', - type: 'undirected' -}]; -/** - * Function iterating over edges from the given object to match one of them. - * - * @param {object} object - Target object. - * @param {function} callback - Function to call. - */ - -function forEachSimple(breakable, object, callback, avoid) { - var shouldBreak = false; - - for (var k in object) { - if (k === avoid) continue; - var edgeData = object[k]; - shouldBreak = callback(edgeData.key, edgeData.attributes, edgeData.source.key, edgeData.target.key, edgeData.source.attributes, edgeData.target.attributes, edgeData.undirected); - if (breakable && shouldBreak) return edgeData.key; - } - - return; -} - -function forEachMulti(breakable, object, callback, avoid) { - var edgeData, source, target; - var shouldBreak = false; - - for (var k in object) { - if (k === avoid) continue; - edgeData = object[k]; - - do { - source = edgeData.source; - target = edgeData.target; - shouldBreak = callback(edgeData.key, edgeData.attributes, source.key, target.key, source.attributes, target.attributes, edgeData.undirected); - if (breakable && shouldBreak) return edgeData.key; - edgeData = edgeData.next; - } while (edgeData !== undefined); - } - - return; -} -/** - * Function returning an iterator over edges from the given object. - * - * @param {object} object - Target object. - * @return {Iterator} - */ - - -function createIterator(object, avoid) { - var keys = Object.keys(object); - var l = keys.length; - var edgeData; - var i = 0; - return new Iterator__default["default"](function next() { - do { - if (!edgeData) { - if (i >= l) return { - done: true - }; - var k = keys[i++]; - - if (k === avoid) { - edgeData = undefined; - continue; - } - - edgeData = object[k]; - } else { - edgeData = edgeData.next; - } - } while (!edgeData); - - return { - done: false, - value: { - edge: edgeData.key, - attributes: edgeData.attributes, - source: edgeData.source.key, - target: edgeData.target.key, - sourceAttributes: edgeData.source.attributes, - targetAttributes: edgeData.target.attributes, - undirected: edgeData.undirected - } - }; - }); -} -/** - * Function iterating over the egdes from the object at given key to match - * one of them. - * - * @param {object} object - Target object. - * @param {mixed} k - Neighbor key. - * @param {function} callback - Callback to use. - */ - - -function forEachForKeySimple(breakable, object, k, callback) { - var edgeData = object[k]; - if (!edgeData) return; - var sourceData = edgeData.source; - var targetData = edgeData.target; - if (callback(edgeData.key, edgeData.attributes, sourceData.key, targetData.key, sourceData.attributes, targetData.attributes, edgeData.undirected) && breakable) return edgeData.key; -} - -function forEachForKeyMulti(breakable, object, k, callback) { - var edgeData = object[k]; - if (!edgeData) return; - var shouldBreak = false; - - do { - shouldBreak = callback(edgeData.key, edgeData.attributes, edgeData.source.key, edgeData.target.key, edgeData.source.attributes, edgeData.target.attributes, edgeData.undirected); - if (breakable && shouldBreak) return edgeData.key; - edgeData = edgeData.next; - } while (edgeData !== undefined); - - return; -} -/** - * Function returning an iterator over the egdes from the object at given key. - * - * @param {object} object - Target object. - * @param {mixed} k - Neighbor key. - * @return {Iterator} - */ - - -function createIteratorForKey(object, k) { - var edgeData = object[k]; - - if (edgeData.next !== undefined) { - return new Iterator__default["default"](function () { - if (!edgeData) return { - done: true - }; - var value = { - edge: edgeData.key, - attributes: edgeData.attributes, - source: edgeData.source.key, - target: edgeData.target.key, - sourceAttributes: edgeData.source.attributes, - targetAttributes: edgeData.target.attributes, - undirected: edgeData.undirected - }; - edgeData = edgeData.next; - return { - done: false, - value: value - }; - }); - } - - return Iterator__default["default"].of({ - edge: edgeData.key, - attributes: edgeData.attributes, - source: edgeData.source.key, - target: edgeData.target.key, - sourceAttributes: edgeData.source.attributes, - targetAttributes: edgeData.target.attributes, - undirected: edgeData.undirected - }); -} -/** - * Function creating an array of edges for the given type. - * - * @param {Graph} graph - Target Graph instance. - * @param {string} type - Type of edges to retrieve. - * @return {array} - Array of edges. - */ - - -function createEdgeArray(graph, type) { - if (graph.size === 0) return []; - - if (type === 'mixed' || type === graph.type) { - if (typeof Array.from === 'function') return Array.from(graph._edges.keys()); - return take__default["default"](graph._edges.keys(), graph._edges.size); - } - - var size = type === 'undirected' ? graph.undirectedSize : graph.directedSize; - var list = new Array(size), - mask = type === 'undirected'; - - var iterator = graph._edges.values(); - - var i = 0; - var step, data; - - while (step = iterator.next(), step.done !== true) { - data = step.value; - if (data.undirected === mask) list[i++] = data.key; - } - - return list; -} -/** - * Function iterating over a graph's edges using a callback to match one of - * them. - * - * @param {Graph} graph - Target Graph instance. - * @param {string} type - Type of edges to retrieve. - * @param {function} callback - Function to call. - */ - - -function forEachEdge(breakable, graph, type, callback) { - if (graph.size === 0) return; - var shouldFilter = type !== 'mixed' && type !== graph.type; - var mask = type === 'undirected'; - var step, data; - var shouldBreak = false; - - var iterator = graph._edges.values(); - - while (step = iterator.next(), step.done !== true) { - data = step.value; - if (shouldFilter && data.undirected !== mask) continue; - var _data = data, - key = _data.key, - attributes = _data.attributes, - source = _data.source, - target = _data.target; - shouldBreak = callback(key, attributes, source.key, target.key, source.attributes, target.attributes, data.undirected); - if (breakable && shouldBreak) return key; - } - - return; -} -/** - * Function creating an iterator of edges for the given type. - * - * @param {Graph} graph - Target Graph instance. - * @param {string} type - Type of edges to retrieve. - * @return {Iterator} - */ - - -function createEdgeIterator(graph, type) { - if (graph.size === 0) return Iterator__default["default"].empty(); - var shouldFilter = type !== 'mixed' && type !== graph.type; - var mask = type === 'undirected'; - - var iterator = graph._edges.values(); - - return new Iterator__default["default"](function next() { - var step, data; // eslint-disable-next-line no-constant-condition - - while (true) { - step = iterator.next(); - if (step.done) return step; - data = step.value; - if (shouldFilter && data.undirected !== mask) continue; - break; - } - - var value = { - edge: data.key, - attributes: data.attributes, - source: data.source.key, - target: data.target.key, - sourceAttributes: data.source.attributes, - targetAttributes: data.target.attributes, - undirected: data.undirected - }; - return { - value: value, - done: false - }; - }); -} -/** - * Function iterating over a node's edges using a callback to match one of them. - * - * @param {boolean} multi - Whether the graph is multi or not. - * @param {string} type - Type of edges to retrieve. - * @param {string} direction - In or out? - * @param {any} nodeData - Target node's data. - * @param {function} callback - Function to call. - */ - - -function forEachEdgeForNode(breakable, multi, type, direction, nodeData, callback) { - var fn = multi ? forEachMulti : forEachSimple; - var found; - - if (type !== 'undirected') { - if (direction !== 'out') { - found = fn(breakable, nodeData["in"], callback); - if (breakable && found) return found; - } - - if (direction !== 'in') { - found = fn(breakable, nodeData.out, callback, !direction ? nodeData.key : undefined); - if (breakable && found) return found; - } - } - - if (type !== 'directed') { - found = fn(breakable, nodeData.undirected, callback); - if (breakable && found) return found; - } - - return; -} -/** - * Function creating an array of edges for the given type & the given node. - * - * @param {boolean} multi - Whether the graph is multi or not. - * @param {string} type - Type of edges to retrieve. - * @param {string} direction - In or out? - * @param {any} nodeData - Target node's data. - * @return {array} - Array of edges. - */ - - -function createEdgeArrayForNode(multi, type, direction, nodeData) { - var edges = []; // TODO: possibility to know size beforehand or factorize with map - - forEachEdgeForNode(false, multi, type, direction, nodeData, function (key) { - edges.push(key); - }); - return edges; -} -/** - * Function iterating over a node's edges using a callback. - * - * @param {string} type - Type of edges to retrieve. - * @param {string} direction - In or out? - * @param {any} nodeData - Target node's data. - * @return {Iterator} - */ - - -function createEdgeIteratorForNode(type, direction, nodeData) { - var iterator = Iterator__default["default"].empty(); - - if (type !== 'undirected') { - if (direction !== 'out' && typeof nodeData["in"] !== 'undefined') iterator = chain__default["default"](iterator, createIterator(nodeData["in"])); - if (direction !== 'in' && typeof nodeData.out !== 'undefined') iterator = chain__default["default"](iterator, createIterator(nodeData.out, !direction ? nodeData.key : undefined)); - } - - if (type !== 'directed' && typeof nodeData.undirected !== 'undefined') { - iterator = chain__default["default"](iterator, createIterator(nodeData.undirected)); - } - - return iterator; -} -/** - * Function iterating over edges for the given path using a callback to match - * one of them. - * - * @param {string} type - Type of edges to retrieve. - * @param {boolean} multi - Whether the graph is multi. - * @param {string} direction - In or out? - * @param {NodeData} sourceData - Source node's data. - * @param {string} target - Target node. - * @param {function} callback - Function to call. - */ - - -function forEachEdgeForPath(breakable, type, multi, direction, sourceData, target, callback) { - var fn = multi ? forEachForKeyMulti : forEachForKeySimple; - var found; - - if (type !== 'undirected') { - if (typeof sourceData["in"] !== 'undefined' && direction !== 'out') { - found = fn(breakable, sourceData["in"], target, callback); - if (breakable && found) return found; - } - - if (typeof sourceData.out !== 'undefined' && direction !== 'in' && (direction || sourceData.key !== target)) { - found = fn(breakable, sourceData.out, target, callback); - if (breakable && found) return found; - } - } - - if (type !== 'directed') { - if (typeof sourceData.undirected !== 'undefined') { - found = fn(breakable, sourceData.undirected, target, callback); - if (breakable && found) return found; - } - } - - return; -} -/** - * Function creating an array of edges for the given path. - * - * @param {string} type - Type of edges to retrieve. - * @param {boolean} multi - Whether the graph is multi. - * @param {string} direction - In or out? - * @param {NodeData} sourceData - Source node's data. - * @param {any} target - Target node. - * @return {array} - Array of edges. - */ - - -function createEdgeArrayForPath(type, multi, direction, sourceData, target) { - var edges = []; // TODO: possibility to know size beforehand or factorize with map - - forEachEdgeForPath(false, type, multi, direction, sourceData, target, function (key) { - edges.push(key); - }); - return edges; -} -/** - * Function returning an iterator over edges for the given path. - * - * @param {string} type - Type of edges to retrieve. - * @param {string} direction - In or out? - * @param {NodeData} sourceData - Source node's data. - * @param {string} target - Target node. - * @param {function} callback - Function to call. - */ - - -function createEdgeIteratorForPath(type, direction, sourceData, target) { - var iterator = Iterator__default["default"].empty(); - - if (type !== 'undirected') { - if (typeof sourceData["in"] !== 'undefined' && direction !== 'out' && target in sourceData["in"]) iterator = chain__default["default"](iterator, createIteratorForKey(sourceData["in"], target)); - if (typeof sourceData.out !== 'undefined' && direction !== 'in' && target in sourceData.out && (direction || sourceData.key !== target)) iterator = chain__default["default"](iterator, createIteratorForKey(sourceData.out, target)); - } - - if (type !== 'directed') { - if (typeof sourceData.undirected !== 'undefined' && target in sourceData.undirected) iterator = chain__default["default"](iterator, createIteratorForKey(sourceData.undirected, target)); - } - - return iterator; -} -/** - * Function attaching an edge array creator method to the Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ - - -function attachEdgeArrayCreator(Class, description) { - var name = description.name, - type = description.type, - direction = description.direction; - /** - * Function returning an array of certain edges. - * - * Arity 0: Return all the relevant edges. - * - * Arity 1: Return all of a node's relevant edges. - * @param {any} node - Target node. - * - * Arity 2: Return the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * - * @return {array|number} - The edges or the number of edges. - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - Class.prototype[name] = function (source, target) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return []; - if (!arguments.length) return createEdgeArray(this, type); - - if (arguments.length === 1) { - source = '' + source; - - var nodeData = this._nodes.get(source); - - if (typeof nodeData === 'undefined') throw new NotFoundGraphError("Graph.".concat(name, ": could not find the \"").concat(source, "\" node in the graph.")); // Iterating over a node's edges - - return createEdgeArrayForNode(this.multi, type === 'mixed' ? this.type : type, direction, nodeData); - } - - if (arguments.length === 2) { - source = '' + source; - target = '' + target; - - var sourceData = this._nodes.get(source); - - if (!sourceData) throw new NotFoundGraphError("Graph.".concat(name, ": could not find the \"").concat(source, "\" source node in the graph.")); - if (!this._nodes.has(target)) throw new NotFoundGraphError("Graph.".concat(name, ": could not find the \"").concat(target, "\" target node in the graph.")); // Iterating over the edges between source & target - - return createEdgeArrayForPath(type, this.multi, direction, sourceData, target); - } - - throw new InvalidArgumentsGraphError("Graph.".concat(name, ": too many arguments (expecting 0, 1 or 2 and got ").concat(arguments.length, ").")); - }; -} -/** - * Function attaching a edge callback iterator method to the Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ - - -function attachForEachEdge(Class, description) { - var name = description.name, - type = description.type, - direction = description.direction; - var forEachName = 'forEach' + name[0].toUpperCase() + name.slice(1, -1); - /** - * Function iterating over the graph's relevant edges by applying the given - * callback. - * - * Arity 1: Iterate over all the relevant edges. - * @param {function} callback - Callback to use. - * - * Arity 2: Iterate over all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * Arity 3: Iterate over the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} callback - Callback to use. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - Class.prototype[forEachName] = function (source, target, callback) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return; - - if (arguments.length === 1) { - callback = source; - return forEachEdge(false, this, type, callback); - } - - if (arguments.length === 2) { - source = '' + source; - callback = target; - - var nodeData = this._nodes.get(source); - - if (typeof nodeData === 'undefined') throw new NotFoundGraphError("Graph.".concat(forEachName, ": could not find the \"").concat(source, "\" node in the graph.")); // Iterating over a node's edges - // TODO: maybe attach the sub method to the instance dynamically? - - return forEachEdgeForNode(false, this.multi, type === 'mixed' ? this.type : type, direction, nodeData, callback); - } - - if (arguments.length === 3) { - source = '' + source; - target = '' + target; - - var sourceData = this._nodes.get(source); - - if (!sourceData) throw new NotFoundGraphError("Graph.".concat(forEachName, ": could not find the \"").concat(source, "\" source node in the graph.")); - if (!this._nodes.has(target)) throw new NotFoundGraphError("Graph.".concat(forEachName, ": could not find the \"").concat(target, "\" target node in the graph.")); // Iterating over the edges between source & target - - return forEachEdgeForPath(false, type, this.multi, direction, sourceData, target, callback); - } - - throw new InvalidArgumentsGraphError("Graph.".concat(forEachName, ": too many arguments (expecting 1, 2 or 3 and got ").concat(arguments.length, ").")); - }; - /** - * Function mapping the graph's relevant edges by applying the given - * callback. - * - * Arity 1: Map all the relevant edges. - * @param {function} callback - Callback to use. - * - * Arity 2: Map all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * Arity 3: Map the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} callback - Callback to use. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - - var mapName = 'map' + name[0].toUpperCase() + name.slice(1); - - Class.prototype[mapName] = function () { - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - var result; // We know the result length beforehand - - if (args.length === 0) { - var length = 0; - if (type !== 'directed') length += this.undirectedSize; - if (type !== 'undirected') length += this.directedSize; - result = new Array(length); - var i = 0; - args.push(function (e, ea, s, t, sa, ta, u) { - result[i++] = callback(e, ea, s, t, sa, ta, u); - }); - } // We don't know the result length beforehand - // TODO: we can in some instances of simple graphs, knowing degree - else { - result = []; - args.push(function (e, ea, s, t, sa, ta, u) { - result.push(callback(e, ea, s, t, sa, ta, u)); - }); - } - - this[forEachName].apply(this, args); - return result; - }; - /** - * Function filtering the graph's relevant edges using the provided predicate - * function. - * - * Arity 1: Filter all the relevant edges. - * @param {function} predicate - Predicate to use. - * - * Arity 2: Filter all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} predicate - Predicate to use. - * - * Arity 3: Filter the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} predicate - Predicate to use. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - - var filterName = 'filter' + name[0].toUpperCase() + name.slice(1); - - Class.prototype[filterName] = function () { - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - var result = []; - args.push(function (e, ea, s, t, sa, ta, u) { - if (callback(e, ea, s, t, sa, ta, u)) result.push(e); - }); - this[forEachName].apply(this, args); - return result; - }; - /** - * Function reducing the graph's relevant edges using the provided accumulator - * function. - * - * Arity 1: Reduce all the relevant edges. - * @param {function} accumulator - Accumulator to use. - * @param {any} initialValue - Initial value. - * - * Arity 2: Reduce all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} accumulator - Accumulator to use. - * @param {any} initialValue - Initial value. - * - * Arity 3: Reduce the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} accumulator - Accumulator to use. - * @param {any} initialValue - Initial value. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - - var reduceName = 'reduce' + name[0].toUpperCase() + name.slice(1); - - Class.prototype[reduceName] = function () { - var args = Array.prototype.slice.call(arguments); - - if (args.length < 2 || args.length > 4) { - throw new InvalidArgumentsGraphError("Graph.".concat(reduceName, ": invalid number of arguments (expecting 2, 3 or 4 and got ").concat(args.length, ").")); - } - - if (typeof args[args.length - 1] === 'function' && typeof args[args.length - 2] !== 'function') { - throw new InvalidArgumentsGraphError("Graph.".concat(reduceName, ": missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.")); - } - - var callback; - var initialValue; - - if (args.length === 2) { - callback = args[0]; - initialValue = args[1]; - args = []; - } else if (args.length === 3) { - callback = args[1]; - initialValue = args[2]; - args = [args[0]]; - } else if (args.length === 4) { - callback = args[2]; - initialValue = args[3]; - args = [args[0], args[1]]; - } - - var accumulator = initialValue; - args.push(function (e, ea, s, t, sa, ta, u) { - accumulator = callback(accumulator, e, ea, s, t, sa, ta, u); - }); - this[forEachName].apply(this, args); - return accumulator; - }; -} -/** - * Function attaching a breakable edge callback iterator method to the Graph - * prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ - - -function attachFindEdge(Class, description) { - var name = description.name, - type = description.type, - direction = description.direction; - var findEdgeName = 'find' + name[0].toUpperCase() + name.slice(1, -1); - /** - * Function iterating over the graph's relevant edges in order to match - * one of them using the provided predicate function. - * - * Arity 1: Iterate over all the relevant edges. - * @param {function} callback - Callback to use. - * - * Arity 2: Iterate over all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * Arity 3: Iterate over the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} callback - Callback to use. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - Class.prototype[findEdgeName] = function (source, target, callback) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return false; - - if (arguments.length === 1) { - callback = source; - return forEachEdge(true, this, type, callback); - } - - if (arguments.length === 2) { - source = '' + source; - callback = target; - - var nodeData = this._nodes.get(source); - - if (typeof nodeData === 'undefined') throw new NotFoundGraphError("Graph.".concat(findEdgeName, ": could not find the \"").concat(source, "\" node in the graph.")); // Iterating over a node's edges - // TODO: maybe attach the sub method to the instance dynamically? - - return forEachEdgeForNode(true, this.multi, type === 'mixed' ? this.type : type, direction, nodeData, callback); - } - - if (arguments.length === 3) { - source = '' + source; - target = '' + target; - - var sourceData = this._nodes.get(source); - - if (!sourceData) throw new NotFoundGraphError("Graph.".concat(findEdgeName, ": could not find the \"").concat(source, "\" source node in the graph.")); - if (!this._nodes.has(target)) throw new NotFoundGraphError("Graph.".concat(findEdgeName, ": could not find the \"").concat(target, "\" target node in the graph.")); // Iterating over the edges between source & target - - return forEachEdgeForPath(true, type, this.multi, direction, sourceData, target, callback); - } - - throw new InvalidArgumentsGraphError("Graph.".concat(findEdgeName, ": too many arguments (expecting 1, 2 or 3 and got ").concat(arguments.length, ").")); - }; - /** - * Function iterating over the graph's relevant edges in order to assert - * whether any one of them matches the provided predicate function. - * - * Arity 1: Iterate over all the relevant edges. - * @param {function} callback - Callback to use. - * - * Arity 2: Iterate over all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * Arity 3: Iterate over the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} callback - Callback to use. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - - var someName = 'some' + name[0].toUpperCase() + name.slice(1, -1); - - Class.prototype[someName] = function () { - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - args.push(function (e, ea, s, t, sa, ta, u) { - return callback(e, ea, s, t, sa, ta, u); - }); - var found = this[findEdgeName].apply(this, args); - if (found) return true; - return false; - }; - /** - * Function iterating over the graph's relevant edges in order to assert - * whether all of them matche the provided predicate function. - * - * Arity 1: Iterate over all the relevant edges. - * @param {function} callback - Callback to use. - * - * Arity 2: Iterate over all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * Arity 3: Iterate over the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} callback - Callback to use. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - - var everyName = 'every' + name[0].toUpperCase() + name.slice(1, -1); - - Class.prototype[everyName] = function () { - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - args.push(function (e, ea, s, t, sa, ta, u) { - return !callback(e, ea, s, t, sa, ta, u); - }); - var found = this[findEdgeName].apply(this, args); - if (found) return false; - return true; - }; -} -/** - * Function attaching an edge iterator method to the Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ - - -function attachEdgeIteratorCreator(Class, description) { - var originalName = description.name, - type = description.type, - direction = description.direction; - var name = originalName.slice(0, -1) + 'Entries'; - /** - * Function returning an iterator over the graph's edges. - * - * Arity 0: Iterate over all the relevant edges. - * - * Arity 1: Iterate over all of a node's relevant edges. - * @param {any} node - Target node. - * - * Arity 2: Iterate over the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * - * @return {array|number} - The edges or the number of edges. - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - Class.prototype[name] = function (source, target) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return Iterator__default["default"].empty(); - if (!arguments.length) return createEdgeIterator(this, type); - - if (arguments.length === 1) { - source = '' + source; - - var sourceData = this._nodes.get(source); - - if (!sourceData) throw new NotFoundGraphError("Graph.".concat(name, ": could not find the \"").concat(source, "\" node in the graph.")); // Iterating over a node's edges - - return createEdgeIteratorForNode(type, direction, sourceData); - } - - if (arguments.length === 2) { - source = '' + source; - target = '' + target; - - var _sourceData = this._nodes.get(source); - - if (!_sourceData) throw new NotFoundGraphError("Graph.".concat(name, ": could not find the \"").concat(source, "\" source node in the graph.")); - if (!this._nodes.has(target)) throw new NotFoundGraphError("Graph.".concat(name, ": could not find the \"").concat(target, "\" target node in the graph.")); // Iterating over the edges between source & target - - return createEdgeIteratorForPath(type, direction, _sourceData, target); - } - - throw new InvalidArgumentsGraphError("Graph.".concat(name, ": too many arguments (expecting 0, 1 or 2 and got ").concat(arguments.length, ").")); - }; -} -/** - * Function attaching every edge iteration method to the Graph class. - * - * @param {function} Graph - Graph class. - */ - - -function attachEdgeIterationMethods(Graph) { - EDGES_ITERATION.forEach(function (description) { - attachEdgeArrayCreator(Graph, description); - attachForEachEdge(Graph, description); - attachFindEdge(Graph, description); - attachEdgeIteratorCreator(Graph, description); - }); -} - -/** - * Graphology Neighbor Iteration - * ============================== - * - * Attaching some methods to the Graph class to be able to iterate over - * neighbors. - */ -/** - * Definitions. - */ - -var NEIGHBORS_ITERATION = [{ - name: 'neighbors', - type: 'mixed' -}, { - name: 'inNeighbors', - type: 'directed', - direction: 'in' -}, { - name: 'outNeighbors', - type: 'directed', - direction: 'out' -}, { - name: 'inboundNeighbors', - type: 'mixed', - direction: 'in' -}, { - name: 'outboundNeighbors', - type: 'mixed', - direction: 'out' -}, { - name: 'directedNeighbors', - type: 'directed' -}, { - name: 'undirectedNeighbors', - type: 'undirected' -}]; -/** - * Helpers. - */ - -function CompositeSetWrapper() { - this.A = null; - this.B = null; -} - -CompositeSetWrapper.prototype.wrap = function (set) { - if (this.A === null) this.A = set;else if (this.B === null) this.B = set; -}; - -CompositeSetWrapper.prototype.has = function (key) { - if (this.A !== null && key in this.A) return true; - if (this.B !== null && key in this.B) return true; - return false; -}; -/** - * Function iterating over the given node's relevant neighbors to match - * one of them using a predicated function. - * - * @param {string} type - Type of neighbors. - * @param {string} direction - Direction. - * @param {any} nodeData - Target node's data. - * @param {function} callback - Callback to use. - */ - - -function forEachInObjectOnce(breakable, visited, nodeData, object, callback) { - for (var k in object) { - var edgeData = object[k]; - var sourceData = edgeData.source; - var targetData = edgeData.target; - var neighborData = sourceData === nodeData ? targetData : sourceData; - if (visited && visited.has(neighborData.key)) continue; - var shouldBreak = callback(neighborData.key, neighborData.attributes); - if (breakable && shouldBreak) return neighborData.key; - } - - return; -} - -function forEachNeighbor(breakable, type, direction, nodeData, callback) { - // If we want only undirected or in or out, we can roll some optimizations - if (type !== 'mixed') { - if (type === 'undirected') return forEachInObjectOnce(breakable, null, nodeData, nodeData.undirected, callback); - if (typeof direction === 'string') return forEachInObjectOnce(breakable, null, nodeData, nodeData[direction], callback); - } // Else we need to keep a set of neighbors not to return duplicates - // We cheat by querying the other adjacencies - - - var visited = new CompositeSetWrapper(); - var found; - - if (type !== 'undirected') { - if (direction !== 'out') { - found = forEachInObjectOnce(breakable, null, nodeData, nodeData["in"], callback); - if (breakable && found) return found; - visited.wrap(nodeData["in"]); - } - - if (direction !== 'in') { - found = forEachInObjectOnce(breakable, visited, nodeData, nodeData.out, callback); - if (breakable && found) return found; - visited.wrap(nodeData.out); - } - } - - if (type !== 'directed') { - found = forEachInObjectOnce(breakable, visited, nodeData, nodeData.undirected, callback); - if (breakable && found) return found; - } - - return; -} -/** - * Function creating an array of relevant neighbors for the given node. - * - * @param {string} type - Type of neighbors. - * @param {string} direction - Direction. - * @param {any} nodeData - Target node's data. - * @return {Array} - The list of neighbors. - */ - - -function createNeighborArrayForNode(type, direction, nodeData) { - // If we want only undirected or in or out, we can roll some optimizations - if (type !== 'mixed') { - if (type === 'undirected') return Object.keys(nodeData.undirected); - if (typeof direction === 'string') return Object.keys(nodeData[direction]); - } - - var neighbors = []; - forEachNeighbor(false, type, direction, nodeData, function (key) { - neighbors.push(key); - }); - return neighbors; -} -/** - * Function returning an iterator over the given node's relevant neighbors. - * - * @param {string} type - Type of neighbors. - * @param {string} direction - Direction. - * @param {any} nodeData - Target node's data. - * @return {Iterator} - */ - - -function createDedupedObjectIterator(visited, nodeData, object) { - var keys = Object.keys(object); - var l = keys.length; - var i = 0; - return new Iterator__default["default"](function next() { - var neighborData = null; - - do { - if (i >= l) { - if (visited) visited.wrap(object); - return { - done: true - }; - } - - var edgeData = object[keys[i++]]; - var sourceData = edgeData.source; - var targetData = edgeData.target; - neighborData = sourceData === nodeData ? targetData : sourceData; - - if (visited && visited.has(neighborData.key)) { - neighborData = null; - continue; - } - } while (neighborData === null); - - return { - done: false, - value: { - neighbor: neighborData.key, - attributes: neighborData.attributes - } - }; - }); -} - -function createNeighborIterator(type, direction, nodeData) { - // If we want only undirected or in or out, we can roll some optimizations - if (type !== 'mixed') { - if (type === 'undirected') return createDedupedObjectIterator(null, nodeData, nodeData.undirected); - if (typeof direction === 'string') return createDedupedObjectIterator(null, nodeData, nodeData[direction]); - } - - var iterator = Iterator__default["default"].empty(); // Else we need to keep a set of neighbors not to return duplicates - // We cheat by querying the other adjacencies - - var visited = new CompositeSetWrapper(); - - if (type !== 'undirected') { - if (direction !== 'out') { - iterator = chain__default["default"](iterator, createDedupedObjectIterator(visited, nodeData, nodeData["in"])); - } - - if (direction !== 'in') { - iterator = chain__default["default"](iterator, createDedupedObjectIterator(visited, nodeData, nodeData.out)); - } - } - - if (type !== 'directed') { - iterator = chain__default["default"](iterator, createDedupedObjectIterator(visited, nodeData, nodeData.undirected)); - } - - return iterator; -} -/** - * Function attaching a neighbors array creator method to the Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ - - -function attachNeighborArrayCreator(Class, description) { - var name = description.name, - type = description.type, - direction = description.direction; - /** - * Function returning an array of certain neighbors. - * - * @param {any} node - Target node. - * @return {array} - The neighbors of neighbors. - * - * @throws {Error} - Will throw if node is not found in the graph. - */ - - Class.prototype[name] = function (node) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return []; - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (typeof nodeData === 'undefined') throw new NotFoundGraphError("Graph.".concat(name, ": could not find the \"").concat(node, "\" node in the graph.")); // Here, we want to iterate over a node's relevant neighbors - - return createNeighborArrayForNode(type === 'mixed' ? this.type : type, direction, nodeData); - }; -} -/** - * Function attaching a neighbors callback iterator method to the Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ - - -function attachForEachNeighbor(Class, description) { - var name = description.name, - type = description.type, - direction = description.direction; - var forEachName = 'forEach' + name[0].toUpperCase() + name.slice(1, -1); - /** - * Function iterating over all the relevant neighbors using a callback. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - Class.prototype[forEachName] = function (node, callback) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return; - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (typeof nodeData === 'undefined') throw new NotFoundGraphError("Graph.".concat(forEachName, ": could not find the \"").concat(node, "\" node in the graph.")); // Here, we want to iterate over a node's relevant neighbors - - forEachNeighbor(false, type === 'mixed' ? this.type : type, direction, nodeData, callback); - }; - /** - * Function mapping the relevant neighbors using a callback. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - - var mapName = 'map' + name[0].toUpperCase() + name.slice(1); - - Class.prototype[mapName] = function (node, callback) { - // TODO: optimize when size is known beforehand - var result = []; - this[forEachName](node, function (n, a) { - result.push(callback(n, a)); - }); - return result; - }; - /** - * Function filtering the relevant neighbors using a callback. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - - var filterName = 'filter' + name[0].toUpperCase() + name.slice(1); - - Class.prototype[filterName] = function (node, callback) { - var result = []; - this[forEachName](node, function (n, a) { - if (callback(n, a)) result.push(n); - }); - return result; - }; - /** - * Function reducing the relevant neighbors using a callback. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - - var reduceName = 'reduce' + name[0].toUpperCase() + name.slice(1); - - Class.prototype[reduceName] = function (node, callback, initialValue) { - if (arguments.length < 3) throw new InvalidArgumentsGraphError("Graph.".concat(reduceName, ": missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.")); - var accumulator = initialValue; - this[forEachName](node, function (n, a) { - accumulator = callback(accumulator, n, a); - }); - return accumulator; - }; -} -/** - * Function attaching a breakable neighbors callback iterator method to the - * Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ - - -function attachFindNeighbor(Class, description) { - var name = description.name, - type = description.type, - direction = description.direction; - var capitalizedSingular = name[0].toUpperCase() + name.slice(1, -1); - var findName = 'find' + capitalizedSingular; - /** - * Function iterating over all the relevant neighbors using a callback. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - Class.prototype[findName] = function (node, callback) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return; - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (typeof nodeData === 'undefined') throw new NotFoundGraphError("Graph.".concat(findName, ": could not find the \"").concat(node, "\" node in the graph.")); // Here, we want to iterate over a node's relevant neighbors - - return forEachNeighbor(true, type === 'mixed' ? this.type : type, direction, nodeData, callback); - }; - /** - * Function iterating over all the relevant neighbors to find if any of them - * matches the given predicate. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * @return {boolean} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - - var someName = 'some' + capitalizedSingular; - - Class.prototype[someName] = function (node, callback) { - var found = this[findName](node, callback); - if (found) return true; - return false; - }; - /** - * Function iterating over all the relevant neighbors to find if all of them - * matche the given predicate. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * @return {boolean} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - - var everyName = 'every' + capitalizedSingular; - - Class.prototype[everyName] = function (node, callback) { - var found = this[findName](node, function (n, a) { - return !callback(n, a); - }); - if (found) return false; - return true; - }; -} -/** - * Function attaching a neighbors callback iterator method to the Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ - - -function attachNeighborIteratorCreator(Class, description) { - var name = description.name, - type = description.type, - direction = description.direction; - var iteratorName = name.slice(0, -1) + 'Entries'; - /** - * Function returning an iterator over all the relevant neighbors. - * - * @param {any} node - Target node. - * @return {Iterator} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - Class.prototype[iteratorName] = function (node) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return Iterator__default["default"].empty(); - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (typeof nodeData === 'undefined') throw new NotFoundGraphError("Graph.".concat(iteratorName, ": could not find the \"").concat(node, "\" node in the graph.")); // Here, we want to iterate over a node's relevant neighbors - - return createNeighborIterator(type === 'mixed' ? this.type : type, direction, nodeData); - }; -} -/** - * Function attaching every neighbor iteration method to the Graph class. - * - * @param {function} Graph - Graph class. - */ - - -function attachNeighborIterationMethods(Graph) { - NEIGHBORS_ITERATION.forEach(function (description) { - attachNeighborArrayCreator(Graph, description); - attachForEachNeighbor(Graph, description); - attachFindNeighbor(Graph, description); - attachNeighborIteratorCreator(Graph, description); - }); -} - -/** - * Graphology Adjacency Iteration - * =============================== - * - * Attaching some methods to the Graph class to be able to iterate over a - * graph's adjacency. - */ - -/** - * Function iterating over a simple graph's adjacency using a callback. - * - * @param {boolean} breakable - Can we break? - * @param {boolean} assymetric - Whether to emit undirected edges only once. - * @param {boolean} disconnectedNodes - Whether to emit disconnected nodes. - * @param {Graph} graph - Target Graph instance. - * @param {callback} function - Iteration callback. - */ -function forEachAdjacency(breakable, assymetric, disconnectedNodes, graph, callback) { - var iterator = graph._nodes.values(); - - var type = graph.type; - var step, sourceData, neighbor, adj, edgeData, targetData, shouldBreak; - - while (step = iterator.next(), step.done !== true) { - var hasEdges = false; - sourceData = step.value; - - if (type !== 'undirected') { - adj = sourceData.out; - - for (neighbor in adj) { - edgeData = adj[neighbor]; - - do { - targetData = edgeData.target; - hasEdges = true; - shouldBreak = callback(sourceData.key, targetData.key, sourceData.attributes, targetData.attributes, edgeData.key, edgeData.attributes, edgeData.undirected); - if (breakable && shouldBreak) return edgeData; - edgeData = edgeData.next; - } while (edgeData); - } - } - - if (type !== 'directed') { - adj = sourceData.undirected; - - for (neighbor in adj) { - if (assymetric && sourceData.key > neighbor) continue; - edgeData = adj[neighbor]; - - do { - targetData = edgeData.target; - if (targetData.key !== neighbor) targetData = edgeData.source; - hasEdges = true; - shouldBreak = callback(sourceData.key, targetData.key, sourceData.attributes, targetData.attributes, edgeData.key, edgeData.attributes, edgeData.undirected); - if (breakable && shouldBreak) return edgeData; - edgeData = edgeData.next; - } while (edgeData); - } - } - - if (disconnectedNodes && !hasEdges) { - shouldBreak = callback(sourceData.key, null, sourceData.attributes, null, null, null, null); - if (breakable && shouldBreak) return null; - } - } - - return; -} - -/** - * Graphology Serialization Utilities - * =================================== - * - * Collection of functions used by the graph serialization schemes. - */ -/** - * Formats internal node data into a serialized node. - * - * @param {any} key - The node's key. - * @param {object} data - Internal node's data. - * @return {array} - The serialized node. - */ - -function serializeNode(key, data) { - var serialized = { - key: key - }; - if (!isEmpty(data.attributes)) serialized.attributes = assign({}, data.attributes); - return serialized; -} -/** - * Formats internal edge data into a serialized edge. - * - * @param {any} key - The edge's key. - * @param {object} data - Internal edge's data. - * @return {array} - The serialized edge. - */ - -function serializeEdge(key, data) { - var serialized = { - key: key, - source: data.source.key, - target: data.target.key - }; - if (!isEmpty(data.attributes)) serialized.attributes = assign({}, data.attributes); - if (data.undirected) serialized.undirected = true; - return serialized; -} -/** - * Checks whether the given value is a serialized node. - * - * @param {mixed} value - Target value. - * @return {string|null} - */ - -function validateSerializedNode(value) { - if (!isPlainObject(value)) throw new InvalidArgumentsGraphError('Graph.import: invalid serialized node. A serialized node should be a plain object with at least a "key" property.'); - if (!('key' in value)) throw new InvalidArgumentsGraphError('Graph.import: serialized node is missing its key.'); - if ('attributes' in value && (!isPlainObject(value.attributes) || value.attributes === null)) throw new InvalidArgumentsGraphError('Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.'); -} -/** - * Checks whether the given value is a serialized edge. - * - * @param {mixed} value - Target value. - * @return {string|null} - */ - -function validateSerializedEdge(value) { - if (!isPlainObject(value)) throw new InvalidArgumentsGraphError('Graph.import: invalid serialized edge. A serialized edge should be a plain object with at least a "source" & "target" property.'); - if (!('source' in value)) throw new InvalidArgumentsGraphError('Graph.import: serialized edge is missing its source.'); - if (!('target' in value)) throw new InvalidArgumentsGraphError('Graph.import: serialized edge is missing its target.'); - if ('attributes' in value && (!isPlainObject(value.attributes) || value.attributes === null)) throw new InvalidArgumentsGraphError('Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.'); - if ('undirected' in value && typeof value.undirected !== 'boolean') throw new InvalidArgumentsGraphError('Graph.import: invalid undirectedness information. Undirected should be boolean or omitted.'); -} - -/** - * Constants. - */ - -var INSTANCE_ID = incrementalIdStartingFromRandomByte(); -/** - * Enums. - */ - -var TYPES = new Set(['directed', 'undirected', 'mixed']); -var EMITTER_PROPS = new Set(['domain', '_events', '_eventsCount', '_maxListeners']); -var EDGE_ADD_METHODS = [{ - name: function name(verb) { - return "".concat(verb, "Edge"); - }, - generateKey: true -}, { - name: function name(verb) { - return "".concat(verb, "DirectedEdge"); - }, - generateKey: true, - type: 'directed' -}, { - name: function name(verb) { - return "".concat(verb, "UndirectedEdge"); - }, - generateKey: true, - type: 'undirected' -}, { - name: function name(verb) { - return "".concat(verb, "EdgeWithKey"); - } -}, { - name: function name(verb) { - return "".concat(verb, "DirectedEdgeWithKey"); - }, - type: 'directed' -}, { - name: function name(verb) { - return "".concat(verb, "UndirectedEdgeWithKey"); - }, - type: 'undirected' -}]; -/** - * Default options. - */ - -var DEFAULTS = { - allowSelfLoops: true, - multi: false, - type: 'mixed' -}; -/** - * Abstract functions used by the Graph class for various methods. - */ - -/** - * Internal method used to add a node to the given graph - * - * @param {Graph} graph - Target graph. - * @param {any} node - The node's key. - * @param {object} [attributes] - Optional attributes. - * @return {NodeData} - Created node data. - */ - -function _addNode(graph, node, attributes) { - if (attributes && !isPlainObject(attributes)) throw new InvalidArgumentsGraphError("Graph.addNode: invalid attributes. Expecting an object but got \"".concat(attributes, "\"")); // String coercion - - node = '' + node; - attributes = attributes || {}; - if (graph._nodes.has(node)) throw new UsageGraphError("Graph.addNode: the \"".concat(node, "\" node already exist in the graph.")); - var data = new graph.NodeDataClass(node, attributes); // Adding the node to internal register - - graph._nodes.set(node, data); // Emitting - - - graph.emit('nodeAdded', { - key: node, - attributes: attributes - }); - return data; -} -/** - * Same as the above but without sanity checks because we call this in contexts - * where necessary checks were already done. - */ - - -function unsafeAddNode(graph, node, attributes) { - var data = new graph.NodeDataClass(node, attributes); - - graph._nodes.set(node, data); - - graph.emit('nodeAdded', { - key: node, - attributes: attributes - }); - return data; -} -/** - * Internal method used to add an arbitrary edge to the given graph. - * - * @param {Graph} graph - Target graph. - * @param {string} name - Name of the child method for errors. - * @param {boolean} mustGenerateKey - Should the graph generate an id? - * @param {boolean} undirected - Whether the edge is undirected. - * @param {any} edge - The edge's key. - * @param {any} source - The source node. - * @param {any} target - The target node. - * @param {object} [attributes] - Optional attributes. - * @return {any} - The edge. - * - * @throws {Error} - Will throw if the graph is of the wrong type. - * @throws {Error} - Will throw if the given attributes are not an object. - * @throws {Error} - Will throw if source or target doesn't exist. - * @throws {Error} - Will throw if the edge already exist. - */ - - -function addEdge(graph, name, mustGenerateKey, undirected, edge, source, target, attributes) { - // Checking validity of operation - if (!undirected && graph.type === 'undirected') throw new UsageGraphError("Graph.".concat(name, ": you cannot add a directed edge to an undirected graph. Use the #.addEdge or #.addUndirectedEdge instead.")); - if (undirected && graph.type === 'directed') throw new UsageGraphError("Graph.".concat(name, ": you cannot add an undirected edge to a directed graph. Use the #.addEdge or #.addDirectedEdge instead.")); - if (attributes && !isPlainObject(attributes)) throw new InvalidArgumentsGraphError("Graph.".concat(name, ": invalid attributes. Expecting an object but got \"").concat(attributes, "\"")); // Coercion of source & target: - - source = '' + source; - target = '' + target; - attributes = attributes || {}; - if (!graph.allowSelfLoops && source === target) throw new UsageGraphError("Graph.".concat(name, ": source & target are the same (\"").concat(source, "\"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.")); - - var sourceData = graph._nodes.get(source), - targetData = graph._nodes.get(target); - - if (!sourceData) throw new NotFoundGraphError("Graph.".concat(name, ": source node \"").concat(source, "\" not found.")); - if (!targetData) throw new NotFoundGraphError("Graph.".concat(name, ": target node \"").concat(target, "\" not found.")); // Must the graph generate an id for this edge? - - var eventData = { - key: null, - undirected: undirected, - source: source, - target: target, - attributes: attributes - }; - - if (mustGenerateKey) { - // NOTE: in this case we can guarantee that the key does not already - // exist and is already correctly casted as a string - edge = graph._edgeKeyGenerator(); - } else { - // Coercion of edge key - edge = '' + edge; // Here, we have a key collision - - if (graph._edges.has(edge)) throw new UsageGraphError("Graph.".concat(name, ": the \"").concat(edge, "\" edge already exists in the graph.")); - } // Here, we might have a source / target collision - - - if (!graph.multi && (undirected ? typeof sourceData.undirected[target] !== 'undefined' : typeof sourceData.out[target] !== 'undefined')) { - throw new UsageGraphError("Graph.".concat(name, ": an edge linking \"").concat(source, "\" to \"").concat(target, "\" already exists. If you really want to add multiple edges linking those nodes, you should create a multi graph by using the 'multi' option.")); - } // Storing some data - - - var edgeData = new EdgeData(undirected, edge, sourceData, targetData, attributes); // Adding the edge to the internal register - - graph._edges.set(edge, edgeData); // Incrementing node degree counters - - - var isSelfLoop = source === target; - - if (undirected) { - sourceData.undirectedDegree++; - targetData.undirectedDegree++; - if (isSelfLoop) graph._undirectedSelfLoopCount++; - } else { - sourceData.outDegree++; - targetData.inDegree++; - if (isSelfLoop) graph._directedSelfLoopCount++; - } // Updating relevant index - - - if (graph.multi) edgeData.attachMulti();else edgeData.attach(); - if (undirected) graph._undirectedSize++;else graph._directedSize++; // Emitting - - eventData.key = edge; - graph.emit('edgeAdded', eventData); - return edge; -} -/** - * Internal method used to add an arbitrary edge to the given graph. - * - * @param {Graph} graph - Target graph. - * @param {string} name - Name of the child method for errors. - * @param {boolean} mustGenerateKey - Should the graph generate an id? - * @param {boolean} undirected - Whether the edge is undirected. - * @param {any} edge - The edge's key. - * @param {any} source - The source node. - * @param {any} target - The target node. - * @param {object} [attributes] - Optional attributes. - * @param {boolean} [asUpdater] - Are we updating or merging? - * @return {any} - The edge. - * - * @throws {Error} - Will throw if the graph is of the wrong type. - * @throws {Error} - Will throw if the given attributes are not an object. - * @throws {Error} - Will throw if source or target doesn't exist. - * @throws {Error} - Will throw if the edge already exist. - */ - - -function mergeEdge(graph, name, mustGenerateKey, undirected, edge, source, target, attributes, asUpdater) { - // Checking validity of operation - if (!undirected && graph.type === 'undirected') throw new UsageGraphError("Graph.".concat(name, ": you cannot merge/update a directed edge to an undirected graph. Use the #.mergeEdge/#.updateEdge or #.addUndirectedEdge instead.")); - if (undirected && graph.type === 'directed') throw new UsageGraphError("Graph.".concat(name, ": you cannot merge/update an undirected edge to a directed graph. Use the #.mergeEdge/#.updateEdge or #.addDirectedEdge instead.")); - - if (attributes) { - if (asUpdater) { - if (typeof attributes !== 'function') throw new InvalidArgumentsGraphError("Graph.".concat(name, ": invalid updater function. Expecting a function but got \"").concat(attributes, "\"")); - } else { - if (!isPlainObject(attributes)) throw new InvalidArgumentsGraphError("Graph.".concat(name, ": invalid attributes. Expecting an object but got \"").concat(attributes, "\"")); - } - } // Coercion of source & target: - - - source = '' + source; - target = '' + target; - var updater; - - if (asUpdater) { - updater = attributes; - attributes = undefined; - } - - if (!graph.allowSelfLoops && source === target) throw new UsageGraphError("Graph.".concat(name, ": source & target are the same (\"").concat(source, "\"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.")); - - var sourceData = graph._nodes.get(source); - - var targetData = graph._nodes.get(target); - - var edgeData; // Do we need to handle duplicate? - - var alreadyExistingEdgeData; - - if (!mustGenerateKey) { - edgeData = graph._edges.get(edge); - - if (edgeData) { - // Here, we need to ensure, if the user gave a key, that source & target - // are consistent - if (edgeData.source.key !== source || edgeData.target.key !== target) { - // If source or target inconsistent - if (!undirected || edgeData.source.key !== target || edgeData.target.key !== source) { - // If directed, or source/target aren't flipped - throw new UsageGraphError("Graph.".concat(name, ": inconsistency detected when attempting to merge the \"").concat(edge, "\" edge with \"").concat(source, "\" source & \"").concat(target, "\" target vs. (\"").concat(edgeData.source.key, "\", \"").concat(edgeData.target.key, "\").")); - } - } - - alreadyExistingEdgeData = edgeData; - } - } // Here, we might have a source / target collision - - - if (!alreadyExistingEdgeData && !graph.multi && sourceData) { - alreadyExistingEdgeData = undirected ? sourceData.undirected[target] : sourceData.out[target]; - } // Handling duplicates - - - if (alreadyExistingEdgeData) { - var info = [alreadyExistingEdgeData.key, false, false, false]; // We can skip the attribute merging part if the user did not provide them - - if (asUpdater ? !updater : !attributes) return info; // Updating the attributes - - if (asUpdater) { - var oldAttributes = alreadyExistingEdgeData.attributes; - alreadyExistingEdgeData.attributes = updater(oldAttributes); - graph.emit('edgeAttributesUpdated', { - type: 'replace', - key: alreadyExistingEdgeData.key, - attributes: alreadyExistingEdgeData.attributes - }); - } // Merging the attributes - else { - assign(alreadyExistingEdgeData.attributes, attributes); - graph.emit('edgeAttributesUpdated', { - type: 'merge', - key: alreadyExistingEdgeData.key, - attributes: alreadyExistingEdgeData.attributes, - data: attributes - }); - } - - return info; - } - - attributes = attributes || {}; - if (asUpdater && updater) attributes = updater(attributes); // Must the graph generate an id for this edge? - - var eventData = { - key: null, - undirected: undirected, - source: source, - target: target, - attributes: attributes - }; - - if (mustGenerateKey) { - // NOTE: in this case we can guarantee that the key does not already - // exist and is already correctly casted as a string - edge = graph._edgeKeyGenerator(); - } else { - // Coercion of edge key - edge = '' + edge; // Here, we have a key collision - - if (graph._edges.has(edge)) throw new UsageGraphError("Graph.".concat(name, ": the \"").concat(edge, "\" edge already exists in the graph.")); - } - - var sourceWasAdded = false; - var targetWasAdded = false; - - if (!sourceData) { - sourceData = unsafeAddNode(graph, source, {}); - sourceWasAdded = true; - - if (source === target) { - targetData = sourceData; - targetWasAdded = true; - } - } - - if (!targetData) { - targetData = unsafeAddNode(graph, target, {}); - targetWasAdded = true; - } // Storing some data - - - edgeData = new EdgeData(undirected, edge, sourceData, targetData, attributes); // Adding the edge to the internal register - - graph._edges.set(edge, edgeData); // Incrementing node degree counters - - - var isSelfLoop = source === target; - - if (undirected) { - sourceData.undirectedDegree++; - targetData.undirectedDegree++; - if (isSelfLoop) graph._undirectedSelfLoopCount++; - } else { - sourceData.outDegree++; - targetData.inDegree++; - if (isSelfLoop) graph._directedSelfLoopCount++; - } // Updating relevant index - - - if (graph.multi) edgeData.attachMulti();else edgeData.attach(); - if (undirected) graph._undirectedSize++;else graph._directedSize++; // Emitting - - eventData.key = edge; - graph.emit('edgeAdded', eventData); - return [edge, true, sourceWasAdded, targetWasAdded]; -} -/** - * Internal method used to drop an edge. - * - * @param {Graph} graph - Target graph. - * @param {EdgeData} edgeData - Data of the edge to drop. - */ - - -function dropEdgeFromData(graph, edgeData) { - // Dropping the edge from the register - graph._edges["delete"](edgeData.key); // Updating related degrees - - - var sourceData = edgeData.source, - targetData = edgeData.target, - attributes = edgeData.attributes; - var undirected = edgeData.undirected; - var isSelfLoop = sourceData === targetData; - - if (undirected) { - sourceData.undirectedDegree--; - targetData.undirectedDegree--; - if (isSelfLoop) graph._undirectedSelfLoopCount--; - } else { - sourceData.outDegree--; - targetData.inDegree--; - if (isSelfLoop) graph._directedSelfLoopCount--; - } // Clearing index - - - if (graph.multi) edgeData.detachMulti();else edgeData.detach(); - if (undirected) graph._undirectedSize--;else graph._directedSize--; // Emitting - - graph.emit('edgeDropped', { - key: edgeData.key, - attributes: attributes, - source: sourceData.key, - target: targetData.key, - undirected: undirected - }); -} -/** - * Graph class - * - * @constructor - * @param {object} [options] - Options: - * @param {boolean} [allowSelfLoops] - Allow self loops? - * @param {string} [type] - Type of the graph. - * @param {boolean} [map] - Allow references as keys? - * @param {boolean} [multi] - Allow parallel edges? - * - * @throws {Error} - Will throw if the arguments are not valid. - */ - - -var Graph = /*#__PURE__*/function (_EventEmitter) { - _inheritsLoose(Graph, _EventEmitter); - - function Graph(options) { - var _this; - - _this = _EventEmitter.call(this) || this; //-- Solving options - - options = assign({}, DEFAULTS, options); // Enforcing options validity - - if (typeof options.multi !== 'boolean') throw new InvalidArgumentsGraphError("Graph.constructor: invalid 'multi' option. Expecting a boolean but got \"".concat(options.multi, "\".")); - if (!TYPES.has(options.type)) throw new InvalidArgumentsGraphError("Graph.constructor: invalid 'type' option. Should be one of \"mixed\", \"directed\" or \"undirected\" but got \"".concat(options.type, "\".")); - if (typeof options.allowSelfLoops !== 'boolean') throw new InvalidArgumentsGraphError("Graph.constructor: invalid 'allowSelfLoops' option. Expecting a boolean but got \"".concat(options.allowSelfLoops, "\".")); //-- Private properties - // Utilities - - var NodeDataClass = options.type === 'mixed' ? MixedNodeData : options.type === 'directed' ? DirectedNodeData : UndirectedNodeData; - privateProperty(_assertThisInitialized(_this), 'NodeDataClass', NodeDataClass); // Internal edge key generator - // NOTE: this internal generator produce keys that are strings - // composed of a weird prefix, an incremental instance id starting from - // a random byte and finally an internal instance incremental id. - // All this to avoid intra-frame and cross-frame adversarial inputs - // that can force a single #.addEdge call to degenerate into a O(n) - // available key search loop. - // It also ensures that automatically generated edge keys are unlikely - // to produce collisions with arbitrary keys given by users. - - var instancePrefix = 'geid_' + INSTANCE_ID() + '_'; - var edgeId = 0; - - var edgeKeyGenerator = function edgeKeyGenerator() { - var availableEdgeKey; - - do { - availableEdgeKey = instancePrefix + edgeId++; - } while (_this._edges.has(availableEdgeKey)); - - return availableEdgeKey; - }; // Indexes - - - privateProperty(_assertThisInitialized(_this), '_attributes', {}); - privateProperty(_assertThisInitialized(_this), '_nodes', new Map()); - privateProperty(_assertThisInitialized(_this), '_edges', new Map()); - privateProperty(_assertThisInitialized(_this), '_directedSize', 0); - privateProperty(_assertThisInitialized(_this), '_undirectedSize', 0); - privateProperty(_assertThisInitialized(_this), '_directedSelfLoopCount', 0); - privateProperty(_assertThisInitialized(_this), '_undirectedSelfLoopCount', 0); - privateProperty(_assertThisInitialized(_this), '_edgeKeyGenerator', edgeKeyGenerator); // Options - - privateProperty(_assertThisInitialized(_this), '_options', options); // Emitter properties - - EMITTER_PROPS.forEach(function (prop) { - return privateProperty(_assertThisInitialized(_this), prop, _this[prop]); - }); //-- Properties readers - - readOnlyProperty(_assertThisInitialized(_this), 'order', function () { - return _this._nodes.size; - }); - readOnlyProperty(_assertThisInitialized(_this), 'size', function () { - return _this._edges.size; - }); - readOnlyProperty(_assertThisInitialized(_this), 'directedSize', function () { - return _this._directedSize; - }); - readOnlyProperty(_assertThisInitialized(_this), 'undirectedSize', function () { - return _this._undirectedSize; - }); - readOnlyProperty(_assertThisInitialized(_this), 'selfLoopCount', function () { - return _this._directedSelfLoopCount + _this._undirectedSelfLoopCount; - }); - readOnlyProperty(_assertThisInitialized(_this), 'directedSelfLoopCount', function () { - return _this._directedSelfLoopCount; - }); - readOnlyProperty(_assertThisInitialized(_this), 'undirectedSelfLoopCount', function () { - return _this._undirectedSelfLoopCount; - }); - readOnlyProperty(_assertThisInitialized(_this), 'multi', _this._options.multi); - readOnlyProperty(_assertThisInitialized(_this), 'type', _this._options.type); - readOnlyProperty(_assertThisInitialized(_this), 'allowSelfLoops', _this._options.allowSelfLoops); - readOnlyProperty(_assertThisInitialized(_this), 'implementation', function () { - return 'graphology'; - }); - return _this; - } - - var _proto = Graph.prototype; - - _proto._resetInstanceCounters = function _resetInstanceCounters() { - this._directedSize = 0; - this._undirectedSize = 0; - this._directedSelfLoopCount = 0; - this._undirectedSelfLoopCount = 0; - } - /**--------------------------------------------------------------------------- - * Read - **--------------------------------------------------------------------------- - */ - - /** - * Method returning whether the given node is found in the graph. - * - * @param {any} node - The node. - * @return {boolean} - */ - ; - - _proto.hasNode = function hasNode(node) { - return this._nodes.has('' + node); - } - /** - * Method returning whether the given directed edge is found in the graph. - * - * Arity 1: - * @param {any} edge - The edge's key. - * - * Arity 2: - * @param {any} source - The edge's source. - * @param {any} target - The edge's target. - * - * @return {boolean} - * - * @throws {Error} - Will throw if the arguments are invalid. - */ - ; - - _proto.hasDirectedEdge = function hasDirectedEdge(source, target) { - // Early termination - if (this.type === 'undirected') return false; - - if (arguments.length === 1) { - var edge = '' + source; - - var edgeData = this._edges.get(edge); - - return !!edgeData && !edgeData.undirected; - } else if (arguments.length === 2) { - source = '' + source; - target = '' + target; // If the node source or the target is not in the graph we break - - var nodeData = this._nodes.get(source); - - if (!nodeData) return false; // Is there a directed edge pointing toward target? - - var edges = nodeData.out[target]; - if (!edges) return false; - return this.multi ? !!edges.size : true; - } - - throw new InvalidArgumentsGraphError("Graph.hasDirectedEdge: invalid arity (".concat(arguments.length, ", instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.")); - } - /** - * Method returning whether the given undirected edge is found in the graph. - * - * Arity 1: - * @param {any} edge - The edge's key. - * - * Arity 2: - * @param {any} source - The edge's source. - * @param {any} target - The edge's target. - * - * @return {boolean} - * - * @throws {Error} - Will throw if the arguments are invalid. - */ - ; - - _proto.hasUndirectedEdge = function hasUndirectedEdge(source, target) { - // Early termination - if (this.type === 'directed') return false; - - if (arguments.length === 1) { - var edge = '' + source; - - var edgeData = this._edges.get(edge); - - return !!edgeData && edgeData.undirected; - } else if (arguments.length === 2) { - source = '' + source; - target = '' + target; // If the node source or the target is not in the graph we break - - var nodeData = this._nodes.get(source); - - if (!nodeData) return false; // Is there a directed edge pointing toward target? - - var edges = nodeData.undirected[target]; - if (!edges) return false; - return this.multi ? !!edges.size : true; - } - - throw new InvalidArgumentsGraphError("Graph.hasDirectedEdge: invalid arity (".concat(arguments.length, ", instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.")); - } - /** - * Method returning whether the given edge is found in the graph. - * - * Arity 1: - * @param {any} edge - The edge's key. - * - * Arity 2: - * @param {any} source - The edge's source. - * @param {any} target - The edge's target. - * - * @return {boolean} - * - * @throws {Error} - Will throw if the arguments are invalid. - */ - ; - - _proto.hasEdge = function hasEdge(source, target) { - if (arguments.length === 1) { - var edge = '' + source; - return this._edges.has(edge); - } else if (arguments.length === 2) { - source = '' + source; - target = '' + target; // If the node source or the target is not in the graph we break - - var nodeData = this._nodes.get(source); - - if (!nodeData) return false; // Is there a directed edge pointing toward target? - - var edges = typeof nodeData.out !== 'undefined' && nodeData.out[target]; - if (!edges) edges = typeof nodeData.undirected !== 'undefined' && nodeData.undirected[target]; - if (!edges) return false; - return this.multi ? !!edges.size : true; - } - - throw new InvalidArgumentsGraphError("Graph.hasEdge: invalid arity (".concat(arguments.length, ", instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.")); - } - /** - * Method returning the edge matching source & target in a directed fashion. - * - * @param {any} source - The edge's source. - * @param {any} target - The edge's target. - * - * @return {any|undefined} - * - * @throws {Error} - Will throw if the graph is multi. - * @throws {Error} - Will throw if source or target doesn't exist. - */ - ; - - _proto.directedEdge = function directedEdge(source, target) { - if (this.type === 'undirected') return; - source = '' + source; - target = '' + target; - if (this.multi) throw new UsageGraphError('Graph.directedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.directedEdges instead.'); - - var sourceData = this._nodes.get(source); - - if (!sourceData) throw new NotFoundGraphError("Graph.directedEdge: could not find the \"".concat(source, "\" source node in the graph.")); - if (!this._nodes.has(target)) throw new NotFoundGraphError("Graph.directedEdge: could not find the \"".concat(target, "\" target node in the graph.")); - var edgeData = sourceData.out && sourceData.out[target] || undefined; - if (edgeData) return edgeData.key; - } - /** - * Method returning the edge matching source & target in a undirected fashion. - * - * @param {any} source - The edge's source. - * @param {any} target - The edge's target. - * - * @return {any|undefined} - * - * @throws {Error} - Will throw if the graph is multi. - * @throws {Error} - Will throw if source or target doesn't exist. - */ - ; - - _proto.undirectedEdge = function undirectedEdge(source, target) { - if (this.type === 'directed') return; - source = '' + source; - target = '' + target; - if (this.multi) throw new UsageGraphError('Graph.undirectedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.undirectedEdges instead.'); - - var sourceData = this._nodes.get(source); - - if (!sourceData) throw new NotFoundGraphError("Graph.undirectedEdge: could not find the \"".concat(source, "\" source node in the graph.")); - if (!this._nodes.has(target)) throw new NotFoundGraphError("Graph.undirectedEdge: could not find the \"".concat(target, "\" target node in the graph.")); - var edgeData = sourceData.undirected && sourceData.undirected[target] || undefined; - if (edgeData) return edgeData.key; - } - /** - * Method returning the edge matching source & target in a mixed fashion. - * - * @param {any} source - The edge's source. - * @param {any} target - The edge's target. - * - * @return {any|undefined} - * - * @throws {Error} - Will throw if the graph is multi. - * @throws {Error} - Will throw if source or target doesn't exist. - */ - ; - - _proto.edge = function edge(source, target) { - if (this.multi) throw new UsageGraphError('Graph.edge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.edges instead.'); - source = '' + source; - target = '' + target; - - var sourceData = this._nodes.get(source); - - if (!sourceData) throw new NotFoundGraphError("Graph.edge: could not find the \"".concat(source, "\" source node in the graph.")); - if (!this._nodes.has(target)) throw new NotFoundGraphError("Graph.edge: could not find the \"".concat(target, "\" target node in the graph.")); - var edgeData = sourceData.out && sourceData.out[target] || sourceData.undirected && sourceData.undirected[target] || undefined; - if (edgeData) return edgeData.key; - } - /** - * Method returning whether two nodes are directed neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.areDirectedNeighbors = function areDirectedNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.areDirectedNeighbors: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'undirected') return false; - return neighbor in nodeData["in"] || neighbor in nodeData.out; - } - /** - * Method returning whether two nodes are out neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.areOutNeighbors = function areOutNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.areOutNeighbors: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'undirected') return false; - return neighbor in nodeData.out; - } - /** - * Method returning whether two nodes are in neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.areInNeighbors = function areInNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.areInNeighbors: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'undirected') return false; - return neighbor in nodeData["in"]; - } - /** - * Method returning whether two nodes are undirected neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.areUndirectedNeighbors = function areUndirectedNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.areUndirectedNeighbors: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'directed') return false; - return neighbor in nodeData.undirected; - } - /** - * Method returning whether two nodes are neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.areNeighbors = function areNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.areNeighbors: could not find the \"".concat(node, "\" node in the graph.")); - - if (this.type !== 'undirected') { - if (neighbor in nodeData["in"] || neighbor in nodeData.out) return true; - } - - if (this.type !== 'directed') { - if (neighbor in nodeData.undirected) return true; - } - - return false; - } - /** - * Method returning whether two nodes are inbound neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.areInboundNeighbors = function areInboundNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.areInboundNeighbors: could not find the \"".concat(node, "\" node in the graph.")); - - if (this.type !== 'undirected') { - if (neighbor in nodeData["in"]) return true; - } - - if (this.type !== 'directed') { - if (neighbor in nodeData.undirected) return true; - } - - return false; - } - /** - * Method returning whether two nodes are outbound neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.areOutboundNeighbors = function areOutboundNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.areOutboundNeighbors: could not find the \"".concat(node, "\" node in the graph.")); - - if (this.type !== 'undirected') { - if (neighbor in nodeData.out) return true; - } - - if (this.type !== 'directed') { - if (neighbor in nodeData.undirected) return true; - } - - return false; - } - /** - * Method returning the given node's in degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.inDegree = function inDegree(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.inDegree: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'undirected') return 0; - return nodeData.inDegree; - } - /** - * Method returning the given node's out degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.outDegree = function outDegree(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.outDegree: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'undirected') return 0; - return nodeData.outDegree; - } - /** - * Method returning the given node's directed degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.directedDegree = function directedDegree(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.directedDegree: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'undirected') return 0; - return nodeData.inDegree + nodeData.outDegree; - } - /** - * Method returning the given node's undirected degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.undirectedDegree = function undirectedDegree(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.undirectedDegree: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'directed') return 0; - return nodeData.undirectedDegree; - } - /** - * Method returning the given node's inbound degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's inbound degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.inboundDegree = function inboundDegree(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.inboundDegree: could not find the \"".concat(node, "\" node in the graph.")); - var degree = 0; - - if (this.type !== 'directed') { - degree += nodeData.undirectedDegree; - } - - if (this.type !== 'undirected') { - degree += nodeData.inDegree; - } - - return degree; - } - /** - * Method returning the given node's outbound degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's outbound degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.outboundDegree = function outboundDegree(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.outboundDegree: could not find the \"".concat(node, "\" node in the graph.")); - var degree = 0; - - if (this.type !== 'directed') { - degree += nodeData.undirectedDegree; - } - - if (this.type !== 'undirected') { - degree += nodeData.outDegree; - } - - return degree; - } - /** - * Method returning the given node's directed degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.degree = function degree(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.degree: could not find the \"".concat(node, "\" node in the graph.")); - var degree = 0; - - if (this.type !== 'directed') { - degree += nodeData.undirectedDegree; - } - - if (this.type !== 'undirected') { - degree += nodeData.inDegree + nodeData.outDegree; - } - - return degree; - } - /** - * Method returning the given node's in degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.inDegreeWithoutSelfLoops = function inDegreeWithoutSelfLoops(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.inDegreeWithoutSelfLoops: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'undirected') return 0; - var self = nodeData["in"][node]; - var loops = self ? this.multi ? self.size : 1 : 0; - return nodeData.inDegree - loops; - } - /** - * Method returning the given node's out degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.outDegreeWithoutSelfLoops = function outDegreeWithoutSelfLoops(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.outDegreeWithoutSelfLoops: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'undirected') return 0; - var self = nodeData.out[node]; - var loops = self ? this.multi ? self.size : 1 : 0; - return nodeData.outDegree - loops; - } - /** - * Method returning the given node's directed degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.directedDegreeWithoutSelfLoops = function directedDegreeWithoutSelfLoops(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.directedDegreeWithoutSelfLoops: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'undirected') return 0; - var self = nodeData.out[node]; - var loops = self ? this.multi ? self.size : 1 : 0; - return nodeData.inDegree + nodeData.outDegree - loops * 2; - } - /** - * Method returning the given node's undirected degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.undirectedDegreeWithoutSelfLoops = function undirectedDegreeWithoutSelfLoops(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.undirectedDegreeWithoutSelfLoops: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'directed') return 0; - var self = nodeData.undirected[node]; - var loops = self ? this.multi ? self.size : 1 : 0; - return nodeData.undirectedDegree - loops * 2; - } - /** - * Method returning the given node's inbound degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's inbound degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.inboundDegreeWithoutSelfLoops = function inboundDegreeWithoutSelfLoops(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.inboundDegreeWithoutSelfLoops: could not find the \"".concat(node, "\" node in the graph.")); - var self; - var degree = 0; - var loops = 0; - - if (this.type !== 'directed') { - degree += nodeData.undirectedDegree; - self = nodeData.undirected[node]; - loops += (self ? this.multi ? self.size : 1 : 0) * 2; - } - - if (this.type !== 'undirected') { - degree += nodeData.inDegree; - self = nodeData.out[node]; - loops += self ? this.multi ? self.size : 1 : 0; - } - - return degree - loops; - } - /** - * Method returning the given node's outbound degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's outbound degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.outboundDegreeWithoutSelfLoops = function outboundDegreeWithoutSelfLoops(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.outboundDegreeWithoutSelfLoops: could not find the \"".concat(node, "\" node in the graph.")); - var self; - var degree = 0; - var loops = 0; - - if (this.type !== 'directed') { - degree += nodeData.undirectedDegree; - self = nodeData.undirected[node]; - loops += (self ? this.multi ? self.size : 1 : 0) * 2; - } - - if (this.type !== 'undirected') { - degree += nodeData.outDegree; - self = nodeData["in"][node]; - loops += self ? this.multi ? self.size : 1 : 0; - } - - return degree - loops; - } - /** - * Method returning the given node's directed degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.degreeWithoutSelfLoops = function degreeWithoutSelfLoops(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.degreeWithoutSelfLoops: could not find the \"".concat(node, "\" node in the graph.")); - var self; - var degree = 0; - var loops = 0; - - if (this.type !== 'directed') { - degree += nodeData.undirectedDegree; - self = nodeData.undirected[node]; - loops += (self ? this.multi ? self.size : 1 : 0) * 2; - } - - if (this.type !== 'undirected') { - degree += nodeData.inDegree + nodeData.outDegree; - self = nodeData.out[node]; - loops += (self ? this.multi ? self.size : 1 : 0) * 2; - } - - return degree - loops; - } - /** - * Method returning the given edge's source. - * - * @param {any} edge - The edge's key. - * @return {any} - The edge's source. - * - * @throws {Error} - Will throw if the edge isn't in the graph. - */ - ; - - _proto.source = function source(edge) { - edge = '' + edge; - - var data = this._edges.get(edge); - - if (!data) throw new NotFoundGraphError("Graph.source: could not find the \"".concat(edge, "\" edge in the graph.")); - return data.source.key; - } - /** - * Method returning the given edge's target. - * - * @param {any} edge - The edge's key. - * @return {any} - The edge's target. - * - * @throws {Error} - Will throw if the edge isn't in the graph. - */ - ; - - _proto.target = function target(edge) { - edge = '' + edge; - - var data = this._edges.get(edge); - - if (!data) throw new NotFoundGraphError("Graph.target: could not find the \"".concat(edge, "\" edge in the graph.")); - return data.target.key; - } - /** - * Method returning the given edge's extremities. - * - * @param {any} edge - The edge's key. - * @return {array} - The edge's extremities. - * - * @throws {Error} - Will throw if the edge isn't in the graph. - */ - ; - - _proto.extremities = function extremities(edge) { - edge = '' + edge; - - var edgeData = this._edges.get(edge); - - if (!edgeData) throw new NotFoundGraphError("Graph.extremities: could not find the \"".concat(edge, "\" edge in the graph.")); - return [edgeData.source.key, edgeData.target.key]; - } - /** - * Given a node & an edge, returns the other extremity of the edge. - * - * @param {any} node - The node's key. - * @param {any} edge - The edge's key. - * @return {any} - The related node. - * - * @throws {Error} - Will throw if the edge isn't in the graph or if the - * edge & node are not related. - */ - ; - - _proto.opposite = function opposite(node, edge) { - node = '' + node; - edge = '' + edge; - - var data = this._edges.get(edge); - - if (!data) throw new NotFoundGraphError("Graph.opposite: could not find the \"".concat(edge, "\" edge in the graph.")); - var source = data.source.key; - var target = data.target.key; - if (node === source) return target; - if (node === target) return source; - throw new NotFoundGraphError("Graph.opposite: the \"".concat(node, "\" node is not attached to the \"").concat(edge, "\" edge (").concat(source, ", ").concat(target, ").")); - } - /** - * Returns whether the given edge has the given node as extremity. - * - * @param {any} edge - The edge's key. - * @param {any} node - The node's key. - * @return {boolean} - The related node. - * - * @throws {Error} - Will throw if either the node or the edge isn't in the graph. - */ - ; - - _proto.hasExtremity = function hasExtremity(edge, node) { - edge = '' + edge; - node = '' + node; - - var data = this._edges.get(edge); - - if (!data) throw new NotFoundGraphError("Graph.hasExtremity: could not find the \"".concat(edge, "\" edge in the graph.")); - return data.source.key === node || data.target.key === node; - } - /** - * Method returning whether the given edge is undirected. - * - * @param {any} edge - The edge's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the edge isn't in the graph. - */ - ; - - _proto.isUndirected = function isUndirected(edge) { - edge = '' + edge; - - var data = this._edges.get(edge); - - if (!data) throw new NotFoundGraphError("Graph.isUndirected: could not find the \"".concat(edge, "\" edge in the graph.")); - return data.undirected; - } - /** - * Method returning whether the given edge is directed. - * - * @param {any} edge - The edge's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the edge isn't in the graph. - */ - ; - - _proto.isDirected = function isDirected(edge) { - edge = '' + edge; - - var data = this._edges.get(edge); - - if (!data) throw new NotFoundGraphError("Graph.isDirected: could not find the \"".concat(edge, "\" edge in the graph.")); - return !data.undirected; - } - /** - * Method returning whether the given edge is a self loop. - * - * @param {any} edge - The edge's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the edge isn't in the graph. - */ - ; - - _proto.isSelfLoop = function isSelfLoop(edge) { - edge = '' + edge; - - var data = this._edges.get(edge); - - if (!data) throw new NotFoundGraphError("Graph.isSelfLoop: could not find the \"".concat(edge, "\" edge in the graph.")); - return data.source === data.target; - } - /**--------------------------------------------------------------------------- - * Mutation - **--------------------------------------------------------------------------- - */ - - /** - * Method used to add a node to the graph. - * - * @param {any} node - The node. - * @param {object} [attributes] - Optional attributes. - * @return {any} - The node. - * - * @throws {Error} - Will throw if the given node already exist. - * @throws {Error} - Will throw if the given attributes are not an object. - */ - ; - - _proto.addNode = function addNode(node, attributes) { - var nodeData = _addNode(this, node, attributes); - - return nodeData.key; - } - /** - * Method used to merge a node into the graph. - * - * @param {any} node - The node. - * @param {object} [attributes] - Optional attributes. - * @return {any} - The node. - */ - ; - - _proto.mergeNode = function mergeNode(node, attributes) { - if (attributes && !isPlainObject(attributes)) throw new InvalidArgumentsGraphError("Graph.mergeNode: invalid attributes. Expecting an object but got \"".concat(attributes, "\"")); // String coercion - - node = '' + node; - attributes = attributes || {}; // If the node already exists, we merge the attributes - - var data = this._nodes.get(node); - - if (data) { - if (attributes) { - assign(data.attributes, attributes); - this.emit('nodeAttributesUpdated', { - type: 'merge', - key: node, - attributes: data.attributes, - data: attributes - }); - } - - return [node, false]; - } - - data = new this.NodeDataClass(node, attributes); // Adding the node to internal register - - this._nodes.set(node, data); // Emitting - - - this.emit('nodeAdded', { - key: node, - attributes: attributes - }); - return [node, true]; - } - /** - * Method used to add a node if it does not exist in the graph or else to - * update its attributes using a function. - * - * @param {any} node - The node. - * @param {function} [updater] - Optional updater function. - * @return {any} - The node. - */ - ; - - _proto.updateNode = function updateNode(node, updater) { - if (updater && typeof updater !== 'function') throw new InvalidArgumentsGraphError("Graph.updateNode: invalid updater function. Expecting a function but got \"".concat(updater, "\"")); // String coercion - - node = '' + node; // If the node already exists, we update the attributes - - var data = this._nodes.get(node); - - if (data) { - if (updater) { - var oldAttributes = data.attributes; - data.attributes = updater(oldAttributes); - this.emit('nodeAttributesUpdated', { - type: 'replace', - key: node, - attributes: data.attributes - }); - } - - return [node, false]; - } - - var attributes = updater ? updater({}) : {}; - data = new this.NodeDataClass(node, attributes); // Adding the node to internal register - - this._nodes.set(node, data); // Emitting - - - this.emit('nodeAdded', { - key: node, - attributes: attributes - }); - return [node, true]; - } - /** - * Method used to drop a single node & all its attached edges from the graph. - * - * @param {any} node - The node. - * @return {Graph} - * - * @throws {Error} - Will throw if the node doesn't exist. - */ - ; - - _proto.dropNode = function dropNode(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.dropNode: could not find the \"".concat(node, "\" node in the graph.")); - var edgeData; // Removing attached edges - // NOTE: we could be faster here, but this is such a pain to maintain - - if (this.type !== 'undirected') { - for (var neighbor in nodeData.out) { - edgeData = nodeData.out[neighbor]; - - do { - dropEdgeFromData(this, edgeData); - edgeData = edgeData.next; - } while (edgeData); - } - - for (var _neighbor in nodeData["in"]) { - edgeData = nodeData["in"][_neighbor]; - - do { - dropEdgeFromData(this, edgeData); - edgeData = edgeData.next; - } while (edgeData); - } - } - - if (this.type !== 'directed') { - for (var _neighbor2 in nodeData.undirected) { - edgeData = nodeData.undirected[_neighbor2]; - - do { - dropEdgeFromData(this, edgeData); - edgeData = edgeData.next; - } while (edgeData); - } - } // Dropping the node from the register - - - this._nodes["delete"](node); // Emitting - - - this.emit('nodeDropped', { - key: node, - attributes: nodeData.attributes - }); - } - /** - * Method used to drop a single edge from the graph. - * - * Arity 1: - * @param {any} edge - The edge. - * - * Arity 2: - * @param {any} source - Source node. - * @param {any} target - Target node. - * - * @return {Graph} - * - * @throws {Error} - Will throw if the edge doesn't exist. - */ - ; - - _proto.dropEdge = function dropEdge(edge) { - var edgeData; - - if (arguments.length > 1) { - var source = '' + arguments[0]; - var target = '' + arguments[1]; - edgeData = getMatchingEdge(this, source, target, this.type); - if (!edgeData) throw new NotFoundGraphError("Graph.dropEdge: could not find the \"".concat(source, "\" -> \"").concat(target, "\" edge in the graph.")); - } else { - edge = '' + edge; - edgeData = this._edges.get(edge); - if (!edgeData) throw new NotFoundGraphError("Graph.dropEdge: could not find the \"".concat(edge, "\" edge in the graph.")); - } - - dropEdgeFromData(this, edgeData); - return this; - } - /** - * Method used to drop a single directed edge from the graph. - * - * @param {any} source - Source node. - * @param {any} target - Target node. - * - * @return {Graph} - * - * @throws {Error} - Will throw if the edge doesn't exist. - */ - ; - - _proto.dropDirectedEdge = function dropDirectedEdge(source, target) { - if (arguments.length < 2) throw new UsageGraphError('Graph.dropDirectedEdge: it does not make sense to try and drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.'); - if (this.multi) throw new UsageGraphError('Graph.dropDirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.'); - source = '' + source; - target = '' + target; - var edgeData = getMatchingEdge(this, source, target, 'directed'); - if (!edgeData) throw new NotFoundGraphError("Graph.dropDirectedEdge: could not find a \"".concat(source, "\" -> \"").concat(target, "\" edge in the graph.")); - dropEdgeFromData(this, edgeData); - return this; - } - /** - * Method used to drop a single undirected edge from the graph. - * - * @param {any} source - Source node. - * @param {any} target - Target node. - * - * @return {Graph} - * - * @throws {Error} - Will throw if the edge doesn't exist. - */ - ; - - _proto.dropUndirectedEdge = function dropUndirectedEdge(source, target) { - if (arguments.length < 2) throw new UsageGraphError('Graph.dropUndirectedEdge: it does not make sense to drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.'); - if (this.multi) throw new UsageGraphError('Graph.dropUndirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.'); - var edgeData = getMatchingEdge(this, source, target, 'undirected'); - if (!edgeData) throw new NotFoundGraphError("Graph.dropUndirectedEdge: could not find a \"".concat(source, "\" -> \"").concat(target, "\" edge in the graph.")); - dropEdgeFromData(this, edgeData); - return this; - } - /** - * Method used to remove every edge & every node from the graph. - * - * @return {Graph} - */ - ; - - _proto.clear = function clear() { - // Clearing edges - this._edges.clear(); // Clearing nodes - - - this._nodes.clear(); // Reset counters - - - this._resetInstanceCounters(); // Emitting - - - this.emit('cleared'); - } - /** - * Method used to remove every edge from the graph. - * - * @return {Graph} - */ - ; - - _proto.clearEdges = function clearEdges() { - // Clearing structure index - var iterator = this._nodes.values(); - - var step; - - while (step = iterator.next(), step.done !== true) { - step.value.clear(); - } // Clearing edges - - - this._edges.clear(); // Reset counters - - - this._resetInstanceCounters(); // Emitting - - - this.emit('edgesCleared'); - } - /**--------------------------------------------------------------------------- - * Attributes-related methods - **--------------------------------------------------------------------------- - */ - - /** - * Method returning the desired graph's attribute. - * - * @param {string} name - Name of the attribute. - * @return {any} - */ - ; - - _proto.getAttribute = function getAttribute(name) { - return this._attributes[name]; - } - /** - * Method returning the graph's attributes. - * - * @return {object} - */ - ; - - _proto.getAttributes = function getAttributes() { - return this._attributes; - } - /** - * Method returning whether the graph has the desired attribute. - * - * @param {string} name - Name of the attribute. - * @return {boolean} - */ - ; - - _proto.hasAttribute = function hasAttribute(name) { - return this._attributes.hasOwnProperty(name); - } - /** - * Method setting a value for the desired graph's attribute. - * - * @param {string} name - Name of the attribute. - * @param {any} value - Value for the attribute. - * @return {Graph} - */ - ; - - _proto.setAttribute = function setAttribute(name, value) { - this._attributes[name] = value; // Emitting - - this.emit('attributesUpdated', { - type: 'set', - attributes: this._attributes, - name: name - }); - return this; - } - /** - * Method using a function to update the desired graph's attribute's value. - * - * @param {string} name - Name of the attribute. - * @param {function} updater - Function use to update the attribute's value. - * @return {Graph} - */ - ; - - _proto.updateAttribute = function updateAttribute(name, updater) { - if (typeof updater !== 'function') throw new InvalidArgumentsGraphError('Graph.updateAttribute: updater should be a function.'); - var value = this._attributes[name]; - this._attributes[name] = updater(value); // Emitting - - this.emit('attributesUpdated', { - type: 'set', - attributes: this._attributes, - name: name - }); - return this; - } - /** - * Method removing the desired graph's attribute. - * - * @param {string} name - Name of the attribute. - * @return {Graph} - */ - ; - - _proto.removeAttribute = function removeAttribute(name) { - delete this._attributes[name]; // Emitting - - this.emit('attributesUpdated', { - type: 'remove', - attributes: this._attributes, - name: name - }); - return this; - } - /** - * Method replacing the graph's attributes. - * - * @param {object} attributes - New attributes. - * @return {Graph} - * - * @throws {Error} - Will throw if given attributes are not a plain object. - */ - ; - - _proto.replaceAttributes = function replaceAttributes(attributes) { - if (!isPlainObject(attributes)) throw new InvalidArgumentsGraphError('Graph.replaceAttributes: provided attributes are not a plain object.'); - this._attributes = attributes; // Emitting - - this.emit('attributesUpdated', { - type: 'replace', - attributes: this._attributes - }); - return this; - } - /** - * Method merging the graph's attributes. - * - * @param {object} attributes - Attributes to merge. - * @return {Graph} - * - * @throws {Error} - Will throw if given attributes are not a plain object. - */ - ; - - _proto.mergeAttributes = function mergeAttributes(attributes) { - if (!isPlainObject(attributes)) throw new InvalidArgumentsGraphError('Graph.mergeAttributes: provided attributes are not a plain object.'); - assign(this._attributes, attributes); // Emitting - - this.emit('attributesUpdated', { - type: 'merge', - attributes: this._attributes, - data: attributes - }); - return this; - } - /** - * Method updating the graph's attributes. - * - * @param {function} updater - Function used to update the attributes. - * @return {Graph} - * - * @throws {Error} - Will throw if given updater is not a function. - */ - ; - - _proto.updateAttributes = function updateAttributes(updater) { - if (typeof updater !== 'function') throw new InvalidArgumentsGraphError('Graph.updateAttributes: provided updater is not a function.'); - this._attributes = updater(this._attributes); // Emitting - - this.emit('attributesUpdated', { - type: 'update', - attributes: this._attributes - }); - return this; - } - /** - * Method used to update each node's attributes using the given function. - * - * @param {function} updater - Updater function to use. - * @param {object} [hints] - Optional hints. - */ - ; - - _proto.updateEachNodeAttributes = function updateEachNodeAttributes(updater, hints) { - if (typeof updater !== 'function') throw new InvalidArgumentsGraphError('Graph.updateEachNodeAttributes: expecting an updater function.'); - if (hints && !validateHints(hints)) throw new InvalidArgumentsGraphError('Graph.updateEachNodeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}'); - - var iterator = this._nodes.values(); - - var step, nodeData; - - while (step = iterator.next(), step.done !== true) { - nodeData = step.value; - nodeData.attributes = updater(nodeData.key, nodeData.attributes); - } - - this.emit('eachNodeAttributesUpdated', { - hints: hints ? hints : null - }); - } - /** - * Method used to update each edge's attributes using the given function. - * - * @param {function} updater - Updater function to use. - * @param {object} [hints] - Optional hints. - */ - ; - - _proto.updateEachEdgeAttributes = function updateEachEdgeAttributes(updater, hints) { - if (typeof updater !== 'function') throw new InvalidArgumentsGraphError('Graph.updateEachEdgeAttributes: expecting an updater function.'); - if (hints && !validateHints(hints)) throw new InvalidArgumentsGraphError('Graph.updateEachEdgeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}'); - - var iterator = this._edges.values(); - - var step, edgeData, sourceData, targetData; - - while (step = iterator.next(), step.done !== true) { - edgeData = step.value; - sourceData = edgeData.source; - targetData = edgeData.target; - edgeData.attributes = updater(edgeData.key, edgeData.attributes, sourceData.key, targetData.key, sourceData.attributes, targetData.attributes, edgeData.undirected); - } - - this.emit('eachEdgeAttributesUpdated', { - hints: hints ? hints : null - }); - } - /**--------------------------------------------------------------------------- - * Iteration-related methods - **--------------------------------------------------------------------------- - */ - - /** - * Method iterating over the graph's adjacency using the given callback. - * - * @param {function} callback - Callback to use. - */ - ; - - _proto.forEachAdjacencyEntry = function forEachAdjacencyEntry(callback) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.forEachAdjacencyEntry: expecting a callback.'); - forEachAdjacency(false, false, false, this, callback); - }; - - _proto.forEachAdjacencyEntryWithOrphans = function forEachAdjacencyEntryWithOrphans(callback) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.forEachAdjacencyEntryWithOrphans: expecting a callback.'); - forEachAdjacency(false, false, true, this, callback); - } - /** - * Method iterating over the graph's assymetric adjacency using the given callback. - * - * @param {function} callback - Callback to use. - */ - ; - - _proto.forEachAssymetricAdjacencyEntry = function forEachAssymetricAdjacencyEntry(callback) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.forEachAssymetricAdjacencyEntry: expecting a callback.'); - forEachAdjacency(false, true, false, this, callback); - }; - - _proto.forEachAssymetricAdjacencyEntryWithOrphans = function forEachAssymetricAdjacencyEntryWithOrphans(callback) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.forEachAssymetricAdjacencyEntryWithOrphans: expecting a callback.'); - forEachAdjacency(false, true, true, this, callback); - } - /** - * Method returning the list of the graph's nodes. - * - * @return {array} - The nodes. - */ - ; - - _proto.nodes = function nodes() { - if (typeof Array.from === 'function') return Array.from(this._nodes.keys()); - return take__default["default"](this._nodes.keys(), this._nodes.size); - } - /** - * Method iterating over the graph's nodes using the given callback. - * - * @param {function} callback - Callback (key, attributes, index). - */ - ; - - _proto.forEachNode = function forEachNode(callback) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.forEachNode: expecting a callback.'); - - var iterator = this._nodes.values(); - - var step, nodeData; - - while (step = iterator.next(), step.done !== true) { - nodeData = step.value; - callback(nodeData.key, nodeData.attributes); - } - } - /** - * Method iterating attempting to find a node matching the given predicate - * function. - * - * @param {function} callback - Callback (key, attributes). - */ - ; - - _proto.findNode = function findNode(callback) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.findNode: expecting a callback.'); - - var iterator = this._nodes.values(); - - var step, nodeData; - - while (step = iterator.next(), step.done !== true) { - nodeData = step.value; - if (callback(nodeData.key, nodeData.attributes)) return nodeData.key; - } - - return; - } - /** - * Method mapping nodes. - * - * @param {function} callback - Callback (key, attributes). - */ - ; - - _proto.mapNodes = function mapNodes(callback) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.mapNode: expecting a callback.'); - - var iterator = this._nodes.values(); - - var step, nodeData; - var result = new Array(this.order); - var i = 0; - - while (step = iterator.next(), step.done !== true) { - nodeData = step.value; - result[i++] = callback(nodeData.key, nodeData.attributes); - } - - return result; - } - /** - * Method returning whether some node verify the given predicate. - * - * @param {function} callback - Callback (key, attributes). - */ - ; - - _proto.someNode = function someNode(callback) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.someNode: expecting a callback.'); - - var iterator = this._nodes.values(); - - var step, nodeData; - - while (step = iterator.next(), step.done !== true) { - nodeData = step.value; - if (callback(nodeData.key, nodeData.attributes)) return true; - } - - return false; - } - /** - * Method returning whether all node verify the given predicate. - * - * @param {function} callback - Callback (key, attributes). - */ - ; - - _proto.everyNode = function everyNode(callback) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.everyNode: expecting a callback.'); - - var iterator = this._nodes.values(); - - var step, nodeData; - - while (step = iterator.next(), step.done !== true) { - nodeData = step.value; - if (!callback(nodeData.key, nodeData.attributes)) return false; - } - - return true; - } - /** - * Method filtering nodes. - * - * @param {function} callback - Callback (key, attributes). - */ - ; - - _proto.filterNodes = function filterNodes(callback) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.filterNodes: expecting a callback.'); - - var iterator = this._nodes.values(); - - var step, nodeData; - var result = []; - - while (step = iterator.next(), step.done !== true) { - nodeData = step.value; - if (callback(nodeData.key, nodeData.attributes)) result.push(nodeData.key); - } - - return result; - } - /** - * Method reducing nodes. - * - * @param {function} callback - Callback (accumulator, key, attributes). - */ - ; - - _proto.reduceNodes = function reduceNodes(callback, initialValue) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.reduceNodes: expecting a callback.'); - if (arguments.length < 2) throw new InvalidArgumentsGraphError('Graph.reduceNodes: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.'); - var accumulator = initialValue; - - var iterator = this._nodes.values(); - - var step, nodeData; - - while (step = iterator.next(), step.done !== true) { - nodeData = step.value; - accumulator = callback(accumulator, nodeData.key, nodeData.attributes); - } - - return accumulator; - } - /** - * Method returning an iterator over the graph's node entries. - * - * @return {Iterator} - */ - ; - - _proto.nodeEntries = function nodeEntries() { - var iterator = this._nodes.values(); - - return new Iterator__default["default"](function () { - var step = iterator.next(); - if (step.done) return step; - var data = step.value; - return { - value: { - node: data.key, - attributes: data.attributes - }, - done: false - }; - }); - } - /**--------------------------------------------------------------------------- - * Serialization - **--------------------------------------------------------------------------- - */ - - /** - * Method used to export the whole graph. - * - * @return {object} - The serialized graph. - */ - ; - - _proto["export"] = function _export() { - var nodes = new Array(this._nodes.size); - var i = 0; - - this._nodes.forEach(function (data, key) { - nodes[i++] = serializeNode(key, data); - }); - - var edges = new Array(this._edges.size); - i = 0; - - this._edges.forEach(function (data, key) { - edges[i++] = serializeEdge(key, data); - }); - - return { - options: { - type: this.type, - multi: this.multi, - allowSelfLoops: this.allowSelfLoops - }, - attributes: this.getAttributes(), - nodes: nodes, - edges: edges - }; - } - /** - * Method used to import a serialized graph. - * - * @param {object|Graph} data - The serialized graph. - * @param {boolean} merge - Whether to merge data. - * @return {Graph} - Returns itself for chaining. - */ - ; - - _proto["import"] = function _import(data) { - var _this2 = this; - - var merge = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - // Importing a Graph instance directly - if (isGraph(data)) { - // Nodes - data.forEachNode(function (n, a) { - if (merge) _this2.mergeNode(n, a);else _this2.addNode(n, a); - }); // Edges - - data.forEachEdge(function (e, a, s, t, _sa, _ta, u) { - if (merge) { - if (u) _this2.mergeUndirectedEdgeWithKey(e, s, t, a);else _this2.mergeDirectedEdgeWithKey(e, s, t, a); - } else { - if (u) _this2.addUndirectedEdgeWithKey(e, s, t, a);else _this2.addDirectedEdgeWithKey(e, s, t, a); - } - }); - return this; - } // Importing a serialized graph - - - if (!isPlainObject(data)) throw new InvalidArgumentsGraphError('Graph.import: invalid argument. Expecting a serialized graph or, alternatively, a Graph instance.'); - - if (data.attributes) { - if (!isPlainObject(data.attributes)) throw new InvalidArgumentsGraphError('Graph.import: invalid attributes. Expecting a plain object.'); - if (merge) this.mergeAttributes(data.attributes);else this.replaceAttributes(data.attributes); - } - - var i, l, list, node, edge; - - if (data.nodes) { - list = data.nodes; - if (!Array.isArray(list)) throw new InvalidArgumentsGraphError('Graph.import: invalid nodes. Expecting an array.'); - - for (i = 0, l = list.length; i < l; i++) { - node = list[i]; // Validating - - validateSerializedNode(node); // Adding the node - - var _node = node, - key = _node.key, - attributes = _node.attributes; - if (merge) this.mergeNode(key, attributes);else this.addNode(key, attributes); - } - } - - if (data.edges) { - list = data.edges; - if (!Array.isArray(list)) throw new InvalidArgumentsGraphError('Graph.import: invalid edges. Expecting an array.'); - - for (i = 0, l = list.length; i < l; i++) { - edge = list[i]; // Validating - - validateSerializedEdge(edge); // Adding the edge - - var _edge = edge, - source = _edge.source, - target = _edge.target, - _attributes = _edge.attributes, - _edge$undirected = _edge.undirected, - undirected = _edge$undirected === void 0 ? false : _edge$undirected; - var method = void 0; - - if ('key' in edge) { - method = merge ? undirected ? this.mergeUndirectedEdgeWithKey : this.mergeDirectedEdgeWithKey : undirected ? this.addUndirectedEdgeWithKey : this.addDirectedEdgeWithKey; - method.call(this, edge.key, source, target, _attributes); - } else { - method = merge ? undirected ? this.mergeUndirectedEdge : this.mergeDirectedEdge : undirected ? this.addUndirectedEdge : this.addDirectedEdge; - method.call(this, source, target, _attributes); - } - } - } - - return this; - } - /**--------------------------------------------------------------------------- - * Utils - **--------------------------------------------------------------------------- - */ - - /** - * Method returning a null copy of the graph, i.e. a graph without nodes - * & edges but with the exact same options. - * - * @param {object} options - Options to merge with the current ones. - * @return {Graph} - The null copy. - */ - ; - - _proto.nullCopy = function nullCopy(options) { - var graph = new Graph(assign({}, this._options, options)); - graph.replaceAttributes(assign({}, this.getAttributes())); - return graph; - } - /** - * Method returning an empty copy of the graph, i.e. a graph without edges but - * with the exact same options. - * - * @param {object} options - Options to merge with the current ones. - * @return {Graph} - The empty copy. - */ - ; - - _proto.emptyCopy = function emptyCopy(options) { - var graph = this.nullCopy(options); - - this._nodes.forEach(function (nodeData, key) { - var attributes = assign({}, nodeData.attributes); // NOTE: no need to emit events since user cannot access the instance yet - - nodeData = new graph.NodeDataClass(key, attributes); - - graph._nodes.set(key, nodeData); - }); - - return graph; - } - /** - * Method returning an exact copy of the graph. - * - * @param {object} options - Upgrade options. - * @return {Graph} - The copy. - */ - ; - - _proto.copy = function copy(options) { - options = options || {}; - if (typeof options.type === 'string' && options.type !== this.type && options.type !== 'mixed') throw new UsageGraphError("Graph.copy: cannot create an incompatible copy from \"".concat(this.type, "\" type to \"").concat(options.type, "\" because this would mean losing information about the current graph.")); - if (typeof options.multi === 'boolean' && options.multi !== this.multi && options.multi !== true) throw new UsageGraphError('Graph.copy: cannot create an incompatible copy by downgrading a multi graph to a simple one because this would mean losing information about the current graph.'); - if (typeof options.allowSelfLoops === 'boolean' && options.allowSelfLoops !== this.allowSelfLoops && options.allowSelfLoops !== true) throw new UsageGraphError('Graph.copy: cannot create an incompatible copy from a graph allowing self loops to one that does not because this would mean losing information about the current graph.'); - var graph = this.emptyCopy(options); - - var iterator = this._edges.values(); - - var step, edgeData; - - while (step = iterator.next(), step.done !== true) { - edgeData = step.value; // NOTE: no need to emit events since user cannot access the instance yet - - addEdge(graph, 'copy', false, edgeData.undirected, edgeData.key, edgeData.source.key, edgeData.target.key, assign({}, edgeData.attributes)); - } - - return graph; - } - /**--------------------------------------------------------------------------- - * Known methods - **--------------------------------------------------------------------------- - */ - - /** - * Method used by JavaScript to perform JSON serialization. - * - * @return {object} - The serialized graph. - */ - ; - - _proto.toJSON = function toJSON() { - return this["export"](); - } - /** - * Method returning [object Graph]. - */ - ; - - _proto.toString = function toString() { - return '[object Graph]'; - } - /** - * Method used internally by node's console to display a custom object. - * - * @return {object} - Formatted object representation of the graph. - */ - ; - - _proto.inspect = function inspect() { - var _this3 = this; - - var nodes = {}; - - this._nodes.forEach(function (data, key) { - nodes[key] = data.attributes; - }); - - var edges = {}, - multiIndex = {}; - - this._edges.forEach(function (data, key) { - var direction = data.undirected ? '--' : '->'; - var label = ''; - var source = data.source.key; - var target = data.target.key; - var tmp; - - if (data.undirected && source > target) { - tmp = source; - source = target; - target = tmp; - } - - var desc = "(".concat(source, ")").concat(direction, "(").concat(target, ")"); - - if (!key.startsWith('geid_')) { - label += "[".concat(key, "]: "); - } else if (_this3.multi) { - if (typeof multiIndex[desc] === 'undefined') { - multiIndex[desc] = 0; - } else { - multiIndex[desc]++; - } - - label += "".concat(multiIndex[desc], ". "); - } - - label += desc; - edges[label] = data.attributes; - }); - - var dummy = {}; - - for (var k in this) { - if (this.hasOwnProperty(k) && !EMITTER_PROPS.has(k) && typeof this[k] !== 'function' && _typeof(k) !== 'symbol') dummy[k] = this[k]; - } - - dummy.attributes = this._attributes; - dummy.nodes = nodes; - dummy.edges = edges; - privateProperty(dummy, 'constructor', this.constructor); - return dummy; - }; - - return Graph; -}(events.EventEmitter); -if (typeof Symbol !== 'undefined') Graph.prototype[Symbol["for"]('nodejs.util.inspect.custom')] = Graph.prototype.inspect; -/** - * Related to edge addition. - */ - -EDGE_ADD_METHODS.forEach(function (method) { - ['add', 'merge', 'update'].forEach(function (verb) { - var name = method.name(verb); - var fn = verb === 'add' ? addEdge : mergeEdge; - - if (method.generateKey) { - Graph.prototype[name] = function (source, target, attributes) { - return fn(this, name, true, (method.type || this.type) === 'undirected', null, source, target, attributes, verb === 'update'); - }; - } else { - Graph.prototype[name] = function (edge, source, target, attributes) { - return fn(this, name, false, (method.type || this.type) === 'undirected', edge, source, target, attributes, verb === 'update'); - }; - } - }); -}); -/** - * Attributes-related. - */ - -attachNodeAttributesMethods(Graph); -attachEdgeAttributesMethods(Graph); -/** - * Edge iteration-related. - */ - -attachEdgeIterationMethods(Graph); -/** - * Neighbor iteration-related. - */ - -attachNeighborIterationMethods(Graph); - -/** - * Alternative constructors. - */ - -var DirectedGraph = /*#__PURE__*/function (_Graph) { - _inheritsLoose(DirectedGraph, _Graph); - - function DirectedGraph(options) { - var finalOptions = assign({ - type: 'directed' - }, options); - if ('multi' in finalOptions && finalOptions.multi !== false) throw new InvalidArgumentsGraphError('DirectedGraph.from: inconsistent indication that the graph should be multi in given options!'); - if (finalOptions.type !== 'directed') throw new InvalidArgumentsGraphError('DirectedGraph.from: inconsistent "' + finalOptions.type + '" type in given options!'); - return _Graph.call(this, finalOptions) || this; - } - - return DirectedGraph; -}(Graph); - -var UndirectedGraph = /*#__PURE__*/function (_Graph2) { - _inheritsLoose(UndirectedGraph, _Graph2); - - function UndirectedGraph(options) { - var finalOptions = assign({ - type: 'undirected' - }, options); - if ('multi' in finalOptions && finalOptions.multi !== false) throw new InvalidArgumentsGraphError('UndirectedGraph.from: inconsistent indication that the graph should be multi in given options!'); - if (finalOptions.type !== 'undirected') throw new InvalidArgumentsGraphError('UndirectedGraph.from: inconsistent "' + finalOptions.type + '" type in given options!'); - return _Graph2.call(this, finalOptions) || this; - } - - return UndirectedGraph; -}(Graph); - -var MultiGraph = /*#__PURE__*/function (_Graph3) { - _inheritsLoose(MultiGraph, _Graph3); - - function MultiGraph(options) { - var finalOptions = assign({ - multi: true - }, options); - if ('multi' in finalOptions && finalOptions.multi !== true) throw new InvalidArgumentsGraphError('MultiGraph.from: inconsistent indication that the graph should be simple in given options!'); - return _Graph3.call(this, finalOptions) || this; - } - - return MultiGraph; -}(Graph); - -var MultiDirectedGraph = /*#__PURE__*/function (_Graph4) { - _inheritsLoose(MultiDirectedGraph, _Graph4); - - function MultiDirectedGraph(options) { - var finalOptions = assign({ - type: 'directed', - multi: true - }, options); - if ('multi' in finalOptions && finalOptions.multi !== true) throw new InvalidArgumentsGraphError('MultiDirectedGraph.from: inconsistent indication that the graph should be simple in given options!'); - if (finalOptions.type !== 'directed') throw new InvalidArgumentsGraphError('MultiDirectedGraph.from: inconsistent "' + finalOptions.type + '" type in given options!'); - return _Graph4.call(this, finalOptions) || this; - } - - return MultiDirectedGraph; -}(Graph); - -var MultiUndirectedGraph = /*#__PURE__*/function (_Graph5) { - _inheritsLoose(MultiUndirectedGraph, _Graph5); - - function MultiUndirectedGraph(options) { - var finalOptions = assign({ - type: 'undirected', - multi: true - }, options); - if ('multi' in finalOptions && finalOptions.multi !== true) throw new InvalidArgumentsGraphError('MultiUndirectedGraph.from: inconsistent indication that the graph should be simple in given options!'); - if (finalOptions.type !== 'undirected') throw new InvalidArgumentsGraphError('MultiUndirectedGraph.from: inconsistent "' + finalOptions.type + '" type in given options!'); - return _Graph5.call(this, finalOptions) || this; - } - - return MultiUndirectedGraph; -}(Graph); -/** - * Attaching static #.from method to each of the constructors. - */ - - -function attachStaticFromMethod(Class) { - /** - * Builds a graph from serialized data or another graph's data. - * - * @param {Graph|SerializedGraph} data - Hydratation data. - * @param {object} [options] - Options. - * @return {Class} - */ - Class.from = function (data, options) { - // Merging given options with serialized ones - var finalOptions = assign({}, data.options, options); - var instance = new Class(finalOptions); - instance["import"](data); - return instance; - }; -} - -attachStaticFromMethod(Graph); -attachStaticFromMethod(DirectedGraph); -attachStaticFromMethod(UndirectedGraph); -attachStaticFromMethod(MultiGraph); -attachStaticFromMethod(MultiDirectedGraph); -attachStaticFromMethod(MultiUndirectedGraph); -Graph.Graph = Graph; -Graph.DirectedGraph = DirectedGraph; -Graph.UndirectedGraph = UndirectedGraph; -Graph.MultiGraph = MultiGraph; -Graph.MultiDirectedGraph = MultiDirectedGraph; -Graph.MultiUndirectedGraph = MultiUndirectedGraph; -Graph.InvalidArgumentsGraphError = InvalidArgumentsGraphError; -Graph.NotFoundGraphError = NotFoundGraphError; -Graph.UsageGraphError = UsageGraphError; - -/** - * Graphology CommonJS Endoint - * ============================ - * - * Endpoint for CommonJS modules consumers. - */ - -module.exports = Graph; -//# sourceMappingURL=graphology.cjs.js.map diff --git a/libs/shared/graph-layouts/node_modules/graphology/dist/graphology.d.ts b/libs/shared/graph-layouts/node_modules/graphology/dist/graphology.d.ts deleted file mode 100644 index d2f14ffca..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/dist/graphology.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -import {AbstractGraph, Attributes} from 'graphology-types'; - -export default class Graph< - NodeAttributes extends Attributes = Attributes, - EdgeAttributes extends Attributes = Attributes, - GraphAttributes extends Attributes = Attributes -> extends AbstractGraph<NodeAttributes, EdgeAttributes, GraphAttributes> {} -export class DirectedGraph< - NodeAttributes extends Attributes = Attributes, - EdgeAttributes extends Attributes = Attributes, - GraphAttributes extends Attributes = Attributes -> extends Graph<NodeAttributes, EdgeAttributes, GraphAttributes> {} -export class UndirectedGraph< - NodeAttributes extends Attributes = Attributes, - EdgeAttributes extends Attributes = Attributes, - GraphAttributes extends Attributes = Attributes -> extends Graph<NodeAttributes, EdgeAttributes, GraphAttributes> {} -export class MultiGraph< - NodeAttributes extends Attributes = Attributes, - EdgeAttributes extends Attributes = Attributes, - GraphAttributes extends Attributes = Attributes -> extends Graph<NodeAttributes, EdgeAttributes, GraphAttributes> {} -export class MultiDirectedGraph< - NodeAttributes extends Attributes = Attributes, - EdgeAttributes extends Attributes = Attributes, - GraphAttributes extends Attributes = Attributes -> extends Graph<NodeAttributes, EdgeAttributes, GraphAttributes> {} -export class MultiUndirectedGraph< - NodeAttributes extends Attributes = Attributes, - EdgeAttributes extends Attributes = Attributes, - GraphAttributes extends Attributes = Attributes -> extends Graph<NodeAttributes, EdgeAttributes, GraphAttributes> {} - -export class InvalidArgumentsGraphError extends Error {} -export class NotFoundGraphError extends Error {} -export class UsageGraphError extends Error {} diff --git a/libs/shared/graph-layouts/node_modules/graphology/dist/graphology.esm.js b/libs/shared/graph-layouts/node_modules/graphology/dist/graphology.esm.js deleted file mode 100644 index f89b5be2e..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/dist/graphology.esm.js +++ /dev/null @@ -1,6671 +0,0 @@ -import { EventEmitter } from 'events'; -import Iterator from 'obliterator/iterator'; -import take from 'obliterator/take'; -import chain from 'obliterator/chain'; - -/** - * Graphology Utilities - * ===================== - * - * Collection of helpful functions used by the implementation. - */ - -/** - * Object.assign-like polyfill. - * - * @param {object} target - First object. - * @param {object} [...objects] - Objects to merge. - * @return {object} - */ -function assignPolyfill() { - const target = arguments[0]; - - for (let i = 1, l = arguments.length; i < l; i++) { - if (!arguments[i]) continue; - - for (const k in arguments[i]) target[k] = arguments[i][k]; - } - - return target; -} - -let assign = assignPolyfill; - -if (typeof Object.assign === 'function') assign = Object.assign; - -/** - * Function returning the first matching edge for given path. - * Note: this function does not check the existence of source & target. This - * must be performed by the caller. - * - * @param {Graph} graph - Target graph. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {string} type - Type of the edge (mixed, directed or undirected). - * @return {string|null} - */ -function getMatchingEdge(graph, source, target, type) { - const sourceData = graph._nodes.get(source); - - let edge = null; - - if (!sourceData) return edge; - - if (type === 'mixed') { - edge = - (sourceData.out && sourceData.out[target]) || - (sourceData.undirected && sourceData.undirected[target]); - } else if (type === 'directed') { - edge = sourceData.out && sourceData.out[target]; - } else { - edge = sourceData.undirected && sourceData.undirected[target]; - } - - return edge; -} - -/** - * Checks whether the given value is a Graph implementation instance. - * - * @param {mixed} value - Target value. - * @return {boolean} - */ -function isGraph(value) { - return ( - value !== null && - typeof value === 'object' && - typeof value.addUndirectedEdgeWithKey === 'function' && - typeof value.dropNode === 'function' - ); -} - -/** - * Checks whether the given value is a plain object. - * - * @param {mixed} value - Target value. - * @return {boolean} - */ -function isPlainObject(value) { - return ( - typeof value === 'object' && value !== null && value.constructor === Object - ); -} - -/** - * Checks whether the given object is empty. - * - * @param {object} o - Target Object. - * @return {boolean} - */ -function isEmpty(o) { - let k; - - for (k in o) return false; - - return true; -} - -/** - * Creates a "private" property for the given member name by concealing it - * using the `enumerable` option. - * - * @param {object} target - Target object. - * @param {string} name - Member name. - */ -function privateProperty(target, name, value) { - Object.defineProperty(target, name, { - enumerable: false, - configurable: false, - writable: true, - value - }); -} - -/** - * Creates a read-only property for the given member name & the given getter. - * - * @param {object} target - Target object. - * @param {string} name - Member name. - * @param {mixed} value - The attached getter or fixed value. - */ -function readOnlyProperty(target, name, value) { - const descriptor = { - enumerable: true, - configurable: true - }; - - if (typeof value === 'function') { - descriptor.get = value; - } else { - descriptor.value = value; - descriptor.writable = false; - } - - Object.defineProperty(target, name, descriptor); -} - -/** - * Returns whether the given object constitute valid hints. - * - * @param {object} hints - Target object. - */ -function validateHints(hints) { - if (!isPlainObject(hints)) return false; - - if (hints.attributes && !Array.isArray(hints.attributes)) return false; - - return true; -} - -/** - * Creates a function generating incremental ids for edges. - * - * @return {function} - */ -function incrementalIdStartingFromRandomByte() { - let i = Math.floor(Math.random() * 256) & 0xff; - - return () => { - return i++; - }; -} - -/** - * Graphology Custom Errors - * ========================= - * - * Defining custom errors for ease of use & easy unit tests across - * implementations (normalized typology rather than relying on error - * messages to check whether the correct error was found). - */ -class GraphError extends Error { - constructor(message) { - super(); - this.name = 'GraphError'; - this.message = message; - } -} - -class InvalidArgumentsGraphError extends GraphError { - constructor(message) { - super(message); - this.name = 'InvalidArgumentsGraphError'; - - // This is V8 specific to enhance stack readability - if (typeof Error.captureStackTrace === 'function') - Error.captureStackTrace( - this, - InvalidArgumentsGraphError.prototype.constructor - ); - } -} - -class NotFoundGraphError extends GraphError { - constructor(message) { - super(message); - this.name = 'NotFoundGraphError'; - - // This is V8 specific to enhance stack readability - if (typeof Error.captureStackTrace === 'function') - Error.captureStackTrace(this, NotFoundGraphError.prototype.constructor); - } -} - -class UsageGraphError extends GraphError { - constructor(message) { - super(message); - this.name = 'UsageGraphError'; - - // This is V8 specific to enhance stack readability - if (typeof Error.captureStackTrace === 'function') - Error.captureStackTrace(this, UsageGraphError.prototype.constructor); - } -} - -/** - * Graphology Internal Data Classes - * ================================= - * - * Internal classes hopefully reduced to structs by engines & storing - * necessary information for nodes & edges. - * - * Note that those classes don't rely on the `class` keyword to avoid some - * cruft introduced by most of ES2015 transpilers. - */ - -/** - * MixedNodeData class. - * - * @constructor - * @param {string} string - The node's key. - * @param {object} attributes - Node's attributes. - */ -function MixedNodeData(key, attributes) { - // Attributes - this.key = key; - this.attributes = attributes; - - this.clear(); -} - -MixedNodeData.prototype.clear = function () { - // Degrees - this.inDegree = 0; - this.outDegree = 0; - this.undirectedDegree = 0; - - // Indices - this.in = {}; - this.out = {}; - this.undirected = {}; -}; - -/** - * DirectedNodeData class. - * - * @constructor - * @param {string} string - The node's key. - * @param {object} attributes - Node's attributes. - */ -function DirectedNodeData(key, attributes) { - // Attributes - this.key = key; - this.attributes = attributes; - - this.clear(); -} - -DirectedNodeData.prototype.clear = function () { - // Degrees - this.inDegree = 0; - this.outDegree = 0; - - // Indices - this.in = {}; - this.out = {}; -}; - -/** - * UndirectedNodeData class. - * - * @constructor - * @param {string} string - The node's key. - * @param {object} attributes - Node's attributes. - */ -function UndirectedNodeData(key, attributes) { - // Attributes - this.key = key; - this.attributes = attributes; - - this.clear(); -} - -UndirectedNodeData.prototype.clear = function () { - // Degrees - this.undirectedDegree = 0; - - // Indices - this.undirected = {}; -}; - -/** - * EdgeData class. - * - * @constructor - * @param {boolean} undirected - Whether the edge is undirected. - * @param {string} string - The edge's key. - * @param {string} source - Source of the edge. - * @param {string} target - Target of the edge. - * @param {object} attributes - Edge's attributes. - */ -function EdgeData(undirected, key, source, target, attributes) { - // Attributes - this.key = key; - this.attributes = attributes; - this.undirected = undirected; - - // Extremities - this.source = source; - this.target = target; -} - -EdgeData.prototype.attach = function () { - let outKey = 'out'; - let inKey = 'in'; - - if (this.undirected) outKey = inKey = 'undirected'; - - const source = this.source.key; - const target = this.target.key; - - // Handling source - this.source[outKey][target] = this; - - if (this.undirected && source === target) return; - - // Handling target - this.target[inKey][source] = this; -}; - -EdgeData.prototype.attachMulti = function () { - let outKey = 'out'; - let inKey = 'in'; - - const source = this.source.key; - const target = this.target.key; - - if (this.undirected) outKey = inKey = 'undirected'; - - // Handling source - const adj = this.source[outKey]; - const head = adj[target]; - - if (typeof head === 'undefined') { - adj[target] = this; - - // Self-loop optimization - if (!(this.undirected && source === target)) { - // Handling target - this.target[inKey][source] = this; - } - - return; - } - - // Prepending to doubly-linked list - head.previous = this; - this.next = head; - - // Pointing to new head - // NOTE: use mutating swap later to avoid lookup? - adj[target] = this; - this.target[inKey][source] = this; -}; - -EdgeData.prototype.detach = function () { - const source = this.source.key; - const target = this.target.key; - - let outKey = 'out'; - let inKey = 'in'; - - if (this.undirected) outKey = inKey = 'undirected'; - - delete this.source[outKey][target]; - - // No-op delete in case of undirected self-loop - delete this.target[inKey][source]; -}; - -EdgeData.prototype.detachMulti = function () { - const source = this.source.key; - const target = this.target.key; - - let outKey = 'out'; - let inKey = 'in'; - - if (this.undirected) outKey = inKey = 'undirected'; - - // Deleting from doubly-linked list - if (this.previous === undefined) { - // We are dealing with the head - - // Should we delete the adjacency entry because it is now empty? - if (this.next === undefined) { - delete this.source[outKey][target]; - - // No-op delete in case of undirected self-loop - delete this.target[inKey][source]; - } else { - // Detaching - this.next.previous = undefined; - - // NOTE: could avoid the lookups by creating a #.become mutating method - this.source[outKey][target] = this.next; - - // No-op delete in case of undirected self-loop - this.target[inKey][source] = this.next; - } - } else { - // We are dealing with another list node - this.previous.next = this.next; - - // If not last - if (this.next !== undefined) { - this.next.previous = this.previous; - } - } -}; - -/** - * Graphology Node Attributes methods - * =================================== - */ - -const NODE = 0; -const SOURCE = 1; -const TARGET = 2; -const OPPOSITE = 3; - -function findRelevantNodeData( - graph, - method, - mode, - nodeOrEdge, - nameOrEdge, - add1, - add2 -) { - let nodeData, edgeData, arg1, arg2; - - nodeOrEdge = '' + nodeOrEdge; - - if (mode === NODE) { - nodeData = graph._nodes.get(nodeOrEdge); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.${method}: could not find the "${nodeOrEdge}" node in the graph.` - ); - - arg1 = nameOrEdge; - arg2 = add1; - } else if (mode === OPPOSITE) { - nameOrEdge = '' + nameOrEdge; - - edgeData = graph._edges.get(nameOrEdge); - - if (!edgeData) - throw new NotFoundGraphError( - `Graph.${method}: could not find the "${nameOrEdge}" edge in the graph.` - ); - - const source = edgeData.source.key; - const target = edgeData.target.key; - - if (nodeOrEdge === source) { - nodeData = edgeData.target; - } else if (nodeOrEdge === target) { - nodeData = edgeData.source; - } else { - throw new NotFoundGraphError( - `Graph.${method}: the "${nodeOrEdge}" node is not attached to the "${nameOrEdge}" edge (${source}, ${target}).` - ); - } - - arg1 = add1; - arg2 = add2; - } else { - edgeData = graph._edges.get(nodeOrEdge); - - if (!edgeData) - throw new NotFoundGraphError( - `Graph.${method}: could not find the "${nodeOrEdge}" edge in the graph.` - ); - - if (mode === SOURCE) { - nodeData = edgeData.source; - } else { - nodeData = edgeData.target; - } - - arg1 = nameOrEdge; - arg2 = add1; - } - - return [nodeData, arg1, arg2]; -} - -function attachNodeAttributeGetter(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) { - const [data, name] = findRelevantNodeData( - this, - method, - mode, - nodeOrEdge, - nameOrEdge, - add1 - ); - - return data.attributes[name]; - }; -} - -function attachNodeAttributesGetter(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge) { - const [data] = findRelevantNodeData( - this, - method, - mode, - nodeOrEdge, - nameOrEdge - ); - - return data.attributes; - }; -} - -function attachNodeAttributeChecker(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) { - const [data, name] = findRelevantNodeData( - this, - method, - mode, - nodeOrEdge, - nameOrEdge, - add1 - ); - - return data.attributes.hasOwnProperty(name); - }; -} - -function attachNodeAttributeSetter(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1, add2) { - const [data, name, value] = findRelevantNodeData( - this, - method, - mode, - nodeOrEdge, - nameOrEdge, - add1, - add2 - ); - - data.attributes[name] = value; - - // Emitting - this.emit('nodeAttributesUpdated', { - key: data.key, - type: 'set', - attributes: data.attributes, - name - }); - - return this; - }; -} - -function attachNodeAttributeUpdater(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1, add2) { - const [data, name, updater] = findRelevantNodeData( - this, - method, - mode, - nodeOrEdge, - nameOrEdge, - add1, - add2 - ); - - if (typeof updater !== 'function') - throw new InvalidArgumentsGraphError( - `Graph.${method}: updater should be a function.` - ); - - const attributes = data.attributes; - const value = updater(attributes[name]); - - attributes[name] = value; - - // Emitting - this.emit('nodeAttributesUpdated', { - key: data.key, - type: 'set', - attributes: data.attributes, - name - }); - - return this; - }; -} - -function attachNodeAttributeRemover(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) { - const [data, name] = findRelevantNodeData( - this, - method, - mode, - nodeOrEdge, - nameOrEdge, - add1 - ); - - delete data.attributes[name]; - - // Emitting - this.emit('nodeAttributesUpdated', { - key: data.key, - type: 'remove', - attributes: data.attributes, - name - }); - - return this; - }; -} - -function attachNodeAttributesReplacer(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) { - const [data, attributes] = findRelevantNodeData( - this, - method, - mode, - nodeOrEdge, - nameOrEdge, - add1 - ); - - if (!isPlainObject(attributes)) - throw new InvalidArgumentsGraphError( - `Graph.${method}: provided attributes are not a plain object.` - ); - - data.attributes = attributes; - - // Emitting - this.emit('nodeAttributesUpdated', { - key: data.key, - type: 'replace', - attributes: data.attributes - }); - - return this; - }; -} - -function attachNodeAttributesMerger(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) { - const [data, attributes] = findRelevantNodeData( - this, - method, - mode, - nodeOrEdge, - nameOrEdge, - add1 - ); - - if (!isPlainObject(attributes)) - throw new InvalidArgumentsGraphError( - `Graph.${method}: provided attributes are not a plain object.` - ); - - assign(data.attributes, attributes); - - // Emitting - this.emit('nodeAttributesUpdated', { - key: data.key, - type: 'merge', - attributes: data.attributes, - data: attributes - }); - - return this; - }; -} - -function attachNodeAttributesUpdater(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) { - const [data, updater] = findRelevantNodeData( - this, - method, - mode, - nodeOrEdge, - nameOrEdge, - add1 - ); - - if (typeof updater !== 'function') - throw new InvalidArgumentsGraphError( - `Graph.${method}: provided updater is not a function.` - ); - - data.attributes = updater(data.attributes); - - // Emitting - this.emit('nodeAttributesUpdated', { - key: data.key, - type: 'update', - attributes: data.attributes - }); - - return this; - }; -} - -/** - * List of methods to attach. - */ -const NODE_ATTRIBUTES_METHODS = [ - { - name: element => `get${element}Attribute`, - attacher: attachNodeAttributeGetter - }, - { - name: element => `get${element}Attributes`, - attacher: attachNodeAttributesGetter - }, - { - name: element => `has${element}Attribute`, - attacher: attachNodeAttributeChecker - }, - { - name: element => `set${element}Attribute`, - attacher: attachNodeAttributeSetter - }, - { - name: element => `update${element}Attribute`, - attacher: attachNodeAttributeUpdater - }, - { - name: element => `remove${element}Attribute`, - attacher: attachNodeAttributeRemover - }, - { - name: element => `replace${element}Attributes`, - attacher: attachNodeAttributesReplacer - }, - { - name: element => `merge${element}Attributes`, - attacher: attachNodeAttributesMerger - }, - { - name: element => `update${element}Attributes`, - attacher: attachNodeAttributesUpdater - } -]; - -/** - * Attach every attributes-related methods to a Graph class. - * - * @param {function} Graph - Target class. - */ -function attachNodeAttributesMethods(Graph) { - NODE_ATTRIBUTES_METHODS.forEach(function ({name, attacher}) { - // For nodes - attacher(Graph, name('Node'), NODE); - - // For sources - attacher(Graph, name('Source'), SOURCE); - - // For targets - attacher(Graph, name('Target'), TARGET); - - // For opposites - attacher(Graph, name('Opposite'), OPPOSITE); - }); -} - -/** - * Graphology Edge Attributes methods - * =================================== - */ - -/** - * Attach an attribute getter method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ -function attachEdgeAttributeGetter(Class, method, type) { - /** - * Get the desired attribute for the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {string} name - Attribute's name. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {string} name - Attribute's name. - * - * @return {mixed} - The attribute's value. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, name) { - let data; - - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) - throw new UsageGraphError( - `Graph.${method}: cannot find this type of edges in your ${this.type} graph.` - ); - - if (arguments.length > 2) { - if (this.multi) - throw new UsageGraphError( - `Graph.${method}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.` - ); - - const source = '' + element; - const target = '' + name; - - name = arguments[2]; - - data = getMatchingEdge(this, source, target, type); - - if (!data) - throw new NotFoundGraphError( - `Graph.${method}: could not find an edge for the given path ("${source}" - "${target}").` - ); - } else { - if (type !== 'mixed') - throw new UsageGraphError( - `Graph.${method}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.` - ); - - element = '' + element; - data = this._edges.get(element); - - if (!data) - throw new NotFoundGraphError( - `Graph.${method}: could not find the "${element}" edge in the graph.` - ); - } - - return data.attributes[name]; - }; -} - -/** - * Attach an attributes getter method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ -function attachEdgeAttributesGetter(Class, method, type) { - /** - * Retrieves all the target element's attributes. - * - * Arity 2: - * @param {any} element - Target element. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * - * @return {object} - The element's attributes. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element) { - let data; - - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) - throw new UsageGraphError( - `Graph.${method}: cannot find this type of edges in your ${this.type} graph.` - ); - - if (arguments.length > 1) { - if (this.multi) - throw new UsageGraphError( - `Graph.${method}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.` - ); - - const source = '' + element, - target = '' + arguments[1]; - - data = getMatchingEdge(this, source, target, type); - - if (!data) - throw new NotFoundGraphError( - `Graph.${method}: could not find an edge for the given path ("${source}" - "${target}").` - ); - } else { - if (type !== 'mixed') - throw new UsageGraphError( - `Graph.${method}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.` - ); - - element = '' + element; - data = this._edges.get(element); - - if (!data) - throw new NotFoundGraphError( - `Graph.${method}: could not find the "${element}" edge in the graph.` - ); - } - - return data.attributes; - }; -} - -/** - * Attach an attribute checker method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ -function attachEdgeAttributeChecker(Class, method, type) { - /** - * Checks whether the desired attribute is set for the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {string} name - Attribute's name. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {string} name - Attribute's name. - * - * @return {boolean} - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, name) { - let data; - - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) - throw new UsageGraphError( - `Graph.${method}: cannot find this type of edges in your ${this.type} graph.` - ); - - if (arguments.length > 2) { - if (this.multi) - throw new UsageGraphError( - `Graph.${method}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.` - ); - - const source = '' + element; - const target = '' + name; - - name = arguments[2]; - - data = getMatchingEdge(this, source, target, type); - - if (!data) - throw new NotFoundGraphError( - `Graph.${method}: could not find an edge for the given path ("${source}" - "${target}").` - ); - } else { - if (type !== 'mixed') - throw new UsageGraphError( - `Graph.${method}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.` - ); - - element = '' + element; - data = this._edges.get(element); - - if (!data) - throw new NotFoundGraphError( - `Graph.${method}: could not find the "${element}" edge in the graph.` - ); - } - - return data.attributes.hasOwnProperty(name); - }; -} - -/** - * Attach an attribute setter method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ -function attachEdgeAttributeSetter(Class, method, type) { - /** - * Set the desired attribute for the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {string} name - Attribute's name. - * @param {mixed} value - New attribute value. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {string} name - Attribute's name. - * @param {mixed} value - New attribute value. - * - * @return {Graph} - Returns itself for chaining. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, name, value) { - let data; - - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) - throw new UsageGraphError( - `Graph.${method}: cannot find this type of edges in your ${this.type} graph.` - ); - - if (arguments.length > 3) { - if (this.multi) - throw new UsageGraphError( - `Graph.${method}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.` - ); - - const source = '' + element; - const target = '' + name; - - name = arguments[2]; - value = arguments[3]; - - data = getMatchingEdge(this, source, target, type); - - if (!data) - throw new NotFoundGraphError( - `Graph.${method}: could not find an edge for the given path ("${source}" - "${target}").` - ); - } else { - if (type !== 'mixed') - throw new UsageGraphError( - `Graph.${method}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.` - ); - - element = '' + element; - data = this._edges.get(element); - - if (!data) - throw new NotFoundGraphError( - `Graph.${method}: could not find the "${element}" edge in the graph.` - ); - } - - data.attributes[name] = value; - - // Emitting - this.emit('edgeAttributesUpdated', { - key: data.key, - type: 'set', - attributes: data.attributes, - name - }); - - return this; - }; -} - -/** - * Attach an attribute updater method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ -function attachEdgeAttributeUpdater(Class, method, type) { - /** - * Update the desired attribute for the given element (node or edge) using - * the provided function. - * - * Arity 2: - * @param {any} element - Target element. - * @param {string} name - Attribute's name. - * @param {function} updater - Updater function. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {string} name - Attribute's name. - * @param {function} updater - Updater function. - * - * @return {Graph} - Returns itself for chaining. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, name, updater) { - let data; - - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) - throw new UsageGraphError( - `Graph.${method}: cannot find this type of edges in your ${this.type} graph.` - ); - - if (arguments.length > 3) { - if (this.multi) - throw new UsageGraphError( - `Graph.${method}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.` - ); - - const source = '' + element; - const target = '' + name; - - name = arguments[2]; - updater = arguments[3]; - - data = getMatchingEdge(this, source, target, type); - - if (!data) - throw new NotFoundGraphError( - `Graph.${method}: could not find an edge for the given path ("${source}" - "${target}").` - ); - } else { - if (type !== 'mixed') - throw new UsageGraphError( - `Graph.${method}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.` - ); - - element = '' + element; - data = this._edges.get(element); - - if (!data) - throw new NotFoundGraphError( - `Graph.${method}: could not find the "${element}" edge in the graph.` - ); - } - - if (typeof updater !== 'function') - throw new InvalidArgumentsGraphError( - `Graph.${method}: updater should be a function.` - ); - - data.attributes[name] = updater(data.attributes[name]); - - // Emitting - this.emit('edgeAttributesUpdated', { - key: data.key, - type: 'set', - attributes: data.attributes, - name - }); - - return this; - }; -} - -/** - * Attach an attribute remover method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ -function attachEdgeAttributeRemover(Class, method, type) { - /** - * Remove the desired attribute for the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {string} name - Attribute's name. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {string} name - Attribute's name. - * - * @return {Graph} - Returns itself for chaining. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, name) { - let data; - - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) - throw new UsageGraphError( - `Graph.${method}: cannot find this type of edges in your ${this.type} graph.` - ); - - if (arguments.length > 2) { - if (this.multi) - throw new UsageGraphError( - `Graph.${method}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.` - ); - - const source = '' + element; - const target = '' + name; - - name = arguments[2]; - - data = getMatchingEdge(this, source, target, type); - - if (!data) - throw new NotFoundGraphError( - `Graph.${method}: could not find an edge for the given path ("${source}" - "${target}").` - ); - } else { - if (type !== 'mixed') - throw new UsageGraphError( - `Graph.${method}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.` - ); - - element = '' + element; - data = this._edges.get(element); - - if (!data) - throw new NotFoundGraphError( - `Graph.${method}: could not find the "${element}" edge in the graph.` - ); - } - - delete data.attributes[name]; - - // Emitting - this.emit('edgeAttributesUpdated', { - key: data.key, - type: 'remove', - attributes: data.attributes, - name - }); - - return this; - }; -} - -/** - * Attach an attribute replacer method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ -function attachEdgeAttributesReplacer(Class, method, type) { - /** - * Replace the attributes for the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {object} attributes - New attributes. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {object} attributes - New attributes. - * - * @return {Graph} - Returns itself for chaining. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, attributes) { - let data; - - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) - throw new UsageGraphError( - `Graph.${method}: cannot find this type of edges in your ${this.type} graph.` - ); - - if (arguments.length > 2) { - if (this.multi) - throw new UsageGraphError( - `Graph.${method}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.` - ); - - const source = '' + element, - target = '' + attributes; - - attributes = arguments[2]; - - data = getMatchingEdge(this, source, target, type); - - if (!data) - throw new NotFoundGraphError( - `Graph.${method}: could not find an edge for the given path ("${source}" - "${target}").` - ); - } else { - if (type !== 'mixed') - throw new UsageGraphError( - `Graph.${method}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.` - ); - - element = '' + element; - data = this._edges.get(element); - - if (!data) - throw new NotFoundGraphError( - `Graph.${method}: could not find the "${element}" edge in the graph.` - ); - } - - if (!isPlainObject(attributes)) - throw new InvalidArgumentsGraphError( - `Graph.${method}: provided attributes are not a plain object.` - ); - - data.attributes = attributes; - - // Emitting - this.emit('edgeAttributesUpdated', { - key: data.key, - type: 'replace', - attributes: data.attributes - }); - - return this; - }; -} - -/** - * Attach an attribute merger method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ -function attachEdgeAttributesMerger(Class, method, type) { - /** - * Merge the attributes for the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {object} attributes - Attributes to merge. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {object} attributes - Attributes to merge. - * - * @return {Graph} - Returns itself for chaining. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, attributes) { - let data; - - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) - throw new UsageGraphError( - `Graph.${method}: cannot find this type of edges in your ${this.type} graph.` - ); - - if (arguments.length > 2) { - if (this.multi) - throw new UsageGraphError( - `Graph.${method}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.` - ); - - const source = '' + element, - target = '' + attributes; - - attributes = arguments[2]; - - data = getMatchingEdge(this, source, target, type); - - if (!data) - throw new NotFoundGraphError( - `Graph.${method}: could not find an edge for the given path ("${source}" - "${target}").` - ); - } else { - if (type !== 'mixed') - throw new UsageGraphError( - `Graph.${method}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.` - ); - - element = '' + element; - data = this._edges.get(element); - - if (!data) - throw new NotFoundGraphError( - `Graph.${method}: could not find the "${element}" edge in the graph.` - ); - } - - if (!isPlainObject(attributes)) - throw new InvalidArgumentsGraphError( - `Graph.${method}: provided attributes are not a plain object.` - ); - - assign(data.attributes, attributes); - - // Emitting - this.emit('edgeAttributesUpdated', { - key: data.key, - type: 'merge', - attributes: data.attributes, - data: attributes - }); - - return this; - }; -} - -/** - * Attach an attribute updater method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ -function attachEdgeAttributesUpdater(Class, method, type) { - /** - * Update the attributes of the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {function} updater - Updater function. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {function} updater - Updater function. - * - * @return {Graph} - Returns itself for chaining. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, updater) { - let data; - - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) - throw new UsageGraphError( - `Graph.${method}: cannot find this type of edges in your ${this.type} graph.` - ); - - if (arguments.length > 2) { - if (this.multi) - throw new UsageGraphError( - `Graph.${method}: cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.` - ); - - const source = '' + element, - target = '' + updater; - - updater = arguments[2]; - - data = getMatchingEdge(this, source, target, type); - - if (!data) - throw new NotFoundGraphError( - `Graph.${method}: could not find an edge for the given path ("${source}" - "${target}").` - ); - } else { - if (type !== 'mixed') - throw new UsageGraphError( - `Graph.${method}: calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.` - ); - - element = '' + element; - data = this._edges.get(element); - - if (!data) - throw new NotFoundGraphError( - `Graph.${method}: could not find the "${element}" edge in the graph.` - ); - } - - if (typeof updater !== 'function') - throw new InvalidArgumentsGraphError( - `Graph.${method}: provided updater is not a function.` - ); - - data.attributes = updater(data.attributes); - - // Emitting - this.emit('edgeAttributesUpdated', { - key: data.key, - type: 'update', - attributes: data.attributes - }); - - return this; - }; -} - -/** - * List of methods to attach. - */ -const EDGE_ATTRIBUTES_METHODS = [ - { - name: element => `get${element}Attribute`, - attacher: attachEdgeAttributeGetter - }, - { - name: element => `get${element}Attributes`, - attacher: attachEdgeAttributesGetter - }, - { - name: element => `has${element}Attribute`, - attacher: attachEdgeAttributeChecker - }, - { - name: element => `set${element}Attribute`, - attacher: attachEdgeAttributeSetter - }, - { - name: element => `update${element}Attribute`, - attacher: attachEdgeAttributeUpdater - }, - { - name: element => `remove${element}Attribute`, - attacher: attachEdgeAttributeRemover - }, - { - name: element => `replace${element}Attributes`, - attacher: attachEdgeAttributesReplacer - }, - { - name: element => `merge${element}Attributes`, - attacher: attachEdgeAttributesMerger - }, - { - name: element => `update${element}Attributes`, - attacher: attachEdgeAttributesUpdater - } -]; - -/** - * Attach every attributes-related methods to a Graph class. - * - * @param {function} Graph - Target class. - */ -function attachEdgeAttributesMethods(Graph) { - EDGE_ATTRIBUTES_METHODS.forEach(function ({name, attacher}) { - // For edges - attacher(Graph, name('Edge'), 'mixed'); - - // For directed edges - attacher(Graph, name('DirectedEdge'), 'directed'); - - // For undirected edges - attacher(Graph, name('UndirectedEdge'), 'undirected'); - }); -} - -/** - * Graphology Edge Iteration - * ========================== - * - * Attaching some methods to the Graph class to be able to iterate over a - * graph's edges. - */ - -/** - * Definitions. - */ -const EDGES_ITERATION = [ - { - name: 'edges', - type: 'mixed' - }, - { - name: 'inEdges', - type: 'directed', - direction: 'in' - }, - { - name: 'outEdges', - type: 'directed', - direction: 'out' - }, - { - name: 'inboundEdges', - type: 'mixed', - direction: 'in' - }, - { - name: 'outboundEdges', - type: 'mixed', - direction: 'out' - }, - { - name: 'directedEdges', - type: 'directed' - }, - { - name: 'undirectedEdges', - type: 'undirected' - } -]; - -/** - * Function iterating over edges from the given object to match one of them. - * - * @param {object} object - Target object. - * @param {function} callback - Function to call. - */ -function forEachSimple(breakable, object, callback, avoid) { - let shouldBreak = false; - - for (const k in object) { - if (k === avoid) continue; - - const edgeData = object[k]; - - shouldBreak = callback( - edgeData.key, - edgeData.attributes, - edgeData.source.key, - edgeData.target.key, - edgeData.source.attributes, - edgeData.target.attributes, - edgeData.undirected - ); - - if (breakable && shouldBreak) return edgeData.key; - } - - return; -} - -function forEachMulti(breakable, object, callback, avoid) { - let edgeData, source, target; - - let shouldBreak = false; - - for (const k in object) { - if (k === avoid) continue; - - edgeData = object[k]; - - do { - source = edgeData.source; - target = edgeData.target; - - shouldBreak = callback( - edgeData.key, - edgeData.attributes, - source.key, - target.key, - source.attributes, - target.attributes, - edgeData.undirected - ); - - if (breakable && shouldBreak) return edgeData.key; - - edgeData = edgeData.next; - } while (edgeData !== undefined); - } - - return; -} - -/** - * Function returning an iterator over edges from the given object. - * - * @param {object} object - Target object. - * @return {Iterator} - */ -function createIterator(object, avoid) { - const keys = Object.keys(object); - const l = keys.length; - - let edgeData; - let i = 0; - - return new Iterator(function next() { - do { - if (!edgeData) { - if (i >= l) return {done: true}; - - const k = keys[i++]; - - if (k === avoid) { - edgeData = undefined; - continue; - } - - edgeData = object[k]; - } else { - edgeData = edgeData.next; - } - } while (!edgeData); - - return { - done: false, - value: { - edge: edgeData.key, - attributes: edgeData.attributes, - source: edgeData.source.key, - target: edgeData.target.key, - sourceAttributes: edgeData.source.attributes, - targetAttributes: edgeData.target.attributes, - undirected: edgeData.undirected - } - }; - }); -} - -/** - * Function iterating over the egdes from the object at given key to match - * one of them. - * - * @param {object} object - Target object. - * @param {mixed} k - Neighbor key. - * @param {function} callback - Callback to use. - */ -function forEachForKeySimple(breakable, object, k, callback) { - const edgeData = object[k]; - - if (!edgeData) return; - - const sourceData = edgeData.source; - const targetData = edgeData.target; - - if ( - callback( - edgeData.key, - edgeData.attributes, - sourceData.key, - targetData.key, - sourceData.attributes, - targetData.attributes, - edgeData.undirected - ) && - breakable - ) - return edgeData.key; -} - -function forEachForKeyMulti(breakable, object, k, callback) { - let edgeData = object[k]; - - if (!edgeData) return; - - let shouldBreak = false; - - do { - shouldBreak = callback( - edgeData.key, - edgeData.attributes, - edgeData.source.key, - edgeData.target.key, - edgeData.source.attributes, - edgeData.target.attributes, - edgeData.undirected - ); - - if (breakable && shouldBreak) return edgeData.key; - - edgeData = edgeData.next; - } while (edgeData !== undefined); - - return; -} - -/** - * Function returning an iterator over the egdes from the object at given key. - * - * @param {object} object - Target object. - * @param {mixed} k - Neighbor key. - * @return {Iterator} - */ -function createIteratorForKey(object, k) { - let edgeData = object[k]; - - if (edgeData.next !== undefined) { - return new Iterator(function () { - if (!edgeData) return {done: true}; - - const value = { - edge: edgeData.key, - attributes: edgeData.attributes, - source: edgeData.source.key, - target: edgeData.target.key, - sourceAttributes: edgeData.source.attributes, - targetAttributes: edgeData.target.attributes, - undirected: edgeData.undirected - }; - - edgeData = edgeData.next; - - return { - done: false, - value - }; - }); - } - - return Iterator.of({ - edge: edgeData.key, - attributes: edgeData.attributes, - source: edgeData.source.key, - target: edgeData.target.key, - sourceAttributes: edgeData.source.attributes, - targetAttributes: edgeData.target.attributes, - undirected: edgeData.undirected - }); -} - -/** - * Function creating an array of edges for the given type. - * - * @param {Graph} graph - Target Graph instance. - * @param {string} type - Type of edges to retrieve. - * @return {array} - Array of edges. - */ -function createEdgeArray(graph, type) { - if (graph.size === 0) return []; - - if (type === 'mixed' || type === graph.type) { - if (typeof Array.from === 'function') - return Array.from(graph._edges.keys()); - - return take(graph._edges.keys(), graph._edges.size); - } - - const size = - type === 'undirected' ? graph.undirectedSize : graph.directedSize; - - const list = new Array(size), - mask = type === 'undirected'; - - const iterator = graph._edges.values(); - - let i = 0; - let step, data; - - while (((step = iterator.next()), step.done !== true)) { - data = step.value; - - if (data.undirected === mask) list[i++] = data.key; - } - - return list; -} - -/** - * Function iterating over a graph's edges using a callback to match one of - * them. - * - * @param {Graph} graph - Target Graph instance. - * @param {string} type - Type of edges to retrieve. - * @param {function} callback - Function to call. - */ -function forEachEdge(breakable, graph, type, callback) { - if (graph.size === 0) return; - - const shouldFilter = type !== 'mixed' && type !== graph.type; - const mask = type === 'undirected'; - - let step, data; - let shouldBreak = false; - const iterator = graph._edges.values(); - - while (((step = iterator.next()), step.done !== true)) { - data = step.value; - - if (shouldFilter && data.undirected !== mask) continue; - - const {key, attributes, source, target} = data; - - shouldBreak = callback( - key, - attributes, - source.key, - target.key, - source.attributes, - target.attributes, - data.undirected - ); - - if (breakable && shouldBreak) return key; - } - - return; -} - -/** - * Function creating an iterator of edges for the given type. - * - * @param {Graph} graph - Target Graph instance. - * @param {string} type - Type of edges to retrieve. - * @return {Iterator} - */ -function createEdgeIterator(graph, type) { - if (graph.size === 0) return Iterator.empty(); - - const shouldFilter = type !== 'mixed' && type !== graph.type; - const mask = type === 'undirected'; - - const iterator = graph._edges.values(); - - return new Iterator(function next() { - let step, data; - - // eslint-disable-next-line no-constant-condition - while (true) { - step = iterator.next(); - - if (step.done) return step; - - data = step.value; - - if (shouldFilter && data.undirected !== mask) continue; - - break; - } - - const value = { - edge: data.key, - attributes: data.attributes, - source: data.source.key, - target: data.target.key, - sourceAttributes: data.source.attributes, - targetAttributes: data.target.attributes, - undirected: data.undirected - }; - - return {value, done: false}; - }); -} - -/** - * Function iterating over a node's edges using a callback to match one of them. - * - * @param {boolean} multi - Whether the graph is multi or not. - * @param {string} type - Type of edges to retrieve. - * @param {string} direction - In or out? - * @param {any} nodeData - Target node's data. - * @param {function} callback - Function to call. - */ -function forEachEdgeForNode( - breakable, - multi, - type, - direction, - nodeData, - callback -) { - const fn = multi ? forEachMulti : forEachSimple; - - let found; - - if (type !== 'undirected') { - if (direction !== 'out') { - found = fn(breakable, nodeData.in, callback); - - if (breakable && found) return found; - } - if (direction !== 'in') { - found = fn( - breakable, - nodeData.out, - callback, - !direction ? nodeData.key : undefined - ); - - if (breakable && found) return found; - } - } - - if (type !== 'directed') { - found = fn(breakable, nodeData.undirected, callback); - - if (breakable && found) return found; - } - - return; -} - -/** - * Function creating an array of edges for the given type & the given node. - * - * @param {boolean} multi - Whether the graph is multi or not. - * @param {string} type - Type of edges to retrieve. - * @param {string} direction - In or out? - * @param {any} nodeData - Target node's data. - * @return {array} - Array of edges. - */ -function createEdgeArrayForNode(multi, type, direction, nodeData) { - const edges = []; // TODO: possibility to know size beforehand or factorize with map - - forEachEdgeForNode(false, multi, type, direction, nodeData, function (key) { - edges.push(key); - }); - - return edges; -} - -/** - * Function iterating over a node's edges using a callback. - * - * @param {string} type - Type of edges to retrieve. - * @param {string} direction - In or out? - * @param {any} nodeData - Target node's data. - * @return {Iterator} - */ -function createEdgeIteratorForNode(type, direction, nodeData) { - let iterator = Iterator.empty(); - - if (type !== 'undirected') { - if (direction !== 'out' && typeof nodeData.in !== 'undefined') - iterator = chain(iterator, createIterator(nodeData.in)); - if (direction !== 'in' && typeof nodeData.out !== 'undefined') - iterator = chain( - iterator, - createIterator(nodeData.out, !direction ? nodeData.key : undefined) - ); - } - - if (type !== 'directed' && typeof nodeData.undirected !== 'undefined') { - iterator = chain(iterator, createIterator(nodeData.undirected)); - } - - return iterator; -} - -/** - * Function iterating over edges for the given path using a callback to match - * one of them. - * - * @param {string} type - Type of edges to retrieve. - * @param {boolean} multi - Whether the graph is multi. - * @param {string} direction - In or out? - * @param {NodeData} sourceData - Source node's data. - * @param {string} target - Target node. - * @param {function} callback - Function to call. - */ -function forEachEdgeForPath( - breakable, - type, - multi, - direction, - sourceData, - target, - callback -) { - const fn = multi ? forEachForKeyMulti : forEachForKeySimple; - - let found; - - if (type !== 'undirected') { - if (typeof sourceData.in !== 'undefined' && direction !== 'out') { - found = fn(breakable, sourceData.in, target, callback); - - if (breakable && found) return found; - } - - if ( - typeof sourceData.out !== 'undefined' && - direction !== 'in' && - (direction || sourceData.key !== target) - ) { - found = fn(breakable, sourceData.out, target, callback); - - if (breakable && found) return found; - } - } - - if (type !== 'directed') { - if (typeof sourceData.undirected !== 'undefined') { - found = fn(breakable, sourceData.undirected, target, callback); - - if (breakable && found) return found; - } - } - - return; -} - -/** - * Function creating an array of edges for the given path. - * - * @param {string} type - Type of edges to retrieve. - * @param {boolean} multi - Whether the graph is multi. - * @param {string} direction - In or out? - * @param {NodeData} sourceData - Source node's data. - * @param {any} target - Target node. - * @return {array} - Array of edges. - */ -function createEdgeArrayForPath(type, multi, direction, sourceData, target) { - const edges = []; // TODO: possibility to know size beforehand or factorize with map - - forEachEdgeForPath( - false, - type, - multi, - direction, - sourceData, - target, - function (key) { - edges.push(key); - } - ); - - return edges; -} - -/** - * Function returning an iterator over edges for the given path. - * - * @param {string} type - Type of edges to retrieve. - * @param {string} direction - In or out? - * @param {NodeData} sourceData - Source node's data. - * @param {string} target - Target node. - * @param {function} callback - Function to call. - */ -function createEdgeIteratorForPath(type, direction, sourceData, target) { - let iterator = Iterator.empty(); - - if (type !== 'undirected') { - if ( - typeof sourceData.in !== 'undefined' && - direction !== 'out' && - target in sourceData.in - ) - iterator = chain(iterator, createIteratorForKey(sourceData.in, target)); - - if ( - typeof sourceData.out !== 'undefined' && - direction !== 'in' && - target in sourceData.out && - (direction || sourceData.key !== target) - ) - iterator = chain(iterator, createIteratorForKey(sourceData.out, target)); - } - - if (type !== 'directed') { - if ( - typeof sourceData.undirected !== 'undefined' && - target in sourceData.undirected - ) - iterator = chain( - iterator, - createIteratorForKey(sourceData.undirected, target) - ); - } - - return iterator; -} - -/** - * Function attaching an edge array creator method to the Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ -function attachEdgeArrayCreator(Class, description) { - const {name, type, direction} = description; - - /** - * Function returning an array of certain edges. - * - * Arity 0: Return all the relevant edges. - * - * Arity 1: Return all of a node's relevant edges. - * @param {any} node - Target node. - * - * Arity 2: Return the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * - * @return {array|number} - The edges or the number of edges. - * - * @throws {Error} - Will throw if there are too many arguments. - */ - Class.prototype[name] = function (source, target) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) - return []; - - if (!arguments.length) return createEdgeArray(this, type); - - if (arguments.length === 1) { - source = '' + source; - - const nodeData = this._nodes.get(source); - - if (typeof nodeData === 'undefined') - throw new NotFoundGraphError( - `Graph.${name}: could not find the "${source}" node in the graph.` - ); - - // Iterating over a node's edges - return createEdgeArrayForNode( - this.multi, - type === 'mixed' ? this.type : type, - direction, - nodeData - ); - } - - if (arguments.length === 2) { - source = '' + source; - target = '' + target; - - const sourceData = this._nodes.get(source); - - if (!sourceData) - throw new NotFoundGraphError( - `Graph.${name}: could not find the "${source}" source node in the graph.` - ); - - if (!this._nodes.has(target)) - throw new NotFoundGraphError( - `Graph.${name}: could not find the "${target}" target node in the graph.` - ); - - // Iterating over the edges between source & target - return createEdgeArrayForPath( - type, - this.multi, - direction, - sourceData, - target - ); - } - - throw new InvalidArgumentsGraphError( - `Graph.${name}: too many arguments (expecting 0, 1 or 2 and got ${arguments.length}).` - ); - }; -} - -/** - * Function attaching a edge callback iterator method to the Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ -function attachForEachEdge(Class, description) { - const {name, type, direction} = description; - - const forEachName = 'forEach' + name[0].toUpperCase() + name.slice(1, -1); - - /** - * Function iterating over the graph's relevant edges by applying the given - * callback. - * - * Arity 1: Iterate over all the relevant edges. - * @param {function} callback - Callback to use. - * - * Arity 2: Iterate over all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * Arity 3: Iterate over the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} callback - Callback to use. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - Class.prototype[forEachName] = function (source, target, callback) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return; - - if (arguments.length === 1) { - callback = source; - return forEachEdge(false, this, type, callback); - } - - if (arguments.length === 2) { - source = '' + source; - callback = target; - - const nodeData = this._nodes.get(source); - - if (typeof nodeData === 'undefined') - throw new NotFoundGraphError( - `Graph.${forEachName}: could not find the "${source}" node in the graph.` - ); - - // Iterating over a node's edges - // TODO: maybe attach the sub method to the instance dynamically? - return forEachEdgeForNode( - false, - this.multi, - type === 'mixed' ? this.type : type, - direction, - nodeData, - callback - ); - } - - if (arguments.length === 3) { - source = '' + source; - target = '' + target; - - const sourceData = this._nodes.get(source); - - if (!sourceData) - throw new NotFoundGraphError( - `Graph.${forEachName}: could not find the "${source}" source node in the graph.` - ); - - if (!this._nodes.has(target)) - throw new NotFoundGraphError( - `Graph.${forEachName}: could not find the "${target}" target node in the graph.` - ); - - // Iterating over the edges between source & target - return forEachEdgeForPath( - false, - type, - this.multi, - direction, - sourceData, - target, - callback - ); - } - - throw new InvalidArgumentsGraphError( - `Graph.${forEachName}: too many arguments (expecting 1, 2 or 3 and got ${arguments.length}).` - ); - }; - - /** - * Function mapping the graph's relevant edges by applying the given - * callback. - * - * Arity 1: Map all the relevant edges. - * @param {function} callback - Callback to use. - * - * Arity 2: Map all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * Arity 3: Map the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} callback - Callback to use. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - const mapName = 'map' + name[0].toUpperCase() + name.slice(1); - - Class.prototype[mapName] = function () { - const args = Array.prototype.slice.call(arguments); - const callback = args.pop(); - - let result; - - // We know the result length beforehand - if (args.length === 0) { - let length = 0; - - if (type !== 'directed') length += this.undirectedSize; - if (type !== 'undirected') length += this.directedSize; - - result = new Array(length); - - let i = 0; - - args.push((e, ea, s, t, sa, ta, u) => { - result[i++] = callback(e, ea, s, t, sa, ta, u); - }); - } - - // We don't know the result length beforehand - // TODO: we can in some instances of simple graphs, knowing degree - else { - result = []; - - args.push((e, ea, s, t, sa, ta, u) => { - result.push(callback(e, ea, s, t, sa, ta, u)); - }); - } - - this[forEachName].apply(this, args); - - return result; - }; - - /** - * Function filtering the graph's relevant edges using the provided predicate - * function. - * - * Arity 1: Filter all the relevant edges. - * @param {function} predicate - Predicate to use. - * - * Arity 2: Filter all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} predicate - Predicate to use. - * - * Arity 3: Filter the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} predicate - Predicate to use. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - const filterName = 'filter' + name[0].toUpperCase() + name.slice(1); - - Class.prototype[filterName] = function () { - const args = Array.prototype.slice.call(arguments); - const callback = args.pop(); - - const result = []; - - args.push((e, ea, s, t, sa, ta, u) => { - if (callback(e, ea, s, t, sa, ta, u)) result.push(e); - }); - - this[forEachName].apply(this, args); - - return result; - }; - - /** - * Function reducing the graph's relevant edges using the provided accumulator - * function. - * - * Arity 1: Reduce all the relevant edges. - * @param {function} accumulator - Accumulator to use. - * @param {any} initialValue - Initial value. - * - * Arity 2: Reduce all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} accumulator - Accumulator to use. - * @param {any} initialValue - Initial value. - * - * Arity 3: Reduce the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} accumulator - Accumulator to use. - * @param {any} initialValue - Initial value. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - const reduceName = 'reduce' + name[0].toUpperCase() + name.slice(1); - - Class.prototype[reduceName] = function () { - let args = Array.prototype.slice.call(arguments); - - if (args.length < 2 || args.length > 4) { - throw new InvalidArgumentsGraphError( - `Graph.${reduceName}: invalid number of arguments (expecting 2, 3 or 4 and got ${args.length}).` - ); - } - - if ( - typeof args[args.length - 1] === 'function' && - typeof args[args.length - 2] !== 'function' - ) { - throw new InvalidArgumentsGraphError( - `Graph.${reduceName}: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.` - ); - } - - let callback; - let initialValue; - - if (args.length === 2) { - callback = args[0]; - initialValue = args[1]; - args = []; - } else if (args.length === 3) { - callback = args[1]; - initialValue = args[2]; - args = [args[0]]; - } else if (args.length === 4) { - callback = args[2]; - initialValue = args[3]; - args = [args[0], args[1]]; - } - - let accumulator = initialValue; - - args.push((e, ea, s, t, sa, ta, u) => { - accumulator = callback(accumulator, e, ea, s, t, sa, ta, u); - }); - - this[forEachName].apply(this, args); - - return accumulator; - }; -} - -/** - * Function attaching a breakable edge callback iterator method to the Graph - * prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ -function attachFindEdge(Class, description) { - const {name, type, direction} = description; - - const findEdgeName = 'find' + name[0].toUpperCase() + name.slice(1, -1); - - /** - * Function iterating over the graph's relevant edges in order to match - * one of them using the provided predicate function. - * - * Arity 1: Iterate over all the relevant edges. - * @param {function} callback - Callback to use. - * - * Arity 2: Iterate over all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * Arity 3: Iterate over the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} callback - Callback to use. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - Class.prototype[findEdgeName] = function (source, target, callback) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) - return false; - - if (arguments.length === 1) { - callback = source; - return forEachEdge(true, this, type, callback); - } - - if (arguments.length === 2) { - source = '' + source; - callback = target; - - const nodeData = this._nodes.get(source); - - if (typeof nodeData === 'undefined') - throw new NotFoundGraphError( - `Graph.${findEdgeName}: could not find the "${source}" node in the graph.` - ); - - // Iterating over a node's edges - // TODO: maybe attach the sub method to the instance dynamically? - return forEachEdgeForNode( - true, - this.multi, - type === 'mixed' ? this.type : type, - direction, - nodeData, - callback - ); - } - - if (arguments.length === 3) { - source = '' + source; - target = '' + target; - - const sourceData = this._nodes.get(source); - - if (!sourceData) - throw new NotFoundGraphError( - `Graph.${findEdgeName}: could not find the "${source}" source node in the graph.` - ); - - if (!this._nodes.has(target)) - throw new NotFoundGraphError( - `Graph.${findEdgeName}: could not find the "${target}" target node in the graph.` - ); - - // Iterating over the edges between source & target - return forEachEdgeForPath( - true, - type, - this.multi, - direction, - sourceData, - target, - callback - ); - } - - throw new InvalidArgumentsGraphError( - `Graph.${findEdgeName}: too many arguments (expecting 1, 2 or 3 and got ${arguments.length}).` - ); - }; - - /** - * Function iterating over the graph's relevant edges in order to assert - * whether any one of them matches the provided predicate function. - * - * Arity 1: Iterate over all the relevant edges. - * @param {function} callback - Callback to use. - * - * Arity 2: Iterate over all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * Arity 3: Iterate over the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} callback - Callback to use. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - const someName = 'some' + name[0].toUpperCase() + name.slice(1, -1); - - Class.prototype[someName] = function () { - const args = Array.prototype.slice.call(arguments); - const callback = args.pop(); - - args.push((e, ea, s, t, sa, ta, u) => { - return callback(e, ea, s, t, sa, ta, u); - }); - - const found = this[findEdgeName].apply(this, args); - - if (found) return true; - - return false; - }; - - /** - * Function iterating over the graph's relevant edges in order to assert - * whether all of them matche the provided predicate function. - * - * Arity 1: Iterate over all the relevant edges. - * @param {function} callback - Callback to use. - * - * Arity 2: Iterate over all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * Arity 3: Iterate over the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} callback - Callback to use. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - const everyName = 'every' + name[0].toUpperCase() + name.slice(1, -1); - - Class.prototype[everyName] = function () { - const args = Array.prototype.slice.call(arguments); - const callback = args.pop(); - - args.push((e, ea, s, t, sa, ta, u) => { - return !callback(e, ea, s, t, sa, ta, u); - }); - - const found = this[findEdgeName].apply(this, args); - - if (found) return false; - - return true; - }; -} - -/** - * Function attaching an edge iterator method to the Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ -function attachEdgeIteratorCreator(Class, description) { - const {name: originalName, type, direction} = description; - - const name = originalName.slice(0, -1) + 'Entries'; - - /** - * Function returning an iterator over the graph's edges. - * - * Arity 0: Iterate over all the relevant edges. - * - * Arity 1: Iterate over all of a node's relevant edges. - * @param {any} node - Target node. - * - * Arity 2: Iterate over the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * - * @return {array|number} - The edges or the number of edges. - * - * @throws {Error} - Will throw if there are too many arguments. - */ - Class.prototype[name] = function (source, target) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) - return Iterator.empty(); - - if (!arguments.length) return createEdgeIterator(this, type); - - if (arguments.length === 1) { - source = '' + source; - - const sourceData = this._nodes.get(source); - - if (!sourceData) - throw new NotFoundGraphError( - `Graph.${name}: could not find the "${source}" node in the graph.` - ); - - // Iterating over a node's edges - return createEdgeIteratorForNode(type, direction, sourceData); - } - - if (arguments.length === 2) { - source = '' + source; - target = '' + target; - - const sourceData = this._nodes.get(source); - - if (!sourceData) - throw new NotFoundGraphError( - `Graph.${name}: could not find the "${source}" source node in the graph.` - ); - - if (!this._nodes.has(target)) - throw new NotFoundGraphError( - `Graph.${name}: could not find the "${target}" target node in the graph.` - ); - - // Iterating over the edges between source & target - return createEdgeIteratorForPath(type, direction, sourceData, target); - } - - throw new InvalidArgumentsGraphError( - `Graph.${name}: too many arguments (expecting 0, 1 or 2 and got ${arguments.length}).` - ); - }; -} - -/** - * Function attaching every edge iteration method to the Graph class. - * - * @param {function} Graph - Graph class. - */ -function attachEdgeIterationMethods(Graph) { - EDGES_ITERATION.forEach(description => { - attachEdgeArrayCreator(Graph, description); - attachForEachEdge(Graph, description); - attachFindEdge(Graph, description); - attachEdgeIteratorCreator(Graph, description); - }); -} - -/** - * Graphology Neighbor Iteration - * ============================== - * - * Attaching some methods to the Graph class to be able to iterate over - * neighbors. - */ - -/** - * Definitions. - */ -const NEIGHBORS_ITERATION = [ - { - name: 'neighbors', - type: 'mixed' - }, - { - name: 'inNeighbors', - type: 'directed', - direction: 'in' - }, - { - name: 'outNeighbors', - type: 'directed', - direction: 'out' - }, - { - name: 'inboundNeighbors', - type: 'mixed', - direction: 'in' - }, - { - name: 'outboundNeighbors', - type: 'mixed', - direction: 'out' - }, - { - name: 'directedNeighbors', - type: 'directed' - }, - { - name: 'undirectedNeighbors', - type: 'undirected' - } -]; - -/** - * Helpers. - */ -function CompositeSetWrapper() { - this.A = null; - this.B = null; -} - -CompositeSetWrapper.prototype.wrap = function (set) { - if (this.A === null) this.A = set; - else if (this.B === null) this.B = set; -}; - -CompositeSetWrapper.prototype.has = function (key) { - if (this.A !== null && key in this.A) return true; - if (this.B !== null && key in this.B) return true; - return false; -}; - -/** - * Function iterating over the given node's relevant neighbors to match - * one of them using a predicated function. - * - * @param {string} type - Type of neighbors. - * @param {string} direction - Direction. - * @param {any} nodeData - Target node's data. - * @param {function} callback - Callback to use. - */ -function forEachInObjectOnce(breakable, visited, nodeData, object, callback) { - for (const k in object) { - const edgeData = object[k]; - - const sourceData = edgeData.source; - const targetData = edgeData.target; - - const neighborData = sourceData === nodeData ? targetData : sourceData; - - if (visited && visited.has(neighborData.key)) continue; - - const shouldBreak = callback(neighborData.key, neighborData.attributes); - - if (breakable && shouldBreak) return neighborData.key; - } - - return; -} - -function forEachNeighbor(breakable, type, direction, nodeData, callback) { - // If we want only undirected or in or out, we can roll some optimizations - if (type !== 'mixed') { - if (type === 'undirected') - return forEachInObjectOnce( - breakable, - null, - nodeData, - nodeData.undirected, - callback - ); - - if (typeof direction === 'string') - return forEachInObjectOnce( - breakable, - null, - nodeData, - nodeData[direction], - callback - ); - } - - // Else we need to keep a set of neighbors not to return duplicates - // We cheat by querying the other adjacencies - const visited = new CompositeSetWrapper(); - - let found; - - if (type !== 'undirected') { - if (direction !== 'out') { - found = forEachInObjectOnce( - breakable, - null, - nodeData, - nodeData.in, - callback - ); - - if (breakable && found) return found; - - visited.wrap(nodeData.in); - } - if (direction !== 'in') { - found = forEachInObjectOnce( - breakable, - visited, - nodeData, - nodeData.out, - callback - ); - - if (breakable && found) return found; - - visited.wrap(nodeData.out); - } - } - - if (type !== 'directed') { - found = forEachInObjectOnce( - breakable, - visited, - nodeData, - nodeData.undirected, - callback - ); - - if (breakable && found) return found; - } - - return; -} - -/** - * Function creating an array of relevant neighbors for the given node. - * - * @param {string} type - Type of neighbors. - * @param {string} direction - Direction. - * @param {any} nodeData - Target node's data. - * @return {Array} - The list of neighbors. - */ -function createNeighborArrayForNode(type, direction, nodeData) { - // If we want only undirected or in or out, we can roll some optimizations - if (type !== 'mixed') { - if (type === 'undirected') return Object.keys(nodeData.undirected); - - if (typeof direction === 'string') return Object.keys(nodeData[direction]); - } - - const neighbors = []; - - forEachNeighbor(false, type, direction, nodeData, function (key) { - neighbors.push(key); - }); - - return neighbors; -} - -/** - * Function returning an iterator over the given node's relevant neighbors. - * - * @param {string} type - Type of neighbors. - * @param {string} direction - Direction. - * @param {any} nodeData - Target node's data. - * @return {Iterator} - */ -function createDedupedObjectIterator(visited, nodeData, object) { - const keys = Object.keys(object); - const l = keys.length; - - let i = 0; - - return new Iterator(function next() { - let neighborData = null; - - do { - if (i >= l) { - if (visited) visited.wrap(object); - return {done: true}; - } - - const edgeData = object[keys[i++]]; - - const sourceData = edgeData.source; - const targetData = edgeData.target; - - neighborData = sourceData === nodeData ? targetData : sourceData; - - if (visited && visited.has(neighborData.key)) { - neighborData = null; - continue; - } - } while (neighborData === null); - - return { - done: false, - value: {neighbor: neighborData.key, attributes: neighborData.attributes} - }; - }); -} - -function createNeighborIterator(type, direction, nodeData) { - // If we want only undirected or in or out, we can roll some optimizations - if (type !== 'mixed') { - if (type === 'undirected') - return createDedupedObjectIterator(null, nodeData, nodeData.undirected); - - if (typeof direction === 'string') - return createDedupedObjectIterator(null, nodeData, nodeData[direction]); - } - - let iterator = Iterator.empty(); - - // Else we need to keep a set of neighbors not to return duplicates - // We cheat by querying the other adjacencies - const visited = new CompositeSetWrapper(); - - if (type !== 'undirected') { - if (direction !== 'out') { - iterator = chain( - iterator, - createDedupedObjectIterator(visited, nodeData, nodeData.in) - ); - } - if (direction !== 'in') { - iterator = chain( - iterator, - createDedupedObjectIterator(visited, nodeData, nodeData.out) - ); - } - } - - if (type !== 'directed') { - iterator = chain( - iterator, - createDedupedObjectIterator(visited, nodeData, nodeData.undirected) - ); - } - - return iterator; -} - -/** - * Function attaching a neighbors array creator method to the Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ -function attachNeighborArrayCreator(Class, description) { - const {name, type, direction} = description; - - /** - * Function returning an array of certain neighbors. - * - * @param {any} node - Target node. - * @return {array} - The neighbors of neighbors. - * - * @throws {Error} - Will throw if node is not found in the graph. - */ - Class.prototype[name] = function (node) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) - return []; - - node = '' + node; - - const nodeData = this._nodes.get(node); - - if (typeof nodeData === 'undefined') - throw new NotFoundGraphError( - `Graph.${name}: could not find the "${node}" node in the graph.` - ); - - // Here, we want to iterate over a node's relevant neighbors - return createNeighborArrayForNode( - type === 'mixed' ? this.type : type, - direction, - nodeData - ); - }; -} - -/** - * Function attaching a neighbors callback iterator method to the Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ -function attachForEachNeighbor(Class, description) { - const {name, type, direction} = description; - - const forEachName = 'forEach' + name[0].toUpperCase() + name.slice(1, -1); - - /** - * Function iterating over all the relevant neighbors using a callback. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - Class.prototype[forEachName] = function (node, callback) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return; - - node = '' + node; - - const nodeData = this._nodes.get(node); - - if (typeof nodeData === 'undefined') - throw new NotFoundGraphError( - `Graph.${forEachName}: could not find the "${node}" node in the graph.` - ); - - // Here, we want to iterate over a node's relevant neighbors - forEachNeighbor( - false, - type === 'mixed' ? this.type : type, - direction, - nodeData, - callback - ); - }; - - /** - * Function mapping the relevant neighbors using a callback. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * @throws {Error} - Will throw if there are too many arguments. - */ - const mapName = 'map' + name[0].toUpperCase() + name.slice(1); - - Class.prototype[mapName] = function (node, callback) { - // TODO: optimize when size is known beforehand - const result = []; - - this[forEachName](node, (n, a) => { - result.push(callback(n, a)); - }); - - return result; - }; - - /** - * Function filtering the relevant neighbors using a callback. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * @throws {Error} - Will throw if there are too many arguments. - */ - const filterName = 'filter' + name[0].toUpperCase() + name.slice(1); - - Class.prototype[filterName] = function (node, callback) { - const result = []; - - this[forEachName](node, (n, a) => { - if (callback(n, a)) result.push(n); - }); - - return result; - }; - - /** - * Function reducing the relevant neighbors using a callback. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * @throws {Error} - Will throw if there are too many arguments. - */ - const reduceName = 'reduce' + name[0].toUpperCase() + name.slice(1); - - Class.prototype[reduceName] = function (node, callback, initialValue) { - if (arguments.length < 3) - throw new InvalidArgumentsGraphError( - `Graph.${reduceName}: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.` - ); - - let accumulator = initialValue; - - this[forEachName](node, (n, a) => { - accumulator = callback(accumulator, n, a); - }); - - return accumulator; - }; -} - -/** - * Function attaching a breakable neighbors callback iterator method to the - * Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ -function attachFindNeighbor(Class, description) { - const {name, type, direction} = description; - - const capitalizedSingular = name[0].toUpperCase() + name.slice(1, -1); - - const findName = 'find' + capitalizedSingular; - - /** - * Function iterating over all the relevant neighbors using a callback. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - Class.prototype[findName] = function (node, callback) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return; - - node = '' + node; - - const nodeData = this._nodes.get(node); - - if (typeof nodeData === 'undefined') - throw new NotFoundGraphError( - `Graph.${findName}: could not find the "${node}" node in the graph.` - ); - - // Here, we want to iterate over a node's relevant neighbors - return forEachNeighbor( - true, - type === 'mixed' ? this.type : type, - direction, - nodeData, - callback - ); - }; - - /** - * Function iterating over all the relevant neighbors to find if any of them - * matches the given predicate. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * @return {boolean} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - const someName = 'some' + capitalizedSingular; - - Class.prototype[someName] = function (node, callback) { - const found = this[findName](node, callback); - - if (found) return true; - - return false; - }; - - /** - * Function iterating over all the relevant neighbors to find if all of them - * matche the given predicate. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * @return {boolean} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - const everyName = 'every' + capitalizedSingular; - - Class.prototype[everyName] = function (node, callback) { - const found = this[findName](node, (n, a) => { - return !callback(n, a); - }); - - if (found) return false; - - return true; - }; -} - -/** - * Function attaching a neighbors callback iterator method to the Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ -function attachNeighborIteratorCreator(Class, description) { - const {name, type, direction} = description; - - const iteratorName = name.slice(0, -1) + 'Entries'; - - /** - * Function returning an iterator over all the relevant neighbors. - * - * @param {any} node - Target node. - * @return {Iterator} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - Class.prototype[iteratorName] = function (node) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) - return Iterator.empty(); - - node = '' + node; - - const nodeData = this._nodes.get(node); - - if (typeof nodeData === 'undefined') - throw new NotFoundGraphError( - `Graph.${iteratorName}: could not find the "${node}" node in the graph.` - ); - - // Here, we want to iterate over a node's relevant neighbors - return createNeighborIterator( - type === 'mixed' ? this.type : type, - direction, - nodeData - ); - }; -} - -/** - * Function attaching every neighbor iteration method to the Graph class. - * - * @param {function} Graph - Graph class. - */ -function attachNeighborIterationMethods(Graph) { - NEIGHBORS_ITERATION.forEach(description => { - attachNeighborArrayCreator(Graph, description); - attachForEachNeighbor(Graph, description); - attachFindNeighbor(Graph, description); - attachNeighborIteratorCreator(Graph, description); - }); -} - -/** - * Graphology Adjacency Iteration - * =============================== - * - * Attaching some methods to the Graph class to be able to iterate over a - * graph's adjacency. - */ - -/** - * Function iterating over a simple graph's adjacency using a callback. - * - * @param {boolean} breakable - Can we break? - * @param {boolean} assymetric - Whether to emit undirected edges only once. - * @param {boolean} disconnectedNodes - Whether to emit disconnected nodes. - * @param {Graph} graph - Target Graph instance. - * @param {callback} function - Iteration callback. - */ -function forEachAdjacency( - breakable, - assymetric, - disconnectedNodes, - graph, - callback -) { - const iterator = graph._nodes.values(); - - const type = graph.type; - - let step, sourceData, neighbor, adj, edgeData, targetData, shouldBreak; - - while (((step = iterator.next()), step.done !== true)) { - let hasEdges = false; - - sourceData = step.value; - - if (type !== 'undirected') { - adj = sourceData.out; - - for (neighbor in adj) { - edgeData = adj[neighbor]; - - do { - targetData = edgeData.target; - - hasEdges = true; - shouldBreak = callback( - sourceData.key, - targetData.key, - sourceData.attributes, - targetData.attributes, - edgeData.key, - edgeData.attributes, - edgeData.undirected - ); - - if (breakable && shouldBreak) return edgeData; - - edgeData = edgeData.next; - } while (edgeData); - } - } - - if (type !== 'directed') { - adj = sourceData.undirected; - - for (neighbor in adj) { - if (assymetric && sourceData.key > neighbor) continue; - - edgeData = adj[neighbor]; - - do { - targetData = edgeData.target; - - if (targetData.key !== neighbor) targetData = edgeData.source; - - hasEdges = true; - shouldBreak = callback( - sourceData.key, - targetData.key, - sourceData.attributes, - targetData.attributes, - edgeData.key, - edgeData.attributes, - edgeData.undirected - ); - - if (breakable && shouldBreak) return edgeData; - - edgeData = edgeData.next; - } while (edgeData); - } - } - - if (disconnectedNodes && !hasEdges) { - shouldBreak = callback( - sourceData.key, - null, - sourceData.attributes, - null, - null, - null, - null - ); - - if (breakable && shouldBreak) return null; - } - } - - return; -} - -/** - * Graphology Serialization Utilities - * =================================== - * - * Collection of functions used by the graph serialization schemes. - */ - -/** - * Formats internal node data into a serialized node. - * - * @param {any} key - The node's key. - * @param {object} data - Internal node's data. - * @return {array} - The serialized node. - */ -function serializeNode(key, data) { - const serialized = {key}; - - if (!isEmpty(data.attributes)) - serialized.attributes = assign({}, data.attributes); - - return serialized; -} - -/** - * Formats internal edge data into a serialized edge. - * - * @param {any} key - The edge's key. - * @param {object} data - Internal edge's data. - * @return {array} - The serialized edge. - */ -function serializeEdge(key, data) { - const serialized = { - key, - source: data.source.key, - target: data.target.key - }; - - if (!isEmpty(data.attributes)) - serialized.attributes = assign({}, data.attributes); - - if (data.undirected) serialized.undirected = true; - - return serialized; -} - -/** - * Checks whether the given value is a serialized node. - * - * @param {mixed} value - Target value. - * @return {string|null} - */ -function validateSerializedNode(value) { - if (!isPlainObject(value)) - throw new InvalidArgumentsGraphError( - 'Graph.import: invalid serialized node. A serialized node should be a plain object with at least a "key" property.' - ); - - if (!('key' in value)) - throw new InvalidArgumentsGraphError( - 'Graph.import: serialized node is missing its key.' - ); - - if ( - 'attributes' in value && - (!isPlainObject(value.attributes) || value.attributes === null) - ) - throw new InvalidArgumentsGraphError( - 'Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.' - ); -} - -/** - * Checks whether the given value is a serialized edge. - * - * @param {mixed} value - Target value. - * @return {string|null} - */ -function validateSerializedEdge(value) { - if (!isPlainObject(value)) - throw new InvalidArgumentsGraphError( - 'Graph.import: invalid serialized edge. A serialized edge should be a plain object with at least a "source" & "target" property.' - ); - - if (!('source' in value)) - throw new InvalidArgumentsGraphError( - 'Graph.import: serialized edge is missing its source.' - ); - - if (!('target' in value)) - throw new InvalidArgumentsGraphError( - 'Graph.import: serialized edge is missing its target.' - ); - - if ( - 'attributes' in value && - (!isPlainObject(value.attributes) || value.attributes === null) - ) - throw new InvalidArgumentsGraphError( - 'Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.' - ); - - if ('undirected' in value && typeof value.undirected !== 'boolean') - throw new InvalidArgumentsGraphError( - 'Graph.import: invalid undirectedness information. Undirected should be boolean or omitted.' - ); -} - -/* eslint no-nested-ternary: 0 */ - -/** - * Constants. - */ -const INSTANCE_ID = incrementalIdStartingFromRandomByte(); - -/** - * Enums. - */ -const TYPES = new Set(['directed', 'undirected', 'mixed']); - -const EMITTER_PROPS = new Set([ - 'domain', - '_events', - '_eventsCount', - '_maxListeners' -]); - -const EDGE_ADD_METHODS = [ - { - name: verb => `${verb}Edge`, - generateKey: true - }, - { - name: verb => `${verb}DirectedEdge`, - generateKey: true, - type: 'directed' - }, - { - name: verb => `${verb}UndirectedEdge`, - generateKey: true, - type: 'undirected' - }, - { - name: verb => `${verb}EdgeWithKey` - }, - { - name: verb => `${verb}DirectedEdgeWithKey`, - type: 'directed' - }, - { - name: verb => `${verb}UndirectedEdgeWithKey`, - type: 'undirected' - } -]; - -/** - * Default options. - */ -const DEFAULTS = { - allowSelfLoops: true, - multi: false, - type: 'mixed' -}; - -/** - * Abstract functions used by the Graph class for various methods. - */ - -/** - * Internal method used to add a node to the given graph - * - * @param {Graph} graph - Target graph. - * @param {any} node - The node's key. - * @param {object} [attributes] - Optional attributes. - * @return {NodeData} - Created node data. - */ -function addNode(graph, node, attributes) { - if (attributes && !isPlainObject(attributes)) - throw new InvalidArgumentsGraphError( - `Graph.addNode: invalid attributes. Expecting an object but got "${attributes}"` - ); - - // String coercion - node = '' + node; - attributes = attributes || {}; - - if (graph._nodes.has(node)) - throw new UsageGraphError( - `Graph.addNode: the "${node}" node already exist in the graph.` - ); - - const data = new graph.NodeDataClass(node, attributes); - - // Adding the node to internal register - graph._nodes.set(node, data); - - // Emitting - graph.emit('nodeAdded', { - key: node, - attributes - }); - - return data; -} - -/** - * Same as the above but without sanity checks because we call this in contexts - * where necessary checks were already done. - */ -function unsafeAddNode(graph, node, attributes) { - const data = new graph.NodeDataClass(node, attributes); - - graph._nodes.set(node, data); - - graph.emit('nodeAdded', { - key: node, - attributes - }); - - return data; -} - -/** - * Internal method used to add an arbitrary edge to the given graph. - * - * @param {Graph} graph - Target graph. - * @param {string} name - Name of the child method for errors. - * @param {boolean} mustGenerateKey - Should the graph generate an id? - * @param {boolean} undirected - Whether the edge is undirected. - * @param {any} edge - The edge's key. - * @param {any} source - The source node. - * @param {any} target - The target node. - * @param {object} [attributes] - Optional attributes. - * @return {any} - The edge. - * - * @throws {Error} - Will throw if the graph is of the wrong type. - * @throws {Error} - Will throw if the given attributes are not an object. - * @throws {Error} - Will throw if source or target doesn't exist. - * @throws {Error} - Will throw if the edge already exist. - */ -function addEdge( - graph, - name, - mustGenerateKey, - undirected, - edge, - source, - target, - attributes -) { - // Checking validity of operation - if (!undirected && graph.type === 'undirected') - throw new UsageGraphError( - `Graph.${name}: you cannot add a directed edge to an undirected graph. Use the #.addEdge or #.addUndirectedEdge instead.` - ); - - if (undirected && graph.type === 'directed') - throw new UsageGraphError( - `Graph.${name}: you cannot add an undirected edge to a directed graph. Use the #.addEdge or #.addDirectedEdge instead.` - ); - - if (attributes && !isPlainObject(attributes)) - throw new InvalidArgumentsGraphError( - `Graph.${name}: invalid attributes. Expecting an object but got "${attributes}"` - ); - - // Coercion of source & target: - source = '' + source; - target = '' + target; - attributes = attributes || {}; - - if (!graph.allowSelfLoops && source === target) - throw new UsageGraphError( - `Graph.${name}: source & target are the same ("${source}"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.` - ); - - const sourceData = graph._nodes.get(source), - targetData = graph._nodes.get(target); - - if (!sourceData) - throw new NotFoundGraphError( - `Graph.${name}: source node "${source}" not found.` - ); - - if (!targetData) - throw new NotFoundGraphError( - `Graph.${name}: target node "${target}" not found.` - ); - - // Must the graph generate an id for this edge? - const eventData = { - key: null, - undirected, - source, - target, - attributes - }; - - if (mustGenerateKey) { - // NOTE: in this case we can guarantee that the key does not already - // exist and is already correctly casted as a string - edge = graph._edgeKeyGenerator(); - } else { - // Coercion of edge key - edge = '' + edge; - - // Here, we have a key collision - if (graph._edges.has(edge)) - throw new UsageGraphError( - `Graph.${name}: the "${edge}" edge already exists in the graph.` - ); - } - - // Here, we might have a source / target collision - if ( - !graph.multi && - (undirected - ? typeof sourceData.undirected[target] !== 'undefined' - : typeof sourceData.out[target] !== 'undefined') - ) { - throw new UsageGraphError( - `Graph.${name}: an edge linking "${source}" to "${target}" already exists. If you really want to add multiple edges linking those nodes, you should create a multi graph by using the 'multi' option.` - ); - } - - // Storing some data - const edgeData = new EdgeData( - undirected, - edge, - sourceData, - targetData, - attributes - ); - - // Adding the edge to the internal register - graph._edges.set(edge, edgeData); - - // Incrementing node degree counters - const isSelfLoop = source === target; - - if (undirected) { - sourceData.undirectedDegree++; - targetData.undirectedDegree++; - - if (isSelfLoop) graph._undirectedSelfLoopCount++; - } else { - sourceData.outDegree++; - targetData.inDegree++; - - if (isSelfLoop) graph._directedSelfLoopCount++; - } - - // Updating relevant index - if (graph.multi) edgeData.attachMulti(); - else edgeData.attach(); - - if (undirected) graph._undirectedSize++; - else graph._directedSize++; - - // Emitting - eventData.key = edge; - - graph.emit('edgeAdded', eventData); - - return edge; -} - -/** - * Internal method used to add an arbitrary edge to the given graph. - * - * @param {Graph} graph - Target graph. - * @param {string} name - Name of the child method for errors. - * @param {boolean} mustGenerateKey - Should the graph generate an id? - * @param {boolean} undirected - Whether the edge is undirected. - * @param {any} edge - The edge's key. - * @param {any} source - The source node. - * @param {any} target - The target node. - * @param {object} [attributes] - Optional attributes. - * @param {boolean} [asUpdater] - Are we updating or merging? - * @return {any} - The edge. - * - * @throws {Error} - Will throw if the graph is of the wrong type. - * @throws {Error} - Will throw if the given attributes are not an object. - * @throws {Error} - Will throw if source or target doesn't exist. - * @throws {Error} - Will throw if the edge already exist. - */ -function mergeEdge( - graph, - name, - mustGenerateKey, - undirected, - edge, - source, - target, - attributes, - asUpdater -) { - // Checking validity of operation - if (!undirected && graph.type === 'undirected') - throw new UsageGraphError( - `Graph.${name}: you cannot merge/update a directed edge to an undirected graph. Use the #.mergeEdge/#.updateEdge or #.addUndirectedEdge instead.` - ); - - if (undirected && graph.type === 'directed') - throw new UsageGraphError( - `Graph.${name}: you cannot merge/update an undirected edge to a directed graph. Use the #.mergeEdge/#.updateEdge or #.addDirectedEdge instead.` - ); - - if (attributes) { - if (asUpdater) { - if (typeof attributes !== 'function') - throw new InvalidArgumentsGraphError( - `Graph.${name}: invalid updater function. Expecting a function but got "${attributes}"` - ); - } else { - if (!isPlainObject(attributes)) - throw new InvalidArgumentsGraphError( - `Graph.${name}: invalid attributes. Expecting an object but got "${attributes}"` - ); - } - } - - // Coercion of source & target: - source = '' + source; - target = '' + target; - - let updater; - - if (asUpdater) { - updater = attributes; - attributes = undefined; - } - - if (!graph.allowSelfLoops && source === target) - throw new UsageGraphError( - `Graph.${name}: source & target are the same ("${source}"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.` - ); - - let sourceData = graph._nodes.get(source); - let targetData = graph._nodes.get(target); - let edgeData; - - // Do we need to handle duplicate? - let alreadyExistingEdgeData; - - if (!mustGenerateKey) { - edgeData = graph._edges.get(edge); - - if (edgeData) { - // Here, we need to ensure, if the user gave a key, that source & target - // are consistent - if (edgeData.source.key !== source || edgeData.target.key !== target) { - // If source or target inconsistent - if ( - !undirected || - edgeData.source.key !== target || - edgeData.target.key !== source - ) { - // If directed, or source/target aren't flipped - throw new UsageGraphError( - `Graph.${name}: inconsistency detected when attempting to merge the "${edge}" edge with "${source}" source & "${target}" target vs. ("${edgeData.source.key}", "${edgeData.target.key}").` - ); - } - } - - alreadyExistingEdgeData = edgeData; - } - } - - // Here, we might have a source / target collision - if (!alreadyExistingEdgeData && !graph.multi && sourceData) { - alreadyExistingEdgeData = undirected - ? sourceData.undirected[target] - : sourceData.out[target]; - } - - // Handling duplicates - if (alreadyExistingEdgeData) { - const info = [alreadyExistingEdgeData.key, false, false, false]; - - // We can skip the attribute merging part if the user did not provide them - if (asUpdater ? !updater : !attributes) return info; - - // Updating the attributes - if (asUpdater) { - const oldAttributes = alreadyExistingEdgeData.attributes; - alreadyExistingEdgeData.attributes = updater(oldAttributes); - - graph.emit('edgeAttributesUpdated', { - type: 'replace', - key: alreadyExistingEdgeData.key, - attributes: alreadyExistingEdgeData.attributes - }); - } - - // Merging the attributes - else { - assign(alreadyExistingEdgeData.attributes, attributes); - - graph.emit('edgeAttributesUpdated', { - type: 'merge', - key: alreadyExistingEdgeData.key, - attributes: alreadyExistingEdgeData.attributes, - data: attributes - }); - } - - return info; - } - - attributes = attributes || {}; - - if (asUpdater && updater) attributes = updater(attributes); - - // Must the graph generate an id for this edge? - const eventData = { - key: null, - undirected, - source, - target, - attributes - }; - - if (mustGenerateKey) { - // NOTE: in this case we can guarantee that the key does not already - // exist and is already correctly casted as a string - edge = graph._edgeKeyGenerator(); - } else { - // Coercion of edge key - edge = '' + edge; - - // Here, we have a key collision - if (graph._edges.has(edge)) - throw new UsageGraphError( - `Graph.${name}: the "${edge}" edge already exists in the graph.` - ); - } - - let sourceWasAdded = false; - let targetWasAdded = false; - - if (!sourceData) { - sourceData = unsafeAddNode(graph, source, {}); - sourceWasAdded = true; - - if (source === target) { - targetData = sourceData; - targetWasAdded = true; - } - } - if (!targetData) { - targetData = unsafeAddNode(graph, target, {}); - targetWasAdded = true; - } - - // Storing some data - edgeData = new EdgeData(undirected, edge, sourceData, targetData, attributes); - - // Adding the edge to the internal register - graph._edges.set(edge, edgeData); - - // Incrementing node degree counters - const isSelfLoop = source === target; - - if (undirected) { - sourceData.undirectedDegree++; - targetData.undirectedDegree++; - - if (isSelfLoop) graph._undirectedSelfLoopCount++; - } else { - sourceData.outDegree++; - targetData.inDegree++; - - if (isSelfLoop) graph._directedSelfLoopCount++; - } - - // Updating relevant index - if (graph.multi) edgeData.attachMulti(); - else edgeData.attach(); - - if (undirected) graph._undirectedSize++; - else graph._directedSize++; - - // Emitting - eventData.key = edge; - - graph.emit('edgeAdded', eventData); - - return [edge, true, sourceWasAdded, targetWasAdded]; -} - -/** - * Internal method used to drop an edge. - * - * @param {Graph} graph - Target graph. - * @param {EdgeData} edgeData - Data of the edge to drop. - */ -function dropEdgeFromData(graph, edgeData) { - // Dropping the edge from the register - graph._edges.delete(edgeData.key); - - // Updating related degrees - const {source: sourceData, target: targetData, attributes} = edgeData; - - const undirected = edgeData.undirected; - - const isSelfLoop = sourceData === targetData; - - if (undirected) { - sourceData.undirectedDegree--; - targetData.undirectedDegree--; - - if (isSelfLoop) graph._undirectedSelfLoopCount--; - } else { - sourceData.outDegree--; - targetData.inDegree--; - - if (isSelfLoop) graph._directedSelfLoopCount--; - } - - // Clearing index - if (graph.multi) edgeData.detachMulti(); - else edgeData.detach(); - - if (undirected) graph._undirectedSize--; - else graph._directedSize--; - - // Emitting - graph.emit('edgeDropped', { - key: edgeData.key, - attributes, - source: sourceData.key, - target: targetData.key, - undirected - }); -} - -/** - * Graph class - * - * @constructor - * @param {object} [options] - Options: - * @param {boolean} [allowSelfLoops] - Allow self loops? - * @param {string} [type] - Type of the graph. - * @param {boolean} [map] - Allow references as keys? - * @param {boolean} [multi] - Allow parallel edges? - * - * @throws {Error} - Will throw if the arguments are not valid. - */ -class Graph extends EventEmitter { - constructor(options) { - super(); - - //-- Solving options - options = assign({}, DEFAULTS, options); - - // Enforcing options validity - if (typeof options.multi !== 'boolean') - throw new InvalidArgumentsGraphError( - `Graph.constructor: invalid 'multi' option. Expecting a boolean but got "${options.multi}".` - ); - - if (!TYPES.has(options.type)) - throw new InvalidArgumentsGraphError( - `Graph.constructor: invalid 'type' option. Should be one of "mixed", "directed" or "undirected" but got "${options.type}".` - ); - - if (typeof options.allowSelfLoops !== 'boolean') - throw new InvalidArgumentsGraphError( - `Graph.constructor: invalid 'allowSelfLoops' option. Expecting a boolean but got "${options.allowSelfLoops}".` - ); - - //-- Private properties - - // Utilities - const NodeDataClass = - options.type === 'mixed' - ? MixedNodeData - : options.type === 'directed' - ? DirectedNodeData - : UndirectedNodeData; - - privateProperty(this, 'NodeDataClass', NodeDataClass); - - // Internal edge key generator - - // NOTE: this internal generator produce keys that are strings - // composed of a weird prefix, an incremental instance id starting from - // a random byte and finally an internal instance incremental id. - // All this to avoid intra-frame and cross-frame adversarial inputs - // that can force a single #.addEdge call to degenerate into a O(n) - // available key search loop. - - // It also ensures that automatically generated edge keys are unlikely - // to produce collisions with arbitrary keys given by users. - const instancePrefix = 'geid_' + INSTANCE_ID() + '_'; - let edgeId = 0; - - const edgeKeyGenerator = () => { - let availableEdgeKey; - - do { - availableEdgeKey = instancePrefix + edgeId++; - } while (this._edges.has(availableEdgeKey)); - - return availableEdgeKey; - }; - - // Indexes - privateProperty(this, '_attributes', {}); - privateProperty(this, '_nodes', new Map()); - privateProperty(this, '_edges', new Map()); - privateProperty(this, '_directedSize', 0); - privateProperty(this, '_undirectedSize', 0); - privateProperty(this, '_directedSelfLoopCount', 0); - privateProperty(this, '_undirectedSelfLoopCount', 0); - privateProperty(this, '_edgeKeyGenerator', edgeKeyGenerator); - - // Options - privateProperty(this, '_options', options); - - // Emitter properties - EMITTER_PROPS.forEach(prop => privateProperty(this, prop, this[prop])); - - //-- Properties readers - readOnlyProperty(this, 'order', () => this._nodes.size); - readOnlyProperty(this, 'size', () => this._edges.size); - readOnlyProperty(this, 'directedSize', () => this._directedSize); - readOnlyProperty(this, 'undirectedSize', () => this._undirectedSize); - readOnlyProperty( - this, - 'selfLoopCount', - () => this._directedSelfLoopCount + this._undirectedSelfLoopCount - ); - readOnlyProperty( - this, - 'directedSelfLoopCount', - () => this._directedSelfLoopCount - ); - readOnlyProperty( - this, - 'undirectedSelfLoopCount', - () => this._undirectedSelfLoopCount - ); - readOnlyProperty(this, 'multi', this._options.multi); - readOnlyProperty(this, 'type', this._options.type); - readOnlyProperty(this, 'allowSelfLoops', this._options.allowSelfLoops); - readOnlyProperty(this, 'implementation', () => 'graphology'); - } - - _resetInstanceCounters() { - this._directedSize = 0; - this._undirectedSize = 0; - this._directedSelfLoopCount = 0; - this._undirectedSelfLoopCount = 0; - } - - /**--------------------------------------------------------------------------- - * Read - **--------------------------------------------------------------------------- - */ - - /** - * Method returning whether the given node is found in the graph. - * - * @param {any} node - The node. - * @return {boolean} - */ - hasNode(node) { - return this._nodes.has('' + node); - } - - /** - * Method returning whether the given directed edge is found in the graph. - * - * Arity 1: - * @param {any} edge - The edge's key. - * - * Arity 2: - * @param {any} source - The edge's source. - * @param {any} target - The edge's target. - * - * @return {boolean} - * - * @throws {Error} - Will throw if the arguments are invalid. - */ - hasDirectedEdge(source, target) { - // Early termination - if (this.type === 'undirected') return false; - - if (arguments.length === 1) { - const edge = '' + source; - - const edgeData = this._edges.get(edge); - - return !!edgeData && !edgeData.undirected; - } else if (arguments.length === 2) { - source = '' + source; - target = '' + target; - - // If the node source or the target is not in the graph we break - const nodeData = this._nodes.get(source); - - if (!nodeData) return false; - - // Is there a directed edge pointing toward target? - const edges = nodeData.out[target]; - - if (!edges) return false; - - return this.multi ? !!edges.size : true; - } - - throw new InvalidArgumentsGraphError( - `Graph.hasDirectedEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.` - ); - } - - /** - * Method returning whether the given undirected edge is found in the graph. - * - * Arity 1: - * @param {any} edge - The edge's key. - * - * Arity 2: - * @param {any} source - The edge's source. - * @param {any} target - The edge's target. - * - * @return {boolean} - * - * @throws {Error} - Will throw if the arguments are invalid. - */ - hasUndirectedEdge(source, target) { - // Early termination - if (this.type === 'directed') return false; - - if (arguments.length === 1) { - const edge = '' + source; - - const edgeData = this._edges.get(edge); - - return !!edgeData && edgeData.undirected; - } else if (arguments.length === 2) { - source = '' + source; - target = '' + target; - - // If the node source or the target is not in the graph we break - const nodeData = this._nodes.get(source); - - if (!nodeData) return false; - - // Is there a directed edge pointing toward target? - const edges = nodeData.undirected[target]; - - if (!edges) return false; - - return this.multi ? !!edges.size : true; - } - - throw new InvalidArgumentsGraphError( - `Graph.hasDirectedEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.` - ); - } - - /** - * Method returning whether the given edge is found in the graph. - * - * Arity 1: - * @param {any} edge - The edge's key. - * - * Arity 2: - * @param {any} source - The edge's source. - * @param {any} target - The edge's target. - * - * @return {boolean} - * - * @throws {Error} - Will throw if the arguments are invalid. - */ - hasEdge(source, target) { - if (arguments.length === 1) { - const edge = '' + source; - - return this._edges.has(edge); - } else if (arguments.length === 2) { - source = '' + source; - target = '' + target; - - // If the node source or the target is not in the graph we break - const nodeData = this._nodes.get(source); - - if (!nodeData) return false; - - // Is there a directed edge pointing toward target? - let edges = typeof nodeData.out !== 'undefined' && nodeData.out[target]; - - if (!edges) - edges = - typeof nodeData.undirected !== 'undefined' && - nodeData.undirected[target]; - - if (!edges) return false; - - return this.multi ? !!edges.size : true; - } - - throw new InvalidArgumentsGraphError( - `Graph.hasEdge: invalid arity (${arguments.length}, instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.` - ); - } - - /** - * Method returning the edge matching source & target in a directed fashion. - * - * @param {any} source - The edge's source. - * @param {any} target - The edge's target. - * - * @return {any|undefined} - * - * @throws {Error} - Will throw if the graph is multi. - * @throws {Error} - Will throw if source or target doesn't exist. - */ - directedEdge(source, target) { - if (this.type === 'undirected') return; - - source = '' + source; - target = '' + target; - - if (this.multi) - throw new UsageGraphError( - 'Graph.directedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.directedEdges instead.' - ); - - const sourceData = this._nodes.get(source); - - if (!sourceData) - throw new NotFoundGraphError( - `Graph.directedEdge: could not find the "${source}" source node in the graph.` - ); - - if (!this._nodes.has(target)) - throw new NotFoundGraphError( - `Graph.directedEdge: could not find the "${target}" target node in the graph.` - ); - - const edgeData = (sourceData.out && sourceData.out[target]) || undefined; - - if (edgeData) return edgeData.key; - } - - /** - * Method returning the edge matching source & target in a undirected fashion. - * - * @param {any} source - The edge's source. - * @param {any} target - The edge's target. - * - * @return {any|undefined} - * - * @throws {Error} - Will throw if the graph is multi. - * @throws {Error} - Will throw if source or target doesn't exist. - */ - undirectedEdge(source, target) { - if (this.type === 'directed') return; - - source = '' + source; - target = '' + target; - - if (this.multi) - throw new UsageGraphError( - 'Graph.undirectedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.undirectedEdges instead.' - ); - - const sourceData = this._nodes.get(source); - - if (!sourceData) - throw new NotFoundGraphError( - `Graph.undirectedEdge: could not find the "${source}" source node in the graph.` - ); - - if (!this._nodes.has(target)) - throw new NotFoundGraphError( - `Graph.undirectedEdge: could not find the "${target}" target node in the graph.` - ); - - const edgeData = - (sourceData.undirected && sourceData.undirected[target]) || undefined; - - if (edgeData) return edgeData.key; - } - - /** - * Method returning the edge matching source & target in a mixed fashion. - * - * @param {any} source - The edge's source. - * @param {any} target - The edge's target. - * - * @return {any|undefined} - * - * @throws {Error} - Will throw if the graph is multi. - * @throws {Error} - Will throw if source or target doesn't exist. - */ - edge(source, target) { - if (this.multi) - throw new UsageGraphError( - 'Graph.edge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.edges instead.' - ); - - source = '' + source; - target = '' + target; - - const sourceData = this._nodes.get(source); - - if (!sourceData) - throw new NotFoundGraphError( - `Graph.edge: could not find the "${source}" source node in the graph.` - ); - - if (!this._nodes.has(target)) - throw new NotFoundGraphError( - `Graph.edge: could not find the "${target}" target node in the graph.` - ); - - const edgeData = - (sourceData.out && sourceData.out[target]) || - (sourceData.undirected && sourceData.undirected[target]) || - undefined; - - if (edgeData) return edgeData.key; - } - - /** - * Method returning whether two nodes are directed neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - areDirectedNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.areDirectedNeighbors: could not find the "${node}" node in the graph.` - ); - - if (this.type === 'undirected') return false; - - return neighbor in nodeData.in || neighbor in nodeData.out; - } - - /** - * Method returning whether two nodes are out neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - areOutNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.areOutNeighbors: could not find the "${node}" node in the graph.` - ); - - if (this.type === 'undirected') return false; - - return neighbor in nodeData.out; - } - - /** - * Method returning whether two nodes are in neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - areInNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.areInNeighbors: could not find the "${node}" node in the graph.` - ); - - if (this.type === 'undirected') return false; - - return neighbor in nodeData.in; - } - - /** - * Method returning whether two nodes are undirected neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - areUndirectedNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.areUndirectedNeighbors: could not find the "${node}" node in the graph.` - ); - - if (this.type === 'directed') return false; - - return neighbor in nodeData.undirected; - } - - /** - * Method returning whether two nodes are neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - areNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.areNeighbors: could not find the "${node}" node in the graph.` - ); - - if (this.type !== 'undirected') { - if (neighbor in nodeData.in || neighbor in nodeData.out) return true; - } - - if (this.type !== 'directed') { - if (neighbor in nodeData.undirected) return true; - } - - return false; - } - - /** - * Method returning whether two nodes are inbound neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - areInboundNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.areInboundNeighbors: could not find the "${node}" node in the graph.` - ); - - if (this.type !== 'undirected') { - if (neighbor in nodeData.in) return true; - } - - if (this.type !== 'directed') { - if (neighbor in nodeData.undirected) return true; - } - - return false; - } - - /** - * Method returning whether two nodes are outbound neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - areOutboundNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.areOutboundNeighbors: could not find the "${node}" node in the graph.` - ); - - if (this.type !== 'undirected') { - if (neighbor in nodeData.out) return true; - } - - if (this.type !== 'directed') { - if (neighbor in nodeData.undirected) return true; - } - - return false; - } - - /** - * Method returning the given node's in degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - inDegree(node) { - node = '' + node; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.inDegree: could not find the "${node}" node in the graph.` - ); - - if (this.type === 'undirected') return 0; - - return nodeData.inDegree; - } - - /** - * Method returning the given node's out degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - outDegree(node) { - node = '' + node; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.outDegree: could not find the "${node}" node in the graph.` - ); - - if (this.type === 'undirected') return 0; - - return nodeData.outDegree; - } - - /** - * Method returning the given node's directed degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - directedDegree(node) { - node = '' + node; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.directedDegree: could not find the "${node}" node in the graph.` - ); - - if (this.type === 'undirected') return 0; - - return nodeData.inDegree + nodeData.outDegree; - } - - /** - * Method returning the given node's undirected degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - undirectedDegree(node) { - node = '' + node; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.undirectedDegree: could not find the "${node}" node in the graph.` - ); - - if (this.type === 'directed') return 0; - - return nodeData.undirectedDegree; - } - - /** - * Method returning the given node's inbound degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's inbound degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - inboundDegree(node) { - node = '' + node; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.inboundDegree: could not find the "${node}" node in the graph.` - ); - - let degree = 0; - - if (this.type !== 'directed') { - degree += nodeData.undirectedDegree; - } - - if (this.type !== 'undirected') { - degree += nodeData.inDegree; - } - - return degree; - } - - /** - * Method returning the given node's outbound degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's outbound degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - outboundDegree(node) { - node = '' + node; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.outboundDegree: could not find the "${node}" node in the graph.` - ); - - let degree = 0; - - if (this.type !== 'directed') { - degree += nodeData.undirectedDegree; - } - - if (this.type !== 'undirected') { - degree += nodeData.outDegree; - } - - return degree; - } - - /** - * Method returning the given node's directed degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - degree(node) { - node = '' + node; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.degree: could not find the "${node}" node in the graph.` - ); - - let degree = 0; - - if (this.type !== 'directed') { - degree += nodeData.undirectedDegree; - } - - if (this.type !== 'undirected') { - degree += nodeData.inDegree + nodeData.outDegree; - } - - return degree; - } - - /** - * Method returning the given node's in degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - inDegreeWithoutSelfLoops(node) { - node = '' + node; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.inDegreeWithoutSelfLoops: could not find the "${node}" node in the graph.` - ); - - if (this.type === 'undirected') return 0; - - const self = nodeData.in[node]; - const loops = self ? (this.multi ? self.size : 1) : 0; - - return nodeData.inDegree - loops; - } - - /** - * Method returning the given node's out degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - outDegreeWithoutSelfLoops(node) { - node = '' + node; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.outDegreeWithoutSelfLoops: could not find the "${node}" node in the graph.` - ); - - if (this.type === 'undirected') return 0; - - const self = nodeData.out[node]; - const loops = self ? (this.multi ? self.size : 1) : 0; - - return nodeData.outDegree - loops; - } - - /** - * Method returning the given node's directed degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - directedDegreeWithoutSelfLoops(node) { - node = '' + node; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.directedDegreeWithoutSelfLoops: could not find the "${node}" node in the graph.` - ); - - if (this.type === 'undirected') return 0; - - const self = nodeData.out[node]; - const loops = self ? (this.multi ? self.size : 1) : 0; - - return nodeData.inDegree + nodeData.outDegree - loops * 2; - } - - /** - * Method returning the given node's undirected degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - undirectedDegreeWithoutSelfLoops(node) { - node = '' + node; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.undirectedDegreeWithoutSelfLoops: could not find the "${node}" node in the graph.` - ); - - if (this.type === 'directed') return 0; - - const self = nodeData.undirected[node]; - const loops = self ? (this.multi ? self.size : 1) : 0; - - return nodeData.undirectedDegree - loops * 2; - } - - /** - * Method returning the given node's inbound degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's inbound degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - inboundDegreeWithoutSelfLoops(node) { - node = '' + node; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.inboundDegreeWithoutSelfLoops: could not find the "${node}" node in the graph.` - ); - - let self; - let degree = 0; - let loops = 0; - - if (this.type !== 'directed') { - degree += nodeData.undirectedDegree; - - self = nodeData.undirected[node]; - loops += (self ? (this.multi ? self.size : 1) : 0) * 2; - } - - if (this.type !== 'undirected') { - degree += nodeData.inDegree; - - self = nodeData.out[node]; - loops += self ? (this.multi ? self.size : 1) : 0; - } - - return degree - loops; - } - - /** - * Method returning the given node's outbound degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's outbound degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - outboundDegreeWithoutSelfLoops(node) { - node = '' + node; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.outboundDegreeWithoutSelfLoops: could not find the "${node}" node in the graph.` - ); - - let self; - let degree = 0; - let loops = 0; - - if (this.type !== 'directed') { - degree += nodeData.undirectedDegree; - - self = nodeData.undirected[node]; - loops += (self ? (this.multi ? self.size : 1) : 0) * 2; - } - - if (this.type !== 'undirected') { - degree += nodeData.outDegree; - - self = nodeData.in[node]; - loops += self ? (this.multi ? self.size : 1) : 0; - } - - return degree - loops; - } - - /** - * Method returning the given node's directed degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - degreeWithoutSelfLoops(node) { - node = '' + node; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.degreeWithoutSelfLoops: could not find the "${node}" node in the graph.` - ); - - let self; - let degree = 0; - let loops = 0; - - if (this.type !== 'directed') { - degree += nodeData.undirectedDegree; - - self = nodeData.undirected[node]; - loops += (self ? (this.multi ? self.size : 1) : 0) * 2; - } - - if (this.type !== 'undirected') { - degree += nodeData.inDegree + nodeData.outDegree; - - self = nodeData.out[node]; - loops += (self ? (this.multi ? self.size : 1) : 0) * 2; - } - - return degree - loops; - } - - /** - * Method returning the given edge's source. - * - * @param {any} edge - The edge's key. - * @return {any} - The edge's source. - * - * @throws {Error} - Will throw if the edge isn't in the graph. - */ - source(edge) { - edge = '' + edge; - - const data = this._edges.get(edge); - - if (!data) - throw new NotFoundGraphError( - `Graph.source: could not find the "${edge}" edge in the graph.` - ); - - return data.source.key; - } - - /** - * Method returning the given edge's target. - * - * @param {any} edge - The edge's key. - * @return {any} - The edge's target. - * - * @throws {Error} - Will throw if the edge isn't in the graph. - */ - target(edge) { - edge = '' + edge; - - const data = this._edges.get(edge); - - if (!data) - throw new NotFoundGraphError( - `Graph.target: could not find the "${edge}" edge in the graph.` - ); - - return data.target.key; - } - - /** - * Method returning the given edge's extremities. - * - * @param {any} edge - The edge's key. - * @return {array} - The edge's extremities. - * - * @throws {Error} - Will throw if the edge isn't in the graph. - */ - extremities(edge) { - edge = '' + edge; - - const edgeData = this._edges.get(edge); - - if (!edgeData) - throw new NotFoundGraphError( - `Graph.extremities: could not find the "${edge}" edge in the graph.` - ); - - return [edgeData.source.key, edgeData.target.key]; - } - - /** - * Given a node & an edge, returns the other extremity of the edge. - * - * @param {any} node - The node's key. - * @param {any} edge - The edge's key. - * @return {any} - The related node. - * - * @throws {Error} - Will throw if the edge isn't in the graph or if the - * edge & node are not related. - */ - opposite(node, edge) { - node = '' + node; - edge = '' + edge; - - const data = this._edges.get(edge); - - if (!data) - throw new NotFoundGraphError( - `Graph.opposite: could not find the "${edge}" edge in the graph.` - ); - - const source = data.source.key; - const target = data.target.key; - - if (node === source) return target; - if (node === target) return source; - - throw new NotFoundGraphError( - `Graph.opposite: the "${node}" node is not attached to the "${edge}" edge (${source}, ${target}).` - ); - } - - /** - * Returns whether the given edge has the given node as extremity. - * - * @param {any} edge - The edge's key. - * @param {any} node - The node's key. - * @return {boolean} - The related node. - * - * @throws {Error} - Will throw if either the node or the edge isn't in the graph. - */ - hasExtremity(edge, node) { - edge = '' + edge; - node = '' + node; - - const data = this._edges.get(edge); - - if (!data) - throw new NotFoundGraphError( - `Graph.hasExtremity: could not find the "${edge}" edge in the graph.` - ); - - return data.source.key === node || data.target.key === node; - } - - /** - * Method returning whether the given edge is undirected. - * - * @param {any} edge - The edge's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the edge isn't in the graph. - */ - isUndirected(edge) { - edge = '' + edge; - - const data = this._edges.get(edge); - - if (!data) - throw new NotFoundGraphError( - `Graph.isUndirected: could not find the "${edge}" edge in the graph.` - ); - - return data.undirected; - } - - /** - * Method returning whether the given edge is directed. - * - * @param {any} edge - The edge's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the edge isn't in the graph. - */ - isDirected(edge) { - edge = '' + edge; - - const data = this._edges.get(edge); - - if (!data) - throw new NotFoundGraphError( - `Graph.isDirected: could not find the "${edge}" edge in the graph.` - ); - - return !data.undirected; - } - - /** - * Method returning whether the given edge is a self loop. - * - * @param {any} edge - The edge's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the edge isn't in the graph. - */ - isSelfLoop(edge) { - edge = '' + edge; - - const data = this._edges.get(edge); - - if (!data) - throw new NotFoundGraphError( - `Graph.isSelfLoop: could not find the "${edge}" edge in the graph.` - ); - - return data.source === data.target; - } - - /**--------------------------------------------------------------------------- - * Mutation - **--------------------------------------------------------------------------- - */ - - /** - * Method used to add a node to the graph. - * - * @param {any} node - The node. - * @param {object} [attributes] - Optional attributes. - * @return {any} - The node. - * - * @throws {Error} - Will throw if the given node already exist. - * @throws {Error} - Will throw if the given attributes are not an object. - */ - addNode(node, attributes) { - const nodeData = addNode(this, node, attributes); - - return nodeData.key; - } - - /** - * Method used to merge a node into the graph. - * - * @param {any} node - The node. - * @param {object} [attributes] - Optional attributes. - * @return {any} - The node. - */ - mergeNode(node, attributes) { - if (attributes && !isPlainObject(attributes)) - throw new InvalidArgumentsGraphError( - `Graph.mergeNode: invalid attributes. Expecting an object but got "${attributes}"` - ); - - // String coercion - node = '' + node; - attributes = attributes || {}; - - // If the node already exists, we merge the attributes - let data = this._nodes.get(node); - - if (data) { - if (attributes) { - assign(data.attributes, attributes); - - this.emit('nodeAttributesUpdated', { - type: 'merge', - key: node, - attributes: data.attributes, - data: attributes - }); - } - return [node, false]; - } - - data = new this.NodeDataClass(node, attributes); - - // Adding the node to internal register - this._nodes.set(node, data); - - // Emitting - this.emit('nodeAdded', { - key: node, - attributes - }); - - return [node, true]; - } - - /** - * Method used to add a node if it does not exist in the graph or else to - * update its attributes using a function. - * - * @param {any} node - The node. - * @param {function} [updater] - Optional updater function. - * @return {any} - The node. - */ - updateNode(node, updater) { - if (updater && typeof updater !== 'function') - throw new InvalidArgumentsGraphError( - `Graph.updateNode: invalid updater function. Expecting a function but got "${updater}"` - ); - - // String coercion - node = '' + node; - - // If the node already exists, we update the attributes - let data = this._nodes.get(node); - - if (data) { - if (updater) { - const oldAttributes = data.attributes; - data.attributes = updater(oldAttributes); - - this.emit('nodeAttributesUpdated', { - type: 'replace', - key: node, - attributes: data.attributes - }); - } - return [node, false]; - } - - const attributes = updater ? updater({}) : {}; - - data = new this.NodeDataClass(node, attributes); - - // Adding the node to internal register - this._nodes.set(node, data); - - // Emitting - this.emit('nodeAdded', { - key: node, - attributes - }); - - return [node, true]; - } - - /** - * Method used to drop a single node & all its attached edges from the graph. - * - * @param {any} node - The node. - * @return {Graph} - * - * @throws {Error} - Will throw if the node doesn't exist. - */ - dropNode(node) { - node = '' + node; - - const nodeData = this._nodes.get(node); - - if (!nodeData) - throw new NotFoundGraphError( - `Graph.dropNode: could not find the "${node}" node in the graph.` - ); - - let edgeData; - - // Removing attached edges - // NOTE: we could be faster here, but this is such a pain to maintain - if (this.type !== 'undirected') { - for (const neighbor in nodeData.out) { - edgeData = nodeData.out[neighbor]; - - do { - dropEdgeFromData(this, edgeData); - edgeData = edgeData.next; - } while (edgeData); - } - - for (const neighbor in nodeData.in) { - edgeData = nodeData.in[neighbor]; - - do { - dropEdgeFromData(this, edgeData); - edgeData = edgeData.next; - } while (edgeData); - } - } - - if (this.type !== 'directed') { - for (const neighbor in nodeData.undirected) { - edgeData = nodeData.undirected[neighbor]; - - do { - dropEdgeFromData(this, edgeData); - edgeData = edgeData.next; - } while (edgeData); - } - } - - // Dropping the node from the register - this._nodes.delete(node); - - // Emitting - this.emit('nodeDropped', { - key: node, - attributes: nodeData.attributes - }); - } - - /** - * Method used to drop a single edge from the graph. - * - * Arity 1: - * @param {any} edge - The edge. - * - * Arity 2: - * @param {any} source - Source node. - * @param {any} target - Target node. - * - * @return {Graph} - * - * @throws {Error} - Will throw if the edge doesn't exist. - */ - dropEdge(edge) { - let edgeData; - - if (arguments.length > 1) { - const source = '' + arguments[0]; - const target = '' + arguments[1]; - - edgeData = getMatchingEdge(this, source, target, this.type); - - if (!edgeData) - throw new NotFoundGraphError( - `Graph.dropEdge: could not find the "${source}" -> "${target}" edge in the graph.` - ); - } else { - edge = '' + edge; - - edgeData = this._edges.get(edge); - - if (!edgeData) - throw new NotFoundGraphError( - `Graph.dropEdge: could not find the "${edge}" edge in the graph.` - ); - } - - dropEdgeFromData(this, edgeData); - - return this; - } - - /** - * Method used to drop a single directed edge from the graph. - * - * @param {any} source - Source node. - * @param {any} target - Target node. - * - * @return {Graph} - * - * @throws {Error} - Will throw if the edge doesn't exist. - */ - dropDirectedEdge(source, target) { - if (arguments.length < 2) - throw new UsageGraphError( - 'Graph.dropDirectedEdge: it does not make sense to try and drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.' - ); - - if (this.multi) - throw new UsageGraphError( - 'Graph.dropDirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.' - ); - - source = '' + source; - target = '' + target; - - const edgeData = getMatchingEdge(this, source, target, 'directed'); - - if (!edgeData) - throw new NotFoundGraphError( - `Graph.dropDirectedEdge: could not find a "${source}" -> "${target}" edge in the graph.` - ); - - dropEdgeFromData(this, edgeData); - - return this; - } - - /** - * Method used to drop a single undirected edge from the graph. - * - * @param {any} source - Source node. - * @param {any} target - Target node. - * - * @return {Graph} - * - * @throws {Error} - Will throw if the edge doesn't exist. - */ - dropUndirectedEdge(source, target) { - if (arguments.length < 2) - throw new UsageGraphError( - 'Graph.dropUndirectedEdge: it does not make sense to drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.' - ); - - if (this.multi) - throw new UsageGraphError( - 'Graph.dropUndirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.' - ); - - const edgeData = getMatchingEdge(this, source, target, 'undirected'); - - if (!edgeData) - throw new NotFoundGraphError( - `Graph.dropUndirectedEdge: could not find a "${source}" -> "${target}" edge in the graph.` - ); - - dropEdgeFromData(this, edgeData); - - return this; - } - - /** - * Method used to remove every edge & every node from the graph. - * - * @return {Graph} - */ - clear() { - // Clearing edges - this._edges.clear(); - - // Clearing nodes - this._nodes.clear(); - - // Reset counters - this._resetInstanceCounters(); - - // Emitting - this.emit('cleared'); - } - - /** - * Method used to remove every edge from the graph. - * - * @return {Graph} - */ - clearEdges() { - // Clearing structure index - const iterator = this._nodes.values(); - - let step; - - while (((step = iterator.next()), step.done !== true)) { - step.value.clear(); - } - - // Clearing edges - this._edges.clear(); - - // Reset counters - this._resetInstanceCounters(); - - // Emitting - this.emit('edgesCleared'); - } - - /**--------------------------------------------------------------------------- - * Attributes-related methods - **--------------------------------------------------------------------------- - */ - - /** - * Method returning the desired graph's attribute. - * - * @param {string} name - Name of the attribute. - * @return {any} - */ - getAttribute(name) { - return this._attributes[name]; - } - - /** - * Method returning the graph's attributes. - * - * @return {object} - */ - getAttributes() { - return this._attributes; - } - - /** - * Method returning whether the graph has the desired attribute. - * - * @param {string} name - Name of the attribute. - * @return {boolean} - */ - hasAttribute(name) { - return this._attributes.hasOwnProperty(name); - } - - /** - * Method setting a value for the desired graph's attribute. - * - * @param {string} name - Name of the attribute. - * @param {any} value - Value for the attribute. - * @return {Graph} - */ - setAttribute(name, value) { - this._attributes[name] = value; - - // Emitting - this.emit('attributesUpdated', { - type: 'set', - attributes: this._attributes, - name - }); - - return this; - } - - /** - * Method using a function to update the desired graph's attribute's value. - * - * @param {string} name - Name of the attribute. - * @param {function} updater - Function use to update the attribute's value. - * @return {Graph} - */ - updateAttribute(name, updater) { - if (typeof updater !== 'function') - throw new InvalidArgumentsGraphError( - 'Graph.updateAttribute: updater should be a function.' - ); - - const value = this._attributes[name]; - - this._attributes[name] = updater(value); - - // Emitting - this.emit('attributesUpdated', { - type: 'set', - attributes: this._attributes, - name - }); - - return this; - } - - /** - * Method removing the desired graph's attribute. - * - * @param {string} name - Name of the attribute. - * @return {Graph} - */ - removeAttribute(name) { - delete this._attributes[name]; - - // Emitting - this.emit('attributesUpdated', { - type: 'remove', - attributes: this._attributes, - name - }); - - return this; - } - - /** - * Method replacing the graph's attributes. - * - * @param {object} attributes - New attributes. - * @return {Graph} - * - * @throws {Error} - Will throw if given attributes are not a plain object. - */ - replaceAttributes(attributes) { - if (!isPlainObject(attributes)) - throw new InvalidArgumentsGraphError( - 'Graph.replaceAttributes: provided attributes are not a plain object.' - ); - - this._attributes = attributes; - - // Emitting - this.emit('attributesUpdated', { - type: 'replace', - attributes: this._attributes - }); - - return this; - } - - /** - * Method merging the graph's attributes. - * - * @param {object} attributes - Attributes to merge. - * @return {Graph} - * - * @throws {Error} - Will throw if given attributes are not a plain object. - */ - mergeAttributes(attributes) { - if (!isPlainObject(attributes)) - throw new InvalidArgumentsGraphError( - 'Graph.mergeAttributes: provided attributes are not a plain object.' - ); - - assign(this._attributes, attributes); - - // Emitting - this.emit('attributesUpdated', { - type: 'merge', - attributes: this._attributes, - data: attributes - }); - - return this; - } - - /** - * Method updating the graph's attributes. - * - * @param {function} updater - Function used to update the attributes. - * @return {Graph} - * - * @throws {Error} - Will throw if given updater is not a function. - */ - updateAttributes(updater) { - if (typeof updater !== 'function') - throw new InvalidArgumentsGraphError( - 'Graph.updateAttributes: provided updater is not a function.' - ); - - this._attributes = updater(this._attributes); - - // Emitting - this.emit('attributesUpdated', { - type: 'update', - attributes: this._attributes - }); - - return this; - } - - /** - * Method used to update each node's attributes using the given function. - * - * @param {function} updater - Updater function to use. - * @param {object} [hints] - Optional hints. - */ - updateEachNodeAttributes(updater, hints) { - if (typeof updater !== 'function') - throw new InvalidArgumentsGraphError( - 'Graph.updateEachNodeAttributes: expecting an updater function.' - ); - - if (hints && !validateHints(hints)) - throw new InvalidArgumentsGraphError( - 'Graph.updateEachNodeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}' - ); - - const iterator = this._nodes.values(); - - let step, nodeData; - - while (((step = iterator.next()), step.done !== true)) { - nodeData = step.value; - nodeData.attributes = updater(nodeData.key, nodeData.attributes); - } - - this.emit('eachNodeAttributesUpdated', { - hints: hints ? hints : null - }); - } - - /** - * Method used to update each edge's attributes using the given function. - * - * @param {function} updater - Updater function to use. - * @param {object} [hints] - Optional hints. - */ - updateEachEdgeAttributes(updater, hints) { - if (typeof updater !== 'function') - throw new InvalidArgumentsGraphError( - 'Graph.updateEachEdgeAttributes: expecting an updater function.' - ); - - if (hints && !validateHints(hints)) - throw new InvalidArgumentsGraphError( - 'Graph.updateEachEdgeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}' - ); - - const iterator = this._edges.values(); - - let step, edgeData, sourceData, targetData; - - while (((step = iterator.next()), step.done !== true)) { - edgeData = step.value; - sourceData = edgeData.source; - targetData = edgeData.target; - - edgeData.attributes = updater( - edgeData.key, - edgeData.attributes, - sourceData.key, - targetData.key, - sourceData.attributes, - targetData.attributes, - edgeData.undirected - ); - } - - this.emit('eachEdgeAttributesUpdated', { - hints: hints ? hints : null - }); - } - - /**--------------------------------------------------------------------------- - * Iteration-related methods - **--------------------------------------------------------------------------- - */ - - /** - * Method iterating over the graph's adjacency using the given callback. - * - * @param {function} callback - Callback to use. - */ - forEachAdjacencyEntry(callback) { - if (typeof callback !== 'function') - throw new InvalidArgumentsGraphError( - 'Graph.forEachAdjacencyEntry: expecting a callback.' - ); - - forEachAdjacency(false, false, false, this, callback); - } - forEachAdjacencyEntryWithOrphans(callback) { - if (typeof callback !== 'function') - throw new InvalidArgumentsGraphError( - 'Graph.forEachAdjacencyEntryWithOrphans: expecting a callback.' - ); - - forEachAdjacency(false, false, true, this, callback); - } - - /** - * Method iterating over the graph's assymetric adjacency using the given callback. - * - * @param {function} callback - Callback to use. - */ - forEachAssymetricAdjacencyEntry(callback) { - if (typeof callback !== 'function') - throw new InvalidArgumentsGraphError( - 'Graph.forEachAssymetricAdjacencyEntry: expecting a callback.' - ); - - forEachAdjacency(false, true, false, this, callback); - } - forEachAssymetricAdjacencyEntryWithOrphans(callback) { - if (typeof callback !== 'function') - throw new InvalidArgumentsGraphError( - 'Graph.forEachAssymetricAdjacencyEntryWithOrphans: expecting a callback.' - ); - - forEachAdjacency(false, true, true, this, callback); - } - - /** - * Method returning the list of the graph's nodes. - * - * @return {array} - The nodes. - */ - nodes() { - if (typeof Array.from === 'function') return Array.from(this._nodes.keys()); - - return take(this._nodes.keys(), this._nodes.size); - } - - /** - * Method iterating over the graph's nodes using the given callback. - * - * @param {function} callback - Callback (key, attributes, index). - */ - forEachNode(callback) { - if (typeof callback !== 'function') - throw new InvalidArgumentsGraphError( - 'Graph.forEachNode: expecting a callback.' - ); - - const iterator = this._nodes.values(); - - let step, nodeData; - - while (((step = iterator.next()), step.done !== true)) { - nodeData = step.value; - callback(nodeData.key, nodeData.attributes); - } - } - - /** - * Method iterating attempting to find a node matching the given predicate - * function. - * - * @param {function} callback - Callback (key, attributes). - */ - findNode(callback) { - if (typeof callback !== 'function') - throw new InvalidArgumentsGraphError( - 'Graph.findNode: expecting a callback.' - ); - - const iterator = this._nodes.values(); - - let step, nodeData; - - while (((step = iterator.next()), step.done !== true)) { - nodeData = step.value; - - if (callback(nodeData.key, nodeData.attributes)) return nodeData.key; - } - - return; - } - - /** - * Method mapping nodes. - * - * @param {function} callback - Callback (key, attributes). - */ - mapNodes(callback) { - if (typeof callback !== 'function') - throw new InvalidArgumentsGraphError( - 'Graph.mapNode: expecting a callback.' - ); - - const iterator = this._nodes.values(); - - let step, nodeData; - - const result = new Array(this.order); - let i = 0; - - while (((step = iterator.next()), step.done !== true)) { - nodeData = step.value; - result[i++] = callback(nodeData.key, nodeData.attributes); - } - - return result; - } - - /** - * Method returning whether some node verify the given predicate. - * - * @param {function} callback - Callback (key, attributes). - */ - someNode(callback) { - if (typeof callback !== 'function') - throw new InvalidArgumentsGraphError( - 'Graph.someNode: expecting a callback.' - ); - - const iterator = this._nodes.values(); - - let step, nodeData; - - while (((step = iterator.next()), step.done !== true)) { - nodeData = step.value; - - if (callback(nodeData.key, nodeData.attributes)) return true; - } - - return false; - } - - /** - * Method returning whether all node verify the given predicate. - * - * @param {function} callback - Callback (key, attributes). - */ - everyNode(callback) { - if (typeof callback !== 'function') - throw new InvalidArgumentsGraphError( - 'Graph.everyNode: expecting a callback.' - ); - - const iterator = this._nodes.values(); - - let step, nodeData; - - while (((step = iterator.next()), step.done !== true)) { - nodeData = step.value; - - if (!callback(nodeData.key, nodeData.attributes)) return false; - } - - return true; - } - - /** - * Method filtering nodes. - * - * @param {function} callback - Callback (key, attributes). - */ - filterNodes(callback) { - if (typeof callback !== 'function') - throw new InvalidArgumentsGraphError( - 'Graph.filterNodes: expecting a callback.' - ); - - const iterator = this._nodes.values(); - - let step, nodeData; - - const result = []; - - while (((step = iterator.next()), step.done !== true)) { - nodeData = step.value; - - if (callback(nodeData.key, nodeData.attributes)) - result.push(nodeData.key); - } - - return result; - } - - /** - * Method reducing nodes. - * - * @param {function} callback - Callback (accumulator, key, attributes). - */ - reduceNodes(callback, initialValue) { - if (typeof callback !== 'function') - throw new InvalidArgumentsGraphError( - 'Graph.reduceNodes: expecting a callback.' - ); - - if (arguments.length < 2) - throw new InvalidArgumentsGraphError( - 'Graph.reduceNodes: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.' - ); - - let accumulator = initialValue; - - const iterator = this._nodes.values(); - - let step, nodeData; - - while (((step = iterator.next()), step.done !== true)) { - nodeData = step.value; - accumulator = callback(accumulator, nodeData.key, nodeData.attributes); - } - - return accumulator; - } - - /** - * Method returning an iterator over the graph's node entries. - * - * @return {Iterator} - */ - nodeEntries() { - const iterator = this._nodes.values(); - - return new Iterator(() => { - const step = iterator.next(); - - if (step.done) return step; - - const data = step.value; - - return { - value: {node: data.key, attributes: data.attributes}, - done: false - }; - }); - } - - /**--------------------------------------------------------------------------- - * Serialization - **--------------------------------------------------------------------------- - */ - - /** - * Method used to export the whole graph. - * - * @return {object} - The serialized graph. - */ - export() { - const nodes = new Array(this._nodes.size); - - let i = 0; - - this._nodes.forEach((data, key) => { - nodes[i++] = serializeNode(key, data); - }); - - const edges = new Array(this._edges.size); - - i = 0; - - this._edges.forEach((data, key) => { - edges[i++] = serializeEdge(key, data); - }); - - return { - options: { - type: this.type, - multi: this.multi, - allowSelfLoops: this.allowSelfLoops - }, - attributes: this.getAttributes(), - nodes, - edges - }; - } - - /** - * Method used to import a serialized graph. - * - * @param {object|Graph} data - The serialized graph. - * @param {boolean} merge - Whether to merge data. - * @return {Graph} - Returns itself for chaining. - */ - import(data, merge = false) { - // Importing a Graph instance directly - if (isGraph(data)) { - // Nodes - data.forEachNode((n, a) => { - if (merge) this.mergeNode(n, a); - else this.addNode(n, a); - }); - - // Edges - data.forEachEdge((e, a, s, t, _sa, _ta, u) => { - if (merge) { - if (u) this.mergeUndirectedEdgeWithKey(e, s, t, a); - else this.mergeDirectedEdgeWithKey(e, s, t, a); - } else { - if (u) this.addUndirectedEdgeWithKey(e, s, t, a); - else this.addDirectedEdgeWithKey(e, s, t, a); - } - }); - - return this; - } - - // Importing a serialized graph - if (!isPlainObject(data)) - throw new InvalidArgumentsGraphError( - 'Graph.import: invalid argument. Expecting a serialized graph or, alternatively, a Graph instance.' - ); - - if (data.attributes) { - if (!isPlainObject(data.attributes)) - throw new InvalidArgumentsGraphError( - 'Graph.import: invalid attributes. Expecting a plain object.' - ); - - if (merge) this.mergeAttributes(data.attributes); - else this.replaceAttributes(data.attributes); - } - - let i, l, list, node, edge; - - if (data.nodes) { - list = data.nodes; - - if (!Array.isArray(list)) - throw new InvalidArgumentsGraphError( - 'Graph.import: invalid nodes. Expecting an array.' - ); - - for (i = 0, l = list.length; i < l; i++) { - node = list[i]; - - // Validating - validateSerializedNode(node); - - // Adding the node - const {key, attributes} = node; - - if (merge) this.mergeNode(key, attributes); - else this.addNode(key, attributes); - } - } - - if (data.edges) { - list = data.edges; - - if (!Array.isArray(list)) - throw new InvalidArgumentsGraphError( - 'Graph.import: invalid edges. Expecting an array.' - ); - - for (i = 0, l = list.length; i < l; i++) { - edge = list[i]; - - // Validating - validateSerializedEdge(edge); - - // Adding the edge - const {source, target, attributes, undirected = false} = edge; - - let method; - - if ('key' in edge) { - method = merge - ? undirected - ? this.mergeUndirectedEdgeWithKey - : this.mergeDirectedEdgeWithKey - : undirected - ? this.addUndirectedEdgeWithKey - : this.addDirectedEdgeWithKey; - - method.call(this, edge.key, source, target, attributes); - } else { - method = merge - ? undirected - ? this.mergeUndirectedEdge - : this.mergeDirectedEdge - : undirected - ? this.addUndirectedEdge - : this.addDirectedEdge; - - method.call(this, source, target, attributes); - } - } - } - - return this; - } - - /**--------------------------------------------------------------------------- - * Utils - **--------------------------------------------------------------------------- - */ - - /** - * Method returning a null copy of the graph, i.e. a graph without nodes - * & edges but with the exact same options. - * - * @param {object} options - Options to merge with the current ones. - * @return {Graph} - The null copy. - */ - nullCopy(options) { - const graph = new Graph(assign({}, this._options, options)); - graph.replaceAttributes(assign({}, this.getAttributes())); - return graph; - } - - /** - * Method returning an empty copy of the graph, i.e. a graph without edges but - * with the exact same options. - * - * @param {object} options - Options to merge with the current ones. - * @return {Graph} - The empty copy. - */ - emptyCopy(options) { - const graph = this.nullCopy(options); - - this._nodes.forEach((nodeData, key) => { - const attributes = assign({}, nodeData.attributes); - - // NOTE: no need to emit events since user cannot access the instance yet - nodeData = new graph.NodeDataClass(key, attributes); - graph._nodes.set(key, nodeData); - }); - - return graph; - } - - /** - * Method returning an exact copy of the graph. - * - * @param {object} options - Upgrade options. - * @return {Graph} - The copy. - */ - copy(options) { - options = options || {}; - - if ( - typeof options.type === 'string' && - options.type !== this.type && - options.type !== 'mixed' - ) - throw new UsageGraphError( - `Graph.copy: cannot create an incompatible copy from "${this.type}" type to "${options.type}" because this would mean losing information about the current graph.` - ); - - if ( - typeof options.multi === 'boolean' && - options.multi !== this.multi && - options.multi !== true - ) - throw new UsageGraphError( - 'Graph.copy: cannot create an incompatible copy by downgrading a multi graph to a simple one because this would mean losing information about the current graph.' - ); - - if ( - typeof options.allowSelfLoops === 'boolean' && - options.allowSelfLoops !== this.allowSelfLoops && - options.allowSelfLoops !== true - ) - throw new UsageGraphError( - 'Graph.copy: cannot create an incompatible copy from a graph allowing self loops to one that does not because this would mean losing information about the current graph.' - ); - - const graph = this.emptyCopy(options); - - const iterator = this._edges.values(); - - let step, edgeData; - - while (((step = iterator.next()), step.done !== true)) { - edgeData = step.value; - - // NOTE: no need to emit events since user cannot access the instance yet - addEdge( - graph, - 'copy', - false, - edgeData.undirected, - edgeData.key, - edgeData.source.key, - edgeData.target.key, - assign({}, edgeData.attributes) - ); - } - - return graph; - } - - /**--------------------------------------------------------------------------- - * Known methods - **--------------------------------------------------------------------------- - */ - - /** - * Method used by JavaScript to perform JSON serialization. - * - * @return {object} - The serialized graph. - */ - toJSON() { - return this.export(); - } - - /** - * Method returning [object Graph]. - */ - toString() { - return '[object Graph]'; - } - - /** - * Method used internally by node's console to display a custom object. - * - * @return {object} - Formatted object representation of the graph. - */ - inspect() { - const nodes = {}; - this._nodes.forEach((data, key) => { - nodes[key] = data.attributes; - }); - - const edges = {}, - multiIndex = {}; - - this._edges.forEach((data, key) => { - const direction = data.undirected ? '--' : '->'; - - let label = ''; - - let source = data.source.key; - let target = data.target.key; - let tmp; - - if (data.undirected && source > target) { - tmp = source; - source = target; - target = tmp; - } - - const desc = `(${source})${direction}(${target})`; - - if (!key.startsWith('geid_')) { - label += `[${key}]: `; - } else if (this.multi) { - if (typeof multiIndex[desc] === 'undefined') { - multiIndex[desc] = 0; - } else { - multiIndex[desc]++; - } - - label += `${multiIndex[desc]}. `; - } - - label += desc; - - edges[label] = data.attributes; - }); - - const dummy = {}; - - for (const k in this) { - if ( - this.hasOwnProperty(k) && - !EMITTER_PROPS.has(k) && - typeof this[k] !== 'function' && - typeof k !== 'symbol' - ) - dummy[k] = this[k]; - } - - dummy.attributes = this._attributes; - dummy.nodes = nodes; - dummy.edges = edges; - - privateProperty(dummy, 'constructor', this.constructor); - - return dummy; - } -} - -/** - * Attaching methods to the prototype. - * - * Here, we are attaching a wide variety of methods to the Graph class' - * prototype when those are very numerous and when their creation is - * abstracted. - */ - -/** - * Attaching custom inspect method for node >= 10. - */ -if (typeof Symbol !== 'undefined') - Graph.prototype[Symbol.for('nodejs.util.inspect.custom')] = - Graph.prototype.inspect; - -/** - * Related to edge addition. - */ -EDGE_ADD_METHODS.forEach(method => { - ['add', 'merge', 'update'].forEach(verb => { - const name = method.name(verb); - const fn = verb === 'add' ? addEdge : mergeEdge; - - if (method.generateKey) { - Graph.prototype[name] = function (source, target, attributes) { - return fn( - this, - name, - true, - (method.type || this.type) === 'undirected', - null, - source, - target, - attributes, - verb === 'update' - ); - }; - } else { - Graph.prototype[name] = function (edge, source, target, attributes) { - return fn( - this, - name, - false, - (method.type || this.type) === 'undirected', - edge, - source, - target, - attributes, - verb === 'update' - ); - }; - } - }); -}); - -/** - * Attributes-related. - */ -attachNodeAttributesMethods(Graph); -attachEdgeAttributesMethods(Graph); - -/** - * Edge iteration-related. - */ -attachEdgeIterationMethods(Graph); - -/** - * Neighbor iteration-related. - */ -attachNeighborIterationMethods(Graph); - -/** - * Graphology Helper Classes - * ========================== - * - * Building some higher-order classes instantiating the graph with - * predefinite options. - */ - -/** - * Alternative constructors. - */ -class DirectedGraph extends Graph { - constructor(options) { - const finalOptions = assign({type: 'directed'}, options); - - if ('multi' in finalOptions && finalOptions.multi !== false) - throw new InvalidArgumentsGraphError( - 'DirectedGraph.from: inconsistent indication that the graph should be multi in given options!' - ); - - if (finalOptions.type !== 'directed') - throw new InvalidArgumentsGraphError( - 'DirectedGraph.from: inconsistent "' + - finalOptions.type + - '" type in given options!' - ); - - super(finalOptions); - } -} -class UndirectedGraph extends Graph { - constructor(options) { - const finalOptions = assign({type: 'undirected'}, options); - - if ('multi' in finalOptions && finalOptions.multi !== false) - throw new InvalidArgumentsGraphError( - 'UndirectedGraph.from: inconsistent indication that the graph should be multi in given options!' - ); - - if (finalOptions.type !== 'undirected') - throw new InvalidArgumentsGraphError( - 'UndirectedGraph.from: inconsistent "' + - finalOptions.type + - '" type in given options!' - ); - - super(finalOptions); - } -} -class MultiGraph extends Graph { - constructor(options) { - const finalOptions = assign({multi: true}, options); - - if ('multi' in finalOptions && finalOptions.multi !== true) - throw new InvalidArgumentsGraphError( - 'MultiGraph.from: inconsistent indication that the graph should be simple in given options!' - ); - - super(finalOptions); - } -} -class MultiDirectedGraph extends Graph { - constructor(options) { - const finalOptions = assign({type: 'directed', multi: true}, options); - - if ('multi' in finalOptions && finalOptions.multi !== true) - throw new InvalidArgumentsGraphError( - 'MultiDirectedGraph.from: inconsistent indication that the graph should be simple in given options!' - ); - - if (finalOptions.type !== 'directed') - throw new InvalidArgumentsGraphError( - 'MultiDirectedGraph.from: inconsistent "' + - finalOptions.type + - '" type in given options!' - ); - - super(finalOptions); - } -} -class MultiUndirectedGraph extends Graph { - constructor(options) { - const finalOptions = assign({type: 'undirected', multi: true}, options); - - if ('multi' in finalOptions && finalOptions.multi !== true) - throw new InvalidArgumentsGraphError( - 'MultiUndirectedGraph.from: inconsistent indication that the graph should be simple in given options!' - ); - - if (finalOptions.type !== 'undirected') - throw new InvalidArgumentsGraphError( - 'MultiUndirectedGraph.from: inconsistent "' + - finalOptions.type + - '" type in given options!' - ); - - super(finalOptions); - } -} - -/** - * Attaching static #.from method to each of the constructors. - */ -function attachStaticFromMethod(Class) { - /** - * Builds a graph from serialized data or another graph's data. - * - * @param {Graph|SerializedGraph} data - Hydratation data. - * @param {object} [options] - Options. - * @return {Class} - */ - Class.from = function (data, options) { - // Merging given options with serialized ones - const finalOptions = assign({}, data.options, options); - - const instance = new Class(finalOptions); - instance.import(data); - - return instance; - }; -} - -attachStaticFromMethod(Graph); -attachStaticFromMethod(DirectedGraph); -attachStaticFromMethod(UndirectedGraph); -attachStaticFromMethod(MultiGraph); -attachStaticFromMethod(MultiDirectedGraph); -attachStaticFromMethod(MultiUndirectedGraph); - -Graph.Graph = Graph; -Graph.DirectedGraph = DirectedGraph; -Graph.UndirectedGraph = UndirectedGraph; -Graph.MultiGraph = MultiGraph; -Graph.MultiDirectedGraph = MultiDirectedGraph; -Graph.MultiUndirectedGraph = MultiUndirectedGraph; - -Graph.InvalidArgumentsGraphError = InvalidArgumentsGraphError; -Graph.NotFoundGraphError = NotFoundGraphError; -Graph.UsageGraphError = UsageGraphError; - -/** - * Graphology ESM Endoint - * ======================= - * - * Endpoint for ESM modules consumers. - */ - -export { DirectedGraph, Graph, InvalidArgumentsGraphError, MultiDirectedGraph, MultiGraph, MultiUndirectedGraph, NotFoundGraphError, UndirectedGraph, UsageGraphError, Graph as default }; -//# sourceMappingURL=graphology.esm.js.map diff --git a/libs/shared/graph-layouts/node_modules/graphology/dist/graphology.umd.js b/libs/shared/graph-layouts/node_modules/graphology/dist/graphology.umd.js deleted file mode 100644 index d3d07b30a..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/dist/graphology.umd.js +++ /dev/null @@ -1,6125 +0,0 @@ -(function (global, factory) { - typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : - typeof define === 'function' && define.amd ? define(factory) : - (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.graphology = factory()); -})(this, (function () { 'use strict'; - - function _typeof(obj) { - "@babel/helpers - typeof"; - - return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { - return typeof obj; - } : function (obj) { - return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; - }, _typeof(obj); - } - - function _inheritsLoose(subClass, superClass) { - subClass.prototype = Object.create(superClass.prototype); - subClass.prototype.constructor = subClass; - - _setPrototypeOf(subClass, superClass); - } - - function _getPrototypeOf(o) { - _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { - return o.__proto__ || Object.getPrototypeOf(o); - }; - return _getPrototypeOf(o); - } - - function _setPrototypeOf(o, p) { - _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { - o.__proto__ = p; - return o; - }; - - return _setPrototypeOf(o, p); - } - - function _isNativeReflectConstruct() { - if (typeof Reflect === "undefined" || !Reflect.construct) return false; - if (Reflect.construct.sham) return false; - if (typeof Proxy === "function") return true; - - try { - Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); - return true; - } catch (e) { - return false; - } - } - - function _construct(Parent, args, Class) { - if (_isNativeReflectConstruct()) { - _construct = Reflect.construct; - } else { - _construct = function _construct(Parent, args, Class) { - var a = [null]; - a.push.apply(a, args); - var Constructor = Function.bind.apply(Parent, a); - var instance = new Constructor(); - if (Class) _setPrototypeOf(instance, Class.prototype); - return instance; - }; - } - - return _construct.apply(null, arguments); - } - - function _isNativeFunction(fn) { - return Function.toString.call(fn).indexOf("[native code]") !== -1; - } - - function _wrapNativeSuper(Class) { - var _cache = typeof Map === "function" ? new Map() : undefined; - - _wrapNativeSuper = function _wrapNativeSuper(Class) { - if (Class === null || !_isNativeFunction(Class)) return Class; - - if (typeof Class !== "function") { - throw new TypeError("Super expression must either be null or a function"); - } - - if (typeof _cache !== "undefined") { - if (_cache.has(Class)) return _cache.get(Class); - - _cache.set(Class, Wrapper); - } - - function Wrapper() { - return _construct(Class, arguments, _getPrototypeOf(this).constructor); - } - - Wrapper.prototype = Object.create(Class.prototype, { - constructor: { - value: Wrapper, - enumerable: false, - writable: true, - configurable: true - } - }); - return _setPrototypeOf(Wrapper, Class); - }; - - return _wrapNativeSuper(Class); - } - - function _assertThisInitialized(self) { - if (self === void 0) { - throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); - } - - return self; - } - - /** - * Graphology Utilities - * ===================== - * - * Collection of helpful functions used by the implementation. - */ - - /** - * Object.assign-like polyfill. - * - * @param {object} target - First object. - * @param {object} [...objects] - Objects to merge. - * @return {object} - */ - function assignPolyfill() { - var target = arguments[0]; - - for (var i = 1, l = arguments.length; i < l; i++) { - if (!arguments[i]) continue; - - for (var k in arguments[i]) { - target[k] = arguments[i][k]; - } - } - - return target; - } - - var assign = assignPolyfill; - if (typeof Object.assign === 'function') assign = Object.assign; - /** - * Function returning the first matching edge for given path. - * Note: this function does not check the existence of source & target. This - * must be performed by the caller. - * - * @param {Graph} graph - Target graph. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {string} type - Type of the edge (mixed, directed or undirected). - * @return {string|null} - */ - - function getMatchingEdge(graph, source, target, type) { - var sourceData = graph._nodes.get(source); - - var edge = null; - if (!sourceData) return edge; - - if (type === 'mixed') { - edge = sourceData.out && sourceData.out[target] || sourceData.undirected && sourceData.undirected[target]; - } else if (type === 'directed') { - edge = sourceData.out && sourceData.out[target]; - } else { - edge = sourceData.undirected && sourceData.undirected[target]; - } - - return edge; - } - /** - * Checks whether the given value is a Graph implementation instance. - * - * @param {mixed} value - Target value. - * @return {boolean} - */ - - function isGraph(value) { - return value !== null && _typeof(value) === 'object' && typeof value.addUndirectedEdgeWithKey === 'function' && typeof value.dropNode === 'function'; - } - /** - * Checks whether the given value is a plain object. - * - * @param {mixed} value - Target value. - * @return {boolean} - */ - - function isPlainObject(value) { - return _typeof(value) === 'object' && value !== null && value.constructor === Object; - } - /** - * Checks whether the given object is empty. - * - * @param {object} o - Target Object. - * @return {boolean} - */ - - function isEmpty(o) { - var k; - - for (k in o) { - return false; - } - - return true; - } - /** - * Creates a "private" property for the given member name by concealing it - * using the `enumerable` option. - * - * @param {object} target - Target object. - * @param {string} name - Member name. - */ - - function privateProperty(target, name, value) { - Object.defineProperty(target, name, { - enumerable: false, - configurable: false, - writable: true, - value: value - }); - } - /** - * Creates a read-only property for the given member name & the given getter. - * - * @param {object} target - Target object. - * @param {string} name - Member name. - * @param {mixed} value - The attached getter or fixed value. - */ - - function readOnlyProperty(target, name, value) { - var descriptor = { - enumerable: true, - configurable: true - }; - - if (typeof value === 'function') { - descriptor.get = value; - } else { - descriptor.value = value; - descriptor.writable = false; - } - - Object.defineProperty(target, name, descriptor); - } - /** - * Returns whether the given object constitute valid hints. - * - * @param {object} hints - Target object. - */ - - function validateHints(hints) { - if (!isPlainObject(hints)) return false; - if (hints.attributes && !Array.isArray(hints.attributes)) return false; - return true; - } - /** - * Creates a function generating incremental ids for edges. - * - * @return {function} - */ - - function incrementalIdStartingFromRandomByte() { - var i = Math.floor(Math.random() * 256) & 0xff; - return function () { - return i++; - }; - } - - var events = {exports: {}}; - - var R = typeof Reflect === 'object' ? Reflect : null; - var ReflectApply = R && typeof R.apply === 'function' ? R.apply : function ReflectApply(target, receiver, args) { - return Function.prototype.apply.call(target, receiver, args); - }; - var ReflectOwnKeys; - - if (R && typeof R.ownKeys === 'function') { - ReflectOwnKeys = R.ownKeys; - } else if (Object.getOwnPropertySymbols) { - ReflectOwnKeys = function ReflectOwnKeys(target) { - return Object.getOwnPropertyNames(target).concat(Object.getOwnPropertySymbols(target)); - }; - } else { - ReflectOwnKeys = function ReflectOwnKeys(target) { - return Object.getOwnPropertyNames(target); - }; - } - - function ProcessEmitWarning(warning) { - if (console && console.warn) console.warn(warning); - } - - var NumberIsNaN = Number.isNaN || function NumberIsNaN(value) { - return value !== value; - }; - - function EventEmitter() { - EventEmitter.init.call(this); - } - - events.exports = EventEmitter; - events.exports.once = once; // Backwards-compat with node 0.10.x - - EventEmitter.EventEmitter = EventEmitter; - EventEmitter.prototype._events = undefined; - EventEmitter.prototype._eventsCount = 0; - EventEmitter.prototype._maxListeners = undefined; // By default EventEmitters will print a warning if more than 10 listeners are - // added to it. This is a useful default which helps finding memory leaks. - - var defaultMaxListeners = 10; - - function checkListener(listener) { - if (typeof listener !== 'function') { - throw new TypeError('The "listener" argument must be of type Function. Received type ' + typeof listener); - } - } - - Object.defineProperty(EventEmitter, 'defaultMaxListeners', { - enumerable: true, - get: function () { - return defaultMaxListeners; - }, - set: function (arg) { - if (typeof arg !== 'number' || arg < 0 || NumberIsNaN(arg)) { - throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received ' + arg + '.'); - } - - defaultMaxListeners = arg; - } - }); - - EventEmitter.init = function () { - if (this._events === undefined || this._events === Object.getPrototypeOf(this)._events) { - this._events = Object.create(null); - this._eventsCount = 0; - } - - this._maxListeners = this._maxListeners || undefined; - }; // Obviously not all Emitters should be limited to 10. This function allows - // that to be increased. Set to zero for unlimited. - - - EventEmitter.prototype.setMaxListeners = function setMaxListeners(n) { - if (typeof n !== 'number' || n < 0 || NumberIsNaN(n)) { - throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received ' + n + '.'); - } - - this._maxListeners = n; - return this; - }; - - function _getMaxListeners(that) { - if (that._maxListeners === undefined) return EventEmitter.defaultMaxListeners; - return that._maxListeners; - } - - EventEmitter.prototype.getMaxListeners = function getMaxListeners() { - return _getMaxListeners(this); - }; - - EventEmitter.prototype.emit = function emit(type) { - var args = []; - - for (var i = 1; i < arguments.length; i++) args.push(arguments[i]); - - var doError = type === 'error'; - var events = this._events; - if (events !== undefined) doError = doError && events.error === undefined;else if (!doError) return false; // If there is no 'error' event listener then throw. - - if (doError) { - var er; - if (args.length > 0) er = args[0]; - - if (er instanceof Error) { - // Note: The comments on the `throw` lines are intentional, they show - // up in Node's output if this results in an unhandled exception. - throw er; // Unhandled 'error' event - } // At least give some kind of context to the user - - - var err = new Error('Unhandled error.' + (er ? ' (' + er.message + ')' : '')); - err.context = er; - throw err; // Unhandled 'error' event - } - - var handler = events[type]; - if (handler === undefined) return false; - - if (typeof handler === 'function') { - ReflectApply(handler, this, args); - } else { - var len = handler.length; - var listeners = arrayClone(handler, len); - - for (var i = 0; i < len; ++i) ReflectApply(listeners[i], this, args); - } - - return true; - }; - - function _addListener(target, type, listener, prepend) { - var m; - var events; - var existing; - checkListener(listener); - events = target._events; - - if (events === undefined) { - events = target._events = Object.create(null); - target._eventsCount = 0; - } else { - // To avoid recursion in the case that type === "newListener"! Before - // adding it to the listeners, first emit "newListener". - if (events.newListener !== undefined) { - target.emit('newListener', type, listener.listener ? listener.listener : listener); // Re-assign `events` because a newListener handler could have caused the - // this._events to be assigned to a new object - - events = target._events; - } - - existing = events[type]; - } - - if (existing === undefined) { - // Optimize the case of one listener. Don't need the extra array object. - existing = events[type] = listener; - ++target._eventsCount; - } else { - if (typeof existing === 'function') { - // Adding the second element, need to change to array. - existing = events[type] = prepend ? [listener, existing] : [existing, listener]; // If we've already got an array, just append. - } else if (prepend) { - existing.unshift(listener); - } else { - existing.push(listener); - } // Check for listener leak - - - m = _getMaxListeners(target); - - if (m > 0 && existing.length > m && !existing.warned) { - existing.warned = true; // No error code for this since it is a Warning - // eslint-disable-next-line no-restricted-syntax - - var w = new Error('Possible EventEmitter memory leak detected. ' + existing.length + ' ' + String(type) + ' listeners ' + 'added. Use emitter.setMaxListeners() to ' + 'increase limit'); - w.name = 'MaxListenersExceededWarning'; - w.emitter = target; - w.type = type; - w.count = existing.length; - ProcessEmitWarning(w); - } - } - - return target; - } - - EventEmitter.prototype.addListener = function addListener(type, listener) { - return _addListener(this, type, listener, false); - }; - - EventEmitter.prototype.on = EventEmitter.prototype.addListener; - - EventEmitter.prototype.prependListener = function prependListener(type, listener) { - return _addListener(this, type, listener, true); - }; - - function onceWrapper() { - if (!this.fired) { - this.target.removeListener(this.type, this.wrapFn); - this.fired = true; - if (arguments.length === 0) return this.listener.call(this.target); - return this.listener.apply(this.target, arguments); - } - } - - function _onceWrap(target, type, listener) { - var state = { - fired: false, - wrapFn: undefined, - target: target, - type: type, - listener: listener - }; - var wrapped = onceWrapper.bind(state); - wrapped.listener = listener; - state.wrapFn = wrapped; - return wrapped; - } - - EventEmitter.prototype.once = function once(type, listener) { - checkListener(listener); - this.on(type, _onceWrap(this, type, listener)); - return this; - }; - - EventEmitter.prototype.prependOnceListener = function prependOnceListener(type, listener) { - checkListener(listener); - this.prependListener(type, _onceWrap(this, type, listener)); - return this; - }; // Emits a 'removeListener' event if and only if the listener was removed. - - - EventEmitter.prototype.removeListener = function removeListener(type, listener) { - var list, events, position, i, originalListener; - checkListener(listener); - events = this._events; - if (events === undefined) return this; - list = events[type]; - if (list === undefined) return this; - - if (list === listener || list.listener === listener) { - if (--this._eventsCount === 0) this._events = Object.create(null);else { - delete events[type]; - if (events.removeListener) this.emit('removeListener', type, list.listener || listener); - } - } else if (typeof list !== 'function') { - position = -1; - - for (i = list.length - 1; i >= 0; i--) { - if (list[i] === listener || list[i].listener === listener) { - originalListener = list[i].listener; - position = i; - break; - } - } - - if (position < 0) return this; - if (position === 0) list.shift();else { - spliceOne(list, position); - } - if (list.length === 1) events[type] = list[0]; - if (events.removeListener !== undefined) this.emit('removeListener', type, originalListener || listener); - } - - return this; - }; - - EventEmitter.prototype.off = EventEmitter.prototype.removeListener; - - EventEmitter.prototype.removeAllListeners = function removeAllListeners(type) { - var listeners, events, i; - events = this._events; - if (events === undefined) return this; // not listening for removeListener, no need to emit - - if (events.removeListener === undefined) { - if (arguments.length === 0) { - this._events = Object.create(null); - this._eventsCount = 0; - } else if (events[type] !== undefined) { - if (--this._eventsCount === 0) this._events = Object.create(null);else delete events[type]; - } - - return this; - } // emit removeListener for all listeners on all events - - - if (arguments.length === 0) { - var keys = Object.keys(events); - var key; - - for (i = 0; i < keys.length; ++i) { - key = keys[i]; - if (key === 'removeListener') continue; - this.removeAllListeners(key); - } - - this.removeAllListeners('removeListener'); - this._events = Object.create(null); - this._eventsCount = 0; - return this; - } - - listeners = events[type]; - - if (typeof listeners === 'function') { - this.removeListener(type, listeners); - } else if (listeners !== undefined) { - // LIFO order - for (i = listeners.length - 1; i >= 0; i--) { - this.removeListener(type, listeners[i]); - } - } - - return this; - }; - - function _listeners(target, type, unwrap) { - var events = target._events; - if (events === undefined) return []; - var evlistener = events[type]; - if (evlistener === undefined) return []; - if (typeof evlistener === 'function') return unwrap ? [evlistener.listener || evlistener] : [evlistener]; - return unwrap ? unwrapListeners(evlistener) : arrayClone(evlistener, evlistener.length); - } - - EventEmitter.prototype.listeners = function listeners(type) { - return _listeners(this, type, true); - }; - - EventEmitter.prototype.rawListeners = function rawListeners(type) { - return _listeners(this, type, false); - }; - - EventEmitter.listenerCount = function (emitter, type) { - if (typeof emitter.listenerCount === 'function') { - return emitter.listenerCount(type); - } else { - return listenerCount.call(emitter, type); - } - }; - - EventEmitter.prototype.listenerCount = listenerCount; - - function listenerCount(type) { - var events = this._events; - - if (events !== undefined) { - var evlistener = events[type]; - - if (typeof evlistener === 'function') { - return 1; - } else if (evlistener !== undefined) { - return evlistener.length; - } - } - - return 0; - } - - EventEmitter.prototype.eventNames = function eventNames() { - return this._eventsCount > 0 ? ReflectOwnKeys(this._events) : []; - }; - - function arrayClone(arr, n) { - var copy = new Array(n); - - for (var i = 0; i < n; ++i) copy[i] = arr[i]; - - return copy; - } - - function spliceOne(list, index) { - for (; index + 1 < list.length; index++) list[index] = list[index + 1]; - - list.pop(); - } - - function unwrapListeners(arr) { - var ret = new Array(arr.length); - - for (var i = 0; i < ret.length; ++i) { - ret[i] = arr[i].listener || arr[i]; - } - - return ret; - } - - function once(emitter, name) { - return new Promise(function (resolve, reject) { - function errorListener(err) { - emitter.removeListener(name, resolver); - reject(err); - } - - function resolver() { - if (typeof emitter.removeListener === 'function') { - emitter.removeListener('error', errorListener); - } - - resolve([].slice.call(arguments)); - } - eventTargetAgnosticAddListener(emitter, name, resolver, { - once: true - }); - - if (name !== 'error') { - addErrorHandlerIfEventEmitter(emitter, errorListener, { - once: true - }); - } - }); - } - - function addErrorHandlerIfEventEmitter(emitter, handler, flags) { - if (typeof emitter.on === 'function') { - eventTargetAgnosticAddListener(emitter, 'error', handler, flags); - } - } - - function eventTargetAgnosticAddListener(emitter, name, listener, flags) { - if (typeof emitter.on === 'function') { - if (flags.once) { - emitter.once(name, listener); - } else { - emitter.on(name, listener); - } - } else if (typeof emitter.addEventListener === 'function') { - // EventTarget does not have `error` event semantics like Node - // EventEmitters, we do not listen for `error` events here. - emitter.addEventListener(name, function wrapListener(arg) { - // IE does not have builtin `{ once: true }` support so we - // have to do it manually. - if (flags.once) { - emitter.removeEventListener(name, wrapListener); - } - - listener(arg); - }); - } else { - throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type ' + typeof emitter); - } - } - - /** - * Obliterator Iterator Class - * =========================== - * - * Simple class representing the library's iterators. - */ - /** - * Iterator class. - * - * @constructor - * @param {function} next - Next function. - */ - - function Iterator$2(next) { - if (typeof next !== 'function') throw new Error('obliterator/iterator: expecting a function!'); - this.next = next; - } - /** - * If symbols are supported, we add `next` to `Symbol.iterator`. - */ - - - if (typeof Symbol !== 'undefined') Iterator$2.prototype[Symbol.iterator] = function () { - return this; - }; - /** - * Returning an iterator of the given values. - * - * @param {any...} values - Values. - * @return {Iterator} - */ - - Iterator$2.of = function () { - var args = arguments, - l = args.length, - i = 0; - return new Iterator$2(function () { - if (i >= l) return { - done: true - }; - return { - done: false, - value: args[i++] - }; - }); - }; - /** - * Returning an empty iterator. - * - * @return {Iterator} - */ - - - Iterator$2.empty = function () { - var iterator = new Iterator$2(function () { - return { - done: true - }; - }); - return iterator; - }; - /** - * Returning an iterator over the given indexed sequence. - * - * @param {string|Array} sequence - Target sequence. - * @return {Iterator} - */ - - - Iterator$2.fromSequence = function (sequence) { - var i = 0, - l = sequence.length; - return new Iterator$2(function () { - if (i >= l) return { - done: true - }; - return { - done: false, - value: sequence[i++] - }; - }); - }; - /** - * Returning whether the given value is an iterator. - * - * @param {any} value - Value. - * @return {boolean} - */ - - - Iterator$2.is = function (value) { - if (value instanceof Iterator$2) return true; - return typeof value === 'object' && value !== null && typeof value.next === 'function'; - }; - /** - * Exporting. - */ - - - var iterator = Iterator$2; - - var support$1 = {}; - - support$1.ARRAY_BUFFER_SUPPORT = typeof ArrayBuffer !== 'undefined'; - support$1.SYMBOL_SUPPORT = typeof Symbol !== 'undefined'; - - /** - * Obliterator Iter Function - * ========================== - * - * Function coercing values to an iterator. It can be quite useful when needing - * to handle iterables and iterators the same way. - */ - var Iterator$1 = iterator; - var support = support$1; - var ARRAY_BUFFER_SUPPORT = support.ARRAY_BUFFER_SUPPORT; - var SYMBOL_SUPPORT = support.SYMBOL_SUPPORT; - - function iterOrNull(target) { - // Indexed sequence - if (typeof target === 'string' || Array.isArray(target) || ARRAY_BUFFER_SUPPORT && ArrayBuffer.isView(target)) return Iterator$1.fromSequence(target); // Invalid value - - if (typeof target !== 'object' || target === null) return null; // Iterable - - if (SYMBOL_SUPPORT && typeof target[Symbol.iterator] === 'function') return target[Symbol.iterator](); // Iterator duck-typing - - if (typeof target.next === 'function') return target; // Invalid object - - return null; - } - - var iter$2 = function iter(target) { - var iterator = iterOrNull(target); - if (!iterator) throw new Error('obliterator: target is not iterable nor a valid iterator.'); - return iterator; - }; - - /* eslint no-constant-condition: 0 */ - /** - * Obliterator Take Function - * ========================== - * - * Function taking n or every value of the given iterator and returns them - * into an array. - */ - - var iter$1 = iter$2; - /** - * Take. - * - * @param {Iterable} iterable - Target iterable. - * @param {number} [n] - Optional number of items to take. - * @return {array} - */ - - var take = function take(iterable, n) { - var l = arguments.length > 1 ? n : Infinity, - array = l !== Infinity ? new Array(l) : [], - step, - i = 0; - var iterator = iter$1(iterable); - - while (true) { - if (i === l) return array; - step = iterator.next(); - - if (step.done) { - if (i !== n) array.length = i; - return array; - } - - array[i++] = step.value; - } - }; - - /** - * Graphology Custom Errors - * ========================= - * - * Defining custom errors for ease of use & easy unit tests across - * implementations (normalized typology rather than relying on error - * messages to check whether the correct error was found). - */ - var GraphError = /*#__PURE__*/function (_Error) { - _inheritsLoose(GraphError, _Error); - - function GraphError(message) { - var _this; - - _this = _Error.call(this) || this; - _this.name = 'GraphError'; - _this.message = message; - return _this; - } - - return GraphError; - }( /*#__PURE__*/_wrapNativeSuper(Error)); - var InvalidArgumentsGraphError = /*#__PURE__*/function (_GraphError) { - _inheritsLoose(InvalidArgumentsGraphError, _GraphError); - - function InvalidArgumentsGraphError(message) { - var _this2; - - _this2 = _GraphError.call(this, message) || this; - _this2.name = 'InvalidArgumentsGraphError'; // This is V8 specific to enhance stack readability - - if (typeof Error.captureStackTrace === 'function') Error.captureStackTrace(_assertThisInitialized(_this2), InvalidArgumentsGraphError.prototype.constructor); - return _this2; - } - - return InvalidArgumentsGraphError; - }(GraphError); - var NotFoundGraphError = /*#__PURE__*/function (_GraphError2) { - _inheritsLoose(NotFoundGraphError, _GraphError2); - - function NotFoundGraphError(message) { - var _this3; - - _this3 = _GraphError2.call(this, message) || this; - _this3.name = 'NotFoundGraphError'; // This is V8 specific to enhance stack readability - - if (typeof Error.captureStackTrace === 'function') Error.captureStackTrace(_assertThisInitialized(_this3), NotFoundGraphError.prototype.constructor); - return _this3; - } - - return NotFoundGraphError; - }(GraphError); - var UsageGraphError = /*#__PURE__*/function (_GraphError3) { - _inheritsLoose(UsageGraphError, _GraphError3); - - function UsageGraphError(message) { - var _this4; - - _this4 = _GraphError3.call(this, message) || this; - _this4.name = 'UsageGraphError'; // This is V8 specific to enhance stack readability - - if (typeof Error.captureStackTrace === 'function') Error.captureStackTrace(_assertThisInitialized(_this4), UsageGraphError.prototype.constructor); - return _this4; - } - - return UsageGraphError; - }(GraphError); - - /** - * Graphology Internal Data Classes - * ================================= - * - * Internal classes hopefully reduced to structs by engines & storing - * necessary information for nodes & edges. - * - * Note that those classes don't rely on the `class` keyword to avoid some - * cruft introduced by most of ES2015 transpilers. - */ - - /** - * MixedNodeData class. - * - * @constructor - * @param {string} string - The node's key. - * @param {object} attributes - Node's attributes. - */ - function MixedNodeData(key, attributes) { - // Attributes - this.key = key; - this.attributes = attributes; - this.clear(); - } - - MixedNodeData.prototype.clear = function () { - // Degrees - this.inDegree = 0; - this.outDegree = 0; - this.undirectedDegree = 0; // Indices - - this["in"] = {}; - this.out = {}; - this.undirected = {}; - }; - /** - * DirectedNodeData class. - * - * @constructor - * @param {string} string - The node's key. - * @param {object} attributes - Node's attributes. - */ - - - function DirectedNodeData(key, attributes) { - // Attributes - this.key = key; - this.attributes = attributes; - this.clear(); - } - - DirectedNodeData.prototype.clear = function () { - // Degrees - this.inDegree = 0; - this.outDegree = 0; // Indices - - this["in"] = {}; - this.out = {}; - }; - /** - * UndirectedNodeData class. - * - * @constructor - * @param {string} string - The node's key. - * @param {object} attributes - Node's attributes. - */ - - - function UndirectedNodeData(key, attributes) { - // Attributes - this.key = key; - this.attributes = attributes; - this.clear(); - } - - UndirectedNodeData.prototype.clear = function () { - // Degrees - this.undirectedDegree = 0; // Indices - - this.undirected = {}; - }; - /** - * EdgeData class. - * - * @constructor - * @param {boolean} undirected - Whether the edge is undirected. - * @param {string} string - The edge's key. - * @param {string} source - Source of the edge. - * @param {string} target - Target of the edge. - * @param {object} attributes - Edge's attributes. - */ - - - function EdgeData(undirected, key, source, target, attributes) { - // Attributes - this.key = key; - this.attributes = attributes; - this.undirected = undirected; // Extremities - - this.source = source; - this.target = target; - } - - EdgeData.prototype.attach = function () { - var outKey = 'out'; - var inKey = 'in'; - if (this.undirected) outKey = inKey = 'undirected'; - var source = this.source.key; - var target = this.target.key; // Handling source - - this.source[outKey][target] = this; - if (this.undirected && source === target) return; // Handling target - - this.target[inKey][source] = this; - }; - - EdgeData.prototype.attachMulti = function () { - var outKey = 'out'; - var inKey = 'in'; - var source = this.source.key; - var target = this.target.key; - if (this.undirected) outKey = inKey = 'undirected'; // Handling source - - var adj = this.source[outKey]; - var head = adj[target]; - - if (typeof head === 'undefined') { - adj[target] = this; // Self-loop optimization - - if (!(this.undirected && source === target)) { - // Handling target - this.target[inKey][source] = this; - } - - return; - } // Prepending to doubly-linked list - - - head.previous = this; - this.next = head; // Pointing to new head - // NOTE: use mutating swap later to avoid lookup? - - adj[target] = this; - this.target[inKey][source] = this; - }; - - EdgeData.prototype.detach = function () { - var source = this.source.key; - var target = this.target.key; - var outKey = 'out'; - var inKey = 'in'; - if (this.undirected) outKey = inKey = 'undirected'; - delete this.source[outKey][target]; // No-op delete in case of undirected self-loop - - delete this.target[inKey][source]; - }; - - EdgeData.prototype.detachMulti = function () { - var source = this.source.key; - var target = this.target.key; - var outKey = 'out'; - var inKey = 'in'; - if (this.undirected) outKey = inKey = 'undirected'; // Deleting from doubly-linked list - - if (this.previous === undefined) { - // We are dealing with the head - // Should we delete the adjacency entry because it is now empty? - if (this.next === undefined) { - delete this.source[outKey][target]; // No-op delete in case of undirected self-loop - - delete this.target[inKey][source]; - } else { - // Detaching - this.next.previous = undefined; // NOTE: could avoid the lookups by creating a #.become mutating method - - this.source[outKey][target] = this.next; // No-op delete in case of undirected self-loop - - this.target[inKey][source] = this.next; - } - } else { - // We are dealing with another list node - this.previous.next = this.next; // If not last - - if (this.next !== undefined) { - this.next.previous = this.previous; - } - } - }; - - /** - * Graphology Node Attributes methods - * =================================== - */ - var NODE = 0; - var SOURCE = 1; - var TARGET = 2; - var OPPOSITE = 3; - - function findRelevantNodeData(graph, method, mode, nodeOrEdge, nameOrEdge, add1, add2) { - var nodeData, edgeData, arg1, arg2; - nodeOrEdge = '' + nodeOrEdge; - - if (mode === NODE) { - nodeData = graph._nodes.get(nodeOrEdge); - if (!nodeData) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(nodeOrEdge, "\" node in the graph.")); - arg1 = nameOrEdge; - arg2 = add1; - } else if (mode === OPPOSITE) { - nameOrEdge = '' + nameOrEdge; - edgeData = graph._edges.get(nameOrEdge); - if (!edgeData) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(nameOrEdge, "\" edge in the graph.")); - var source = edgeData.source.key; - var target = edgeData.target.key; - - if (nodeOrEdge === source) { - nodeData = edgeData.target; - } else if (nodeOrEdge === target) { - nodeData = edgeData.source; - } else { - throw new NotFoundGraphError("Graph.".concat(method, ": the \"").concat(nodeOrEdge, "\" node is not attached to the \"").concat(nameOrEdge, "\" edge (").concat(source, ", ").concat(target, ").")); - } - - arg1 = add1; - arg2 = add2; - } else { - edgeData = graph._edges.get(nodeOrEdge); - if (!edgeData) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(nodeOrEdge, "\" edge in the graph.")); - - if (mode === SOURCE) { - nodeData = edgeData.source; - } else { - nodeData = edgeData.target; - } - - arg1 = nameOrEdge; - arg2 = add1; - } - - return [nodeData, arg1, arg2]; - } - - function attachNodeAttributeGetter(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) { - var _findRelevantNodeData = findRelevantNodeData(this, method, mode, nodeOrEdge, nameOrEdge, add1), - data = _findRelevantNodeData[0], - name = _findRelevantNodeData[1]; - - return data.attributes[name]; - }; - } - - function attachNodeAttributesGetter(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge) { - var _findRelevantNodeData2 = findRelevantNodeData(this, method, mode, nodeOrEdge, nameOrEdge), - data = _findRelevantNodeData2[0]; - - return data.attributes; - }; - } - - function attachNodeAttributeChecker(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) { - var _findRelevantNodeData3 = findRelevantNodeData(this, method, mode, nodeOrEdge, nameOrEdge, add1), - data = _findRelevantNodeData3[0], - name = _findRelevantNodeData3[1]; - - return data.attributes.hasOwnProperty(name); - }; - } - - function attachNodeAttributeSetter(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1, add2) { - var _findRelevantNodeData4 = findRelevantNodeData(this, method, mode, nodeOrEdge, nameOrEdge, add1, add2), - data = _findRelevantNodeData4[0], - name = _findRelevantNodeData4[1], - value = _findRelevantNodeData4[2]; - - data.attributes[name] = value; // Emitting - - this.emit('nodeAttributesUpdated', { - key: data.key, - type: 'set', - attributes: data.attributes, - name: name - }); - return this; - }; - } - - function attachNodeAttributeUpdater(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1, add2) { - var _findRelevantNodeData5 = findRelevantNodeData(this, method, mode, nodeOrEdge, nameOrEdge, add1, add2), - data = _findRelevantNodeData5[0], - name = _findRelevantNodeData5[1], - updater = _findRelevantNodeData5[2]; - - if (typeof updater !== 'function') throw new InvalidArgumentsGraphError("Graph.".concat(method, ": updater should be a function.")); - var attributes = data.attributes; - var value = updater(attributes[name]); - attributes[name] = value; // Emitting - - this.emit('nodeAttributesUpdated', { - key: data.key, - type: 'set', - attributes: data.attributes, - name: name - }); - return this; - }; - } - - function attachNodeAttributeRemover(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) { - var _findRelevantNodeData6 = findRelevantNodeData(this, method, mode, nodeOrEdge, nameOrEdge, add1), - data = _findRelevantNodeData6[0], - name = _findRelevantNodeData6[1]; - - delete data.attributes[name]; // Emitting - - this.emit('nodeAttributesUpdated', { - key: data.key, - type: 'remove', - attributes: data.attributes, - name: name - }); - return this; - }; - } - - function attachNodeAttributesReplacer(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) { - var _findRelevantNodeData7 = findRelevantNodeData(this, method, mode, nodeOrEdge, nameOrEdge, add1), - data = _findRelevantNodeData7[0], - attributes = _findRelevantNodeData7[1]; - - if (!isPlainObject(attributes)) throw new InvalidArgumentsGraphError("Graph.".concat(method, ": provided attributes are not a plain object.")); - data.attributes = attributes; // Emitting - - this.emit('nodeAttributesUpdated', { - key: data.key, - type: 'replace', - attributes: data.attributes - }); - return this; - }; - } - - function attachNodeAttributesMerger(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) { - var _findRelevantNodeData8 = findRelevantNodeData(this, method, mode, nodeOrEdge, nameOrEdge, add1), - data = _findRelevantNodeData8[0], - attributes = _findRelevantNodeData8[1]; - - if (!isPlainObject(attributes)) throw new InvalidArgumentsGraphError("Graph.".concat(method, ": provided attributes are not a plain object.")); - assign(data.attributes, attributes); // Emitting - - this.emit('nodeAttributesUpdated', { - key: data.key, - type: 'merge', - attributes: data.attributes, - data: attributes - }); - return this; - }; - } - - function attachNodeAttributesUpdater(Class, method, mode) { - Class.prototype[method] = function (nodeOrEdge, nameOrEdge, add1) { - var _findRelevantNodeData9 = findRelevantNodeData(this, method, mode, nodeOrEdge, nameOrEdge, add1), - data = _findRelevantNodeData9[0], - updater = _findRelevantNodeData9[1]; - - if (typeof updater !== 'function') throw new InvalidArgumentsGraphError("Graph.".concat(method, ": provided updater is not a function.")); - data.attributes = updater(data.attributes); // Emitting - - this.emit('nodeAttributesUpdated', { - key: data.key, - type: 'update', - attributes: data.attributes - }); - return this; - }; - } - /** - * List of methods to attach. - */ - - - var NODE_ATTRIBUTES_METHODS = [{ - name: function name(element) { - return "get".concat(element, "Attribute"); - }, - attacher: attachNodeAttributeGetter - }, { - name: function name(element) { - return "get".concat(element, "Attributes"); - }, - attacher: attachNodeAttributesGetter - }, { - name: function name(element) { - return "has".concat(element, "Attribute"); - }, - attacher: attachNodeAttributeChecker - }, { - name: function name(element) { - return "set".concat(element, "Attribute"); - }, - attacher: attachNodeAttributeSetter - }, { - name: function name(element) { - return "update".concat(element, "Attribute"); - }, - attacher: attachNodeAttributeUpdater - }, { - name: function name(element) { - return "remove".concat(element, "Attribute"); - }, - attacher: attachNodeAttributeRemover - }, { - name: function name(element) { - return "replace".concat(element, "Attributes"); - }, - attacher: attachNodeAttributesReplacer - }, { - name: function name(element) { - return "merge".concat(element, "Attributes"); - }, - attacher: attachNodeAttributesMerger - }, { - name: function name(element) { - return "update".concat(element, "Attributes"); - }, - attacher: attachNodeAttributesUpdater - }]; - /** - * Attach every attributes-related methods to a Graph class. - * - * @param {function} Graph - Target class. - */ - - function attachNodeAttributesMethods(Graph) { - NODE_ATTRIBUTES_METHODS.forEach(function (_ref) { - var name = _ref.name, - attacher = _ref.attacher; - // For nodes - attacher(Graph, name('Node'), NODE); // For sources - - attacher(Graph, name('Source'), SOURCE); // For targets - - attacher(Graph, name('Target'), TARGET); // For opposites - - attacher(Graph, name('Opposite'), OPPOSITE); - }); - } - - /** - * Graphology Edge Attributes methods - * =================================== - */ - /** - * Attach an attribute getter method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ - - function attachEdgeAttributeGetter(Class, method, type) { - /** - * Get the desired attribute for the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {string} name - Attribute's name. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {string} name - Attribute's name. - * - * @return {mixed} - The attribute's value. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, name) { - var data; - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) throw new UsageGraphError("Graph.".concat(method, ": cannot find this type of edges in your ").concat(this.type, " graph.")); - - if (arguments.length > 2) { - if (this.multi) throw new UsageGraphError("Graph.".concat(method, ": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.")); - var source = '' + element; - var target = '' + name; - name = arguments[2]; - data = getMatchingEdge(this, source, target, type); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find an edge for the given path (\"").concat(source, "\" - \"").concat(target, "\").")); - } else { - if (type !== 'mixed') throw new UsageGraphError("Graph.".concat(method, ": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.")); - element = '' + element; - data = this._edges.get(element); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(element, "\" edge in the graph.")); - } - - return data.attributes[name]; - }; - } - /** - * Attach an attributes getter method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ - - - function attachEdgeAttributesGetter(Class, method, type) { - /** - * Retrieves all the target element's attributes. - * - * Arity 2: - * @param {any} element - Target element. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * - * @return {object} - The element's attributes. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element) { - var data; - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) throw new UsageGraphError("Graph.".concat(method, ": cannot find this type of edges in your ").concat(this.type, " graph.")); - - if (arguments.length > 1) { - if (this.multi) throw new UsageGraphError("Graph.".concat(method, ": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.")); - var source = '' + element, - target = '' + arguments[1]; - data = getMatchingEdge(this, source, target, type); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find an edge for the given path (\"").concat(source, "\" - \"").concat(target, "\").")); - } else { - if (type !== 'mixed') throw new UsageGraphError("Graph.".concat(method, ": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.")); - element = '' + element; - data = this._edges.get(element); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(element, "\" edge in the graph.")); - } - - return data.attributes; - }; - } - /** - * Attach an attribute checker method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ - - - function attachEdgeAttributeChecker(Class, method, type) { - /** - * Checks whether the desired attribute is set for the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {string} name - Attribute's name. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {string} name - Attribute's name. - * - * @return {boolean} - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, name) { - var data; - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) throw new UsageGraphError("Graph.".concat(method, ": cannot find this type of edges in your ").concat(this.type, " graph.")); - - if (arguments.length > 2) { - if (this.multi) throw new UsageGraphError("Graph.".concat(method, ": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.")); - var source = '' + element; - var target = '' + name; - name = arguments[2]; - data = getMatchingEdge(this, source, target, type); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find an edge for the given path (\"").concat(source, "\" - \"").concat(target, "\").")); - } else { - if (type !== 'mixed') throw new UsageGraphError("Graph.".concat(method, ": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.")); - element = '' + element; - data = this._edges.get(element); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(element, "\" edge in the graph.")); - } - - return data.attributes.hasOwnProperty(name); - }; - } - /** - * Attach an attribute setter method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ - - - function attachEdgeAttributeSetter(Class, method, type) { - /** - * Set the desired attribute for the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {string} name - Attribute's name. - * @param {mixed} value - New attribute value. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {string} name - Attribute's name. - * @param {mixed} value - New attribute value. - * - * @return {Graph} - Returns itself for chaining. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, name, value) { - var data; - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) throw new UsageGraphError("Graph.".concat(method, ": cannot find this type of edges in your ").concat(this.type, " graph.")); - - if (arguments.length > 3) { - if (this.multi) throw new UsageGraphError("Graph.".concat(method, ": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.")); - var source = '' + element; - var target = '' + name; - name = arguments[2]; - value = arguments[3]; - data = getMatchingEdge(this, source, target, type); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find an edge for the given path (\"").concat(source, "\" - \"").concat(target, "\").")); - } else { - if (type !== 'mixed') throw new UsageGraphError("Graph.".concat(method, ": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.")); - element = '' + element; - data = this._edges.get(element); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(element, "\" edge in the graph.")); - } - - data.attributes[name] = value; // Emitting - - this.emit('edgeAttributesUpdated', { - key: data.key, - type: 'set', - attributes: data.attributes, - name: name - }); - return this; - }; - } - /** - * Attach an attribute updater method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ - - - function attachEdgeAttributeUpdater(Class, method, type) { - /** - * Update the desired attribute for the given element (node or edge) using - * the provided function. - * - * Arity 2: - * @param {any} element - Target element. - * @param {string} name - Attribute's name. - * @param {function} updater - Updater function. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {string} name - Attribute's name. - * @param {function} updater - Updater function. - * - * @return {Graph} - Returns itself for chaining. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, name, updater) { - var data; - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) throw new UsageGraphError("Graph.".concat(method, ": cannot find this type of edges in your ").concat(this.type, " graph.")); - - if (arguments.length > 3) { - if (this.multi) throw new UsageGraphError("Graph.".concat(method, ": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.")); - var source = '' + element; - var target = '' + name; - name = arguments[2]; - updater = arguments[3]; - data = getMatchingEdge(this, source, target, type); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find an edge for the given path (\"").concat(source, "\" - \"").concat(target, "\").")); - } else { - if (type !== 'mixed') throw new UsageGraphError("Graph.".concat(method, ": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.")); - element = '' + element; - data = this._edges.get(element); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(element, "\" edge in the graph.")); - } - - if (typeof updater !== 'function') throw new InvalidArgumentsGraphError("Graph.".concat(method, ": updater should be a function.")); - data.attributes[name] = updater(data.attributes[name]); // Emitting - - this.emit('edgeAttributesUpdated', { - key: data.key, - type: 'set', - attributes: data.attributes, - name: name - }); - return this; - }; - } - /** - * Attach an attribute remover method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ - - - function attachEdgeAttributeRemover(Class, method, type) { - /** - * Remove the desired attribute for the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {string} name - Attribute's name. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {string} name - Attribute's name. - * - * @return {Graph} - Returns itself for chaining. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, name) { - var data; - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) throw new UsageGraphError("Graph.".concat(method, ": cannot find this type of edges in your ").concat(this.type, " graph.")); - - if (arguments.length > 2) { - if (this.multi) throw new UsageGraphError("Graph.".concat(method, ": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.")); - var source = '' + element; - var target = '' + name; - name = arguments[2]; - data = getMatchingEdge(this, source, target, type); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find an edge for the given path (\"").concat(source, "\" - \"").concat(target, "\").")); - } else { - if (type !== 'mixed') throw new UsageGraphError("Graph.".concat(method, ": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.")); - element = '' + element; - data = this._edges.get(element); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(element, "\" edge in the graph.")); - } - - delete data.attributes[name]; // Emitting - - this.emit('edgeAttributesUpdated', { - key: data.key, - type: 'remove', - attributes: data.attributes, - name: name - }); - return this; - }; - } - /** - * Attach an attribute replacer method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ - - - function attachEdgeAttributesReplacer(Class, method, type) { - /** - * Replace the attributes for the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {object} attributes - New attributes. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {object} attributes - New attributes. - * - * @return {Graph} - Returns itself for chaining. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, attributes) { - var data; - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) throw new UsageGraphError("Graph.".concat(method, ": cannot find this type of edges in your ").concat(this.type, " graph.")); - - if (arguments.length > 2) { - if (this.multi) throw new UsageGraphError("Graph.".concat(method, ": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.")); - var source = '' + element, - target = '' + attributes; - attributes = arguments[2]; - data = getMatchingEdge(this, source, target, type); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find an edge for the given path (\"").concat(source, "\" - \"").concat(target, "\").")); - } else { - if (type !== 'mixed') throw new UsageGraphError("Graph.".concat(method, ": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.")); - element = '' + element; - data = this._edges.get(element); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(element, "\" edge in the graph.")); - } - - if (!isPlainObject(attributes)) throw new InvalidArgumentsGraphError("Graph.".concat(method, ": provided attributes are not a plain object.")); - data.attributes = attributes; // Emitting - - this.emit('edgeAttributesUpdated', { - key: data.key, - type: 'replace', - attributes: data.attributes - }); - return this; - }; - } - /** - * Attach an attribute merger method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ - - - function attachEdgeAttributesMerger(Class, method, type) { - /** - * Merge the attributes for the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {object} attributes - Attributes to merge. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {object} attributes - Attributes to merge. - * - * @return {Graph} - Returns itself for chaining. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, attributes) { - var data; - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) throw new UsageGraphError("Graph.".concat(method, ": cannot find this type of edges in your ").concat(this.type, " graph.")); - - if (arguments.length > 2) { - if (this.multi) throw new UsageGraphError("Graph.".concat(method, ": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.")); - var source = '' + element, - target = '' + attributes; - attributes = arguments[2]; - data = getMatchingEdge(this, source, target, type); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find an edge for the given path (\"").concat(source, "\" - \"").concat(target, "\").")); - } else { - if (type !== 'mixed') throw new UsageGraphError("Graph.".concat(method, ": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.")); - element = '' + element; - data = this._edges.get(element); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(element, "\" edge in the graph.")); - } - - if (!isPlainObject(attributes)) throw new InvalidArgumentsGraphError("Graph.".concat(method, ": provided attributes are not a plain object.")); - assign(data.attributes, attributes); // Emitting - - this.emit('edgeAttributesUpdated', { - key: data.key, - type: 'merge', - attributes: data.attributes, - data: attributes - }); - return this; - }; - } - /** - * Attach an attribute updater method onto the provided class. - * - * @param {function} Class - Target class. - * @param {string} method - Method name. - * @param {string} type - Type of the edge to find. - */ - - - function attachEdgeAttributesUpdater(Class, method, type) { - /** - * Update the attributes of the given element (node or edge). - * - * Arity 2: - * @param {any} element - Target element. - * @param {function} updater - Updater function. - * - * Arity 3 (only for edges): - * @param {any} source - Source element. - * @param {any} target - Target element. - * @param {function} updater - Updater function. - * - * @return {Graph} - Returns itself for chaining. - * - * @throws {Error} - Will throw if too many arguments are provided. - * @throws {Error} - Will throw if any of the elements is not found. - */ - Class.prototype[method] = function (element, updater) { - var data; - if (this.type !== 'mixed' && type !== 'mixed' && type !== this.type) throw new UsageGraphError("Graph.".concat(method, ": cannot find this type of edges in your ").concat(this.type, " graph.")); - - if (arguments.length > 2) { - if (this.multi) throw new UsageGraphError("Graph.".concat(method, ": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about.")); - var source = '' + element, - target = '' + updater; - updater = arguments[2]; - data = getMatchingEdge(this, source, target, type); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find an edge for the given path (\"").concat(source, "\" - \"").concat(target, "\").")); - } else { - if (type !== 'mixed') throw new UsageGraphError("Graph.".concat(method, ": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type.")); - element = '' + element; - data = this._edges.get(element); - if (!data) throw new NotFoundGraphError("Graph.".concat(method, ": could not find the \"").concat(element, "\" edge in the graph.")); - } - - if (typeof updater !== 'function') throw new InvalidArgumentsGraphError("Graph.".concat(method, ": provided updater is not a function.")); - data.attributes = updater(data.attributes); // Emitting - - this.emit('edgeAttributesUpdated', { - key: data.key, - type: 'update', - attributes: data.attributes - }); - return this; - }; - } - /** - * List of methods to attach. - */ - - - var EDGE_ATTRIBUTES_METHODS = [{ - name: function name(element) { - return "get".concat(element, "Attribute"); - }, - attacher: attachEdgeAttributeGetter - }, { - name: function name(element) { - return "get".concat(element, "Attributes"); - }, - attacher: attachEdgeAttributesGetter - }, { - name: function name(element) { - return "has".concat(element, "Attribute"); - }, - attacher: attachEdgeAttributeChecker - }, { - name: function name(element) { - return "set".concat(element, "Attribute"); - }, - attacher: attachEdgeAttributeSetter - }, { - name: function name(element) { - return "update".concat(element, "Attribute"); - }, - attacher: attachEdgeAttributeUpdater - }, { - name: function name(element) { - return "remove".concat(element, "Attribute"); - }, - attacher: attachEdgeAttributeRemover - }, { - name: function name(element) { - return "replace".concat(element, "Attributes"); - }, - attacher: attachEdgeAttributesReplacer - }, { - name: function name(element) { - return "merge".concat(element, "Attributes"); - }, - attacher: attachEdgeAttributesMerger - }, { - name: function name(element) { - return "update".concat(element, "Attributes"); - }, - attacher: attachEdgeAttributesUpdater - }]; - /** - * Attach every attributes-related methods to a Graph class. - * - * @param {function} Graph - Target class. - */ - - function attachEdgeAttributesMethods(Graph) { - EDGE_ATTRIBUTES_METHODS.forEach(function (_ref) { - var name = _ref.name, - attacher = _ref.attacher; - // For edges - attacher(Graph, name('Edge'), 'mixed'); // For directed edges - - attacher(Graph, name('DirectedEdge'), 'directed'); // For undirected edges - - attacher(Graph, name('UndirectedEdge'), 'undirected'); - }); - } - - /** - * Obliterator Chain Function - * =========================== - * - * Variadic function combining the given iterables. - */ - var Iterator = iterator; - var iter = iter$2; - /** - * Chain. - * - * @param {...Iterator} iterables - Target iterables. - * @return {Iterator} - */ - - var chain = function chain() { - var iterables = arguments; - var current = null; - var i = -1; - /* eslint-disable no-constant-condition */ - - return new Iterator(function next() { - var step = null; - - do { - if (current === null) { - i++; - if (i >= iterables.length) return { - done: true - }; - current = iter(iterables[i]); - } - - step = current.next(); - - if (step.done === true) { - current = null; - continue; - } - - break; - } while (true); - - return step; - }); - }; - - /** - * Graphology Edge Iteration - * ========================== - * - * Attaching some methods to the Graph class to be able to iterate over a - * graph's edges. - */ - /** - * Definitions. - */ - - var EDGES_ITERATION = [{ - name: 'edges', - type: 'mixed' - }, { - name: 'inEdges', - type: 'directed', - direction: 'in' - }, { - name: 'outEdges', - type: 'directed', - direction: 'out' - }, { - name: 'inboundEdges', - type: 'mixed', - direction: 'in' - }, { - name: 'outboundEdges', - type: 'mixed', - direction: 'out' - }, { - name: 'directedEdges', - type: 'directed' - }, { - name: 'undirectedEdges', - type: 'undirected' - }]; - /** - * Function iterating over edges from the given object to match one of them. - * - * @param {object} object - Target object. - * @param {function} callback - Function to call. - */ - - function forEachSimple(breakable, object, callback, avoid) { - var shouldBreak = false; - - for (var k in object) { - if (k === avoid) continue; - var edgeData = object[k]; - shouldBreak = callback(edgeData.key, edgeData.attributes, edgeData.source.key, edgeData.target.key, edgeData.source.attributes, edgeData.target.attributes, edgeData.undirected); - if (breakable && shouldBreak) return edgeData.key; - } - - return; - } - - function forEachMulti(breakable, object, callback, avoid) { - var edgeData, source, target; - var shouldBreak = false; - - for (var k in object) { - if (k === avoid) continue; - edgeData = object[k]; - - do { - source = edgeData.source; - target = edgeData.target; - shouldBreak = callback(edgeData.key, edgeData.attributes, source.key, target.key, source.attributes, target.attributes, edgeData.undirected); - if (breakable && shouldBreak) return edgeData.key; - edgeData = edgeData.next; - } while (edgeData !== undefined); - } - - return; - } - /** - * Function returning an iterator over edges from the given object. - * - * @param {object} object - Target object. - * @return {Iterator} - */ - - - function createIterator(object, avoid) { - var keys = Object.keys(object); - var l = keys.length; - var edgeData; - var i = 0; - return new iterator(function next() { - do { - if (!edgeData) { - if (i >= l) return { - done: true - }; - var k = keys[i++]; - - if (k === avoid) { - edgeData = undefined; - continue; - } - - edgeData = object[k]; - } else { - edgeData = edgeData.next; - } - } while (!edgeData); - - return { - done: false, - value: { - edge: edgeData.key, - attributes: edgeData.attributes, - source: edgeData.source.key, - target: edgeData.target.key, - sourceAttributes: edgeData.source.attributes, - targetAttributes: edgeData.target.attributes, - undirected: edgeData.undirected - } - }; - }); - } - /** - * Function iterating over the egdes from the object at given key to match - * one of them. - * - * @param {object} object - Target object. - * @param {mixed} k - Neighbor key. - * @param {function} callback - Callback to use. - */ - - - function forEachForKeySimple(breakable, object, k, callback) { - var edgeData = object[k]; - if (!edgeData) return; - var sourceData = edgeData.source; - var targetData = edgeData.target; - if (callback(edgeData.key, edgeData.attributes, sourceData.key, targetData.key, sourceData.attributes, targetData.attributes, edgeData.undirected) && breakable) return edgeData.key; - } - - function forEachForKeyMulti(breakable, object, k, callback) { - var edgeData = object[k]; - if (!edgeData) return; - var shouldBreak = false; - - do { - shouldBreak = callback(edgeData.key, edgeData.attributes, edgeData.source.key, edgeData.target.key, edgeData.source.attributes, edgeData.target.attributes, edgeData.undirected); - if (breakable && shouldBreak) return edgeData.key; - edgeData = edgeData.next; - } while (edgeData !== undefined); - - return; - } - /** - * Function returning an iterator over the egdes from the object at given key. - * - * @param {object} object - Target object. - * @param {mixed} k - Neighbor key. - * @return {Iterator} - */ - - - function createIteratorForKey(object, k) { - var edgeData = object[k]; - - if (edgeData.next !== undefined) { - return new iterator(function () { - if (!edgeData) return { - done: true - }; - var value = { - edge: edgeData.key, - attributes: edgeData.attributes, - source: edgeData.source.key, - target: edgeData.target.key, - sourceAttributes: edgeData.source.attributes, - targetAttributes: edgeData.target.attributes, - undirected: edgeData.undirected - }; - edgeData = edgeData.next; - return { - done: false, - value: value - }; - }); - } - - return iterator.of({ - edge: edgeData.key, - attributes: edgeData.attributes, - source: edgeData.source.key, - target: edgeData.target.key, - sourceAttributes: edgeData.source.attributes, - targetAttributes: edgeData.target.attributes, - undirected: edgeData.undirected - }); - } - /** - * Function creating an array of edges for the given type. - * - * @param {Graph} graph - Target Graph instance. - * @param {string} type - Type of edges to retrieve. - * @return {array} - Array of edges. - */ - - - function createEdgeArray(graph, type) { - if (graph.size === 0) return []; - - if (type === 'mixed' || type === graph.type) { - if (typeof Array.from === 'function') return Array.from(graph._edges.keys()); - return take(graph._edges.keys(), graph._edges.size); - } - - var size = type === 'undirected' ? graph.undirectedSize : graph.directedSize; - var list = new Array(size), - mask = type === 'undirected'; - - var iterator = graph._edges.values(); - - var i = 0; - var step, data; - - while (step = iterator.next(), step.done !== true) { - data = step.value; - if (data.undirected === mask) list[i++] = data.key; - } - - return list; - } - /** - * Function iterating over a graph's edges using a callback to match one of - * them. - * - * @param {Graph} graph - Target Graph instance. - * @param {string} type - Type of edges to retrieve. - * @param {function} callback - Function to call. - */ - - - function forEachEdge(breakable, graph, type, callback) { - if (graph.size === 0) return; - var shouldFilter = type !== 'mixed' && type !== graph.type; - var mask = type === 'undirected'; - var step, data; - var shouldBreak = false; - - var iterator = graph._edges.values(); - - while (step = iterator.next(), step.done !== true) { - data = step.value; - if (shouldFilter && data.undirected !== mask) continue; - var _data = data, - key = _data.key, - attributes = _data.attributes, - source = _data.source, - target = _data.target; - shouldBreak = callback(key, attributes, source.key, target.key, source.attributes, target.attributes, data.undirected); - if (breakable && shouldBreak) return key; - } - - return; - } - /** - * Function creating an iterator of edges for the given type. - * - * @param {Graph} graph - Target Graph instance. - * @param {string} type - Type of edges to retrieve. - * @return {Iterator} - */ - - - function createEdgeIterator(graph, type) { - if (graph.size === 0) return iterator.empty(); - var shouldFilter = type !== 'mixed' && type !== graph.type; - var mask = type === 'undirected'; - - var iterator$1 = graph._edges.values(); - - return new iterator(function next() { - var step, data; // eslint-disable-next-line no-constant-condition - - while (true) { - step = iterator$1.next(); - if (step.done) return step; - data = step.value; - if (shouldFilter && data.undirected !== mask) continue; - break; - } - - var value = { - edge: data.key, - attributes: data.attributes, - source: data.source.key, - target: data.target.key, - sourceAttributes: data.source.attributes, - targetAttributes: data.target.attributes, - undirected: data.undirected - }; - return { - value: value, - done: false - }; - }); - } - /** - * Function iterating over a node's edges using a callback to match one of them. - * - * @param {boolean} multi - Whether the graph is multi or not. - * @param {string} type - Type of edges to retrieve. - * @param {string} direction - In or out? - * @param {any} nodeData - Target node's data. - * @param {function} callback - Function to call. - */ - - - function forEachEdgeForNode(breakable, multi, type, direction, nodeData, callback) { - var fn = multi ? forEachMulti : forEachSimple; - var found; - - if (type !== 'undirected') { - if (direction !== 'out') { - found = fn(breakable, nodeData["in"], callback); - if (breakable && found) return found; - } - - if (direction !== 'in') { - found = fn(breakable, nodeData.out, callback, !direction ? nodeData.key : undefined); - if (breakable && found) return found; - } - } - - if (type !== 'directed') { - found = fn(breakable, nodeData.undirected, callback); - if (breakable && found) return found; - } - - return; - } - /** - * Function creating an array of edges for the given type & the given node. - * - * @param {boolean} multi - Whether the graph is multi or not. - * @param {string} type - Type of edges to retrieve. - * @param {string} direction - In or out? - * @param {any} nodeData - Target node's data. - * @return {array} - Array of edges. - */ - - - function createEdgeArrayForNode(multi, type, direction, nodeData) { - var edges = []; // TODO: possibility to know size beforehand or factorize with map - - forEachEdgeForNode(false, multi, type, direction, nodeData, function (key) { - edges.push(key); - }); - return edges; - } - /** - * Function iterating over a node's edges using a callback. - * - * @param {string} type - Type of edges to retrieve. - * @param {string} direction - In or out? - * @param {any} nodeData - Target node's data. - * @return {Iterator} - */ - - - function createEdgeIteratorForNode(type, direction, nodeData) { - var iterator$1 = iterator.empty(); - - if (type !== 'undirected') { - if (direction !== 'out' && typeof nodeData["in"] !== 'undefined') iterator$1 = chain(iterator$1, createIterator(nodeData["in"])); - if (direction !== 'in' && typeof nodeData.out !== 'undefined') iterator$1 = chain(iterator$1, createIterator(nodeData.out, !direction ? nodeData.key : undefined)); - } - - if (type !== 'directed' && typeof nodeData.undirected !== 'undefined') { - iterator$1 = chain(iterator$1, createIterator(nodeData.undirected)); - } - - return iterator$1; - } - /** - * Function iterating over edges for the given path using a callback to match - * one of them. - * - * @param {string} type - Type of edges to retrieve. - * @param {boolean} multi - Whether the graph is multi. - * @param {string} direction - In or out? - * @param {NodeData} sourceData - Source node's data. - * @param {string} target - Target node. - * @param {function} callback - Function to call. - */ - - - function forEachEdgeForPath(breakable, type, multi, direction, sourceData, target, callback) { - var fn = multi ? forEachForKeyMulti : forEachForKeySimple; - var found; - - if (type !== 'undirected') { - if (typeof sourceData["in"] !== 'undefined' && direction !== 'out') { - found = fn(breakable, sourceData["in"], target, callback); - if (breakable && found) return found; - } - - if (typeof sourceData.out !== 'undefined' && direction !== 'in' && (direction || sourceData.key !== target)) { - found = fn(breakable, sourceData.out, target, callback); - if (breakable && found) return found; - } - } - - if (type !== 'directed') { - if (typeof sourceData.undirected !== 'undefined') { - found = fn(breakable, sourceData.undirected, target, callback); - if (breakable && found) return found; - } - } - - return; - } - /** - * Function creating an array of edges for the given path. - * - * @param {string} type - Type of edges to retrieve. - * @param {boolean} multi - Whether the graph is multi. - * @param {string} direction - In or out? - * @param {NodeData} sourceData - Source node's data. - * @param {any} target - Target node. - * @return {array} - Array of edges. - */ - - - function createEdgeArrayForPath(type, multi, direction, sourceData, target) { - var edges = []; // TODO: possibility to know size beforehand or factorize with map - - forEachEdgeForPath(false, type, multi, direction, sourceData, target, function (key) { - edges.push(key); - }); - return edges; - } - /** - * Function returning an iterator over edges for the given path. - * - * @param {string} type - Type of edges to retrieve. - * @param {string} direction - In or out? - * @param {NodeData} sourceData - Source node's data. - * @param {string} target - Target node. - * @param {function} callback - Function to call. - */ - - - function createEdgeIteratorForPath(type, direction, sourceData, target) { - var iterator$1 = iterator.empty(); - - if (type !== 'undirected') { - if (typeof sourceData["in"] !== 'undefined' && direction !== 'out' && target in sourceData["in"]) iterator$1 = chain(iterator$1, createIteratorForKey(sourceData["in"], target)); - if (typeof sourceData.out !== 'undefined' && direction !== 'in' && target in sourceData.out && (direction || sourceData.key !== target)) iterator$1 = chain(iterator$1, createIteratorForKey(sourceData.out, target)); - } - - if (type !== 'directed') { - if (typeof sourceData.undirected !== 'undefined' && target in sourceData.undirected) iterator$1 = chain(iterator$1, createIteratorForKey(sourceData.undirected, target)); - } - - return iterator$1; - } - /** - * Function attaching an edge array creator method to the Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ - - - function attachEdgeArrayCreator(Class, description) { - var name = description.name, - type = description.type, - direction = description.direction; - /** - * Function returning an array of certain edges. - * - * Arity 0: Return all the relevant edges. - * - * Arity 1: Return all of a node's relevant edges. - * @param {any} node - Target node. - * - * Arity 2: Return the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * - * @return {array|number} - The edges or the number of edges. - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - Class.prototype[name] = function (source, target) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return []; - if (!arguments.length) return createEdgeArray(this, type); - - if (arguments.length === 1) { - source = '' + source; - - var nodeData = this._nodes.get(source); - - if (typeof nodeData === 'undefined') throw new NotFoundGraphError("Graph.".concat(name, ": could not find the \"").concat(source, "\" node in the graph.")); // Iterating over a node's edges - - return createEdgeArrayForNode(this.multi, type === 'mixed' ? this.type : type, direction, nodeData); - } - - if (arguments.length === 2) { - source = '' + source; - target = '' + target; - - var sourceData = this._nodes.get(source); - - if (!sourceData) throw new NotFoundGraphError("Graph.".concat(name, ": could not find the \"").concat(source, "\" source node in the graph.")); - if (!this._nodes.has(target)) throw new NotFoundGraphError("Graph.".concat(name, ": could not find the \"").concat(target, "\" target node in the graph.")); // Iterating over the edges between source & target - - return createEdgeArrayForPath(type, this.multi, direction, sourceData, target); - } - - throw new InvalidArgumentsGraphError("Graph.".concat(name, ": too many arguments (expecting 0, 1 or 2 and got ").concat(arguments.length, ").")); - }; - } - /** - * Function attaching a edge callback iterator method to the Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ - - - function attachForEachEdge(Class, description) { - var name = description.name, - type = description.type, - direction = description.direction; - var forEachName = 'forEach' + name[0].toUpperCase() + name.slice(1, -1); - /** - * Function iterating over the graph's relevant edges by applying the given - * callback. - * - * Arity 1: Iterate over all the relevant edges. - * @param {function} callback - Callback to use. - * - * Arity 2: Iterate over all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * Arity 3: Iterate over the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} callback - Callback to use. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - Class.prototype[forEachName] = function (source, target, callback) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return; - - if (arguments.length === 1) { - callback = source; - return forEachEdge(false, this, type, callback); - } - - if (arguments.length === 2) { - source = '' + source; - callback = target; - - var nodeData = this._nodes.get(source); - - if (typeof nodeData === 'undefined') throw new NotFoundGraphError("Graph.".concat(forEachName, ": could not find the \"").concat(source, "\" node in the graph.")); // Iterating over a node's edges - // TODO: maybe attach the sub method to the instance dynamically? - - return forEachEdgeForNode(false, this.multi, type === 'mixed' ? this.type : type, direction, nodeData, callback); - } - - if (arguments.length === 3) { - source = '' + source; - target = '' + target; - - var sourceData = this._nodes.get(source); - - if (!sourceData) throw new NotFoundGraphError("Graph.".concat(forEachName, ": could not find the \"").concat(source, "\" source node in the graph.")); - if (!this._nodes.has(target)) throw new NotFoundGraphError("Graph.".concat(forEachName, ": could not find the \"").concat(target, "\" target node in the graph.")); // Iterating over the edges between source & target - - return forEachEdgeForPath(false, type, this.multi, direction, sourceData, target, callback); - } - - throw new InvalidArgumentsGraphError("Graph.".concat(forEachName, ": too many arguments (expecting 1, 2 or 3 and got ").concat(arguments.length, ").")); - }; - /** - * Function mapping the graph's relevant edges by applying the given - * callback. - * - * Arity 1: Map all the relevant edges. - * @param {function} callback - Callback to use. - * - * Arity 2: Map all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * Arity 3: Map the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} callback - Callback to use. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - - var mapName = 'map' + name[0].toUpperCase() + name.slice(1); - - Class.prototype[mapName] = function () { - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - var result; // We know the result length beforehand - - if (args.length === 0) { - var length = 0; - if (type !== 'directed') length += this.undirectedSize; - if (type !== 'undirected') length += this.directedSize; - result = new Array(length); - var i = 0; - args.push(function (e, ea, s, t, sa, ta, u) { - result[i++] = callback(e, ea, s, t, sa, ta, u); - }); - } // We don't know the result length beforehand - // TODO: we can in some instances of simple graphs, knowing degree - else { - result = []; - args.push(function (e, ea, s, t, sa, ta, u) { - result.push(callback(e, ea, s, t, sa, ta, u)); - }); - } - - this[forEachName].apply(this, args); - return result; - }; - /** - * Function filtering the graph's relevant edges using the provided predicate - * function. - * - * Arity 1: Filter all the relevant edges. - * @param {function} predicate - Predicate to use. - * - * Arity 2: Filter all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} predicate - Predicate to use. - * - * Arity 3: Filter the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} predicate - Predicate to use. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - - var filterName = 'filter' + name[0].toUpperCase() + name.slice(1); - - Class.prototype[filterName] = function () { - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - var result = []; - args.push(function (e, ea, s, t, sa, ta, u) { - if (callback(e, ea, s, t, sa, ta, u)) result.push(e); - }); - this[forEachName].apply(this, args); - return result; - }; - /** - * Function reducing the graph's relevant edges using the provided accumulator - * function. - * - * Arity 1: Reduce all the relevant edges. - * @param {function} accumulator - Accumulator to use. - * @param {any} initialValue - Initial value. - * - * Arity 2: Reduce all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} accumulator - Accumulator to use. - * @param {any} initialValue - Initial value. - * - * Arity 3: Reduce the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} accumulator - Accumulator to use. - * @param {any} initialValue - Initial value. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - - var reduceName = 'reduce' + name[0].toUpperCase() + name.slice(1); - - Class.prototype[reduceName] = function () { - var args = Array.prototype.slice.call(arguments); - - if (args.length < 2 || args.length > 4) { - throw new InvalidArgumentsGraphError("Graph.".concat(reduceName, ": invalid number of arguments (expecting 2, 3 or 4 and got ").concat(args.length, ").")); - } - - if (typeof args[args.length - 1] === 'function' && typeof args[args.length - 2] !== 'function') { - throw new InvalidArgumentsGraphError("Graph.".concat(reduceName, ": missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.")); - } - - var callback; - var initialValue; - - if (args.length === 2) { - callback = args[0]; - initialValue = args[1]; - args = []; - } else if (args.length === 3) { - callback = args[1]; - initialValue = args[2]; - args = [args[0]]; - } else if (args.length === 4) { - callback = args[2]; - initialValue = args[3]; - args = [args[0], args[1]]; - } - - var accumulator = initialValue; - args.push(function (e, ea, s, t, sa, ta, u) { - accumulator = callback(accumulator, e, ea, s, t, sa, ta, u); - }); - this[forEachName].apply(this, args); - return accumulator; - }; - } - /** - * Function attaching a breakable edge callback iterator method to the Graph - * prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ - - - function attachFindEdge(Class, description) { - var name = description.name, - type = description.type, - direction = description.direction; - var findEdgeName = 'find' + name[0].toUpperCase() + name.slice(1, -1); - /** - * Function iterating over the graph's relevant edges in order to match - * one of them using the provided predicate function. - * - * Arity 1: Iterate over all the relevant edges. - * @param {function} callback - Callback to use. - * - * Arity 2: Iterate over all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * Arity 3: Iterate over the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} callback - Callback to use. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - Class.prototype[findEdgeName] = function (source, target, callback) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return false; - - if (arguments.length === 1) { - callback = source; - return forEachEdge(true, this, type, callback); - } - - if (arguments.length === 2) { - source = '' + source; - callback = target; - - var nodeData = this._nodes.get(source); - - if (typeof nodeData === 'undefined') throw new NotFoundGraphError("Graph.".concat(findEdgeName, ": could not find the \"").concat(source, "\" node in the graph.")); // Iterating over a node's edges - // TODO: maybe attach the sub method to the instance dynamically? - - return forEachEdgeForNode(true, this.multi, type === 'mixed' ? this.type : type, direction, nodeData, callback); - } - - if (arguments.length === 3) { - source = '' + source; - target = '' + target; - - var sourceData = this._nodes.get(source); - - if (!sourceData) throw new NotFoundGraphError("Graph.".concat(findEdgeName, ": could not find the \"").concat(source, "\" source node in the graph.")); - if (!this._nodes.has(target)) throw new NotFoundGraphError("Graph.".concat(findEdgeName, ": could not find the \"").concat(target, "\" target node in the graph.")); // Iterating over the edges between source & target - - return forEachEdgeForPath(true, type, this.multi, direction, sourceData, target, callback); - } - - throw new InvalidArgumentsGraphError("Graph.".concat(findEdgeName, ": too many arguments (expecting 1, 2 or 3 and got ").concat(arguments.length, ").")); - }; - /** - * Function iterating over the graph's relevant edges in order to assert - * whether any one of them matches the provided predicate function. - * - * Arity 1: Iterate over all the relevant edges. - * @param {function} callback - Callback to use. - * - * Arity 2: Iterate over all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * Arity 3: Iterate over the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} callback - Callback to use. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - - var someName = 'some' + name[0].toUpperCase() + name.slice(1, -1); - - Class.prototype[someName] = function () { - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - args.push(function (e, ea, s, t, sa, ta, u) { - return callback(e, ea, s, t, sa, ta, u); - }); - var found = this[findEdgeName].apply(this, args); - if (found) return true; - return false; - }; - /** - * Function iterating over the graph's relevant edges in order to assert - * whether all of them matche the provided predicate function. - * - * Arity 1: Iterate over all the relevant edges. - * @param {function} callback - Callback to use. - * - * Arity 2: Iterate over all of a node's relevant edges. - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * Arity 3: Iterate over the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * @param {function} callback - Callback to use. - * - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - - var everyName = 'every' + name[0].toUpperCase() + name.slice(1, -1); - - Class.prototype[everyName] = function () { - var args = Array.prototype.slice.call(arguments); - var callback = args.pop(); - args.push(function (e, ea, s, t, sa, ta, u) { - return !callback(e, ea, s, t, sa, ta, u); - }); - var found = this[findEdgeName].apply(this, args); - if (found) return false; - return true; - }; - } - /** - * Function attaching an edge iterator method to the Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ - - - function attachEdgeIteratorCreator(Class, description) { - var originalName = description.name, - type = description.type, - direction = description.direction; - var name = originalName.slice(0, -1) + 'Entries'; - /** - * Function returning an iterator over the graph's edges. - * - * Arity 0: Iterate over all the relevant edges. - * - * Arity 1: Iterate over all of a node's relevant edges. - * @param {any} node - Target node. - * - * Arity 2: Iterate over the relevant edges across the given path. - * @param {any} source - Source node. - * @param {any} target - Target node. - * - * @return {array|number} - The edges or the number of edges. - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - Class.prototype[name] = function (source, target) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return iterator.empty(); - if (!arguments.length) return createEdgeIterator(this, type); - - if (arguments.length === 1) { - source = '' + source; - - var sourceData = this._nodes.get(source); - - if (!sourceData) throw new NotFoundGraphError("Graph.".concat(name, ": could not find the \"").concat(source, "\" node in the graph.")); // Iterating over a node's edges - - return createEdgeIteratorForNode(type, direction, sourceData); - } - - if (arguments.length === 2) { - source = '' + source; - target = '' + target; - - var _sourceData = this._nodes.get(source); - - if (!_sourceData) throw new NotFoundGraphError("Graph.".concat(name, ": could not find the \"").concat(source, "\" source node in the graph.")); - if (!this._nodes.has(target)) throw new NotFoundGraphError("Graph.".concat(name, ": could not find the \"").concat(target, "\" target node in the graph.")); // Iterating over the edges between source & target - - return createEdgeIteratorForPath(type, direction, _sourceData, target); - } - - throw new InvalidArgumentsGraphError("Graph.".concat(name, ": too many arguments (expecting 0, 1 or 2 and got ").concat(arguments.length, ").")); - }; - } - /** - * Function attaching every edge iteration method to the Graph class. - * - * @param {function} Graph - Graph class. - */ - - - function attachEdgeIterationMethods(Graph) { - EDGES_ITERATION.forEach(function (description) { - attachEdgeArrayCreator(Graph, description); - attachForEachEdge(Graph, description); - attachFindEdge(Graph, description); - attachEdgeIteratorCreator(Graph, description); - }); - } - - /** - * Graphology Neighbor Iteration - * ============================== - * - * Attaching some methods to the Graph class to be able to iterate over - * neighbors. - */ - /** - * Definitions. - */ - - var NEIGHBORS_ITERATION = [{ - name: 'neighbors', - type: 'mixed' - }, { - name: 'inNeighbors', - type: 'directed', - direction: 'in' - }, { - name: 'outNeighbors', - type: 'directed', - direction: 'out' - }, { - name: 'inboundNeighbors', - type: 'mixed', - direction: 'in' - }, { - name: 'outboundNeighbors', - type: 'mixed', - direction: 'out' - }, { - name: 'directedNeighbors', - type: 'directed' - }, { - name: 'undirectedNeighbors', - type: 'undirected' - }]; - /** - * Helpers. - */ - - function CompositeSetWrapper() { - this.A = null; - this.B = null; - } - - CompositeSetWrapper.prototype.wrap = function (set) { - if (this.A === null) this.A = set;else if (this.B === null) this.B = set; - }; - - CompositeSetWrapper.prototype.has = function (key) { - if (this.A !== null && key in this.A) return true; - if (this.B !== null && key in this.B) return true; - return false; - }; - /** - * Function iterating over the given node's relevant neighbors to match - * one of them using a predicated function. - * - * @param {string} type - Type of neighbors. - * @param {string} direction - Direction. - * @param {any} nodeData - Target node's data. - * @param {function} callback - Callback to use. - */ - - - function forEachInObjectOnce(breakable, visited, nodeData, object, callback) { - for (var k in object) { - var edgeData = object[k]; - var sourceData = edgeData.source; - var targetData = edgeData.target; - var neighborData = sourceData === nodeData ? targetData : sourceData; - if (visited && visited.has(neighborData.key)) continue; - var shouldBreak = callback(neighborData.key, neighborData.attributes); - if (breakable && shouldBreak) return neighborData.key; - } - - return; - } - - function forEachNeighbor(breakable, type, direction, nodeData, callback) { - // If we want only undirected or in or out, we can roll some optimizations - if (type !== 'mixed') { - if (type === 'undirected') return forEachInObjectOnce(breakable, null, nodeData, nodeData.undirected, callback); - if (typeof direction === 'string') return forEachInObjectOnce(breakable, null, nodeData, nodeData[direction], callback); - } // Else we need to keep a set of neighbors not to return duplicates - // We cheat by querying the other adjacencies - - - var visited = new CompositeSetWrapper(); - var found; - - if (type !== 'undirected') { - if (direction !== 'out') { - found = forEachInObjectOnce(breakable, null, nodeData, nodeData["in"], callback); - if (breakable && found) return found; - visited.wrap(nodeData["in"]); - } - - if (direction !== 'in') { - found = forEachInObjectOnce(breakable, visited, nodeData, nodeData.out, callback); - if (breakable && found) return found; - visited.wrap(nodeData.out); - } - } - - if (type !== 'directed') { - found = forEachInObjectOnce(breakable, visited, nodeData, nodeData.undirected, callback); - if (breakable && found) return found; - } - - return; - } - /** - * Function creating an array of relevant neighbors for the given node. - * - * @param {string} type - Type of neighbors. - * @param {string} direction - Direction. - * @param {any} nodeData - Target node's data. - * @return {Array} - The list of neighbors. - */ - - - function createNeighborArrayForNode(type, direction, nodeData) { - // If we want only undirected or in or out, we can roll some optimizations - if (type !== 'mixed') { - if (type === 'undirected') return Object.keys(nodeData.undirected); - if (typeof direction === 'string') return Object.keys(nodeData[direction]); - } - - var neighbors = []; - forEachNeighbor(false, type, direction, nodeData, function (key) { - neighbors.push(key); - }); - return neighbors; - } - /** - * Function returning an iterator over the given node's relevant neighbors. - * - * @param {string} type - Type of neighbors. - * @param {string} direction - Direction. - * @param {any} nodeData - Target node's data. - * @return {Iterator} - */ - - - function createDedupedObjectIterator(visited, nodeData, object) { - var keys = Object.keys(object); - var l = keys.length; - var i = 0; - return new iterator(function next() { - var neighborData = null; - - do { - if (i >= l) { - if (visited) visited.wrap(object); - return { - done: true - }; - } - - var edgeData = object[keys[i++]]; - var sourceData = edgeData.source; - var targetData = edgeData.target; - neighborData = sourceData === nodeData ? targetData : sourceData; - - if (visited && visited.has(neighborData.key)) { - neighborData = null; - continue; - } - } while (neighborData === null); - - return { - done: false, - value: { - neighbor: neighborData.key, - attributes: neighborData.attributes - } - }; - }); - } - - function createNeighborIterator(type, direction, nodeData) { - // If we want only undirected or in or out, we can roll some optimizations - if (type !== 'mixed') { - if (type === 'undirected') return createDedupedObjectIterator(null, nodeData, nodeData.undirected); - if (typeof direction === 'string') return createDedupedObjectIterator(null, nodeData, nodeData[direction]); - } - - var iterator$1 = iterator.empty(); // Else we need to keep a set of neighbors not to return duplicates - // We cheat by querying the other adjacencies - - var visited = new CompositeSetWrapper(); - - if (type !== 'undirected') { - if (direction !== 'out') { - iterator$1 = chain(iterator$1, createDedupedObjectIterator(visited, nodeData, nodeData["in"])); - } - - if (direction !== 'in') { - iterator$1 = chain(iterator$1, createDedupedObjectIterator(visited, nodeData, nodeData.out)); - } - } - - if (type !== 'directed') { - iterator$1 = chain(iterator$1, createDedupedObjectIterator(visited, nodeData, nodeData.undirected)); - } - - return iterator$1; - } - /** - * Function attaching a neighbors array creator method to the Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ - - - function attachNeighborArrayCreator(Class, description) { - var name = description.name, - type = description.type, - direction = description.direction; - /** - * Function returning an array of certain neighbors. - * - * @param {any} node - Target node. - * @return {array} - The neighbors of neighbors. - * - * @throws {Error} - Will throw if node is not found in the graph. - */ - - Class.prototype[name] = function (node) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return []; - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (typeof nodeData === 'undefined') throw new NotFoundGraphError("Graph.".concat(name, ": could not find the \"").concat(node, "\" node in the graph.")); // Here, we want to iterate over a node's relevant neighbors - - return createNeighborArrayForNode(type === 'mixed' ? this.type : type, direction, nodeData); - }; - } - /** - * Function attaching a neighbors callback iterator method to the Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ - - - function attachForEachNeighbor(Class, description) { - var name = description.name, - type = description.type, - direction = description.direction; - var forEachName = 'forEach' + name[0].toUpperCase() + name.slice(1, -1); - /** - * Function iterating over all the relevant neighbors using a callback. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - Class.prototype[forEachName] = function (node, callback) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return; - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (typeof nodeData === 'undefined') throw new NotFoundGraphError("Graph.".concat(forEachName, ": could not find the \"").concat(node, "\" node in the graph.")); // Here, we want to iterate over a node's relevant neighbors - - forEachNeighbor(false, type === 'mixed' ? this.type : type, direction, nodeData, callback); - }; - /** - * Function mapping the relevant neighbors using a callback. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - - var mapName = 'map' + name[0].toUpperCase() + name.slice(1); - - Class.prototype[mapName] = function (node, callback) { - // TODO: optimize when size is known beforehand - var result = []; - this[forEachName](node, function (n, a) { - result.push(callback(n, a)); - }); - return result; - }; - /** - * Function filtering the relevant neighbors using a callback. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - - var filterName = 'filter' + name[0].toUpperCase() + name.slice(1); - - Class.prototype[filterName] = function (node, callback) { - var result = []; - this[forEachName](node, function (n, a) { - if (callback(n, a)) result.push(n); - }); - return result; - }; - /** - * Function reducing the relevant neighbors using a callback. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - - var reduceName = 'reduce' + name[0].toUpperCase() + name.slice(1); - - Class.prototype[reduceName] = function (node, callback, initialValue) { - if (arguments.length < 3) throw new InvalidArgumentsGraphError("Graph.".concat(reduceName, ": missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.")); - var accumulator = initialValue; - this[forEachName](node, function (n, a) { - accumulator = callback(accumulator, n, a); - }); - return accumulator; - }; - } - /** - * Function attaching a breakable neighbors callback iterator method to the - * Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ - - - function attachFindNeighbor(Class, description) { - var name = description.name, - type = description.type, - direction = description.direction; - var capitalizedSingular = name[0].toUpperCase() + name.slice(1, -1); - var findName = 'find' + capitalizedSingular; - /** - * Function iterating over all the relevant neighbors using a callback. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * @return {undefined} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - Class.prototype[findName] = function (node, callback) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return; - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (typeof nodeData === 'undefined') throw new NotFoundGraphError("Graph.".concat(findName, ": could not find the \"").concat(node, "\" node in the graph.")); // Here, we want to iterate over a node's relevant neighbors - - return forEachNeighbor(true, type === 'mixed' ? this.type : type, direction, nodeData, callback); - }; - /** - * Function iterating over all the relevant neighbors to find if any of them - * matches the given predicate. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * @return {boolean} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - - var someName = 'some' + capitalizedSingular; - - Class.prototype[someName] = function (node, callback) { - var found = this[findName](node, callback); - if (found) return true; - return false; - }; - /** - * Function iterating over all the relevant neighbors to find if all of them - * matche the given predicate. - * - * @param {any} node - Target node. - * @param {function} callback - Callback to use. - * @return {boolean} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - - var everyName = 'every' + capitalizedSingular; - - Class.prototype[everyName] = function (node, callback) { - var found = this[findName](node, function (n, a) { - return !callback(n, a); - }); - if (found) return false; - return true; - }; - } - /** - * Function attaching a neighbors callback iterator method to the Graph prototype. - * - * @param {function} Class - Target class. - * @param {object} description - Method description. - */ - - - function attachNeighborIteratorCreator(Class, description) { - var name = description.name, - type = description.type, - direction = description.direction; - var iteratorName = name.slice(0, -1) + 'Entries'; - /** - * Function returning an iterator over all the relevant neighbors. - * - * @param {any} node - Target node. - * @return {Iterator} - * - * @throws {Error} - Will throw if there are too many arguments. - */ - - Class.prototype[iteratorName] = function (node) { - // Early termination - if (type !== 'mixed' && this.type !== 'mixed' && type !== this.type) return iterator.empty(); - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (typeof nodeData === 'undefined') throw new NotFoundGraphError("Graph.".concat(iteratorName, ": could not find the \"").concat(node, "\" node in the graph.")); // Here, we want to iterate over a node's relevant neighbors - - return createNeighborIterator(type === 'mixed' ? this.type : type, direction, nodeData); - }; - } - /** - * Function attaching every neighbor iteration method to the Graph class. - * - * @param {function} Graph - Graph class. - */ - - - function attachNeighborIterationMethods(Graph) { - NEIGHBORS_ITERATION.forEach(function (description) { - attachNeighborArrayCreator(Graph, description); - attachForEachNeighbor(Graph, description); - attachFindNeighbor(Graph, description); - attachNeighborIteratorCreator(Graph, description); - }); - } - - /** - * Graphology Adjacency Iteration - * =============================== - * - * Attaching some methods to the Graph class to be able to iterate over a - * graph's adjacency. - */ - - /** - * Function iterating over a simple graph's adjacency using a callback. - * - * @param {boolean} breakable - Can we break? - * @param {boolean} assymetric - Whether to emit undirected edges only once. - * @param {boolean} disconnectedNodes - Whether to emit disconnected nodes. - * @param {Graph} graph - Target Graph instance. - * @param {callback} function - Iteration callback. - */ - function forEachAdjacency(breakable, assymetric, disconnectedNodes, graph, callback) { - var iterator = graph._nodes.values(); - - var type = graph.type; - var step, sourceData, neighbor, adj, edgeData, targetData, shouldBreak; - - while (step = iterator.next(), step.done !== true) { - var hasEdges = false; - sourceData = step.value; - - if (type !== 'undirected') { - adj = sourceData.out; - - for (neighbor in adj) { - edgeData = adj[neighbor]; - - do { - targetData = edgeData.target; - hasEdges = true; - shouldBreak = callback(sourceData.key, targetData.key, sourceData.attributes, targetData.attributes, edgeData.key, edgeData.attributes, edgeData.undirected); - if (breakable && shouldBreak) return edgeData; - edgeData = edgeData.next; - } while (edgeData); - } - } - - if (type !== 'directed') { - adj = sourceData.undirected; - - for (neighbor in adj) { - if (assymetric && sourceData.key > neighbor) continue; - edgeData = adj[neighbor]; - - do { - targetData = edgeData.target; - if (targetData.key !== neighbor) targetData = edgeData.source; - hasEdges = true; - shouldBreak = callback(sourceData.key, targetData.key, sourceData.attributes, targetData.attributes, edgeData.key, edgeData.attributes, edgeData.undirected); - if (breakable && shouldBreak) return edgeData; - edgeData = edgeData.next; - } while (edgeData); - } - } - - if (disconnectedNodes && !hasEdges) { - shouldBreak = callback(sourceData.key, null, sourceData.attributes, null, null, null, null); - if (breakable && shouldBreak) return null; - } - } - - return; - } - - /** - * Graphology Serialization Utilities - * =================================== - * - * Collection of functions used by the graph serialization schemes. - */ - /** - * Formats internal node data into a serialized node. - * - * @param {any} key - The node's key. - * @param {object} data - Internal node's data. - * @return {array} - The serialized node. - */ - - function serializeNode(key, data) { - var serialized = { - key: key - }; - if (!isEmpty(data.attributes)) serialized.attributes = assign({}, data.attributes); - return serialized; - } - /** - * Formats internal edge data into a serialized edge. - * - * @param {any} key - The edge's key. - * @param {object} data - Internal edge's data. - * @return {array} - The serialized edge. - */ - - function serializeEdge(key, data) { - var serialized = { - key: key, - source: data.source.key, - target: data.target.key - }; - if (!isEmpty(data.attributes)) serialized.attributes = assign({}, data.attributes); - if (data.undirected) serialized.undirected = true; - return serialized; - } - /** - * Checks whether the given value is a serialized node. - * - * @param {mixed} value - Target value. - * @return {string|null} - */ - - function validateSerializedNode(value) { - if (!isPlainObject(value)) throw new InvalidArgumentsGraphError('Graph.import: invalid serialized node. A serialized node should be a plain object with at least a "key" property.'); - if (!('key' in value)) throw new InvalidArgumentsGraphError('Graph.import: serialized node is missing its key.'); - if ('attributes' in value && (!isPlainObject(value.attributes) || value.attributes === null)) throw new InvalidArgumentsGraphError('Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.'); - } - /** - * Checks whether the given value is a serialized edge. - * - * @param {mixed} value - Target value. - * @return {string|null} - */ - - function validateSerializedEdge(value) { - if (!isPlainObject(value)) throw new InvalidArgumentsGraphError('Graph.import: invalid serialized edge. A serialized edge should be a plain object with at least a "source" & "target" property.'); - if (!('source' in value)) throw new InvalidArgumentsGraphError('Graph.import: serialized edge is missing its source.'); - if (!('target' in value)) throw new InvalidArgumentsGraphError('Graph.import: serialized edge is missing its target.'); - if ('attributes' in value && (!isPlainObject(value.attributes) || value.attributes === null)) throw new InvalidArgumentsGraphError('Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.'); - if ('undirected' in value && typeof value.undirected !== 'boolean') throw new InvalidArgumentsGraphError('Graph.import: invalid undirectedness information. Undirected should be boolean or omitted.'); - } - - /** - * Constants. - */ - - var INSTANCE_ID = incrementalIdStartingFromRandomByte(); - /** - * Enums. - */ - - var TYPES = new Set(['directed', 'undirected', 'mixed']); - var EMITTER_PROPS = new Set(['domain', '_events', '_eventsCount', '_maxListeners']); - var EDGE_ADD_METHODS = [{ - name: function name(verb) { - return "".concat(verb, "Edge"); - }, - generateKey: true - }, { - name: function name(verb) { - return "".concat(verb, "DirectedEdge"); - }, - generateKey: true, - type: 'directed' - }, { - name: function name(verb) { - return "".concat(verb, "UndirectedEdge"); - }, - generateKey: true, - type: 'undirected' - }, { - name: function name(verb) { - return "".concat(verb, "EdgeWithKey"); - } - }, { - name: function name(verb) { - return "".concat(verb, "DirectedEdgeWithKey"); - }, - type: 'directed' - }, { - name: function name(verb) { - return "".concat(verb, "UndirectedEdgeWithKey"); - }, - type: 'undirected' - }]; - /** - * Default options. - */ - - var DEFAULTS = { - allowSelfLoops: true, - multi: false, - type: 'mixed' - }; - /** - * Abstract functions used by the Graph class for various methods. - */ - - /** - * Internal method used to add a node to the given graph - * - * @param {Graph} graph - Target graph. - * @param {any} node - The node's key. - * @param {object} [attributes] - Optional attributes. - * @return {NodeData} - Created node data. - */ - - function _addNode(graph, node, attributes) { - if (attributes && !isPlainObject(attributes)) throw new InvalidArgumentsGraphError("Graph.addNode: invalid attributes. Expecting an object but got \"".concat(attributes, "\"")); // String coercion - - node = '' + node; - attributes = attributes || {}; - if (graph._nodes.has(node)) throw new UsageGraphError("Graph.addNode: the \"".concat(node, "\" node already exist in the graph.")); - var data = new graph.NodeDataClass(node, attributes); // Adding the node to internal register - - graph._nodes.set(node, data); // Emitting - - - graph.emit('nodeAdded', { - key: node, - attributes: attributes - }); - return data; - } - /** - * Same as the above but without sanity checks because we call this in contexts - * where necessary checks were already done. - */ - - - function unsafeAddNode(graph, node, attributes) { - var data = new graph.NodeDataClass(node, attributes); - - graph._nodes.set(node, data); - - graph.emit('nodeAdded', { - key: node, - attributes: attributes - }); - return data; - } - /** - * Internal method used to add an arbitrary edge to the given graph. - * - * @param {Graph} graph - Target graph. - * @param {string} name - Name of the child method for errors. - * @param {boolean} mustGenerateKey - Should the graph generate an id? - * @param {boolean} undirected - Whether the edge is undirected. - * @param {any} edge - The edge's key. - * @param {any} source - The source node. - * @param {any} target - The target node. - * @param {object} [attributes] - Optional attributes. - * @return {any} - The edge. - * - * @throws {Error} - Will throw if the graph is of the wrong type. - * @throws {Error} - Will throw if the given attributes are not an object. - * @throws {Error} - Will throw if source or target doesn't exist. - * @throws {Error} - Will throw if the edge already exist. - */ - - - function addEdge(graph, name, mustGenerateKey, undirected, edge, source, target, attributes) { - // Checking validity of operation - if (!undirected && graph.type === 'undirected') throw new UsageGraphError("Graph.".concat(name, ": you cannot add a directed edge to an undirected graph. Use the #.addEdge or #.addUndirectedEdge instead.")); - if (undirected && graph.type === 'directed') throw new UsageGraphError("Graph.".concat(name, ": you cannot add an undirected edge to a directed graph. Use the #.addEdge or #.addDirectedEdge instead.")); - if (attributes && !isPlainObject(attributes)) throw new InvalidArgumentsGraphError("Graph.".concat(name, ": invalid attributes. Expecting an object but got \"").concat(attributes, "\"")); // Coercion of source & target: - - source = '' + source; - target = '' + target; - attributes = attributes || {}; - if (!graph.allowSelfLoops && source === target) throw new UsageGraphError("Graph.".concat(name, ": source & target are the same (\"").concat(source, "\"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.")); - - var sourceData = graph._nodes.get(source), - targetData = graph._nodes.get(target); - - if (!sourceData) throw new NotFoundGraphError("Graph.".concat(name, ": source node \"").concat(source, "\" not found.")); - if (!targetData) throw new NotFoundGraphError("Graph.".concat(name, ": target node \"").concat(target, "\" not found.")); // Must the graph generate an id for this edge? - - var eventData = { - key: null, - undirected: undirected, - source: source, - target: target, - attributes: attributes - }; - - if (mustGenerateKey) { - // NOTE: in this case we can guarantee that the key does not already - // exist and is already correctly casted as a string - edge = graph._edgeKeyGenerator(); - } else { - // Coercion of edge key - edge = '' + edge; // Here, we have a key collision - - if (graph._edges.has(edge)) throw new UsageGraphError("Graph.".concat(name, ": the \"").concat(edge, "\" edge already exists in the graph.")); - } // Here, we might have a source / target collision - - - if (!graph.multi && (undirected ? typeof sourceData.undirected[target] !== 'undefined' : typeof sourceData.out[target] !== 'undefined')) { - throw new UsageGraphError("Graph.".concat(name, ": an edge linking \"").concat(source, "\" to \"").concat(target, "\" already exists. If you really want to add multiple edges linking those nodes, you should create a multi graph by using the 'multi' option.")); - } // Storing some data - - - var edgeData = new EdgeData(undirected, edge, sourceData, targetData, attributes); // Adding the edge to the internal register - - graph._edges.set(edge, edgeData); // Incrementing node degree counters - - - var isSelfLoop = source === target; - - if (undirected) { - sourceData.undirectedDegree++; - targetData.undirectedDegree++; - if (isSelfLoop) graph._undirectedSelfLoopCount++; - } else { - sourceData.outDegree++; - targetData.inDegree++; - if (isSelfLoop) graph._directedSelfLoopCount++; - } // Updating relevant index - - - if (graph.multi) edgeData.attachMulti();else edgeData.attach(); - if (undirected) graph._undirectedSize++;else graph._directedSize++; // Emitting - - eventData.key = edge; - graph.emit('edgeAdded', eventData); - return edge; - } - /** - * Internal method used to add an arbitrary edge to the given graph. - * - * @param {Graph} graph - Target graph. - * @param {string} name - Name of the child method for errors. - * @param {boolean} mustGenerateKey - Should the graph generate an id? - * @param {boolean} undirected - Whether the edge is undirected. - * @param {any} edge - The edge's key. - * @param {any} source - The source node. - * @param {any} target - The target node. - * @param {object} [attributes] - Optional attributes. - * @param {boolean} [asUpdater] - Are we updating or merging? - * @return {any} - The edge. - * - * @throws {Error} - Will throw if the graph is of the wrong type. - * @throws {Error} - Will throw if the given attributes are not an object. - * @throws {Error} - Will throw if source or target doesn't exist. - * @throws {Error} - Will throw if the edge already exist. - */ - - - function mergeEdge(graph, name, mustGenerateKey, undirected, edge, source, target, attributes, asUpdater) { - // Checking validity of operation - if (!undirected && graph.type === 'undirected') throw new UsageGraphError("Graph.".concat(name, ": you cannot merge/update a directed edge to an undirected graph. Use the #.mergeEdge/#.updateEdge or #.addUndirectedEdge instead.")); - if (undirected && graph.type === 'directed') throw new UsageGraphError("Graph.".concat(name, ": you cannot merge/update an undirected edge to a directed graph. Use the #.mergeEdge/#.updateEdge or #.addDirectedEdge instead.")); - - if (attributes) { - if (asUpdater) { - if (typeof attributes !== 'function') throw new InvalidArgumentsGraphError("Graph.".concat(name, ": invalid updater function. Expecting a function but got \"").concat(attributes, "\"")); - } else { - if (!isPlainObject(attributes)) throw new InvalidArgumentsGraphError("Graph.".concat(name, ": invalid attributes. Expecting an object but got \"").concat(attributes, "\"")); - } - } // Coercion of source & target: - - - source = '' + source; - target = '' + target; - var updater; - - if (asUpdater) { - updater = attributes; - attributes = undefined; - } - - if (!graph.allowSelfLoops && source === target) throw new UsageGraphError("Graph.".concat(name, ": source & target are the same (\"").concat(source, "\"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false.")); - - var sourceData = graph._nodes.get(source); - - var targetData = graph._nodes.get(target); - - var edgeData; // Do we need to handle duplicate? - - var alreadyExistingEdgeData; - - if (!mustGenerateKey) { - edgeData = graph._edges.get(edge); - - if (edgeData) { - // Here, we need to ensure, if the user gave a key, that source & target - // are consistent - if (edgeData.source.key !== source || edgeData.target.key !== target) { - // If source or target inconsistent - if (!undirected || edgeData.source.key !== target || edgeData.target.key !== source) { - // If directed, or source/target aren't flipped - throw new UsageGraphError("Graph.".concat(name, ": inconsistency detected when attempting to merge the \"").concat(edge, "\" edge with \"").concat(source, "\" source & \"").concat(target, "\" target vs. (\"").concat(edgeData.source.key, "\", \"").concat(edgeData.target.key, "\").")); - } - } - - alreadyExistingEdgeData = edgeData; - } - } // Here, we might have a source / target collision - - - if (!alreadyExistingEdgeData && !graph.multi && sourceData) { - alreadyExistingEdgeData = undirected ? sourceData.undirected[target] : sourceData.out[target]; - } // Handling duplicates - - - if (alreadyExistingEdgeData) { - var info = [alreadyExistingEdgeData.key, false, false, false]; // We can skip the attribute merging part if the user did not provide them - - if (asUpdater ? !updater : !attributes) return info; // Updating the attributes - - if (asUpdater) { - var oldAttributes = alreadyExistingEdgeData.attributes; - alreadyExistingEdgeData.attributes = updater(oldAttributes); - graph.emit('edgeAttributesUpdated', { - type: 'replace', - key: alreadyExistingEdgeData.key, - attributes: alreadyExistingEdgeData.attributes - }); - } // Merging the attributes - else { - assign(alreadyExistingEdgeData.attributes, attributes); - graph.emit('edgeAttributesUpdated', { - type: 'merge', - key: alreadyExistingEdgeData.key, - attributes: alreadyExistingEdgeData.attributes, - data: attributes - }); - } - - return info; - } - - attributes = attributes || {}; - if (asUpdater && updater) attributes = updater(attributes); // Must the graph generate an id for this edge? - - var eventData = { - key: null, - undirected: undirected, - source: source, - target: target, - attributes: attributes - }; - - if (mustGenerateKey) { - // NOTE: in this case we can guarantee that the key does not already - // exist and is already correctly casted as a string - edge = graph._edgeKeyGenerator(); - } else { - // Coercion of edge key - edge = '' + edge; // Here, we have a key collision - - if (graph._edges.has(edge)) throw new UsageGraphError("Graph.".concat(name, ": the \"").concat(edge, "\" edge already exists in the graph.")); - } - - var sourceWasAdded = false; - var targetWasAdded = false; - - if (!sourceData) { - sourceData = unsafeAddNode(graph, source, {}); - sourceWasAdded = true; - - if (source === target) { - targetData = sourceData; - targetWasAdded = true; - } - } - - if (!targetData) { - targetData = unsafeAddNode(graph, target, {}); - targetWasAdded = true; - } // Storing some data - - - edgeData = new EdgeData(undirected, edge, sourceData, targetData, attributes); // Adding the edge to the internal register - - graph._edges.set(edge, edgeData); // Incrementing node degree counters - - - var isSelfLoop = source === target; - - if (undirected) { - sourceData.undirectedDegree++; - targetData.undirectedDegree++; - if (isSelfLoop) graph._undirectedSelfLoopCount++; - } else { - sourceData.outDegree++; - targetData.inDegree++; - if (isSelfLoop) graph._directedSelfLoopCount++; - } // Updating relevant index - - - if (graph.multi) edgeData.attachMulti();else edgeData.attach(); - if (undirected) graph._undirectedSize++;else graph._directedSize++; // Emitting - - eventData.key = edge; - graph.emit('edgeAdded', eventData); - return [edge, true, sourceWasAdded, targetWasAdded]; - } - /** - * Internal method used to drop an edge. - * - * @param {Graph} graph - Target graph. - * @param {EdgeData} edgeData - Data of the edge to drop. - */ - - - function dropEdgeFromData(graph, edgeData) { - // Dropping the edge from the register - graph._edges["delete"](edgeData.key); // Updating related degrees - - - var sourceData = edgeData.source, - targetData = edgeData.target, - attributes = edgeData.attributes; - var undirected = edgeData.undirected; - var isSelfLoop = sourceData === targetData; - - if (undirected) { - sourceData.undirectedDegree--; - targetData.undirectedDegree--; - if (isSelfLoop) graph._undirectedSelfLoopCount--; - } else { - sourceData.outDegree--; - targetData.inDegree--; - if (isSelfLoop) graph._directedSelfLoopCount--; - } // Clearing index - - - if (graph.multi) edgeData.detachMulti();else edgeData.detach(); - if (undirected) graph._undirectedSize--;else graph._directedSize--; // Emitting - - graph.emit('edgeDropped', { - key: edgeData.key, - attributes: attributes, - source: sourceData.key, - target: targetData.key, - undirected: undirected - }); - } - /** - * Graph class - * - * @constructor - * @param {object} [options] - Options: - * @param {boolean} [allowSelfLoops] - Allow self loops? - * @param {string} [type] - Type of the graph. - * @param {boolean} [map] - Allow references as keys? - * @param {boolean} [multi] - Allow parallel edges? - * - * @throws {Error} - Will throw if the arguments are not valid. - */ - - - var Graph = /*#__PURE__*/function (_EventEmitter) { - _inheritsLoose(Graph, _EventEmitter); - - function Graph(options) { - var _this; - - _this = _EventEmitter.call(this) || this; //-- Solving options - - options = assign({}, DEFAULTS, options); // Enforcing options validity - - if (typeof options.multi !== 'boolean') throw new InvalidArgumentsGraphError("Graph.constructor: invalid 'multi' option. Expecting a boolean but got \"".concat(options.multi, "\".")); - if (!TYPES.has(options.type)) throw new InvalidArgumentsGraphError("Graph.constructor: invalid 'type' option. Should be one of \"mixed\", \"directed\" or \"undirected\" but got \"".concat(options.type, "\".")); - if (typeof options.allowSelfLoops !== 'boolean') throw new InvalidArgumentsGraphError("Graph.constructor: invalid 'allowSelfLoops' option. Expecting a boolean but got \"".concat(options.allowSelfLoops, "\".")); //-- Private properties - // Utilities - - var NodeDataClass = options.type === 'mixed' ? MixedNodeData : options.type === 'directed' ? DirectedNodeData : UndirectedNodeData; - privateProperty(_assertThisInitialized(_this), 'NodeDataClass', NodeDataClass); // Internal edge key generator - // NOTE: this internal generator produce keys that are strings - // composed of a weird prefix, an incremental instance id starting from - // a random byte and finally an internal instance incremental id. - // All this to avoid intra-frame and cross-frame adversarial inputs - // that can force a single #.addEdge call to degenerate into a O(n) - // available key search loop. - // It also ensures that automatically generated edge keys are unlikely - // to produce collisions with arbitrary keys given by users. - - var instancePrefix = 'geid_' + INSTANCE_ID() + '_'; - var edgeId = 0; - - var edgeKeyGenerator = function edgeKeyGenerator() { - var availableEdgeKey; - - do { - availableEdgeKey = instancePrefix + edgeId++; - } while (_this._edges.has(availableEdgeKey)); - - return availableEdgeKey; - }; // Indexes - - - privateProperty(_assertThisInitialized(_this), '_attributes', {}); - privateProperty(_assertThisInitialized(_this), '_nodes', new Map()); - privateProperty(_assertThisInitialized(_this), '_edges', new Map()); - privateProperty(_assertThisInitialized(_this), '_directedSize', 0); - privateProperty(_assertThisInitialized(_this), '_undirectedSize', 0); - privateProperty(_assertThisInitialized(_this), '_directedSelfLoopCount', 0); - privateProperty(_assertThisInitialized(_this), '_undirectedSelfLoopCount', 0); - privateProperty(_assertThisInitialized(_this), '_edgeKeyGenerator', edgeKeyGenerator); // Options - - privateProperty(_assertThisInitialized(_this), '_options', options); // Emitter properties - - EMITTER_PROPS.forEach(function (prop) { - return privateProperty(_assertThisInitialized(_this), prop, _this[prop]); - }); //-- Properties readers - - readOnlyProperty(_assertThisInitialized(_this), 'order', function () { - return _this._nodes.size; - }); - readOnlyProperty(_assertThisInitialized(_this), 'size', function () { - return _this._edges.size; - }); - readOnlyProperty(_assertThisInitialized(_this), 'directedSize', function () { - return _this._directedSize; - }); - readOnlyProperty(_assertThisInitialized(_this), 'undirectedSize', function () { - return _this._undirectedSize; - }); - readOnlyProperty(_assertThisInitialized(_this), 'selfLoopCount', function () { - return _this._directedSelfLoopCount + _this._undirectedSelfLoopCount; - }); - readOnlyProperty(_assertThisInitialized(_this), 'directedSelfLoopCount', function () { - return _this._directedSelfLoopCount; - }); - readOnlyProperty(_assertThisInitialized(_this), 'undirectedSelfLoopCount', function () { - return _this._undirectedSelfLoopCount; - }); - readOnlyProperty(_assertThisInitialized(_this), 'multi', _this._options.multi); - readOnlyProperty(_assertThisInitialized(_this), 'type', _this._options.type); - readOnlyProperty(_assertThisInitialized(_this), 'allowSelfLoops', _this._options.allowSelfLoops); - readOnlyProperty(_assertThisInitialized(_this), 'implementation', function () { - return 'graphology'; - }); - return _this; - } - - var _proto = Graph.prototype; - - _proto._resetInstanceCounters = function _resetInstanceCounters() { - this._directedSize = 0; - this._undirectedSize = 0; - this._directedSelfLoopCount = 0; - this._undirectedSelfLoopCount = 0; - } - /**--------------------------------------------------------------------------- - * Read - **--------------------------------------------------------------------------- - */ - - /** - * Method returning whether the given node is found in the graph. - * - * @param {any} node - The node. - * @return {boolean} - */ - ; - - _proto.hasNode = function hasNode(node) { - return this._nodes.has('' + node); - } - /** - * Method returning whether the given directed edge is found in the graph. - * - * Arity 1: - * @param {any} edge - The edge's key. - * - * Arity 2: - * @param {any} source - The edge's source. - * @param {any} target - The edge's target. - * - * @return {boolean} - * - * @throws {Error} - Will throw if the arguments are invalid. - */ - ; - - _proto.hasDirectedEdge = function hasDirectedEdge(source, target) { - // Early termination - if (this.type === 'undirected') return false; - - if (arguments.length === 1) { - var edge = '' + source; - - var edgeData = this._edges.get(edge); - - return !!edgeData && !edgeData.undirected; - } else if (arguments.length === 2) { - source = '' + source; - target = '' + target; // If the node source or the target is not in the graph we break - - var nodeData = this._nodes.get(source); - - if (!nodeData) return false; // Is there a directed edge pointing toward target? - - var edges = nodeData.out[target]; - if (!edges) return false; - return this.multi ? !!edges.size : true; - } - - throw new InvalidArgumentsGraphError("Graph.hasDirectedEdge: invalid arity (".concat(arguments.length, ", instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.")); - } - /** - * Method returning whether the given undirected edge is found in the graph. - * - * Arity 1: - * @param {any} edge - The edge's key. - * - * Arity 2: - * @param {any} source - The edge's source. - * @param {any} target - The edge's target. - * - * @return {boolean} - * - * @throws {Error} - Will throw if the arguments are invalid. - */ - ; - - _proto.hasUndirectedEdge = function hasUndirectedEdge(source, target) { - // Early termination - if (this.type === 'directed') return false; - - if (arguments.length === 1) { - var edge = '' + source; - - var edgeData = this._edges.get(edge); - - return !!edgeData && edgeData.undirected; - } else if (arguments.length === 2) { - source = '' + source; - target = '' + target; // If the node source or the target is not in the graph we break - - var nodeData = this._nodes.get(source); - - if (!nodeData) return false; // Is there a directed edge pointing toward target? - - var edges = nodeData.undirected[target]; - if (!edges) return false; - return this.multi ? !!edges.size : true; - } - - throw new InvalidArgumentsGraphError("Graph.hasDirectedEdge: invalid arity (".concat(arguments.length, ", instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.")); - } - /** - * Method returning whether the given edge is found in the graph. - * - * Arity 1: - * @param {any} edge - The edge's key. - * - * Arity 2: - * @param {any} source - The edge's source. - * @param {any} target - The edge's target. - * - * @return {boolean} - * - * @throws {Error} - Will throw if the arguments are invalid. - */ - ; - - _proto.hasEdge = function hasEdge(source, target) { - if (arguments.length === 1) { - var edge = '' + source; - return this._edges.has(edge); - } else if (arguments.length === 2) { - source = '' + source; - target = '' + target; // If the node source or the target is not in the graph we break - - var nodeData = this._nodes.get(source); - - if (!nodeData) return false; // Is there a directed edge pointing toward target? - - var edges = typeof nodeData.out !== 'undefined' && nodeData.out[target]; - if (!edges) edges = typeof nodeData.undirected !== 'undefined' && nodeData.undirected[target]; - if (!edges) return false; - return this.multi ? !!edges.size : true; - } - - throw new InvalidArgumentsGraphError("Graph.hasEdge: invalid arity (".concat(arguments.length, ", instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target.")); - } - /** - * Method returning the edge matching source & target in a directed fashion. - * - * @param {any} source - The edge's source. - * @param {any} target - The edge's target. - * - * @return {any|undefined} - * - * @throws {Error} - Will throw if the graph is multi. - * @throws {Error} - Will throw if source or target doesn't exist. - */ - ; - - _proto.directedEdge = function directedEdge(source, target) { - if (this.type === 'undirected') return; - source = '' + source; - target = '' + target; - if (this.multi) throw new UsageGraphError('Graph.directedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.directedEdges instead.'); - - var sourceData = this._nodes.get(source); - - if (!sourceData) throw new NotFoundGraphError("Graph.directedEdge: could not find the \"".concat(source, "\" source node in the graph.")); - if (!this._nodes.has(target)) throw new NotFoundGraphError("Graph.directedEdge: could not find the \"".concat(target, "\" target node in the graph.")); - var edgeData = sourceData.out && sourceData.out[target] || undefined; - if (edgeData) return edgeData.key; - } - /** - * Method returning the edge matching source & target in a undirected fashion. - * - * @param {any} source - The edge's source. - * @param {any} target - The edge's target. - * - * @return {any|undefined} - * - * @throws {Error} - Will throw if the graph is multi. - * @throws {Error} - Will throw if source or target doesn't exist. - */ - ; - - _proto.undirectedEdge = function undirectedEdge(source, target) { - if (this.type === 'directed') return; - source = '' + source; - target = '' + target; - if (this.multi) throw new UsageGraphError('Graph.undirectedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.undirectedEdges instead.'); - - var sourceData = this._nodes.get(source); - - if (!sourceData) throw new NotFoundGraphError("Graph.undirectedEdge: could not find the \"".concat(source, "\" source node in the graph.")); - if (!this._nodes.has(target)) throw new NotFoundGraphError("Graph.undirectedEdge: could not find the \"".concat(target, "\" target node in the graph.")); - var edgeData = sourceData.undirected && sourceData.undirected[target] || undefined; - if (edgeData) return edgeData.key; - } - /** - * Method returning the edge matching source & target in a mixed fashion. - * - * @param {any} source - The edge's source. - * @param {any} target - The edge's target. - * - * @return {any|undefined} - * - * @throws {Error} - Will throw if the graph is multi. - * @throws {Error} - Will throw if source or target doesn't exist. - */ - ; - - _proto.edge = function edge(source, target) { - if (this.multi) throw new UsageGraphError('Graph.edge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.edges instead.'); - source = '' + source; - target = '' + target; - - var sourceData = this._nodes.get(source); - - if (!sourceData) throw new NotFoundGraphError("Graph.edge: could not find the \"".concat(source, "\" source node in the graph.")); - if (!this._nodes.has(target)) throw new NotFoundGraphError("Graph.edge: could not find the \"".concat(target, "\" target node in the graph.")); - var edgeData = sourceData.out && sourceData.out[target] || sourceData.undirected && sourceData.undirected[target] || undefined; - if (edgeData) return edgeData.key; - } - /** - * Method returning whether two nodes are directed neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.areDirectedNeighbors = function areDirectedNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.areDirectedNeighbors: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'undirected') return false; - return neighbor in nodeData["in"] || neighbor in nodeData.out; - } - /** - * Method returning whether two nodes are out neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.areOutNeighbors = function areOutNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.areOutNeighbors: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'undirected') return false; - return neighbor in nodeData.out; - } - /** - * Method returning whether two nodes are in neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.areInNeighbors = function areInNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.areInNeighbors: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'undirected') return false; - return neighbor in nodeData["in"]; - } - /** - * Method returning whether two nodes are undirected neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.areUndirectedNeighbors = function areUndirectedNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.areUndirectedNeighbors: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'directed') return false; - return neighbor in nodeData.undirected; - } - /** - * Method returning whether two nodes are neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.areNeighbors = function areNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.areNeighbors: could not find the \"".concat(node, "\" node in the graph.")); - - if (this.type !== 'undirected') { - if (neighbor in nodeData["in"] || neighbor in nodeData.out) return true; - } - - if (this.type !== 'directed') { - if (neighbor in nodeData.undirected) return true; - } - - return false; - } - /** - * Method returning whether two nodes are inbound neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.areInboundNeighbors = function areInboundNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.areInboundNeighbors: could not find the \"".concat(node, "\" node in the graph.")); - - if (this.type !== 'undirected') { - if (neighbor in nodeData["in"]) return true; - } - - if (this.type !== 'directed') { - if (neighbor in nodeData.undirected) return true; - } - - return false; - } - /** - * Method returning whether two nodes are outbound neighbors. - * - * @param {any} node - The node's key. - * @param {any} neighbor - The neighbor's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.areOutboundNeighbors = function areOutboundNeighbors(node, neighbor) { - node = '' + node; - neighbor = '' + neighbor; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.areOutboundNeighbors: could not find the \"".concat(node, "\" node in the graph.")); - - if (this.type !== 'undirected') { - if (neighbor in nodeData.out) return true; - } - - if (this.type !== 'directed') { - if (neighbor in nodeData.undirected) return true; - } - - return false; - } - /** - * Method returning the given node's in degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.inDegree = function inDegree(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.inDegree: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'undirected') return 0; - return nodeData.inDegree; - } - /** - * Method returning the given node's out degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.outDegree = function outDegree(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.outDegree: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'undirected') return 0; - return nodeData.outDegree; - } - /** - * Method returning the given node's directed degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.directedDegree = function directedDegree(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.directedDegree: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'undirected') return 0; - return nodeData.inDegree + nodeData.outDegree; - } - /** - * Method returning the given node's undirected degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.undirectedDegree = function undirectedDegree(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.undirectedDegree: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'directed') return 0; - return nodeData.undirectedDegree; - } - /** - * Method returning the given node's inbound degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's inbound degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.inboundDegree = function inboundDegree(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.inboundDegree: could not find the \"".concat(node, "\" node in the graph.")); - var degree = 0; - - if (this.type !== 'directed') { - degree += nodeData.undirectedDegree; - } - - if (this.type !== 'undirected') { - degree += nodeData.inDegree; - } - - return degree; - } - /** - * Method returning the given node's outbound degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's outbound degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.outboundDegree = function outboundDegree(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.outboundDegree: could not find the \"".concat(node, "\" node in the graph.")); - var degree = 0; - - if (this.type !== 'directed') { - degree += nodeData.undirectedDegree; - } - - if (this.type !== 'undirected') { - degree += nodeData.outDegree; - } - - return degree; - } - /** - * Method returning the given node's directed degree. - * - * @param {any} node - The node's key. - * @return {number} - The node's degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.degree = function degree(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.degree: could not find the \"".concat(node, "\" node in the graph.")); - var degree = 0; - - if (this.type !== 'directed') { - degree += nodeData.undirectedDegree; - } - - if (this.type !== 'undirected') { - degree += nodeData.inDegree + nodeData.outDegree; - } - - return degree; - } - /** - * Method returning the given node's in degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.inDegreeWithoutSelfLoops = function inDegreeWithoutSelfLoops(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.inDegreeWithoutSelfLoops: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'undirected') return 0; - var self = nodeData["in"][node]; - var loops = self ? this.multi ? self.size : 1 : 0; - return nodeData.inDegree - loops; - } - /** - * Method returning the given node's out degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.outDegreeWithoutSelfLoops = function outDegreeWithoutSelfLoops(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.outDegreeWithoutSelfLoops: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'undirected') return 0; - var self = nodeData.out[node]; - var loops = self ? this.multi ? self.size : 1 : 0; - return nodeData.outDegree - loops; - } - /** - * Method returning the given node's directed degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.directedDegreeWithoutSelfLoops = function directedDegreeWithoutSelfLoops(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.directedDegreeWithoutSelfLoops: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'undirected') return 0; - var self = nodeData.out[node]; - var loops = self ? this.multi ? self.size : 1 : 0; - return nodeData.inDegree + nodeData.outDegree - loops * 2; - } - /** - * Method returning the given node's undirected degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's in degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.undirectedDegreeWithoutSelfLoops = function undirectedDegreeWithoutSelfLoops(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.undirectedDegreeWithoutSelfLoops: could not find the \"".concat(node, "\" node in the graph.")); - if (this.type === 'directed') return 0; - var self = nodeData.undirected[node]; - var loops = self ? this.multi ? self.size : 1 : 0; - return nodeData.undirectedDegree - loops * 2; - } - /** - * Method returning the given node's inbound degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's inbound degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.inboundDegreeWithoutSelfLoops = function inboundDegreeWithoutSelfLoops(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.inboundDegreeWithoutSelfLoops: could not find the \"".concat(node, "\" node in the graph.")); - var self; - var degree = 0; - var loops = 0; - - if (this.type !== 'directed') { - degree += nodeData.undirectedDegree; - self = nodeData.undirected[node]; - loops += (self ? this.multi ? self.size : 1 : 0) * 2; - } - - if (this.type !== 'undirected') { - degree += nodeData.inDegree; - self = nodeData.out[node]; - loops += self ? this.multi ? self.size : 1 : 0; - } - - return degree - loops; - } - /** - * Method returning the given node's outbound degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's outbound degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.outboundDegreeWithoutSelfLoops = function outboundDegreeWithoutSelfLoops(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.outboundDegreeWithoutSelfLoops: could not find the \"".concat(node, "\" node in the graph.")); - var self; - var degree = 0; - var loops = 0; - - if (this.type !== 'directed') { - degree += nodeData.undirectedDegree; - self = nodeData.undirected[node]; - loops += (self ? this.multi ? self.size : 1 : 0) * 2; - } - - if (this.type !== 'undirected') { - degree += nodeData.outDegree; - self = nodeData["in"][node]; - loops += self ? this.multi ? self.size : 1 : 0; - } - - return degree - loops; - } - /** - * Method returning the given node's directed degree without considering self loops. - * - * @param {any} node - The node's key. - * @return {number} - The node's degree. - * - * @throws {Error} - Will throw if the node isn't in the graph. - */ - ; - - _proto.degreeWithoutSelfLoops = function degreeWithoutSelfLoops(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.degreeWithoutSelfLoops: could not find the \"".concat(node, "\" node in the graph.")); - var self; - var degree = 0; - var loops = 0; - - if (this.type !== 'directed') { - degree += nodeData.undirectedDegree; - self = nodeData.undirected[node]; - loops += (self ? this.multi ? self.size : 1 : 0) * 2; - } - - if (this.type !== 'undirected') { - degree += nodeData.inDegree + nodeData.outDegree; - self = nodeData.out[node]; - loops += (self ? this.multi ? self.size : 1 : 0) * 2; - } - - return degree - loops; - } - /** - * Method returning the given edge's source. - * - * @param {any} edge - The edge's key. - * @return {any} - The edge's source. - * - * @throws {Error} - Will throw if the edge isn't in the graph. - */ - ; - - _proto.source = function source(edge) { - edge = '' + edge; - - var data = this._edges.get(edge); - - if (!data) throw new NotFoundGraphError("Graph.source: could not find the \"".concat(edge, "\" edge in the graph.")); - return data.source.key; - } - /** - * Method returning the given edge's target. - * - * @param {any} edge - The edge's key. - * @return {any} - The edge's target. - * - * @throws {Error} - Will throw if the edge isn't in the graph. - */ - ; - - _proto.target = function target(edge) { - edge = '' + edge; - - var data = this._edges.get(edge); - - if (!data) throw new NotFoundGraphError("Graph.target: could not find the \"".concat(edge, "\" edge in the graph.")); - return data.target.key; - } - /** - * Method returning the given edge's extremities. - * - * @param {any} edge - The edge's key. - * @return {array} - The edge's extremities. - * - * @throws {Error} - Will throw if the edge isn't in the graph. - */ - ; - - _proto.extremities = function extremities(edge) { - edge = '' + edge; - - var edgeData = this._edges.get(edge); - - if (!edgeData) throw new NotFoundGraphError("Graph.extremities: could not find the \"".concat(edge, "\" edge in the graph.")); - return [edgeData.source.key, edgeData.target.key]; - } - /** - * Given a node & an edge, returns the other extremity of the edge. - * - * @param {any} node - The node's key. - * @param {any} edge - The edge's key. - * @return {any} - The related node. - * - * @throws {Error} - Will throw if the edge isn't in the graph or if the - * edge & node are not related. - */ - ; - - _proto.opposite = function opposite(node, edge) { - node = '' + node; - edge = '' + edge; - - var data = this._edges.get(edge); - - if (!data) throw new NotFoundGraphError("Graph.opposite: could not find the \"".concat(edge, "\" edge in the graph.")); - var source = data.source.key; - var target = data.target.key; - if (node === source) return target; - if (node === target) return source; - throw new NotFoundGraphError("Graph.opposite: the \"".concat(node, "\" node is not attached to the \"").concat(edge, "\" edge (").concat(source, ", ").concat(target, ").")); - } - /** - * Returns whether the given edge has the given node as extremity. - * - * @param {any} edge - The edge's key. - * @param {any} node - The node's key. - * @return {boolean} - The related node. - * - * @throws {Error} - Will throw if either the node or the edge isn't in the graph. - */ - ; - - _proto.hasExtremity = function hasExtremity(edge, node) { - edge = '' + edge; - node = '' + node; - - var data = this._edges.get(edge); - - if (!data) throw new NotFoundGraphError("Graph.hasExtremity: could not find the \"".concat(edge, "\" edge in the graph.")); - return data.source.key === node || data.target.key === node; - } - /** - * Method returning whether the given edge is undirected. - * - * @param {any} edge - The edge's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the edge isn't in the graph. - */ - ; - - _proto.isUndirected = function isUndirected(edge) { - edge = '' + edge; - - var data = this._edges.get(edge); - - if (!data) throw new NotFoundGraphError("Graph.isUndirected: could not find the \"".concat(edge, "\" edge in the graph.")); - return data.undirected; - } - /** - * Method returning whether the given edge is directed. - * - * @param {any} edge - The edge's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the edge isn't in the graph. - */ - ; - - _proto.isDirected = function isDirected(edge) { - edge = '' + edge; - - var data = this._edges.get(edge); - - if (!data) throw new NotFoundGraphError("Graph.isDirected: could not find the \"".concat(edge, "\" edge in the graph.")); - return !data.undirected; - } - /** - * Method returning whether the given edge is a self loop. - * - * @param {any} edge - The edge's key. - * @return {boolean} - * - * @throws {Error} - Will throw if the edge isn't in the graph. - */ - ; - - _proto.isSelfLoop = function isSelfLoop(edge) { - edge = '' + edge; - - var data = this._edges.get(edge); - - if (!data) throw new NotFoundGraphError("Graph.isSelfLoop: could not find the \"".concat(edge, "\" edge in the graph.")); - return data.source === data.target; - } - /**--------------------------------------------------------------------------- - * Mutation - **--------------------------------------------------------------------------- - */ - - /** - * Method used to add a node to the graph. - * - * @param {any} node - The node. - * @param {object} [attributes] - Optional attributes. - * @return {any} - The node. - * - * @throws {Error} - Will throw if the given node already exist. - * @throws {Error} - Will throw if the given attributes are not an object. - */ - ; - - _proto.addNode = function addNode(node, attributes) { - var nodeData = _addNode(this, node, attributes); - - return nodeData.key; - } - /** - * Method used to merge a node into the graph. - * - * @param {any} node - The node. - * @param {object} [attributes] - Optional attributes. - * @return {any} - The node. - */ - ; - - _proto.mergeNode = function mergeNode(node, attributes) { - if (attributes && !isPlainObject(attributes)) throw new InvalidArgumentsGraphError("Graph.mergeNode: invalid attributes. Expecting an object but got \"".concat(attributes, "\"")); // String coercion - - node = '' + node; - attributes = attributes || {}; // If the node already exists, we merge the attributes - - var data = this._nodes.get(node); - - if (data) { - if (attributes) { - assign(data.attributes, attributes); - this.emit('nodeAttributesUpdated', { - type: 'merge', - key: node, - attributes: data.attributes, - data: attributes - }); - } - - return [node, false]; - } - - data = new this.NodeDataClass(node, attributes); // Adding the node to internal register - - this._nodes.set(node, data); // Emitting - - - this.emit('nodeAdded', { - key: node, - attributes: attributes - }); - return [node, true]; - } - /** - * Method used to add a node if it does not exist in the graph or else to - * update its attributes using a function. - * - * @param {any} node - The node. - * @param {function} [updater] - Optional updater function. - * @return {any} - The node. - */ - ; - - _proto.updateNode = function updateNode(node, updater) { - if (updater && typeof updater !== 'function') throw new InvalidArgumentsGraphError("Graph.updateNode: invalid updater function. Expecting a function but got \"".concat(updater, "\"")); // String coercion - - node = '' + node; // If the node already exists, we update the attributes - - var data = this._nodes.get(node); - - if (data) { - if (updater) { - var oldAttributes = data.attributes; - data.attributes = updater(oldAttributes); - this.emit('nodeAttributesUpdated', { - type: 'replace', - key: node, - attributes: data.attributes - }); - } - - return [node, false]; - } - - var attributes = updater ? updater({}) : {}; - data = new this.NodeDataClass(node, attributes); // Adding the node to internal register - - this._nodes.set(node, data); // Emitting - - - this.emit('nodeAdded', { - key: node, - attributes: attributes - }); - return [node, true]; - } - /** - * Method used to drop a single node & all its attached edges from the graph. - * - * @param {any} node - The node. - * @return {Graph} - * - * @throws {Error} - Will throw if the node doesn't exist. - */ - ; - - _proto.dropNode = function dropNode(node) { - node = '' + node; - - var nodeData = this._nodes.get(node); - - if (!nodeData) throw new NotFoundGraphError("Graph.dropNode: could not find the \"".concat(node, "\" node in the graph.")); - var edgeData; // Removing attached edges - // NOTE: we could be faster here, but this is such a pain to maintain - - if (this.type !== 'undirected') { - for (var neighbor in nodeData.out) { - edgeData = nodeData.out[neighbor]; - - do { - dropEdgeFromData(this, edgeData); - edgeData = edgeData.next; - } while (edgeData); - } - - for (var _neighbor in nodeData["in"]) { - edgeData = nodeData["in"][_neighbor]; - - do { - dropEdgeFromData(this, edgeData); - edgeData = edgeData.next; - } while (edgeData); - } - } - - if (this.type !== 'directed') { - for (var _neighbor2 in nodeData.undirected) { - edgeData = nodeData.undirected[_neighbor2]; - - do { - dropEdgeFromData(this, edgeData); - edgeData = edgeData.next; - } while (edgeData); - } - } // Dropping the node from the register - - - this._nodes["delete"](node); // Emitting - - - this.emit('nodeDropped', { - key: node, - attributes: nodeData.attributes - }); - } - /** - * Method used to drop a single edge from the graph. - * - * Arity 1: - * @param {any} edge - The edge. - * - * Arity 2: - * @param {any} source - Source node. - * @param {any} target - Target node. - * - * @return {Graph} - * - * @throws {Error} - Will throw if the edge doesn't exist. - */ - ; - - _proto.dropEdge = function dropEdge(edge) { - var edgeData; - - if (arguments.length > 1) { - var source = '' + arguments[0]; - var target = '' + arguments[1]; - edgeData = getMatchingEdge(this, source, target, this.type); - if (!edgeData) throw new NotFoundGraphError("Graph.dropEdge: could not find the \"".concat(source, "\" -> \"").concat(target, "\" edge in the graph.")); - } else { - edge = '' + edge; - edgeData = this._edges.get(edge); - if (!edgeData) throw new NotFoundGraphError("Graph.dropEdge: could not find the \"".concat(edge, "\" edge in the graph.")); - } - - dropEdgeFromData(this, edgeData); - return this; - } - /** - * Method used to drop a single directed edge from the graph. - * - * @param {any} source - Source node. - * @param {any} target - Target node. - * - * @return {Graph} - * - * @throws {Error} - Will throw if the edge doesn't exist. - */ - ; - - _proto.dropDirectedEdge = function dropDirectedEdge(source, target) { - if (arguments.length < 2) throw new UsageGraphError('Graph.dropDirectedEdge: it does not make sense to try and drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.'); - if (this.multi) throw new UsageGraphError('Graph.dropDirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.'); - source = '' + source; - target = '' + target; - var edgeData = getMatchingEdge(this, source, target, 'directed'); - if (!edgeData) throw new NotFoundGraphError("Graph.dropDirectedEdge: could not find a \"".concat(source, "\" -> \"").concat(target, "\" edge in the graph.")); - dropEdgeFromData(this, edgeData); - return this; - } - /** - * Method used to drop a single undirected edge from the graph. - * - * @param {any} source - Source node. - * @param {any} target - Target node. - * - * @return {Graph} - * - * @throws {Error} - Will throw if the edge doesn't exist. - */ - ; - - _proto.dropUndirectedEdge = function dropUndirectedEdge(source, target) { - if (arguments.length < 2) throw new UsageGraphError('Graph.dropUndirectedEdge: it does not make sense to drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.'); - if (this.multi) throw new UsageGraphError('Graph.dropUndirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.'); - var edgeData = getMatchingEdge(this, source, target, 'undirected'); - if (!edgeData) throw new NotFoundGraphError("Graph.dropUndirectedEdge: could not find a \"".concat(source, "\" -> \"").concat(target, "\" edge in the graph.")); - dropEdgeFromData(this, edgeData); - return this; - } - /** - * Method used to remove every edge & every node from the graph. - * - * @return {Graph} - */ - ; - - _proto.clear = function clear() { - // Clearing edges - this._edges.clear(); // Clearing nodes - - - this._nodes.clear(); // Reset counters - - - this._resetInstanceCounters(); // Emitting - - - this.emit('cleared'); - } - /** - * Method used to remove every edge from the graph. - * - * @return {Graph} - */ - ; - - _proto.clearEdges = function clearEdges() { - // Clearing structure index - var iterator = this._nodes.values(); - - var step; - - while (step = iterator.next(), step.done !== true) { - step.value.clear(); - } // Clearing edges - - - this._edges.clear(); // Reset counters - - - this._resetInstanceCounters(); // Emitting - - - this.emit('edgesCleared'); - } - /**--------------------------------------------------------------------------- - * Attributes-related methods - **--------------------------------------------------------------------------- - */ - - /** - * Method returning the desired graph's attribute. - * - * @param {string} name - Name of the attribute. - * @return {any} - */ - ; - - _proto.getAttribute = function getAttribute(name) { - return this._attributes[name]; - } - /** - * Method returning the graph's attributes. - * - * @return {object} - */ - ; - - _proto.getAttributes = function getAttributes() { - return this._attributes; - } - /** - * Method returning whether the graph has the desired attribute. - * - * @param {string} name - Name of the attribute. - * @return {boolean} - */ - ; - - _proto.hasAttribute = function hasAttribute(name) { - return this._attributes.hasOwnProperty(name); - } - /** - * Method setting a value for the desired graph's attribute. - * - * @param {string} name - Name of the attribute. - * @param {any} value - Value for the attribute. - * @return {Graph} - */ - ; - - _proto.setAttribute = function setAttribute(name, value) { - this._attributes[name] = value; // Emitting - - this.emit('attributesUpdated', { - type: 'set', - attributes: this._attributes, - name: name - }); - return this; - } - /** - * Method using a function to update the desired graph's attribute's value. - * - * @param {string} name - Name of the attribute. - * @param {function} updater - Function use to update the attribute's value. - * @return {Graph} - */ - ; - - _proto.updateAttribute = function updateAttribute(name, updater) { - if (typeof updater !== 'function') throw new InvalidArgumentsGraphError('Graph.updateAttribute: updater should be a function.'); - var value = this._attributes[name]; - this._attributes[name] = updater(value); // Emitting - - this.emit('attributesUpdated', { - type: 'set', - attributes: this._attributes, - name: name - }); - return this; - } - /** - * Method removing the desired graph's attribute. - * - * @param {string} name - Name of the attribute. - * @return {Graph} - */ - ; - - _proto.removeAttribute = function removeAttribute(name) { - delete this._attributes[name]; // Emitting - - this.emit('attributesUpdated', { - type: 'remove', - attributes: this._attributes, - name: name - }); - return this; - } - /** - * Method replacing the graph's attributes. - * - * @param {object} attributes - New attributes. - * @return {Graph} - * - * @throws {Error} - Will throw if given attributes are not a plain object. - */ - ; - - _proto.replaceAttributes = function replaceAttributes(attributes) { - if (!isPlainObject(attributes)) throw new InvalidArgumentsGraphError('Graph.replaceAttributes: provided attributes are not a plain object.'); - this._attributes = attributes; // Emitting - - this.emit('attributesUpdated', { - type: 'replace', - attributes: this._attributes - }); - return this; - } - /** - * Method merging the graph's attributes. - * - * @param {object} attributes - Attributes to merge. - * @return {Graph} - * - * @throws {Error} - Will throw if given attributes are not a plain object. - */ - ; - - _proto.mergeAttributes = function mergeAttributes(attributes) { - if (!isPlainObject(attributes)) throw new InvalidArgumentsGraphError('Graph.mergeAttributes: provided attributes are not a plain object.'); - assign(this._attributes, attributes); // Emitting - - this.emit('attributesUpdated', { - type: 'merge', - attributes: this._attributes, - data: attributes - }); - return this; - } - /** - * Method updating the graph's attributes. - * - * @param {function} updater - Function used to update the attributes. - * @return {Graph} - * - * @throws {Error} - Will throw if given updater is not a function. - */ - ; - - _proto.updateAttributes = function updateAttributes(updater) { - if (typeof updater !== 'function') throw new InvalidArgumentsGraphError('Graph.updateAttributes: provided updater is not a function.'); - this._attributes = updater(this._attributes); // Emitting - - this.emit('attributesUpdated', { - type: 'update', - attributes: this._attributes - }); - return this; - } - /** - * Method used to update each node's attributes using the given function. - * - * @param {function} updater - Updater function to use. - * @param {object} [hints] - Optional hints. - */ - ; - - _proto.updateEachNodeAttributes = function updateEachNodeAttributes(updater, hints) { - if (typeof updater !== 'function') throw new InvalidArgumentsGraphError('Graph.updateEachNodeAttributes: expecting an updater function.'); - if (hints && !validateHints(hints)) throw new InvalidArgumentsGraphError('Graph.updateEachNodeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}'); - - var iterator = this._nodes.values(); - - var step, nodeData; - - while (step = iterator.next(), step.done !== true) { - nodeData = step.value; - nodeData.attributes = updater(nodeData.key, nodeData.attributes); - } - - this.emit('eachNodeAttributesUpdated', { - hints: hints ? hints : null - }); - } - /** - * Method used to update each edge's attributes using the given function. - * - * @param {function} updater - Updater function to use. - * @param {object} [hints] - Optional hints. - */ - ; - - _proto.updateEachEdgeAttributes = function updateEachEdgeAttributes(updater, hints) { - if (typeof updater !== 'function') throw new InvalidArgumentsGraphError('Graph.updateEachEdgeAttributes: expecting an updater function.'); - if (hints && !validateHints(hints)) throw new InvalidArgumentsGraphError('Graph.updateEachEdgeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}'); - - var iterator = this._edges.values(); - - var step, edgeData, sourceData, targetData; - - while (step = iterator.next(), step.done !== true) { - edgeData = step.value; - sourceData = edgeData.source; - targetData = edgeData.target; - edgeData.attributes = updater(edgeData.key, edgeData.attributes, sourceData.key, targetData.key, sourceData.attributes, targetData.attributes, edgeData.undirected); - } - - this.emit('eachEdgeAttributesUpdated', { - hints: hints ? hints : null - }); - } - /**--------------------------------------------------------------------------- - * Iteration-related methods - **--------------------------------------------------------------------------- - */ - - /** - * Method iterating over the graph's adjacency using the given callback. - * - * @param {function} callback - Callback to use. - */ - ; - - _proto.forEachAdjacencyEntry = function forEachAdjacencyEntry(callback) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.forEachAdjacencyEntry: expecting a callback.'); - forEachAdjacency(false, false, false, this, callback); - }; - - _proto.forEachAdjacencyEntryWithOrphans = function forEachAdjacencyEntryWithOrphans(callback) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.forEachAdjacencyEntryWithOrphans: expecting a callback.'); - forEachAdjacency(false, false, true, this, callback); - } - /** - * Method iterating over the graph's assymetric adjacency using the given callback. - * - * @param {function} callback - Callback to use. - */ - ; - - _proto.forEachAssymetricAdjacencyEntry = function forEachAssymetricAdjacencyEntry(callback) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.forEachAssymetricAdjacencyEntry: expecting a callback.'); - forEachAdjacency(false, true, false, this, callback); - }; - - _proto.forEachAssymetricAdjacencyEntryWithOrphans = function forEachAssymetricAdjacencyEntryWithOrphans(callback) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.forEachAssymetricAdjacencyEntryWithOrphans: expecting a callback.'); - forEachAdjacency(false, true, true, this, callback); - } - /** - * Method returning the list of the graph's nodes. - * - * @return {array} - The nodes. - */ - ; - - _proto.nodes = function nodes() { - if (typeof Array.from === 'function') return Array.from(this._nodes.keys()); - return take(this._nodes.keys(), this._nodes.size); - } - /** - * Method iterating over the graph's nodes using the given callback. - * - * @param {function} callback - Callback (key, attributes, index). - */ - ; - - _proto.forEachNode = function forEachNode(callback) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.forEachNode: expecting a callback.'); - - var iterator = this._nodes.values(); - - var step, nodeData; - - while (step = iterator.next(), step.done !== true) { - nodeData = step.value; - callback(nodeData.key, nodeData.attributes); - } - } - /** - * Method iterating attempting to find a node matching the given predicate - * function. - * - * @param {function} callback - Callback (key, attributes). - */ - ; - - _proto.findNode = function findNode(callback) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.findNode: expecting a callback.'); - - var iterator = this._nodes.values(); - - var step, nodeData; - - while (step = iterator.next(), step.done !== true) { - nodeData = step.value; - if (callback(nodeData.key, nodeData.attributes)) return nodeData.key; - } - - return; - } - /** - * Method mapping nodes. - * - * @param {function} callback - Callback (key, attributes). - */ - ; - - _proto.mapNodes = function mapNodes(callback) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.mapNode: expecting a callback.'); - - var iterator = this._nodes.values(); - - var step, nodeData; - var result = new Array(this.order); - var i = 0; - - while (step = iterator.next(), step.done !== true) { - nodeData = step.value; - result[i++] = callback(nodeData.key, nodeData.attributes); - } - - return result; - } - /** - * Method returning whether some node verify the given predicate. - * - * @param {function} callback - Callback (key, attributes). - */ - ; - - _proto.someNode = function someNode(callback) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.someNode: expecting a callback.'); - - var iterator = this._nodes.values(); - - var step, nodeData; - - while (step = iterator.next(), step.done !== true) { - nodeData = step.value; - if (callback(nodeData.key, nodeData.attributes)) return true; - } - - return false; - } - /** - * Method returning whether all node verify the given predicate. - * - * @param {function} callback - Callback (key, attributes). - */ - ; - - _proto.everyNode = function everyNode(callback) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.everyNode: expecting a callback.'); - - var iterator = this._nodes.values(); - - var step, nodeData; - - while (step = iterator.next(), step.done !== true) { - nodeData = step.value; - if (!callback(nodeData.key, nodeData.attributes)) return false; - } - - return true; - } - /** - * Method filtering nodes. - * - * @param {function} callback - Callback (key, attributes). - */ - ; - - _proto.filterNodes = function filterNodes(callback) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.filterNodes: expecting a callback.'); - - var iterator = this._nodes.values(); - - var step, nodeData; - var result = []; - - while (step = iterator.next(), step.done !== true) { - nodeData = step.value; - if (callback(nodeData.key, nodeData.attributes)) result.push(nodeData.key); - } - - return result; - } - /** - * Method reducing nodes. - * - * @param {function} callback - Callback (accumulator, key, attributes). - */ - ; - - _proto.reduceNodes = function reduceNodes(callback, initialValue) { - if (typeof callback !== 'function') throw new InvalidArgumentsGraphError('Graph.reduceNodes: expecting a callback.'); - if (arguments.length < 2) throw new InvalidArgumentsGraphError('Graph.reduceNodes: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.'); - var accumulator = initialValue; - - var iterator = this._nodes.values(); - - var step, nodeData; - - while (step = iterator.next(), step.done !== true) { - nodeData = step.value; - accumulator = callback(accumulator, nodeData.key, nodeData.attributes); - } - - return accumulator; - } - /** - * Method returning an iterator over the graph's node entries. - * - * @return {Iterator} - */ - ; - - _proto.nodeEntries = function nodeEntries() { - var iterator$1 = this._nodes.values(); - - return new iterator(function () { - var step = iterator$1.next(); - if (step.done) return step; - var data = step.value; - return { - value: { - node: data.key, - attributes: data.attributes - }, - done: false - }; - }); - } - /**--------------------------------------------------------------------------- - * Serialization - **--------------------------------------------------------------------------- - */ - - /** - * Method used to export the whole graph. - * - * @return {object} - The serialized graph. - */ - ; - - _proto["export"] = function _export() { - var nodes = new Array(this._nodes.size); - var i = 0; - - this._nodes.forEach(function (data, key) { - nodes[i++] = serializeNode(key, data); - }); - - var edges = new Array(this._edges.size); - i = 0; - - this._edges.forEach(function (data, key) { - edges[i++] = serializeEdge(key, data); - }); - - return { - options: { - type: this.type, - multi: this.multi, - allowSelfLoops: this.allowSelfLoops - }, - attributes: this.getAttributes(), - nodes: nodes, - edges: edges - }; - } - /** - * Method used to import a serialized graph. - * - * @param {object|Graph} data - The serialized graph. - * @param {boolean} merge - Whether to merge data. - * @return {Graph} - Returns itself for chaining. - */ - ; - - _proto["import"] = function _import(data) { - var _this2 = this; - - var merge = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false; - - // Importing a Graph instance directly - if (isGraph(data)) { - // Nodes - data.forEachNode(function (n, a) { - if (merge) _this2.mergeNode(n, a);else _this2.addNode(n, a); - }); // Edges - - data.forEachEdge(function (e, a, s, t, _sa, _ta, u) { - if (merge) { - if (u) _this2.mergeUndirectedEdgeWithKey(e, s, t, a);else _this2.mergeDirectedEdgeWithKey(e, s, t, a); - } else { - if (u) _this2.addUndirectedEdgeWithKey(e, s, t, a);else _this2.addDirectedEdgeWithKey(e, s, t, a); - } - }); - return this; - } // Importing a serialized graph - - - if (!isPlainObject(data)) throw new InvalidArgumentsGraphError('Graph.import: invalid argument. Expecting a serialized graph or, alternatively, a Graph instance.'); - - if (data.attributes) { - if (!isPlainObject(data.attributes)) throw new InvalidArgumentsGraphError('Graph.import: invalid attributes. Expecting a plain object.'); - if (merge) this.mergeAttributes(data.attributes);else this.replaceAttributes(data.attributes); - } - - var i, l, list, node, edge; - - if (data.nodes) { - list = data.nodes; - if (!Array.isArray(list)) throw new InvalidArgumentsGraphError('Graph.import: invalid nodes. Expecting an array.'); - - for (i = 0, l = list.length; i < l; i++) { - node = list[i]; // Validating - - validateSerializedNode(node); // Adding the node - - var _node = node, - key = _node.key, - attributes = _node.attributes; - if (merge) this.mergeNode(key, attributes);else this.addNode(key, attributes); - } - } - - if (data.edges) { - list = data.edges; - if (!Array.isArray(list)) throw new InvalidArgumentsGraphError('Graph.import: invalid edges. Expecting an array.'); - - for (i = 0, l = list.length; i < l; i++) { - edge = list[i]; // Validating - - validateSerializedEdge(edge); // Adding the edge - - var _edge = edge, - source = _edge.source, - target = _edge.target, - _attributes = _edge.attributes, - _edge$undirected = _edge.undirected, - undirected = _edge$undirected === void 0 ? false : _edge$undirected; - var method = void 0; - - if ('key' in edge) { - method = merge ? undirected ? this.mergeUndirectedEdgeWithKey : this.mergeDirectedEdgeWithKey : undirected ? this.addUndirectedEdgeWithKey : this.addDirectedEdgeWithKey; - method.call(this, edge.key, source, target, _attributes); - } else { - method = merge ? undirected ? this.mergeUndirectedEdge : this.mergeDirectedEdge : undirected ? this.addUndirectedEdge : this.addDirectedEdge; - method.call(this, source, target, _attributes); - } - } - } - - return this; - } - /**--------------------------------------------------------------------------- - * Utils - **--------------------------------------------------------------------------- - */ - - /** - * Method returning a null copy of the graph, i.e. a graph without nodes - * & edges but with the exact same options. - * - * @param {object} options - Options to merge with the current ones. - * @return {Graph} - The null copy. - */ - ; - - _proto.nullCopy = function nullCopy(options) { - var graph = new Graph(assign({}, this._options, options)); - graph.replaceAttributes(assign({}, this.getAttributes())); - return graph; - } - /** - * Method returning an empty copy of the graph, i.e. a graph without edges but - * with the exact same options. - * - * @param {object} options - Options to merge with the current ones. - * @return {Graph} - The empty copy. - */ - ; - - _proto.emptyCopy = function emptyCopy(options) { - var graph = this.nullCopy(options); - - this._nodes.forEach(function (nodeData, key) { - var attributes = assign({}, nodeData.attributes); // NOTE: no need to emit events since user cannot access the instance yet - - nodeData = new graph.NodeDataClass(key, attributes); - - graph._nodes.set(key, nodeData); - }); - - return graph; - } - /** - * Method returning an exact copy of the graph. - * - * @param {object} options - Upgrade options. - * @return {Graph} - The copy. - */ - ; - - _proto.copy = function copy(options) { - options = options || {}; - if (typeof options.type === 'string' && options.type !== this.type && options.type !== 'mixed') throw new UsageGraphError("Graph.copy: cannot create an incompatible copy from \"".concat(this.type, "\" type to \"").concat(options.type, "\" because this would mean losing information about the current graph.")); - if (typeof options.multi === 'boolean' && options.multi !== this.multi && options.multi !== true) throw new UsageGraphError('Graph.copy: cannot create an incompatible copy by downgrading a multi graph to a simple one because this would mean losing information about the current graph.'); - if (typeof options.allowSelfLoops === 'boolean' && options.allowSelfLoops !== this.allowSelfLoops && options.allowSelfLoops !== true) throw new UsageGraphError('Graph.copy: cannot create an incompatible copy from a graph allowing self loops to one that does not because this would mean losing information about the current graph.'); - var graph = this.emptyCopy(options); - - var iterator = this._edges.values(); - - var step, edgeData; - - while (step = iterator.next(), step.done !== true) { - edgeData = step.value; // NOTE: no need to emit events since user cannot access the instance yet - - addEdge(graph, 'copy', false, edgeData.undirected, edgeData.key, edgeData.source.key, edgeData.target.key, assign({}, edgeData.attributes)); - } - - return graph; - } - /**--------------------------------------------------------------------------- - * Known methods - **--------------------------------------------------------------------------- - */ - - /** - * Method used by JavaScript to perform JSON serialization. - * - * @return {object} - The serialized graph. - */ - ; - - _proto.toJSON = function toJSON() { - return this["export"](); - } - /** - * Method returning [object Graph]. - */ - ; - - _proto.toString = function toString() { - return '[object Graph]'; - } - /** - * Method used internally by node's console to display a custom object. - * - * @return {object} - Formatted object representation of the graph. - */ - ; - - _proto.inspect = function inspect() { - var _this3 = this; - - var nodes = {}; - - this._nodes.forEach(function (data, key) { - nodes[key] = data.attributes; - }); - - var edges = {}, - multiIndex = {}; - - this._edges.forEach(function (data, key) { - var direction = data.undirected ? '--' : '->'; - var label = ''; - var source = data.source.key; - var target = data.target.key; - var tmp; - - if (data.undirected && source > target) { - tmp = source; - source = target; - target = tmp; - } - - var desc = "(".concat(source, ")").concat(direction, "(").concat(target, ")"); - - if (!key.startsWith('geid_')) { - label += "[".concat(key, "]: "); - } else if (_this3.multi) { - if (typeof multiIndex[desc] === 'undefined') { - multiIndex[desc] = 0; - } else { - multiIndex[desc]++; - } - - label += "".concat(multiIndex[desc], ". "); - } - - label += desc; - edges[label] = data.attributes; - }); - - var dummy = {}; - - for (var k in this) { - if (this.hasOwnProperty(k) && !EMITTER_PROPS.has(k) && typeof this[k] !== 'function' && _typeof(k) !== 'symbol') dummy[k] = this[k]; - } - - dummy.attributes = this._attributes; - dummy.nodes = nodes; - dummy.edges = edges; - privateProperty(dummy, 'constructor', this.constructor); - return dummy; - }; - - return Graph; - }(events.exports.EventEmitter); - if (typeof Symbol !== 'undefined') Graph.prototype[Symbol["for"]('nodejs.util.inspect.custom')] = Graph.prototype.inspect; - /** - * Related to edge addition. - */ - - EDGE_ADD_METHODS.forEach(function (method) { - ['add', 'merge', 'update'].forEach(function (verb) { - var name = method.name(verb); - var fn = verb === 'add' ? addEdge : mergeEdge; - - if (method.generateKey) { - Graph.prototype[name] = function (source, target, attributes) { - return fn(this, name, true, (method.type || this.type) === 'undirected', null, source, target, attributes, verb === 'update'); - }; - } else { - Graph.prototype[name] = function (edge, source, target, attributes) { - return fn(this, name, false, (method.type || this.type) === 'undirected', edge, source, target, attributes, verb === 'update'); - }; - } - }); - }); - /** - * Attributes-related. - */ - - attachNodeAttributesMethods(Graph); - attachEdgeAttributesMethods(Graph); - /** - * Edge iteration-related. - */ - - attachEdgeIterationMethods(Graph); - /** - * Neighbor iteration-related. - */ - - attachNeighborIterationMethods(Graph); - - /** - * Alternative constructors. - */ - - var DirectedGraph = /*#__PURE__*/function (_Graph) { - _inheritsLoose(DirectedGraph, _Graph); - - function DirectedGraph(options) { - var finalOptions = assign({ - type: 'directed' - }, options); - if ('multi' in finalOptions && finalOptions.multi !== false) throw new InvalidArgumentsGraphError('DirectedGraph.from: inconsistent indication that the graph should be multi in given options!'); - if (finalOptions.type !== 'directed') throw new InvalidArgumentsGraphError('DirectedGraph.from: inconsistent "' + finalOptions.type + '" type in given options!'); - return _Graph.call(this, finalOptions) || this; - } - - return DirectedGraph; - }(Graph); - - var UndirectedGraph = /*#__PURE__*/function (_Graph2) { - _inheritsLoose(UndirectedGraph, _Graph2); - - function UndirectedGraph(options) { - var finalOptions = assign({ - type: 'undirected' - }, options); - if ('multi' in finalOptions && finalOptions.multi !== false) throw new InvalidArgumentsGraphError('UndirectedGraph.from: inconsistent indication that the graph should be multi in given options!'); - if (finalOptions.type !== 'undirected') throw new InvalidArgumentsGraphError('UndirectedGraph.from: inconsistent "' + finalOptions.type + '" type in given options!'); - return _Graph2.call(this, finalOptions) || this; - } - - return UndirectedGraph; - }(Graph); - - var MultiGraph = /*#__PURE__*/function (_Graph3) { - _inheritsLoose(MultiGraph, _Graph3); - - function MultiGraph(options) { - var finalOptions = assign({ - multi: true - }, options); - if ('multi' in finalOptions && finalOptions.multi !== true) throw new InvalidArgumentsGraphError('MultiGraph.from: inconsistent indication that the graph should be simple in given options!'); - return _Graph3.call(this, finalOptions) || this; - } - - return MultiGraph; - }(Graph); - - var MultiDirectedGraph = /*#__PURE__*/function (_Graph4) { - _inheritsLoose(MultiDirectedGraph, _Graph4); - - function MultiDirectedGraph(options) { - var finalOptions = assign({ - type: 'directed', - multi: true - }, options); - if ('multi' in finalOptions && finalOptions.multi !== true) throw new InvalidArgumentsGraphError('MultiDirectedGraph.from: inconsistent indication that the graph should be simple in given options!'); - if (finalOptions.type !== 'directed') throw new InvalidArgumentsGraphError('MultiDirectedGraph.from: inconsistent "' + finalOptions.type + '" type in given options!'); - return _Graph4.call(this, finalOptions) || this; - } - - return MultiDirectedGraph; - }(Graph); - - var MultiUndirectedGraph = /*#__PURE__*/function (_Graph5) { - _inheritsLoose(MultiUndirectedGraph, _Graph5); - - function MultiUndirectedGraph(options) { - var finalOptions = assign({ - type: 'undirected', - multi: true - }, options); - if ('multi' in finalOptions && finalOptions.multi !== true) throw new InvalidArgumentsGraphError('MultiUndirectedGraph.from: inconsistent indication that the graph should be simple in given options!'); - if (finalOptions.type !== 'undirected') throw new InvalidArgumentsGraphError('MultiUndirectedGraph.from: inconsistent "' + finalOptions.type + '" type in given options!'); - return _Graph5.call(this, finalOptions) || this; - } - - return MultiUndirectedGraph; - }(Graph); - /** - * Attaching static #.from method to each of the constructors. - */ - - - function attachStaticFromMethod(Class) { - /** - * Builds a graph from serialized data or another graph's data. - * - * @param {Graph|SerializedGraph} data - Hydratation data. - * @param {object} [options] - Options. - * @return {Class} - */ - Class.from = function (data, options) { - // Merging given options with serialized ones - var finalOptions = assign({}, data.options, options); - var instance = new Class(finalOptions); - instance["import"](data); - return instance; - }; - } - - attachStaticFromMethod(Graph); - attachStaticFromMethod(DirectedGraph); - attachStaticFromMethod(UndirectedGraph); - attachStaticFromMethod(MultiGraph); - attachStaticFromMethod(MultiDirectedGraph); - attachStaticFromMethod(MultiUndirectedGraph); - Graph.Graph = Graph; - Graph.DirectedGraph = DirectedGraph; - Graph.UndirectedGraph = UndirectedGraph; - Graph.MultiGraph = MultiGraph; - Graph.MultiDirectedGraph = MultiDirectedGraph; - Graph.MultiUndirectedGraph = MultiUndirectedGraph; - Graph.InvalidArgumentsGraphError = InvalidArgumentsGraphError; - Graph.NotFoundGraphError = NotFoundGraphError; - Graph.UsageGraphError = UsageGraphError; - - /** - * Graphology CommonJS Endoint - * ============================ - * - * Endpoint for CommonJS modules consumers. - */ - - return Graph; - -})); -//# sourceMappingURL=graphology.umd.js.map diff --git a/libs/shared/graph-layouts/node_modules/graphology/dist/graphology.umd.min.js b/libs/shared/graph-layouts/node_modules/graphology/dist/graphology.umd.min.js deleted file mode 100644 index 9cb5b8ff2..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/dist/graphology.umd.min.js +++ /dev/null @@ -1,2 +0,0 @@ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?module.exports=e():"function"==typeof define&&define.amd?define(e):(t="undefined"!=typeof globalThis?globalThis:t||self).graphology=e()}(this,(function(){"use strict";function t(e){return t="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t},t(e)}function e(t,e){t.prototype=Object.create(e.prototype),t.prototype.constructor=t,r(t,e)}function n(t){return n=Object.setPrototypeOf?Object.getPrototypeOf:function(t){return t.__proto__||Object.getPrototypeOf(t)},n(t)}function r(t,e){return r=Object.setPrototypeOf||function(t,e){return t.__proto__=e,t},r(t,e)}function i(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(t){return!1}}function o(t,e,n){return o=i()?Reflect.construct:function(t,e,n){var i=[null];i.push.apply(i,e);var o=new(Function.bind.apply(t,i));return n&&r(o,n.prototype),o},o.apply(null,arguments)}function a(t){var e="function"==typeof Map?new Map:void 0;return a=function(t){if(null===t||(i=t,-1===Function.toString.call(i).indexOf("[native code]")))return t;var i;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==e){if(e.has(t))return e.get(t);e.set(t,a)}function a(){return o(t,arguments,n(this).constructor)}return a.prototype=Object.create(t.prototype,{constructor:{value:a,enumerable:!1,writable:!0,configurable:!0}}),r(a,t)},a(t)}function u(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}var c=function(){for(var t=arguments[0],e=1,n=arguments.length;e<n;e++)if(arguments[e])for(var r in arguments[e])t[r]=arguments[e][r];return t};function s(t,e,n,r){var i=t._nodes.get(e),o=null;return i?o="mixed"===r?i.out&&i.out[n]||i.undirected&&i.undirected[n]:"directed"===r?i.out&&i.out[n]:i.undirected&&i.undirected[n]:o}function d(e){return null!==e&&"object"===t(e)&&"function"==typeof e.addUndirectedEdgeWithKey&&"function"==typeof e.dropNode}function h(e){return"object"===t(e)&&null!==e&&e.constructor===Object}function p(t){var e;for(e in t)return!1;return!0}function f(t,e,n){Object.defineProperty(t,e,{enumerable:!1,configurable:!1,writable:!0,value:n})}function l(t,e,n){var r={enumerable:!0,configurable:!0};"function"==typeof n?r.get=n:(r.value=n,r.writable=!1),Object.defineProperty(t,e,r)}function g(t){return!!h(t)&&!(t.attributes&&!Array.isArray(t.attributes))}"function"==typeof Object.assign&&(c=Object.assign);var y,w={exports:{}},v="object"==typeof Reflect?Reflect:null,b=v&&"function"==typeof v.apply?v.apply:function(t,e,n){return Function.prototype.apply.call(t,e,n)};y=v&&"function"==typeof v.ownKeys?v.ownKeys:Object.getOwnPropertySymbols?function(t){return Object.getOwnPropertyNames(t).concat(Object.getOwnPropertySymbols(t))}:function(t){return Object.getOwnPropertyNames(t)};var m=Number.isNaN||function(t){return t!=t};function k(){k.init.call(this)}w.exports=k,w.exports.once=function(t,e){return new Promise((function(n,r){function i(n){t.removeListener(e,o),r(n)}function o(){"function"==typeof t.removeListener&&t.removeListener("error",i),n([].slice.call(arguments))}N(t,e,o,{once:!0}),"error"!==e&&function(t,e,n){"function"==typeof t.on&&N(t,"error",e,n)}(t,i,{once:!0})}))},k.EventEmitter=k,k.prototype._events=void 0,k.prototype._eventsCount=0,k.prototype._maxListeners=void 0;var _=10;function G(t){if("function"!=typeof t)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof t)}function x(t){return void 0===t._maxListeners?k.defaultMaxListeners:t._maxListeners}function E(t,e,n,r){var i,o,a,u;if(G(n),void 0===(o=t._events)?(o=t._events=Object.create(null),t._eventsCount=0):(void 0!==o.newListener&&(t.emit("newListener",e,n.listener?n.listener:n),o=t._events),a=o[e]),void 0===a)a=o[e]=n,++t._eventsCount;else if("function"==typeof a?a=o[e]=r?[n,a]:[a,n]:r?a.unshift(n):a.push(n),(i=x(t))>0&&a.length>i&&!a.warned){a.warned=!0;var c=new Error("Possible EventEmitter memory leak detected. "+a.length+" "+String(e)+" listeners added. Use emitter.setMaxListeners() to increase limit");c.name="MaxListenersExceededWarning",c.emitter=t,c.type=e,c.count=a.length,u=c,console&&console.warn&&console.warn(u)}return t}function A(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function S(t,e,n){var r={fired:!1,wrapFn:void 0,target:t,type:e,listener:n},i=A.bind(r);return i.listener=n,r.wrapFn=i,i}function D(t,e,n){var r=t._events;if(void 0===r)return[];var i=r[e];return void 0===i?[]:"function"==typeof i?n?[i.listener||i]:[i]:n?function(t){for(var e=new Array(t.length),n=0;n<e.length;++n)e[n]=t[n].listener||t[n];return e}(i):U(i,i.length)}function L(t){var e=this._events;if(void 0!==e){var n=e[t];if("function"==typeof n)return 1;if(void 0!==n)return n.length}return 0}function U(t,e){for(var n=new Array(e),r=0;r<e;++r)n[r]=t[r];return n}function N(t,e,n,r){if("function"==typeof t.on)r.once?t.once(e,n):t.on(e,n);else{if("function"!=typeof t.addEventListener)throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type '+typeof t);t.addEventListener(e,(function i(o){r.once&&t.removeEventListener(e,i),n(o)}))}}function j(t){if("function"!=typeof t)throw new Error("obliterator/iterator: expecting a function!");this.next=t}Object.defineProperty(k,"defaultMaxListeners",{enumerable:!0,get:function(){return _},set:function(t){if("number"!=typeof t||t<0||m(t))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+t+".");_=t}}),k.init=function(){void 0!==this._events&&this._events!==Object.getPrototypeOf(this)._events||(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0},k.prototype.setMaxListeners=function(t){if("number"!=typeof t||t<0||m(t))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+t+".");return this._maxListeners=t,this},k.prototype.getMaxListeners=function(){return x(this)},k.prototype.emit=function(t){for(var e=[],n=1;n<arguments.length;n++)e.push(arguments[n]);var r="error"===t,i=this._events;if(void 0!==i)r=r&&void 0===i.error;else if(!r)return!1;if(r){var o;if(e.length>0&&(o=e[0]),o instanceof Error)throw o;var a=new Error("Unhandled error."+(o?" ("+o.message+")":""));throw a.context=o,a}var u=i[t];if(void 0===u)return!1;if("function"==typeof u)b(u,this,e);else{var c=u.length,s=U(u,c);for(n=0;n<c;++n)b(s[n],this,e)}return!0},k.prototype.addListener=function(t,e){return E(this,t,e,!1)},k.prototype.on=k.prototype.addListener,k.prototype.prependListener=function(t,e){return E(this,t,e,!0)},k.prototype.once=function(t,e){return G(e),this.on(t,S(this,t,e)),this},k.prototype.prependOnceListener=function(t,e){return G(e),this.prependListener(t,S(this,t,e)),this},k.prototype.removeListener=function(t,e){var n,r,i,o,a;if(G(e),void 0===(r=this._events))return this;if(void 0===(n=r[t]))return this;if(n===e||n.listener===e)0==--this._eventsCount?this._events=Object.create(null):(delete r[t],r.removeListener&&this.emit("removeListener",t,n.listener||e));else if("function"!=typeof n){for(i=-1,o=n.length-1;o>=0;o--)if(n[o]===e||n[o].listener===e){a=n[o].listener,i=o;break}if(i<0)return this;0===i?n.shift():function(t,e){for(;e+1<t.length;e++)t[e]=t[e+1];t.pop()}(n,i),1===n.length&&(r[t]=n[0]),void 0!==r.removeListener&&this.emit("removeListener",t,a||e)}return this},k.prototype.off=k.prototype.removeListener,k.prototype.removeAllListeners=function(t){var e,n,r;if(void 0===(n=this._events))return this;if(void 0===n.removeListener)return 0===arguments.length?(this._events=Object.create(null),this._eventsCount=0):void 0!==n[t]&&(0==--this._eventsCount?this._events=Object.create(null):delete n[t]),this;if(0===arguments.length){var i,o=Object.keys(n);for(r=0;r<o.length;++r)"removeListener"!==(i=o[r])&&this.removeAllListeners(i);return this.removeAllListeners("removeListener"),this._events=Object.create(null),this._eventsCount=0,this}if("function"==typeof(e=n[t]))this.removeListener(t,e);else if(void 0!==e)for(r=e.length-1;r>=0;r--)this.removeListener(t,e[r]);return this},k.prototype.listeners=function(t){return D(this,t,!0)},k.prototype.rawListeners=function(t){return D(this,t,!1)},k.listenerCount=function(t,e){return"function"==typeof t.listenerCount?t.listenerCount(e):L.call(t,e)},k.prototype.listenerCount=L,k.prototype.eventNames=function(){return this._eventsCount>0?y(this._events):[]},"undefined"!=typeof Symbol&&(j.prototype[Symbol.iterator]=function(){return this}),j.of=function(){var t=arguments,e=t.length,n=0;return new j((function(){return n>=e?{done:!0}:{done:!1,value:t[n++]}}))},j.empty=function(){return new j((function(){return{done:!0}}))},j.fromSequence=function(t){var e=0,n=t.length;return new j((function(){return e>=n?{done:!0}:{done:!1,value:t[e++]}}))},j.is=function(t){return t instanceof j||"object"==typeof t&&null!==t&&"function"==typeof t.next};var O=j,C={};C.ARRAY_BUFFER_SUPPORT="undefined"!=typeof ArrayBuffer,C.SYMBOL_SUPPORT="undefined"!=typeof Symbol;var z=O,M=C,W=M.ARRAY_BUFFER_SUPPORT,P=M.SYMBOL_SUPPORT;var R=function(t){var e=function(t){return"string"==typeof t||Array.isArray(t)||W&&ArrayBuffer.isView(t)?z.fromSequence(t):"object"!=typeof t||null===t?null:P&&"function"==typeof t[Symbol.iterator]?t[Symbol.iterator]():"function"==typeof t.next?t:null}(t);if(!e)throw new Error("obliterator: target is not iterable nor a valid iterator.");return e},K=R,T=function(t,e){for(var n,r=arguments.length>1?e:1/0,i=r!==1/0?new Array(r):[],o=0,a=K(t);;){if(o===r)return i;if((n=a.next()).done)return o!==e&&(i.length=o),i;i[o++]=n.value}},B=function(t){function n(e){var n;return(n=t.call(this)||this).name="GraphError",n.message=e,n}return e(n,t),n}(a(Error)),F=function(t){function n(e){var r;return(r=t.call(this,e)||this).name="InvalidArgumentsGraphError","function"==typeof Error.captureStackTrace&&Error.captureStackTrace(u(r),n.prototype.constructor),r}return e(n,t),n}(B),I=function(t){function n(e){var r;return(r=t.call(this,e)||this).name="NotFoundGraphError","function"==typeof Error.captureStackTrace&&Error.captureStackTrace(u(r),n.prototype.constructor),r}return e(n,t),n}(B),Y=function(t){function n(e){var r;return(r=t.call(this,e)||this).name="UsageGraphError","function"==typeof Error.captureStackTrace&&Error.captureStackTrace(u(r),n.prototype.constructor),r}return e(n,t),n}(B);function q(t,e){this.key=t,this.attributes=e,this.clear()}function J(t,e){this.key=t,this.attributes=e,this.clear()}function V(t,e){this.key=t,this.attributes=e,this.clear()}function H(t,e,n,r,i){this.key=e,this.attributes=i,this.undirected=t,this.source=n,this.target=r}q.prototype.clear=function(){this.inDegree=0,this.outDegree=0,this.undirectedDegree=0,this.in={},this.out={},this.undirected={}},J.prototype.clear=function(){this.inDegree=0,this.outDegree=0,this.in={},this.out={}},V.prototype.clear=function(){this.undirectedDegree=0,this.undirected={}},H.prototype.attach=function(){var t="out",e="in";this.undirected&&(t=e="undirected");var n=this.source.key,r=this.target.key;this.source[t][r]=this,this.undirected&&n===r||(this.target[e][n]=this)},H.prototype.attachMulti=function(){var t="out",e="in",n=this.source.key,r=this.target.key;this.undirected&&(t=e="undirected");var i=this.source[t],o=i[r];if(void 0===o)return i[r]=this,void(this.undirected&&n===r||(this.target[e][n]=this));o.previous=this,this.next=o,i[r]=this,this.target[e][n]=this},H.prototype.detach=function(){var t=this.source.key,e=this.target.key,n="out",r="in";this.undirected&&(n=r="undirected"),delete this.source[n][e],delete this.target[r][t]},H.prototype.detachMulti=function(){var t=this.source.key,e=this.target.key,n="out",r="in";this.undirected&&(n=r="undirected"),void 0===this.previous?void 0===this.next?(delete this.source[n][e],delete this.target[r][t]):(this.next.previous=void 0,this.source[n][e]=this.next,this.target[r][t]=this.next):(this.previous.next=this.next,void 0!==this.next&&(this.next.previous=this.previous))};function Q(t,e,n,r,i,o,a){var u,c,s,d;if(r=""+r,0===n){if(!(u=t._nodes.get(r)))throw new I("Graph.".concat(e,': could not find the "').concat(r,'" node in the graph.'));s=i,d=o}else if(3===n){if(i=""+i,!(c=t._edges.get(i)))throw new I("Graph.".concat(e,': could not find the "').concat(i,'" edge in the graph.'));var h=c.source.key,p=c.target.key;if(r===h)u=c.target;else{if(r!==p)throw new I("Graph.".concat(e,': the "').concat(r,'" node is not attached to the "').concat(i,'" edge (').concat(h,", ").concat(p,")."));u=c.source}s=o,d=a}else{if(!(c=t._edges.get(r)))throw new I("Graph.".concat(e,': could not find the "').concat(r,'" edge in the graph.'));u=1===n?c.source:c.target,s=i,d=o}return[u,s,d]}var X=[{name:function(t){return"get".concat(t,"Attribute")},attacher:function(t,e,n){t.prototype[e]=function(t,r,i){var o=Q(this,e,n,t,r,i),a=o[0],u=o[1];return a.attributes[u]}}},{name:function(t){return"get".concat(t,"Attributes")},attacher:function(t,e,n){t.prototype[e]=function(t,r){return Q(this,e,n,t,r)[0].attributes}}},{name:function(t){return"has".concat(t,"Attribute")},attacher:function(t,e,n){t.prototype[e]=function(t,r,i){var o=Q(this,e,n,t,r,i),a=o[0],u=o[1];return a.attributes.hasOwnProperty(u)}}},{name:function(t){return"set".concat(t,"Attribute")},attacher:function(t,e,n){t.prototype[e]=function(t,r,i,o){var a=Q(this,e,n,t,r,i,o),u=a[0],c=a[1],s=a[2];return u.attributes[c]=s,this.emit("nodeAttributesUpdated",{key:u.key,type:"set",attributes:u.attributes,name:c}),this}}},{name:function(t){return"update".concat(t,"Attribute")},attacher:function(t,e,n){t.prototype[e]=function(t,r,i,o){var a=Q(this,e,n,t,r,i,o),u=a[0],c=a[1],s=a[2];if("function"!=typeof s)throw new F("Graph.".concat(e,": updater should be a function."));var d=u.attributes,h=s(d[c]);return d[c]=h,this.emit("nodeAttributesUpdated",{key:u.key,type:"set",attributes:u.attributes,name:c}),this}}},{name:function(t){return"remove".concat(t,"Attribute")},attacher:function(t,e,n){t.prototype[e]=function(t,r,i){var o=Q(this,e,n,t,r,i),a=o[0],u=o[1];return delete a.attributes[u],this.emit("nodeAttributesUpdated",{key:a.key,type:"remove",attributes:a.attributes,name:u}),this}}},{name:function(t){return"replace".concat(t,"Attributes")},attacher:function(t,e,n){t.prototype[e]=function(t,r,i){var o=Q(this,e,n,t,r,i),a=o[0],u=o[1];if(!h(u))throw new F("Graph.".concat(e,": provided attributes are not a plain object."));return a.attributes=u,this.emit("nodeAttributesUpdated",{key:a.key,type:"replace",attributes:a.attributes}),this}}},{name:function(t){return"merge".concat(t,"Attributes")},attacher:function(t,e,n){t.prototype[e]=function(t,r,i){var o=Q(this,e,n,t,r,i),a=o[0],u=o[1];if(!h(u))throw new F("Graph.".concat(e,": provided attributes are not a plain object."));return c(a.attributes,u),this.emit("nodeAttributesUpdated",{key:a.key,type:"merge",attributes:a.attributes,data:u}),this}}},{name:function(t){return"update".concat(t,"Attributes")},attacher:function(t,e,n){t.prototype[e]=function(t,r,i){var o=Q(this,e,n,t,r,i),a=o[0],u=o[1];if("function"!=typeof u)throw new F("Graph.".concat(e,": provided updater is not a function."));return a.attributes=u(a.attributes),this.emit("nodeAttributesUpdated",{key:a.key,type:"update",attributes:a.attributes}),this}}}];var Z=[{name:function(t){return"get".concat(t,"Attribute")},attacher:function(t,e,n){t.prototype[e]=function(t,r){var i;if("mixed"!==this.type&&"mixed"!==n&&n!==this.type)throw new Y("Graph.".concat(e,": cannot find this type of edges in your ").concat(this.type," graph."));if(arguments.length>2){if(this.multi)throw new Y("Graph.".concat(e,": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about."));var o=""+t,a=""+r;if(r=arguments[2],!(i=s(this,o,a,n)))throw new I("Graph.".concat(e,': could not find an edge for the given path ("').concat(o,'" - "').concat(a,'").'))}else{if("mixed"!==n)throw new Y("Graph.".concat(e,": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type."));if(t=""+t,!(i=this._edges.get(t)))throw new I("Graph.".concat(e,': could not find the "').concat(t,'" edge in the graph.'))}return i.attributes[r]}}},{name:function(t){return"get".concat(t,"Attributes")},attacher:function(t,e,n){t.prototype[e]=function(t){var r;if("mixed"!==this.type&&"mixed"!==n&&n!==this.type)throw new Y("Graph.".concat(e,": cannot find this type of edges in your ").concat(this.type," graph."));if(arguments.length>1){if(this.multi)throw new Y("Graph.".concat(e,": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about."));var i=""+t,o=""+arguments[1];if(!(r=s(this,i,o,n)))throw new I("Graph.".concat(e,': could not find an edge for the given path ("').concat(i,'" - "').concat(o,'").'))}else{if("mixed"!==n)throw new Y("Graph.".concat(e,": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type."));if(t=""+t,!(r=this._edges.get(t)))throw new I("Graph.".concat(e,': could not find the "').concat(t,'" edge in the graph.'))}return r.attributes}}},{name:function(t){return"has".concat(t,"Attribute")},attacher:function(t,e,n){t.prototype[e]=function(t,r){var i;if("mixed"!==this.type&&"mixed"!==n&&n!==this.type)throw new Y("Graph.".concat(e,": cannot find this type of edges in your ").concat(this.type," graph."));if(arguments.length>2){if(this.multi)throw new Y("Graph.".concat(e,": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about."));var o=""+t,a=""+r;if(r=arguments[2],!(i=s(this,o,a,n)))throw new I("Graph.".concat(e,': could not find an edge for the given path ("').concat(o,'" - "').concat(a,'").'))}else{if("mixed"!==n)throw new Y("Graph.".concat(e,": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type."));if(t=""+t,!(i=this._edges.get(t)))throw new I("Graph.".concat(e,': could not find the "').concat(t,'" edge in the graph.'))}return i.attributes.hasOwnProperty(r)}}},{name:function(t){return"set".concat(t,"Attribute")},attacher:function(t,e,n){t.prototype[e]=function(t,r,i){var o;if("mixed"!==this.type&&"mixed"!==n&&n!==this.type)throw new Y("Graph.".concat(e,": cannot find this type of edges in your ").concat(this.type," graph."));if(arguments.length>3){if(this.multi)throw new Y("Graph.".concat(e,": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about."));var a=""+t,u=""+r;if(r=arguments[2],i=arguments[3],!(o=s(this,a,u,n)))throw new I("Graph.".concat(e,': could not find an edge for the given path ("').concat(a,'" - "').concat(u,'").'))}else{if("mixed"!==n)throw new Y("Graph.".concat(e,": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type."));if(t=""+t,!(o=this._edges.get(t)))throw new I("Graph.".concat(e,': could not find the "').concat(t,'" edge in the graph.'))}return o.attributes[r]=i,this.emit("edgeAttributesUpdated",{key:o.key,type:"set",attributes:o.attributes,name:r}),this}}},{name:function(t){return"update".concat(t,"Attribute")},attacher:function(t,e,n){t.prototype[e]=function(t,r,i){var o;if("mixed"!==this.type&&"mixed"!==n&&n!==this.type)throw new Y("Graph.".concat(e,": cannot find this type of edges in your ").concat(this.type," graph."));if(arguments.length>3){if(this.multi)throw new Y("Graph.".concat(e,": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about."));var a=""+t,u=""+r;if(r=arguments[2],i=arguments[3],!(o=s(this,a,u,n)))throw new I("Graph.".concat(e,': could not find an edge for the given path ("').concat(a,'" - "').concat(u,'").'))}else{if("mixed"!==n)throw new Y("Graph.".concat(e,": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type."));if(t=""+t,!(o=this._edges.get(t)))throw new I("Graph.".concat(e,': could not find the "').concat(t,'" edge in the graph.'))}if("function"!=typeof i)throw new F("Graph.".concat(e,": updater should be a function."));return o.attributes[r]=i(o.attributes[r]),this.emit("edgeAttributesUpdated",{key:o.key,type:"set",attributes:o.attributes,name:r}),this}}},{name:function(t){return"remove".concat(t,"Attribute")},attacher:function(t,e,n){t.prototype[e]=function(t,r){var i;if("mixed"!==this.type&&"mixed"!==n&&n!==this.type)throw new Y("Graph.".concat(e,": cannot find this type of edges in your ").concat(this.type," graph."));if(arguments.length>2){if(this.multi)throw new Y("Graph.".concat(e,": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about."));var o=""+t,a=""+r;if(r=arguments[2],!(i=s(this,o,a,n)))throw new I("Graph.".concat(e,': could not find an edge for the given path ("').concat(o,'" - "').concat(a,'").'))}else{if("mixed"!==n)throw new Y("Graph.".concat(e,": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type."));if(t=""+t,!(i=this._edges.get(t)))throw new I("Graph.".concat(e,': could not find the "').concat(t,'" edge in the graph.'))}return delete i.attributes[r],this.emit("edgeAttributesUpdated",{key:i.key,type:"remove",attributes:i.attributes,name:r}),this}}},{name:function(t){return"replace".concat(t,"Attributes")},attacher:function(t,e,n){t.prototype[e]=function(t,r){var i;if("mixed"!==this.type&&"mixed"!==n&&n!==this.type)throw new Y("Graph.".concat(e,": cannot find this type of edges in your ").concat(this.type," graph."));if(arguments.length>2){if(this.multi)throw new Y("Graph.".concat(e,": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about."));var o=""+t,a=""+r;if(r=arguments[2],!(i=s(this,o,a,n)))throw new I("Graph.".concat(e,': could not find an edge for the given path ("').concat(o,'" - "').concat(a,'").'))}else{if("mixed"!==n)throw new Y("Graph.".concat(e,": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type."));if(t=""+t,!(i=this._edges.get(t)))throw new I("Graph.".concat(e,': could not find the "').concat(t,'" edge in the graph.'))}if(!h(r))throw new F("Graph.".concat(e,": provided attributes are not a plain object."));return i.attributes=r,this.emit("edgeAttributesUpdated",{key:i.key,type:"replace",attributes:i.attributes}),this}}},{name:function(t){return"merge".concat(t,"Attributes")},attacher:function(t,e,n){t.prototype[e]=function(t,r){var i;if("mixed"!==this.type&&"mixed"!==n&&n!==this.type)throw new Y("Graph.".concat(e,": cannot find this type of edges in your ").concat(this.type," graph."));if(arguments.length>2){if(this.multi)throw new Y("Graph.".concat(e,": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about."));var o=""+t,a=""+r;if(r=arguments[2],!(i=s(this,o,a,n)))throw new I("Graph.".concat(e,': could not find an edge for the given path ("').concat(o,'" - "').concat(a,'").'))}else{if("mixed"!==n)throw new Y("Graph.".concat(e,": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type."));if(t=""+t,!(i=this._edges.get(t)))throw new I("Graph.".concat(e,': could not find the "').concat(t,'" edge in the graph.'))}if(!h(r))throw new F("Graph.".concat(e,": provided attributes are not a plain object."));return c(i.attributes,r),this.emit("edgeAttributesUpdated",{key:i.key,type:"merge",attributes:i.attributes,data:r}),this}}},{name:function(t){return"update".concat(t,"Attributes")},attacher:function(t,e,n){t.prototype[e]=function(t,r){var i;if("mixed"!==this.type&&"mixed"!==n&&n!==this.type)throw new Y("Graph.".concat(e,": cannot find this type of edges in your ").concat(this.type," graph."));if(arguments.length>2){if(this.multi)throw new Y("Graph.".concat(e,": cannot use a {source,target} combo when asking about an edge's attributes in a MultiGraph since we cannot infer the one you want information about."));var o=""+t,a=""+r;if(r=arguments[2],!(i=s(this,o,a,n)))throw new I("Graph.".concat(e,': could not find an edge for the given path ("').concat(o,'" - "').concat(a,'").'))}else{if("mixed"!==n)throw new Y("Graph.".concat(e,": calling this method with only a key (vs. a source and target) does not make sense since an edge with this key could have the other type."));if(t=""+t,!(i=this._edges.get(t)))throw new I("Graph.".concat(e,': could not find the "').concat(t,'" edge in the graph.'))}if("function"!=typeof r)throw new F("Graph.".concat(e,": provided updater is not a function."));return i.attributes=r(i.attributes),this.emit("edgeAttributesUpdated",{key:i.key,type:"update",attributes:i.attributes}),this}}}];var $=O,tt=R,et=function(){var t=arguments,e=null,n=-1;return new $((function(){for(var r=null;;){if(null===e){if(++n>=t.length)return{done:!0};e=tt(t[n])}if(!0!==(r=e.next()).done)break;e=null}return r}))},nt=[{name:"edges",type:"mixed"},{name:"inEdges",type:"directed",direction:"in"},{name:"outEdges",type:"directed",direction:"out"},{name:"inboundEdges",type:"mixed",direction:"in"},{name:"outboundEdges",type:"mixed",direction:"out"},{name:"directedEdges",type:"directed"},{name:"undirectedEdges",type:"undirected"}];function rt(t,e,n,r){var i=!1;for(var o in e)if(o!==r){var a=e[o];if(i=n(a.key,a.attributes,a.source.key,a.target.key,a.source.attributes,a.target.attributes,a.undirected),t&&i)return a.key}}function it(t,e,n,r){var i,o,a,u=!1;for(var c in e)if(c!==r){i=e[c];do{if(o=i.source,a=i.target,u=n(i.key,i.attributes,o.key,a.key,o.attributes,a.attributes,i.undirected),t&&u)return i.key;i=i.next}while(void 0!==i)}}function ot(t,e){var n,r=Object.keys(t),i=r.length,o=0;return new O((function(){do{if(n)n=n.next;else{if(o>=i)return{done:!0};var a=r[o++];if(a===e){n=void 0;continue}n=t[a]}}while(!n);return{done:!1,value:{edge:n.key,attributes:n.attributes,source:n.source.key,target:n.target.key,sourceAttributes:n.source.attributes,targetAttributes:n.target.attributes,undirected:n.undirected}}}))}function at(t,e,n,r){var i=e[n];if(i){var o=i.source,a=i.target;return r(i.key,i.attributes,o.key,a.key,o.attributes,a.attributes,i.undirected)&&t?i.key:void 0}}function ut(t,e,n,r){var i=e[n];if(i){var o=!1;do{if(o=r(i.key,i.attributes,i.source.key,i.target.key,i.source.attributes,i.target.attributes,i.undirected),t&&o)return i.key;i=i.next}while(void 0!==i)}}function ct(t,e){var n=t[e];return void 0!==n.next?new O((function(){if(!n)return{done:!0};var t={edge:n.key,attributes:n.attributes,source:n.source.key,target:n.target.key,sourceAttributes:n.source.attributes,targetAttributes:n.target.attributes,undirected:n.undirected};return n=n.next,{done:!1,value:t}})):O.of({edge:n.key,attributes:n.attributes,source:n.source.key,target:n.target.key,sourceAttributes:n.source.attributes,targetAttributes:n.target.attributes,undirected:n.undirected})}function st(t,e){if(0===t.size)return[];if("mixed"===e||e===t.type)return"function"==typeof Array.from?Array.from(t._edges.keys()):T(t._edges.keys(),t._edges.size);for(var n,r,i="undirected"===e?t.undirectedSize:t.directedSize,o=new Array(i),a="undirected"===e,u=t._edges.values(),c=0;!0!==(n=u.next()).done;)(r=n.value).undirected===a&&(o[c++]=r.key);return o}function dt(t,e,n,r){if(0!==e.size)for(var i,o,a="mixed"!==n&&n!==e.type,u="undirected"===n,c=!1,s=e._edges.values();!0!==(i=s.next()).done;)if(o=i.value,!a||o.undirected===u){var d=o,h=d.key,p=d.attributes,f=d.source,l=d.target;if(c=r(h,p,f.key,l.key,f.attributes,l.attributes,o.undirected),t&&c)return h}}function ht(t,e){if(0===t.size)return O.empty();var n="mixed"!==e&&e!==t.type,r="undirected"===e,i=t._edges.values();return new O((function(){for(var t,e;;){if((t=i.next()).done)return t;if(e=t.value,!n||e.undirected===r)break}return{value:{edge:e.key,attributes:e.attributes,source:e.source.key,target:e.target.key,sourceAttributes:e.source.attributes,targetAttributes:e.target.attributes,undirected:e.undirected},done:!1}}))}function pt(t,e,n,r,i,o){var a,u=e?it:rt;if("undirected"!==n){if("out"!==r&&(a=u(t,i.in,o),t&&a))return a;if("in"!==r&&(a=u(t,i.out,o,r?void 0:i.key),t&&a))return a}if("directed"!==n&&(a=u(t,i.undirected,o),t&&a))return a}function ft(t,e,n,r){var i=[];return pt(!1,t,e,n,r,(function(t){i.push(t)})),i}function lt(t,e,n){var r=O.empty();return"undirected"!==t&&("out"!==e&&void 0!==n.in&&(r=et(r,ot(n.in))),"in"!==e&&void 0!==n.out&&(r=et(r,ot(n.out,e?void 0:n.key)))),"directed"!==t&&void 0!==n.undirected&&(r=et(r,ot(n.undirected))),r}function gt(t,e,n,r,i,o,a){var u,c=n?ut:at;if("undirected"!==e){if(void 0!==i.in&&"out"!==r&&(u=c(t,i.in,o,a),t&&u))return u;if(void 0!==i.out&&"in"!==r&&(r||i.key!==o)&&(u=c(t,i.out,o,a),t&&u))return u}if("directed"!==e&&void 0!==i.undirected&&(u=c(t,i.undirected,o,a),t&&u))return u}function yt(t,e,n,r,i){var o=[];return gt(!1,t,e,n,r,i,(function(t){o.push(t)})),o}function wt(t,e,n,r){var i=O.empty();return"undirected"!==t&&(void 0!==n.in&&"out"!==e&&r in n.in&&(i=et(i,ct(n.in,r))),void 0!==n.out&&"in"!==e&&r in n.out&&(e||n.key!==r)&&(i=et(i,ct(n.out,r)))),"directed"!==t&&void 0!==n.undirected&&r in n.undirected&&(i=et(i,ct(n.undirected,r))),i}var vt=[{name:"neighbors",type:"mixed"},{name:"inNeighbors",type:"directed",direction:"in"},{name:"outNeighbors",type:"directed",direction:"out"},{name:"inboundNeighbors",type:"mixed",direction:"in"},{name:"outboundNeighbors",type:"mixed",direction:"out"},{name:"directedNeighbors",type:"directed"},{name:"undirectedNeighbors",type:"undirected"}];function bt(){this.A=null,this.B=null}function mt(t,e,n,r,i){for(var o in r){var a=r[o],u=a.source,c=a.target,s=u===n?c:u;if(!e||!e.has(s.key)){var d=i(s.key,s.attributes);if(t&&d)return s.key}}}function kt(t,e,n,r,i){if("mixed"!==e){if("undirected"===e)return mt(t,null,r,r.undirected,i);if("string"==typeof n)return mt(t,null,r,r[n],i)}var o,a=new bt;if("undirected"!==e){if("out"!==n){if(o=mt(t,null,r,r.in,i),t&&o)return o;a.wrap(r.in)}if("in"!==n){if(o=mt(t,a,r,r.out,i),t&&o)return o;a.wrap(r.out)}}if("directed"!==e&&(o=mt(t,a,r,r.undirected,i),t&&o))return o}function _t(t,e,n){var r=Object.keys(n),i=r.length,o=0;return new O((function(){var a=null;do{if(o>=i)return t&&t.wrap(n),{done:!0};var u=n[r[o++]],c=u.source,s=u.target;a=c===e?s:c,t&&t.has(a.key)&&(a=null)}while(null===a);return{done:!1,value:{neighbor:a.key,attributes:a.attributes}}}))}function Gt(t,e){var n=e.name,r=e.type,i=e.direction;t.prototype[n]=function(t){if("mixed"!==r&&"mixed"!==this.type&&r!==this.type)return[];t=""+t;var e=this._nodes.get(t);if(void 0===e)throw new I("Graph.".concat(n,': could not find the "').concat(t,'" node in the graph.'));return function(t,e,n){if("mixed"!==t){if("undirected"===t)return Object.keys(n.undirected);if("string"==typeof e)return Object.keys(n[e])}var r=[];return kt(!1,t,e,n,(function(t){r.push(t)})),r}("mixed"===r?this.type:r,i,e)}}function xt(t,e){var n=e.name,r=e.type,i=e.direction,o=n.slice(0,-1)+"Entries";t.prototype[o]=function(t){if("mixed"!==r&&"mixed"!==this.type&&r!==this.type)return O.empty();t=""+t;var e=this._nodes.get(t);if(void 0===e)throw new I("Graph.".concat(o,': could not find the "').concat(t,'" node in the graph.'));return function(t,e,n){if("mixed"!==t){if("undirected"===t)return _t(null,n,n.undirected);if("string"==typeof e)return _t(null,n,n[e])}var r=O.empty(),i=new bt;return"undirected"!==t&&("out"!==e&&(r=et(r,_t(i,n,n.in))),"in"!==e&&(r=et(r,_t(i,n,n.out)))),"directed"!==t&&(r=et(r,_t(i,n,n.undirected))),r}("mixed"===r?this.type:r,i,e)}}function Et(t,e,n,r,i){for(var o,a,u,c,s,d,h,p=r._nodes.values(),f=r.type;!0!==(o=p.next()).done;){var l=!1;if(a=o.value,"undirected"!==f)for(u in c=a.out){s=c[u];do{if(d=s.target,l=!0,h=i(a.key,d.key,a.attributes,d.attributes,s.key,s.attributes,s.undirected),t&&h)return s;s=s.next}while(s)}if("directed"!==f)for(u in c=a.undirected)if(!(e&&a.key>u)){s=c[u];do{if((d=s.target).key!==u&&(d=s.source),l=!0,h=i(a.key,d.key,a.attributes,d.attributes,s.key,s.attributes,s.undirected),t&&h)return s;s=s.next}while(s)}if(n&&!l&&(h=i(a.key,null,a.attributes,null,null,null,null),t&&h))return null}}function At(t){if(!h(t))throw new F('Graph.import: invalid serialized node. A serialized node should be a plain object with at least a "key" property.');if(!("key"in t))throw new F("Graph.import: serialized node is missing its key.");if("attributes"in t&&(!h(t.attributes)||null===t.attributes))throw new F("Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.")}function St(t){if(!h(t))throw new F('Graph.import: invalid serialized edge. A serialized edge should be a plain object with at least a "source" & "target" property.');if(!("source"in t))throw new F("Graph.import: serialized edge is missing its source.");if(!("target"in t))throw new F("Graph.import: serialized edge is missing its target.");if("attributes"in t&&(!h(t.attributes)||null===t.attributes))throw new F("Graph.import: invalid attributes. Attributes should be a plain object, null or omitted.");if("undirected"in t&&"boolean"!=typeof t.undirected)throw new F("Graph.import: invalid undirectedness information. Undirected should be boolean or omitted.")}bt.prototype.wrap=function(t){null===this.A?this.A=t:null===this.B&&(this.B=t)},bt.prototype.has=function(t){return null!==this.A&&t in this.A||null!==this.B&&t in this.B};var Dt,Lt=(Dt=255&Math.floor(256*Math.random()),function(){return Dt++}),Ut=new Set(["directed","undirected","mixed"]),Nt=new Set(["domain","_events","_eventsCount","_maxListeners"]),jt={allowSelfLoops:!0,multi:!1,type:"mixed"};function Ot(t,e,n){var r=new t.NodeDataClass(e,n);return t._nodes.set(e,r),t.emit("nodeAdded",{key:e,attributes:n}),r}function Ct(t,e,n,r,i,o,a,u){if(!r&&"undirected"===t.type)throw new Y("Graph.".concat(e,": you cannot add a directed edge to an undirected graph. Use the #.addEdge or #.addUndirectedEdge instead."));if(r&&"directed"===t.type)throw new Y("Graph.".concat(e,": you cannot add an undirected edge to a directed graph. Use the #.addEdge or #.addDirectedEdge instead."));if(u&&!h(u))throw new F("Graph.".concat(e,': invalid attributes. Expecting an object but got "').concat(u,'"'));if(o=""+o,a=""+a,u=u||{},!t.allowSelfLoops&&o===a)throw new Y("Graph.".concat(e,': source & target are the same ("').concat(o,"\"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false."));var c=t._nodes.get(o),s=t._nodes.get(a);if(!c)throw new I("Graph.".concat(e,': source node "').concat(o,'" not found.'));if(!s)throw new I("Graph.".concat(e,': target node "').concat(a,'" not found.'));var d={key:null,undirected:r,source:o,target:a,attributes:u};if(n)i=t._edgeKeyGenerator();else if(i=""+i,t._edges.has(i))throw new Y("Graph.".concat(e,': the "').concat(i,'" edge already exists in the graph.'));if(!t.multi&&(r?void 0!==c.undirected[a]:void 0!==c.out[a]))throw new Y("Graph.".concat(e,': an edge linking "').concat(o,'" to "').concat(a,"\" already exists. If you really want to add multiple edges linking those nodes, you should create a multi graph by using the 'multi' option."));var p=new H(r,i,c,s,u);t._edges.set(i,p);var f=o===a;return r?(c.undirectedDegree++,s.undirectedDegree++,f&&t._undirectedSelfLoopCount++):(c.outDegree++,s.inDegree++,f&&t._directedSelfLoopCount++),t.multi?p.attachMulti():p.attach(),r?t._undirectedSize++:t._directedSize++,d.key=i,t.emit("edgeAdded",d),i}function zt(t,e,n,r,i,o,a,u,s){if(!r&&"undirected"===t.type)throw new Y("Graph.".concat(e,": you cannot merge/update a directed edge to an undirected graph. Use the #.mergeEdge/#.updateEdge or #.addUndirectedEdge instead."));if(r&&"directed"===t.type)throw new Y("Graph.".concat(e,": you cannot merge/update an undirected edge to a directed graph. Use the #.mergeEdge/#.updateEdge or #.addDirectedEdge instead."));if(u)if(s){if("function"!=typeof u)throw new F("Graph.".concat(e,': invalid updater function. Expecting a function but got "').concat(u,'"'))}else if(!h(u))throw new F("Graph.".concat(e,': invalid attributes. Expecting an object but got "').concat(u,'"'));var d;if(o=""+o,a=""+a,s&&(d=u,u=void 0),!t.allowSelfLoops&&o===a)throw new Y("Graph.".concat(e,': source & target are the same ("').concat(o,"\"), thus creating a loop explicitly forbidden by this graph 'allowSelfLoops' option set to false."));var p,f,l=t._nodes.get(o),g=t._nodes.get(a);if(!n&&(p=t._edges.get(i))){if(!(p.source.key===o&&p.target.key===a||r&&p.source.key===a&&p.target.key===o))throw new Y("Graph.".concat(e,': inconsistency detected when attempting to merge the "').concat(i,'" edge with "').concat(o,'" source & "').concat(a,'" target vs. ("').concat(p.source.key,'", "').concat(p.target.key,'").'));f=p}if(f||t.multi||!l||(f=r?l.undirected[a]:l.out[a]),f){var y=[f.key,!1,!1,!1];if(s?!d:!u)return y;if(s){var w=f.attributes;f.attributes=d(w),t.emit("edgeAttributesUpdated",{type:"replace",key:f.key,attributes:f.attributes})}else c(f.attributes,u),t.emit("edgeAttributesUpdated",{type:"merge",key:f.key,attributes:f.attributes,data:u});return y}u=u||{},s&&d&&(u=d(u));var v={key:null,undirected:r,source:o,target:a,attributes:u};if(n)i=t._edgeKeyGenerator();else if(i=""+i,t._edges.has(i))throw new Y("Graph.".concat(e,': the "').concat(i,'" edge already exists in the graph.'));var b=!1,m=!1;l||(l=Ot(t,o,{}),b=!0,o===a&&(g=l,m=!0)),g||(g=Ot(t,a,{}),m=!0),p=new H(r,i,l,g,u),t._edges.set(i,p);var k=o===a;return r?(l.undirectedDegree++,g.undirectedDegree++,k&&t._undirectedSelfLoopCount++):(l.outDegree++,g.inDegree++,k&&t._directedSelfLoopCount++),t.multi?p.attachMulti():p.attach(),r?t._undirectedSize++:t._directedSize++,v.key=i,t.emit("edgeAdded",v),[i,!0,b,m]}function Mt(t,e){t._edges.delete(e.key);var n=e.source,r=e.target,i=e.attributes,o=e.undirected,a=n===r;o?(n.undirectedDegree--,r.undirectedDegree--,a&&t._undirectedSelfLoopCount--):(n.outDegree--,r.inDegree--,a&&t._directedSelfLoopCount--),t.multi?e.detachMulti():e.detach(),o?t._undirectedSize--:t._directedSize--,t.emit("edgeDropped",{key:e.key,attributes:i,source:n.key,target:r.key,undirected:o})}var Wt=function(n){function r(t){var e;if(e=n.call(this)||this,"boolean"!=typeof(t=c({},jt,t)).multi)throw new F("Graph.constructor: invalid 'multi' option. Expecting a boolean but got \"".concat(t.multi,'".'));if(!Ut.has(t.type))throw new F('Graph.constructor: invalid \'type\' option. Should be one of "mixed", "directed" or "undirected" but got "'.concat(t.type,'".'));if("boolean"!=typeof t.allowSelfLoops)throw new F("Graph.constructor: invalid 'allowSelfLoops' option. Expecting a boolean but got \"".concat(t.allowSelfLoops,'".'));var r="mixed"===t.type?q:"directed"===t.type?J:V;f(u(e),"NodeDataClass",r);var i="geid_"+Lt()+"_",o=0;return f(u(e),"_attributes",{}),f(u(e),"_nodes",new Map),f(u(e),"_edges",new Map),f(u(e),"_directedSize",0),f(u(e),"_undirectedSize",0),f(u(e),"_directedSelfLoopCount",0),f(u(e),"_undirectedSelfLoopCount",0),f(u(e),"_edgeKeyGenerator",(function(){var t;do{t=i+o++}while(e._edges.has(t));return t})),f(u(e),"_options",t),Nt.forEach((function(t){return f(u(e),t,e[t])})),l(u(e),"order",(function(){return e._nodes.size})),l(u(e),"size",(function(){return e._edges.size})),l(u(e),"directedSize",(function(){return e._directedSize})),l(u(e),"undirectedSize",(function(){return e._undirectedSize})),l(u(e),"selfLoopCount",(function(){return e._directedSelfLoopCount+e._undirectedSelfLoopCount})),l(u(e),"directedSelfLoopCount",(function(){return e._directedSelfLoopCount})),l(u(e),"undirectedSelfLoopCount",(function(){return e._undirectedSelfLoopCount})),l(u(e),"multi",e._options.multi),l(u(e),"type",e._options.type),l(u(e),"allowSelfLoops",e._options.allowSelfLoops),l(u(e),"implementation",(function(){return"graphology"})),e}e(r,n);var i=r.prototype;return i._resetInstanceCounters=function(){this._directedSize=0,this._undirectedSize=0,this._directedSelfLoopCount=0,this._undirectedSelfLoopCount=0},i.hasNode=function(t){return this._nodes.has(""+t)},i.hasDirectedEdge=function(t,e){if("undirected"===this.type)return!1;if(1===arguments.length){var n=""+t,r=this._edges.get(n);return!!r&&!r.undirected}if(2===arguments.length){t=""+t,e=""+e;var i=this._nodes.get(t);if(!i)return!1;var o=i.out[e];return!!o&&(!this.multi||!!o.size)}throw new F("Graph.hasDirectedEdge: invalid arity (".concat(arguments.length,", instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target."))},i.hasUndirectedEdge=function(t,e){if("directed"===this.type)return!1;if(1===arguments.length){var n=""+t,r=this._edges.get(n);return!!r&&r.undirected}if(2===arguments.length){t=""+t,e=""+e;var i=this._nodes.get(t);if(!i)return!1;var o=i.undirected[e];return!!o&&(!this.multi||!!o.size)}throw new F("Graph.hasDirectedEdge: invalid arity (".concat(arguments.length,", instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target."))},i.hasEdge=function(t,e){if(1===arguments.length){var n=""+t;return this._edges.has(n)}if(2===arguments.length){t=""+t,e=""+e;var r=this._nodes.get(t);if(!r)return!1;var i=void 0!==r.out&&r.out[e];return i||(i=void 0!==r.undirected&&r.undirected[e]),!!i&&(!this.multi||!!i.size)}throw new F("Graph.hasEdge: invalid arity (".concat(arguments.length,", instead of 1 or 2). You can either ask for an edge id or for the existence of an edge between a source & a target."))},i.directedEdge=function(t,e){if("undirected"!==this.type){if(t=""+t,e=""+e,this.multi)throw new Y("Graph.directedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.directedEdges instead.");var n=this._nodes.get(t);if(!n)throw new I('Graph.directedEdge: could not find the "'.concat(t,'" source node in the graph.'));if(!this._nodes.has(e))throw new I('Graph.directedEdge: could not find the "'.concat(e,'" target node in the graph.'));var r=n.out&&n.out[e]||void 0;return r?r.key:void 0}},i.undirectedEdge=function(t,e){if("directed"!==this.type){if(t=""+t,e=""+e,this.multi)throw new Y("Graph.undirectedEdge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.undirectedEdges instead.");var n=this._nodes.get(t);if(!n)throw new I('Graph.undirectedEdge: could not find the "'.concat(t,'" source node in the graph.'));if(!this._nodes.has(e))throw new I('Graph.undirectedEdge: could not find the "'.concat(e,'" target node in the graph.'));var r=n.undirected&&n.undirected[e]||void 0;return r?r.key:void 0}},i.edge=function(t,e){if(this.multi)throw new Y("Graph.edge: this method is irrelevant with multigraphs since there might be multiple edges between source & target. See #.edges instead.");t=""+t,e=""+e;var n=this._nodes.get(t);if(!n)throw new I('Graph.edge: could not find the "'.concat(t,'" source node in the graph.'));if(!this._nodes.has(e))throw new I('Graph.edge: could not find the "'.concat(e,'" target node in the graph.'));var r=n.out&&n.out[e]||n.undirected&&n.undirected[e]||void 0;if(r)return r.key},i.areDirectedNeighbors=function(t,e){t=""+t,e=""+e;var n=this._nodes.get(t);if(!n)throw new I('Graph.areDirectedNeighbors: could not find the "'.concat(t,'" node in the graph.'));return"undirected"!==this.type&&(e in n.in||e in n.out)},i.areOutNeighbors=function(t,e){t=""+t,e=""+e;var n=this._nodes.get(t);if(!n)throw new I('Graph.areOutNeighbors: could not find the "'.concat(t,'" node in the graph.'));return"undirected"!==this.type&&e in n.out},i.areInNeighbors=function(t,e){t=""+t,e=""+e;var n=this._nodes.get(t);if(!n)throw new I('Graph.areInNeighbors: could not find the "'.concat(t,'" node in the graph.'));return"undirected"!==this.type&&e in n.in},i.areUndirectedNeighbors=function(t,e){t=""+t,e=""+e;var n=this._nodes.get(t);if(!n)throw new I('Graph.areUndirectedNeighbors: could not find the "'.concat(t,'" node in the graph.'));return"directed"!==this.type&&e in n.undirected},i.areNeighbors=function(t,e){t=""+t,e=""+e;var n=this._nodes.get(t);if(!n)throw new I('Graph.areNeighbors: could not find the "'.concat(t,'" node in the graph.'));return"undirected"!==this.type&&(e in n.in||e in n.out)||"directed"!==this.type&&e in n.undirected},i.areInboundNeighbors=function(t,e){t=""+t,e=""+e;var n=this._nodes.get(t);if(!n)throw new I('Graph.areInboundNeighbors: could not find the "'.concat(t,'" node in the graph.'));return"undirected"!==this.type&&e in n.in||"directed"!==this.type&&e in n.undirected},i.areOutboundNeighbors=function(t,e){t=""+t,e=""+e;var n=this._nodes.get(t);if(!n)throw new I('Graph.areOutboundNeighbors: could not find the "'.concat(t,'" node in the graph.'));return"undirected"!==this.type&&e in n.out||"directed"!==this.type&&e in n.undirected},i.inDegree=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new I('Graph.inDegree: could not find the "'.concat(t,'" node in the graph.'));return"undirected"===this.type?0:e.inDegree},i.outDegree=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new I('Graph.outDegree: could not find the "'.concat(t,'" node in the graph.'));return"undirected"===this.type?0:e.outDegree},i.directedDegree=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new I('Graph.directedDegree: could not find the "'.concat(t,'" node in the graph.'));return"undirected"===this.type?0:e.inDegree+e.outDegree},i.undirectedDegree=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new I('Graph.undirectedDegree: could not find the "'.concat(t,'" node in the graph.'));return"directed"===this.type?0:e.undirectedDegree},i.inboundDegree=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new I('Graph.inboundDegree: could not find the "'.concat(t,'" node in the graph.'));var n=0;return"directed"!==this.type&&(n+=e.undirectedDegree),"undirected"!==this.type&&(n+=e.inDegree),n},i.outboundDegree=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new I('Graph.outboundDegree: could not find the "'.concat(t,'" node in the graph.'));var n=0;return"directed"!==this.type&&(n+=e.undirectedDegree),"undirected"!==this.type&&(n+=e.outDegree),n},i.degree=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new I('Graph.degree: could not find the "'.concat(t,'" node in the graph.'));var n=0;return"directed"!==this.type&&(n+=e.undirectedDegree),"undirected"!==this.type&&(n+=e.inDegree+e.outDegree),n},i.inDegreeWithoutSelfLoops=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new I('Graph.inDegreeWithoutSelfLoops: could not find the "'.concat(t,'" node in the graph.'));if("undirected"===this.type)return 0;var n=e.in[t],r=n?this.multi?n.size:1:0;return e.inDegree-r},i.outDegreeWithoutSelfLoops=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new I('Graph.outDegreeWithoutSelfLoops: could not find the "'.concat(t,'" node in the graph.'));if("undirected"===this.type)return 0;var n=e.out[t],r=n?this.multi?n.size:1:0;return e.outDegree-r},i.directedDegreeWithoutSelfLoops=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new I('Graph.directedDegreeWithoutSelfLoops: could not find the "'.concat(t,'" node in the graph.'));if("undirected"===this.type)return 0;var n=e.out[t],r=n?this.multi?n.size:1:0;return e.inDegree+e.outDegree-2*r},i.undirectedDegreeWithoutSelfLoops=function(t){t=""+t;var e=this._nodes.get(t);if(!e)throw new I('Graph.undirectedDegreeWithoutSelfLoops: could not find the "'.concat(t,'" node in the graph.'));if("directed"===this.type)return 0;var n=e.undirected[t],r=n?this.multi?n.size:1:0;return e.undirectedDegree-2*r},i.inboundDegreeWithoutSelfLoops=function(t){t=""+t;var e,n=this._nodes.get(t);if(!n)throw new I('Graph.inboundDegreeWithoutSelfLoops: could not find the "'.concat(t,'" node in the graph.'));var r=0,i=0;return"directed"!==this.type&&(r+=n.undirectedDegree,i+=2*((e=n.undirected[t])?this.multi?e.size:1:0)),"undirected"!==this.type&&(r+=n.inDegree,i+=(e=n.out[t])?this.multi?e.size:1:0),r-i},i.outboundDegreeWithoutSelfLoops=function(t){t=""+t;var e,n=this._nodes.get(t);if(!n)throw new I('Graph.outboundDegreeWithoutSelfLoops: could not find the "'.concat(t,'" node in the graph.'));var r=0,i=0;return"directed"!==this.type&&(r+=n.undirectedDegree,i+=2*((e=n.undirected[t])?this.multi?e.size:1:0)),"undirected"!==this.type&&(r+=n.outDegree,i+=(e=n.in[t])?this.multi?e.size:1:0),r-i},i.degreeWithoutSelfLoops=function(t){t=""+t;var e,n=this._nodes.get(t);if(!n)throw new I('Graph.degreeWithoutSelfLoops: could not find the "'.concat(t,'" node in the graph.'));var r=0,i=0;return"directed"!==this.type&&(r+=n.undirectedDegree,i+=2*((e=n.undirected[t])?this.multi?e.size:1:0)),"undirected"!==this.type&&(r+=n.inDegree+n.outDegree,i+=2*((e=n.out[t])?this.multi?e.size:1:0)),r-i},i.source=function(t){t=""+t;var e=this._edges.get(t);if(!e)throw new I('Graph.source: could not find the "'.concat(t,'" edge in the graph.'));return e.source.key},i.target=function(t){t=""+t;var e=this._edges.get(t);if(!e)throw new I('Graph.target: could not find the "'.concat(t,'" edge in the graph.'));return e.target.key},i.extremities=function(t){t=""+t;var e=this._edges.get(t);if(!e)throw new I('Graph.extremities: could not find the "'.concat(t,'" edge in the graph.'));return[e.source.key,e.target.key]},i.opposite=function(t,e){t=""+t,e=""+e;var n=this._edges.get(e);if(!n)throw new I('Graph.opposite: could not find the "'.concat(e,'" edge in the graph.'));var r=n.source.key,i=n.target.key;if(t===r)return i;if(t===i)return r;throw new I('Graph.opposite: the "'.concat(t,'" node is not attached to the "').concat(e,'" edge (').concat(r,", ").concat(i,")."))},i.hasExtremity=function(t,e){t=""+t,e=""+e;var n=this._edges.get(t);if(!n)throw new I('Graph.hasExtremity: could not find the "'.concat(t,'" edge in the graph.'));return n.source.key===e||n.target.key===e},i.isUndirected=function(t){t=""+t;var e=this._edges.get(t);if(!e)throw new I('Graph.isUndirected: could not find the "'.concat(t,'" edge in the graph.'));return e.undirected},i.isDirected=function(t){t=""+t;var e=this._edges.get(t);if(!e)throw new I('Graph.isDirected: could not find the "'.concat(t,'" edge in the graph.'));return!e.undirected},i.isSelfLoop=function(t){t=""+t;var e=this._edges.get(t);if(!e)throw new I('Graph.isSelfLoop: could not find the "'.concat(t,'" edge in the graph.'));return e.source===e.target},i.addNode=function(t,e){var n=function(t,e,n){if(n&&!h(n))throw new F('Graph.addNode: invalid attributes. Expecting an object but got "'.concat(n,'"'));if(e=""+e,n=n||{},t._nodes.has(e))throw new Y('Graph.addNode: the "'.concat(e,'" node already exist in the graph.'));var r=new t.NodeDataClass(e,n);return t._nodes.set(e,r),t.emit("nodeAdded",{key:e,attributes:n}),r}(this,t,e);return n.key},i.mergeNode=function(t,e){if(e&&!h(e))throw new F('Graph.mergeNode: invalid attributes. Expecting an object but got "'.concat(e,'"'));t=""+t,e=e||{};var n=this._nodes.get(t);return n?(e&&(c(n.attributes,e),this.emit("nodeAttributesUpdated",{type:"merge",key:t,attributes:n.attributes,data:e})),[t,!1]):(n=new this.NodeDataClass(t,e),this._nodes.set(t,n),this.emit("nodeAdded",{key:t,attributes:e}),[t,!0])},i.updateNode=function(t,e){if(e&&"function"!=typeof e)throw new F('Graph.updateNode: invalid updater function. Expecting a function but got "'.concat(e,'"'));t=""+t;var n=this._nodes.get(t);if(n){if(e){var r=n.attributes;n.attributes=e(r),this.emit("nodeAttributesUpdated",{type:"replace",key:t,attributes:n.attributes})}return[t,!1]}var i=e?e({}):{};return n=new this.NodeDataClass(t,i),this._nodes.set(t,n),this.emit("nodeAdded",{key:t,attributes:i}),[t,!0]},i.dropNode=function(t){t=""+t;var e,n=this._nodes.get(t);if(!n)throw new I('Graph.dropNode: could not find the "'.concat(t,'" node in the graph.'));if("undirected"!==this.type){for(var r in n.out){e=n.out[r];do{Mt(this,e),e=e.next}while(e)}for(var i in n.in){e=n.in[i];do{Mt(this,e),e=e.next}while(e)}}if("directed"!==this.type)for(var o in n.undirected){e=n.undirected[o];do{Mt(this,e),e=e.next}while(e)}this._nodes.delete(t),this.emit("nodeDropped",{key:t,attributes:n.attributes})},i.dropEdge=function(t){var e;if(arguments.length>1){var n=""+arguments[0],r=""+arguments[1];if(!(e=s(this,n,r,this.type)))throw new I('Graph.dropEdge: could not find the "'.concat(n,'" -> "').concat(r,'" edge in the graph.'))}else if(t=""+t,!(e=this._edges.get(t)))throw new I('Graph.dropEdge: could not find the "'.concat(t,'" edge in the graph.'));return Mt(this,e),this},i.dropDirectedEdge=function(t,e){if(arguments.length<2)throw new Y("Graph.dropDirectedEdge: it does not make sense to try and drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.");if(this.multi)throw new Y("Graph.dropDirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.");var n=s(this,t=""+t,e=""+e,"directed");if(!n)throw new I('Graph.dropDirectedEdge: could not find a "'.concat(t,'" -> "').concat(e,'" edge in the graph.'));return Mt(this,n),this},i.dropUndirectedEdge=function(t,e){if(arguments.length<2)throw new Y("Graph.dropUndirectedEdge: it does not make sense to drop a directed edge by key. What if the edge with this key is undirected? Use #.dropEdge for this purpose instead.");if(this.multi)throw new Y("Graph.dropUndirectedEdge: cannot use a {source,target} combo when dropping an edge in a MultiGraph since we cannot infer the one you want to delete as there could be multiple ones.");var n=s(this,t,e,"undirected");if(!n)throw new I('Graph.dropUndirectedEdge: could not find a "'.concat(t,'" -> "').concat(e,'" edge in the graph.'));return Mt(this,n),this},i.clear=function(){this._edges.clear(),this._nodes.clear(),this._resetInstanceCounters(),this.emit("cleared")},i.clearEdges=function(){for(var t,e=this._nodes.values();!0!==(t=e.next()).done;)t.value.clear();this._edges.clear(),this._resetInstanceCounters(),this.emit("edgesCleared")},i.getAttribute=function(t){return this._attributes[t]},i.getAttributes=function(){return this._attributes},i.hasAttribute=function(t){return this._attributes.hasOwnProperty(t)},i.setAttribute=function(t,e){return this._attributes[t]=e,this.emit("attributesUpdated",{type:"set",attributes:this._attributes,name:t}),this},i.updateAttribute=function(t,e){if("function"!=typeof e)throw new F("Graph.updateAttribute: updater should be a function.");var n=this._attributes[t];return this._attributes[t]=e(n),this.emit("attributesUpdated",{type:"set",attributes:this._attributes,name:t}),this},i.removeAttribute=function(t){return delete this._attributes[t],this.emit("attributesUpdated",{type:"remove",attributes:this._attributes,name:t}),this},i.replaceAttributes=function(t){if(!h(t))throw new F("Graph.replaceAttributes: provided attributes are not a plain object.");return this._attributes=t,this.emit("attributesUpdated",{type:"replace",attributes:this._attributes}),this},i.mergeAttributes=function(t){if(!h(t))throw new F("Graph.mergeAttributes: provided attributes are not a plain object.");return c(this._attributes,t),this.emit("attributesUpdated",{type:"merge",attributes:this._attributes,data:t}),this},i.updateAttributes=function(t){if("function"!=typeof t)throw new F("Graph.updateAttributes: provided updater is not a function.");return this._attributes=t(this._attributes),this.emit("attributesUpdated",{type:"update",attributes:this._attributes}),this},i.updateEachNodeAttributes=function(t,e){if("function"!=typeof t)throw new F("Graph.updateEachNodeAttributes: expecting an updater function.");if(e&&!g(e))throw new F("Graph.updateEachNodeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}");for(var n,r,i=this._nodes.values();!0!==(n=i.next()).done;)(r=n.value).attributes=t(r.key,r.attributes);this.emit("eachNodeAttributesUpdated",{hints:e||null})},i.updateEachEdgeAttributes=function(t,e){if("function"!=typeof t)throw new F("Graph.updateEachEdgeAttributes: expecting an updater function.");if(e&&!g(e))throw new F("Graph.updateEachEdgeAttributes: invalid hints. Expecting an object having the following shape: {attributes?: [string]}");for(var n,r,i,o,a=this._edges.values();!0!==(n=a.next()).done;)i=(r=n.value).source,o=r.target,r.attributes=t(r.key,r.attributes,i.key,o.key,i.attributes,o.attributes,r.undirected);this.emit("eachEdgeAttributesUpdated",{hints:e||null})},i.forEachAdjacencyEntry=function(t){if("function"!=typeof t)throw new F("Graph.forEachAdjacencyEntry: expecting a callback.");Et(!1,!1,!1,this,t)},i.forEachAdjacencyEntryWithOrphans=function(t){if("function"!=typeof t)throw new F("Graph.forEachAdjacencyEntryWithOrphans: expecting a callback.");Et(!1,!1,!0,this,t)},i.forEachAssymetricAdjacencyEntry=function(t){if("function"!=typeof t)throw new F("Graph.forEachAssymetricAdjacencyEntry: expecting a callback.");Et(!1,!0,!1,this,t)},i.forEachAssymetricAdjacencyEntryWithOrphans=function(t){if("function"!=typeof t)throw new F("Graph.forEachAssymetricAdjacencyEntryWithOrphans: expecting a callback.");Et(!1,!0,!0,this,t)},i.nodes=function(){return"function"==typeof Array.from?Array.from(this._nodes.keys()):T(this._nodes.keys(),this._nodes.size)},i.forEachNode=function(t){if("function"!=typeof t)throw new F("Graph.forEachNode: expecting a callback.");for(var e,n,r=this._nodes.values();!0!==(e=r.next()).done;)t((n=e.value).key,n.attributes)},i.findNode=function(t){if("function"!=typeof t)throw new F("Graph.findNode: expecting a callback.");for(var e,n,r=this._nodes.values();!0!==(e=r.next()).done;)if(t((n=e.value).key,n.attributes))return n.key},i.mapNodes=function(t){if("function"!=typeof t)throw new F("Graph.mapNode: expecting a callback.");for(var e,n,r=this._nodes.values(),i=new Array(this.order),o=0;!0!==(e=r.next()).done;)n=e.value,i[o++]=t(n.key,n.attributes);return i},i.someNode=function(t){if("function"!=typeof t)throw new F("Graph.someNode: expecting a callback.");for(var e,n,r=this._nodes.values();!0!==(e=r.next()).done;)if(t((n=e.value).key,n.attributes))return!0;return!1},i.everyNode=function(t){if("function"!=typeof t)throw new F("Graph.everyNode: expecting a callback.");for(var e,n,r=this._nodes.values();!0!==(e=r.next()).done;)if(!t((n=e.value).key,n.attributes))return!1;return!0},i.filterNodes=function(t){if("function"!=typeof t)throw new F("Graph.filterNodes: expecting a callback.");for(var e,n,r=this._nodes.values(),i=[];!0!==(e=r.next()).done;)t((n=e.value).key,n.attributes)&&i.push(n.key);return i},i.reduceNodes=function(t,e){if("function"!=typeof t)throw new F("Graph.reduceNodes: expecting a callback.");if(arguments.length<2)throw new F("Graph.reduceNodes: missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array.");for(var n,r,i=e,o=this._nodes.values();!0!==(n=o.next()).done;)i=t(i,(r=n.value).key,r.attributes);return i},i.nodeEntries=function(){var t=this._nodes.values();return new O((function(){var e=t.next();if(e.done)return e;var n=e.value;return{value:{node:n.key,attributes:n.attributes},done:!1}}))},i.export=function(){var t=new Array(this._nodes.size),e=0;this._nodes.forEach((function(n,r){t[e++]=function(t,e){var n={key:t};return p(e.attributes)||(n.attributes=c({},e.attributes)),n}(r,n)}));var n=new Array(this._edges.size);return e=0,this._edges.forEach((function(t,r){n[e++]=function(t,e){var n={key:t,source:e.source.key,target:e.target.key};return p(e.attributes)||(n.attributes=c({},e.attributes)),e.undirected&&(n.undirected=!0),n}(r,t)})),{options:{type:this.type,multi:this.multi,allowSelfLoops:this.allowSelfLoops},attributes:this.getAttributes(),nodes:t,edges:n}},i.import=function(t){var e,n,r,i,o,a=this,u=arguments.length>1&&void 0!==arguments[1]&&arguments[1];if(d(t))return t.forEachNode((function(t,e){u?a.mergeNode(t,e):a.addNode(t,e)})),t.forEachEdge((function(t,e,n,r,i,o,c){u?c?a.mergeUndirectedEdgeWithKey(t,n,r,e):a.mergeDirectedEdgeWithKey(t,n,r,e):c?a.addUndirectedEdgeWithKey(t,n,r,e):a.addDirectedEdgeWithKey(t,n,r,e)})),this;if(!h(t))throw new F("Graph.import: invalid argument. Expecting a serialized graph or, alternatively, a Graph instance.");if(t.attributes){if(!h(t.attributes))throw new F("Graph.import: invalid attributes. Expecting a plain object.");u?this.mergeAttributes(t.attributes):this.replaceAttributes(t.attributes)}if(t.nodes){if(r=t.nodes,!Array.isArray(r))throw new F("Graph.import: invalid nodes. Expecting an array.");for(e=0,n=r.length;e<n;e++){At(i=r[e]);var c=i,s=c.key,p=c.attributes;u?this.mergeNode(s,p):this.addNode(s,p)}}if(t.edges){if(r=t.edges,!Array.isArray(r))throw new F("Graph.import: invalid edges. Expecting an array.");for(e=0,n=r.length;e<n;e++){St(o=r[e]);var f=o,l=f.source,g=f.target,y=f.attributes,w=f.undirected,v=void 0!==w&&w;"key"in o?(u?v?this.mergeUndirectedEdgeWithKey:this.mergeDirectedEdgeWithKey:v?this.addUndirectedEdgeWithKey:this.addDirectedEdgeWithKey).call(this,o.key,l,g,y):(u?v?this.mergeUndirectedEdge:this.mergeDirectedEdge:v?this.addUndirectedEdge:this.addDirectedEdge).call(this,l,g,y)}}return this},i.nullCopy=function(t){var e=new r(c({},this._options,t));return e.replaceAttributes(c({},this.getAttributes())),e},i.emptyCopy=function(t){var e=this.nullCopy(t);return this._nodes.forEach((function(t,n){var r=c({},t.attributes);t=new e.NodeDataClass(n,r),e._nodes.set(n,t)})),e},i.copy=function(t){if("string"==typeof(t=t||{}).type&&t.type!==this.type&&"mixed"!==t.type)throw new Y('Graph.copy: cannot create an incompatible copy from "'.concat(this.type,'" type to "').concat(t.type,'" because this would mean losing information about the current graph.'));if("boolean"==typeof t.multi&&t.multi!==this.multi&&!0!==t.multi)throw new Y("Graph.copy: cannot create an incompatible copy by downgrading a multi graph to a simple one because this would mean losing information about the current graph.");if("boolean"==typeof t.allowSelfLoops&&t.allowSelfLoops!==this.allowSelfLoops&&!0!==t.allowSelfLoops)throw new Y("Graph.copy: cannot create an incompatible copy from a graph allowing self loops to one that does not because this would mean losing information about the current graph.");for(var e,n,r=this.emptyCopy(t),i=this._edges.values();!0!==(e=i.next()).done;)Ct(r,"copy",!1,(n=e.value).undirected,n.key,n.source.key,n.target.key,c({},n.attributes));return r},i.toJSON=function(){return this.export()},i.toString=function(){return"[object Graph]"},i.inspect=function(){var e=this,n={};this._nodes.forEach((function(t,e){n[e]=t.attributes}));var r={},i={};this._edges.forEach((function(t,n){var o,a=t.undirected?"--":"->",u="",c=t.source.key,s=t.target.key;t.undirected&&c>s&&(o=c,c=s,s=o);var d="(".concat(c,")").concat(a,"(").concat(s,")");n.startsWith("geid_")?e.multi&&(void 0===i[d]?i[d]=0:i[d]++,u+="".concat(i[d],". ")):u+="[".concat(n,"]: "),r[u+=d]=t.attributes}));var o={};for(var a in this)this.hasOwnProperty(a)&&!Nt.has(a)&&"function"!=typeof this[a]&&"symbol"!==t(a)&&(o[a]=this[a]);return o.attributes=this._attributes,o.nodes=n,o.edges=r,f(o,"constructor",this.constructor),o},r}(w.exports.EventEmitter);"undefined"!=typeof Symbol&&(Wt.prototype[Symbol.for("nodejs.util.inspect.custom")]=Wt.prototype.inspect),[{name:function(t){return"".concat(t,"Edge")},generateKey:!0},{name:function(t){return"".concat(t,"DirectedEdge")},generateKey:!0,type:"directed"},{name:function(t){return"".concat(t,"UndirectedEdge")},generateKey:!0,type:"undirected"},{name:function(t){return"".concat(t,"EdgeWithKey")}},{name:function(t){return"".concat(t,"DirectedEdgeWithKey")},type:"directed"},{name:function(t){return"".concat(t,"UndirectedEdgeWithKey")},type:"undirected"}].forEach((function(t){["add","merge","update"].forEach((function(e){var n=t.name(e),r="add"===e?Ct:zt;t.generateKey?Wt.prototype[n]=function(i,o,a){return r(this,n,!0,"undirected"===(t.type||this.type),null,i,o,a,"update"===e)}:Wt.prototype[n]=function(i,o,a,u){return r(this,n,!1,"undirected"===(t.type||this.type),i,o,a,u,"update"===e)}}))})),function(t){X.forEach((function(e){var n=e.name,r=e.attacher;r(t,n("Node"),0),r(t,n("Source"),1),r(t,n("Target"),2),r(t,n("Opposite"),3)}))}(Wt),function(t){Z.forEach((function(e){var n=e.name,r=e.attacher;r(t,n("Edge"),"mixed"),r(t,n("DirectedEdge"),"directed"),r(t,n("UndirectedEdge"),"undirected")}))}(Wt),function(t){nt.forEach((function(e){!function(t,e){var n=e.name,r=e.type,i=e.direction;t.prototype[n]=function(t,e){if("mixed"!==r&&"mixed"!==this.type&&r!==this.type)return[];if(!arguments.length)return st(this,r);if(1===arguments.length){t=""+t;var o=this._nodes.get(t);if(void 0===o)throw new I("Graph.".concat(n,': could not find the "').concat(t,'" node in the graph.'));return ft(this.multi,"mixed"===r?this.type:r,i,o)}if(2===arguments.length){t=""+t,e=""+e;var a=this._nodes.get(t);if(!a)throw new I("Graph.".concat(n,': could not find the "').concat(t,'" source node in the graph.'));if(!this._nodes.has(e))throw new I("Graph.".concat(n,': could not find the "').concat(e,'" target node in the graph.'));return yt(r,this.multi,i,a,e)}throw new F("Graph.".concat(n,": too many arguments (expecting 0, 1 or 2 and got ").concat(arguments.length,")."))}}(t,e),function(t,e){var n=e.name,r=e.type,i=e.direction,o="forEach"+n[0].toUpperCase()+n.slice(1,-1);t.prototype[o]=function(t,e,n){if("mixed"===r||"mixed"===this.type||r===this.type){if(1===arguments.length)return dt(!1,this,r,n=t);if(2===arguments.length){t=""+t,n=e;var a=this._nodes.get(t);if(void 0===a)throw new I("Graph.".concat(o,': could not find the "').concat(t,'" node in the graph.'));return pt(!1,this.multi,"mixed"===r?this.type:r,i,a,n)}if(3===arguments.length){t=""+t,e=""+e;var u=this._nodes.get(t);if(!u)throw new I("Graph.".concat(o,': could not find the "').concat(t,'" source node in the graph.'));if(!this._nodes.has(e))throw new I("Graph.".concat(o,': could not find the "').concat(e,'" target node in the graph.'));return gt(!1,r,this.multi,i,u,e,n)}throw new F("Graph.".concat(o,": too many arguments (expecting 1, 2 or 3 and got ").concat(arguments.length,")."))}};var a="map"+n[0].toUpperCase()+n.slice(1);t.prototype[a]=function(){var t,e=Array.prototype.slice.call(arguments),n=e.pop();if(0===e.length){var i=0;"directed"!==r&&(i+=this.undirectedSize),"undirected"!==r&&(i+=this.directedSize),t=new Array(i);var a=0;e.push((function(e,r,i,o,u,c,s){t[a++]=n(e,r,i,o,u,c,s)}))}else t=[],e.push((function(e,r,i,o,a,u,c){t.push(n(e,r,i,o,a,u,c))}));return this[o].apply(this,e),t};var u="filter"+n[0].toUpperCase()+n.slice(1);t.prototype[u]=function(){var t=Array.prototype.slice.call(arguments),e=t.pop(),n=[];return t.push((function(t,r,i,o,a,u,c){e(t,r,i,o,a,u,c)&&n.push(t)})),this[o].apply(this,t),n};var c="reduce"+n[0].toUpperCase()+n.slice(1);t.prototype[c]=function(){var t,e,n=Array.prototype.slice.call(arguments);if(n.length<2||n.length>4)throw new F("Graph.".concat(c,": invalid number of arguments (expecting 2, 3 or 4 and got ").concat(n.length,")."));if("function"==typeof n[n.length-1]&&"function"!=typeof n[n.length-2])throw new F("Graph.".concat(c,": missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array."));2===n.length?(t=n[0],e=n[1],n=[]):3===n.length?(t=n[1],e=n[2],n=[n[0]]):4===n.length&&(t=n[2],e=n[3],n=[n[0],n[1]]);var r=e;return n.push((function(e,n,i,o,a,u,c){r=t(r,e,n,i,o,a,u,c)})),this[o].apply(this,n),r}}(t,e),function(t,e){var n=e.name,r=e.type,i=e.direction,o="find"+n[0].toUpperCase()+n.slice(1,-1);t.prototype[o]=function(t,e,n){if("mixed"!==r&&"mixed"!==this.type&&r!==this.type)return!1;if(1===arguments.length)return dt(!0,this,r,n=t);if(2===arguments.length){t=""+t,n=e;var a=this._nodes.get(t);if(void 0===a)throw new I("Graph.".concat(o,': could not find the "').concat(t,'" node in the graph.'));return pt(!0,this.multi,"mixed"===r?this.type:r,i,a,n)}if(3===arguments.length){t=""+t,e=""+e;var u=this._nodes.get(t);if(!u)throw new I("Graph.".concat(o,': could not find the "').concat(t,'" source node in the graph.'));if(!this._nodes.has(e))throw new I("Graph.".concat(o,': could not find the "').concat(e,'" target node in the graph.'));return gt(!0,r,this.multi,i,u,e,n)}throw new F("Graph.".concat(o,": too many arguments (expecting 1, 2 or 3 and got ").concat(arguments.length,")."))};var a="some"+n[0].toUpperCase()+n.slice(1,-1);t.prototype[a]=function(){var t=Array.prototype.slice.call(arguments),e=t.pop();return t.push((function(t,n,r,i,o,a,u){return e(t,n,r,i,o,a,u)})),!!this[o].apply(this,t)};var u="every"+n[0].toUpperCase()+n.slice(1,-1);t.prototype[u]=function(){var t=Array.prototype.slice.call(arguments),e=t.pop();return t.push((function(t,n,r,i,o,a,u){return!e(t,n,r,i,o,a,u)})),!this[o].apply(this,t)}}(t,e),function(t,e){var n=e.name,r=e.type,i=e.direction,o=n.slice(0,-1)+"Entries";t.prototype[o]=function(t,e){if("mixed"!==r&&"mixed"!==this.type&&r!==this.type)return O.empty();if(!arguments.length)return ht(this,r);if(1===arguments.length){t=""+t;var n=this._nodes.get(t);if(!n)throw new I("Graph.".concat(o,': could not find the "').concat(t,'" node in the graph.'));return lt(r,i,n)}if(2===arguments.length){t=""+t,e=""+e;var a=this._nodes.get(t);if(!a)throw new I("Graph.".concat(o,': could not find the "').concat(t,'" source node in the graph.'));if(!this._nodes.has(e))throw new I("Graph.".concat(o,': could not find the "').concat(e,'" target node in the graph.'));return wt(r,i,a,e)}throw new F("Graph.".concat(o,": too many arguments (expecting 0, 1 or 2 and got ").concat(arguments.length,")."))}}(t,e)}))}(Wt),function(t){vt.forEach((function(e){Gt(t,e),function(t,e){var n=e.name,r=e.type,i=e.direction,o="forEach"+n[0].toUpperCase()+n.slice(1,-1);t.prototype[o]=function(t,e){if("mixed"===r||"mixed"===this.type||r===this.type){t=""+t;var n=this._nodes.get(t);if(void 0===n)throw new I("Graph.".concat(o,': could not find the "').concat(t,'" node in the graph.'));kt(!1,"mixed"===r?this.type:r,i,n,e)}};var a="map"+n[0].toUpperCase()+n.slice(1);t.prototype[a]=function(t,e){var n=[];return this[o](t,(function(t,r){n.push(e(t,r))})),n};var u="filter"+n[0].toUpperCase()+n.slice(1);t.prototype[u]=function(t,e){var n=[];return this[o](t,(function(t,r){e(t,r)&&n.push(t)})),n};var c="reduce"+n[0].toUpperCase()+n.slice(1);t.prototype[c]=function(t,e,n){if(arguments.length<3)throw new F("Graph.".concat(c,": missing initial value. You must provide it because the callback takes more than one argument and we cannot infer the initial value from the first iteration, as you could with a simple array."));var r=n;return this[o](t,(function(t,n){r=e(r,t,n)})),r}}(t,e),function(t,e){var n=e.name,r=e.type,i=e.direction,o=n[0].toUpperCase()+n.slice(1,-1),a="find"+o;t.prototype[a]=function(t,e){if("mixed"===r||"mixed"===this.type||r===this.type){t=""+t;var n=this._nodes.get(t);if(void 0===n)throw new I("Graph.".concat(a,': could not find the "').concat(t,'" node in the graph.'));return kt(!0,"mixed"===r?this.type:r,i,n,e)}};var u="some"+o;t.prototype[u]=function(t,e){return!!this[a](t,e)};var c="every"+o;t.prototype[c]=function(t,e){return!this[a](t,(function(t,n){return!e(t,n)}))}}(t,e),xt(t,e)}))}(Wt);var Pt=function(t){function n(e){var n=c({type:"directed"},e);if("multi"in n&&!1!==n.multi)throw new F("DirectedGraph.from: inconsistent indication that the graph should be multi in given options!");if("directed"!==n.type)throw new F('DirectedGraph.from: inconsistent "'+n.type+'" type in given options!');return t.call(this,n)||this}return e(n,t),n}(Wt),Rt=function(t){function n(e){var n=c({type:"undirected"},e);if("multi"in n&&!1!==n.multi)throw new F("UndirectedGraph.from: inconsistent indication that the graph should be multi in given options!");if("undirected"!==n.type)throw new F('UndirectedGraph.from: inconsistent "'+n.type+'" type in given options!');return t.call(this,n)||this}return e(n,t),n}(Wt),Kt=function(t){function n(e){var n=c({multi:!0},e);if("multi"in n&&!0!==n.multi)throw new F("MultiGraph.from: inconsistent indication that the graph should be simple in given options!");return t.call(this,n)||this}return e(n,t),n}(Wt),Tt=function(t){function n(e){var n=c({type:"directed",multi:!0},e);if("multi"in n&&!0!==n.multi)throw new F("MultiDirectedGraph.from: inconsistent indication that the graph should be simple in given options!");if("directed"!==n.type)throw new F('MultiDirectedGraph.from: inconsistent "'+n.type+'" type in given options!');return t.call(this,n)||this}return e(n,t),n}(Wt),Bt=function(t){function n(e){var n=c({type:"undirected",multi:!0},e);if("multi"in n&&!0!==n.multi)throw new F("MultiUndirectedGraph.from: inconsistent indication that the graph should be simple in given options!");if("undirected"!==n.type)throw new F('MultiUndirectedGraph.from: inconsistent "'+n.type+'" type in given options!');return t.call(this,n)||this}return e(n,t),n}(Wt);function Ft(t){t.from=function(e,n){var r=c({},e.options,n),i=new t(r);return i.import(e),i}}return Ft(Wt),Ft(Pt),Ft(Rt),Ft(Kt),Ft(Tt),Ft(Bt),Wt.Graph=Wt,Wt.DirectedGraph=Pt,Wt.UndirectedGraph=Rt,Wt.MultiGraph=Kt,Wt.MultiDirectedGraph=Tt,Wt.MultiUndirectedGraph=Bt,Wt.InvalidArgumentsGraphError=F,Wt.NotFoundGraphError=I,Wt.UsageGraphError=Y,Wt})); -//# sourceMappingURL=graphology.umd.min.js.map diff --git a/libs/shared/graph-layouts/node_modules/graphology/package.json b/libs/shared/graph-layouts/node_modules/graphology/package.json deleted file mode 100644 index 192894e7d..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/package.json +++ /dev/null @@ -1,84 +0,0 @@ -{ - "name": "graphology", - "version": "0.24.1", - "description": "A robust and multipurpose Graph object for JavaScript.", - "main": "dist/graphology.cjs.js", - "module": "dist/graphology.esm.js", - "browser": "dist/graphology.umd.min.js", - "types": "dist/graphology.d.ts", - "scripts": { - "clean": "rimraf dist specs", - "build": "npm run clean && rollup -c && babel tests --out-dir specs && cp src/endpoint.esm.d.ts dist/graphology.d.ts", - "prepare": "npm run build", - "prepublishOnly": "npm test && npm run test:types && npm run build", - "test": "mocha -u exports --require @babel/register ./test.js", - "test:types": "tsc --lib es2015,dom --noEmit --noImplicitAny --noImplicitReturns --strictNullChecks ./test-types.ts" - }, - "files": [ - "dist/*.js", - "dist/*.ts", - "specs" - ], - "keywords": [ - "graph", - "graph theory", - "directed", - "undirected", - "network" - ], - "repository": { - "type": "git", - "url": "git+https://github.com/graphology/graphology.git" - }, - "contributors": [ - { - "name": "Alexis Jacomy", - "url": "http://github.com/jacomyal" - }, - { - "name": "Benjamin Ooghe-Tabanou", - "url": "http://github.com/boogheta" - }, - { - "name": "Guillaume Plique", - "url": "http://github.com/Yomguithereal" - } - ], - "license": "MIT", - "bugs": { - "url": "https://github.com/graphology/graphology/issues" - }, - "homepage": "https://github.com/graphology/graphology#readme", - "dependencies": { - "events": "^3.3.0", - "obliterator": "^2.0.2" - }, - "peerDependencies": { - "graphology-types": ">=0.24.0" - }, - "babel": { - "presets": [ - "@babel/preset-env" - ], - "plugins": [ - [ - "@babel/transform-classes", - { - "loose": true - } - ], - [ - "@babel/transform-destructuring", - { - "loose": true - } - ], - [ - "@babel/transform-spread", - { - "loose": true - } - ] - ] - } -} diff --git a/libs/shared/graph-layouts/node_modules/graphology/specs/attributes.js b/libs/shared/graph-layouts/node_modules/graphology/specs/attributes.js deleted file mode 100644 index f026c38ea..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/specs/attributes.js +++ /dev/null @@ -1,992 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = attributes; - -var _assert = _interopRequireDefault(require("assert")); - -var _helpers = require("./helpers"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -function attributes(Graph, checkers) { - var invalid = checkers.invalid, - notFound = checkers.notFound, - usage = checkers.usage; - - function commonTests(method) { - return _defineProperty({}, '#.' + method, { - 'it should throw if the given path is not found.': function itShouldThrowIfTheGivenPathIsNotFound() { - if (!method.includes('Edge')) return; - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph[method]('source', 'target', 'name', 'value'); - }, notFound()); - }, - 'it should throw when using a path on a multi graph.': function itShouldThrowWhenUsingAPathOnAMultiGraph() { - if (!method.includes('Edge')) return; - var graph = new Graph({ - multi: true - }); - - _assert["default"]["throws"](function () { - graph[method]('source', 'target', 'name', 'value'); - }, usage()); - }, - 'it should throw if the element is not found in the graph.': function itShouldThrowIfTheElementIsNotFoundInTheGraph() { - var graph = new Graph(); - - if (method.includes('Edge') && method.includes('Directed') || method.includes('Undirected')) { - _assert["default"]["throws"](function () { - graph[method]('Test'); - }, usage()); - } else { - _assert["default"]["throws"](function () { - graph[method]('Test'); - }, notFound()); - } - } - }); - } - - var tests = {}; - var relevantMethods = Object.keys(Graph.prototype).filter(function (name) { - return (name.includes('NodeAttribute') || name.includes('EdgeAttribute') || name.includes('SourceAttribute') || name.includes('TargetAttribute') || name.includes('OppositeAttribute')) && !name.includes('Each'); - }); - relevantMethods.forEach(function (method) { - return (0, _helpers.deepMerge)(tests, commonTests(method)); - }); - return (0, _helpers.deepMerge)(tests, { - '#.getAttribute': { - 'it should return the correct value.': function itShouldReturnTheCorrectValue() { - var graph = new Graph(); - graph.setAttribute('name', 'graph'); - - _assert["default"].strictEqual(graph.getAttribute('name'), 'graph'); - }, - 'it should return undefined if the attribute does not exist.': function itShouldReturnUndefinedIfTheAttributeDoesNotExist() { - var graph = new Graph(); - - _assert["default"].strictEqual(graph.getAttribute('name'), undefined); - } - }, - '#.getNodeAttribute': { - 'it should return the correct value.': function itShouldReturnTheCorrectValue() { - var graph = new Graph(); - graph.addNode('Martha', { - age: 34 - }); - - _assert["default"].strictEqual(graph.getNodeAttribute('Martha', 'age'), 34); - }, - 'it should return undefined if the attribute does not exist.': function itShouldReturnUndefinedIfTheAttributeDoesNotExist() { - var graph = new Graph(); - graph.addNode('Martha'); - - _assert["default"].strictEqual(graph.getNodeAttribute('Martha', 'age'), undefined); - } - }, - '#.getSourceAttribute': { - 'it should return the correct value.': function itShouldReturnTheCorrectValue() { - var graph = new Graph(); - graph.addNode('Martha', { - age: 34 - }); - - var _graph$mergeEdge = graph.mergeEdge('Martha', 'Riwan'), - edge = _graph$mergeEdge[0]; - - _assert["default"].strictEqual(graph.getSourceAttribute(edge, 'age'), 34); - }, - 'it should return undefined if the attribute does not exist.': function itShouldReturnUndefinedIfTheAttributeDoesNotExist() { - var graph = new Graph(); - graph.addNode('Martha'); - - var _graph$mergeEdge2 = graph.mergeEdge('Martha', 'Riwan'), - edge = _graph$mergeEdge2[0]; - - _assert["default"].strictEqual(graph.getSourceAttribute(edge, 'age'), undefined); - } - }, - '#.getTargetAttribute': { - 'it should return the correct value.': function itShouldReturnTheCorrectValue() { - var graph = new Graph(); - graph.addNode('Martha', { - age: 34 - }); - - var _graph$mergeEdge3 = graph.mergeEdge('Riwan', 'Martha'), - edge = _graph$mergeEdge3[0]; - - _assert["default"].strictEqual(graph.getTargetAttribute(edge, 'age'), 34); - }, - 'it should return undefined if the attribute does not exist.': function itShouldReturnUndefinedIfTheAttributeDoesNotExist() { - var graph = new Graph(); - graph.addNode('Martha'); - - var _graph$mergeEdge4 = graph.mergeEdge('Riwan', 'Martha'), - edge = _graph$mergeEdge4[0]; - - _assert["default"].strictEqual(graph.getTargetAttribute(edge, 'age'), undefined); - } - }, - '#.getOppositeAttribute': { - 'it should return the correct value.': function itShouldReturnTheCorrectValue() { - var graph = new Graph(); - graph.addNode('Martha', { - age: 34 - }); - graph.addNode('Riwan', { - age: 25 - }); - - var _graph$mergeEdge5 = graph.mergeEdge('Riwan', 'Martha'), - edge = _graph$mergeEdge5[0]; - - _assert["default"].strictEqual(graph.getOppositeAttribute('Riwan', edge, 'age'), 34); - - _assert["default"].strictEqual(graph.getOppositeAttribute('Martha', edge, 'age'), 25); - } - }, - '#.getEdgeAttribute': { - 'it should return the correct value.': function itShouldReturnTheCorrectValue() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - var edge = graph.addEdge('John', 'Thomas', { - weight: 2 - }); - - _assert["default"].strictEqual(graph.getEdgeAttribute(edge, 'weight'), 2); - - _assert["default"].strictEqual(graph.getEdgeAttribute('John', 'Thomas', 'weight'), 2); - }, - 'it should also work with typed edges.': function itShouldAlsoWorkWithTypedEdges() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - graph.addDirectedEdge('John', 'Thomas', { - weight: 2 - }); - graph.addUndirectedEdge('John', 'Thomas', { - weight: 3 - }); - - _assert["default"].strictEqual(graph.getDirectedEdgeAttribute('John', 'Thomas', 'weight'), 2); - - _assert["default"].strictEqual(graph.getUndirectedEdgeAttribute('John', 'Thomas', 'weight'), 3); - }, - 'it should return undefined if the attribute does not exist.': function itShouldReturnUndefinedIfTheAttributeDoesNotExist() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - var edge = graph.addEdge('John', 'Thomas'); - - _assert["default"].strictEqual(graph.getEdgeAttribute(edge, 'weight'), undefined); - } - }, - '#.getAttributes': { - 'it should return the correct value.': function itShouldReturnTheCorrectValue() { - var graph = new Graph(); - graph.setAttribute('name', 'graph'); - - _assert["default"].deepStrictEqual(graph.getAttributes(), { - name: 'graph' - }); - }, - 'it should return an empty object if the node does not have attributes.': function itShouldReturnAnEmptyObjectIfTheNodeDoesNotHaveAttributes() { - var graph = new Graph(); - - _assert["default"].deepStrictEqual(graph.getAttributes(), {}); - } - }, - '#.getNodeAttributes': { - 'it should return the correct value.': function itShouldReturnTheCorrectValue() { - var graph = new Graph(); - graph.addNode('Martha', { - age: 34 - }); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes('Martha'), { - age: 34 - }); - }, - 'it should return an empty object if the node does not have attributes.': function itShouldReturnAnEmptyObjectIfTheNodeDoesNotHaveAttributes() { - var graph = new Graph(); - graph.addNode('Martha'); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes('Martha'), {}); - } - }, - '#.getEdgeAttributes': { - 'it should return the correct value.': function itShouldReturnTheCorrectValue() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - var edge = graph.addEdge('John', 'Thomas', { - weight: 2 - }); - - _assert["default"].deepStrictEqual(graph.getEdgeAttributes(edge), { - weight: 2 - }); - - _assert["default"].deepStrictEqual(graph.getEdgeAttributes('John', 'Thomas'), { - weight: 2 - }); - }, - 'it should also work with typed edges.': function itShouldAlsoWorkWithTypedEdges() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - graph.addDirectedEdge('John', 'Thomas', { - weight: 2 - }); - graph.addUndirectedEdge('John', 'Thomas', { - weight: 3 - }); - - _assert["default"].deepStrictEqual(graph.getDirectedEdgeAttributes('John', 'Thomas', 'weight'), { - weight: 2 - }); - - _assert["default"].deepStrictEqual(graph.getUndirectedEdgeAttributes('John', 'Thomas', 'weight'), { - weight: 3 - }); - }, - 'it should return an empty object if the edge does not have attributes.': function itShouldReturnAnEmptyObjectIfTheEdgeDoesNotHaveAttributes() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - var edge = graph.addEdge('John', 'Thomas'); - - _assert["default"].deepStrictEqual(graph.getEdgeAttributes(edge), {}); - } - }, - '#.hasAttribute': { - 'it should correctly return whether the attribute is set.': function itShouldCorrectlyReturnWhetherTheAttributeIsSet() { - var graph = new Graph(); - graph.setAttribute('name', 'graph'); - - _assert["default"].strictEqual(graph.hasAttribute('name'), true); - - _assert["default"].strictEqual(graph.hasAttribute('info'), false); - }, - 'it does not fail with typical prototypal properties.': function itDoesNotFailWithTypicalPrototypalProperties() { - var graph = new Graph(); - - _assert["default"].strictEqual(graph.hasAttribute('toString'), false); - } - }, - '#.hasNodeAttribute': { - 'it should correctly return whether the attribute is set.': function itShouldCorrectlyReturnWhetherTheAttributeIsSet() { - var graph = new Graph(); - graph.addNode('John', { - age: 20 - }); - - _assert["default"].strictEqual(graph.hasNodeAttribute('John', 'age'), true); - - _assert["default"].strictEqual(graph.hasNodeAttribute('John', 'eyes'), false); - }, - 'it does not fail with typical prototypal properties.': function itDoesNotFailWithTypicalPrototypalProperties() { - var graph = new Graph(); - graph.addNode('John', { - age: 20 - }); - - _assert["default"].strictEqual(graph.hasNodeAttribute('John', 'toString'), false); - } - }, - '#.hasEdgeAttribute': { - 'it should correctly return whether the attribute is set.': function itShouldCorrectlyReturnWhetherTheAttributeIsSet() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Martha']); - graph.addEdgeWithKey('J->M', 'John', 'Martha', { - weight: 10 - }); - - _assert["default"].strictEqual(graph.hasEdgeAttribute('J->M', 'weight'), true); - - _assert["default"].strictEqual(graph.hasEdgeAttribute('J->M', 'type'), false); - }, - 'it should also work with typed edges.': function itShouldAlsoWorkWithTypedEdges() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - graph.addDirectedEdge('John', 'Thomas', { - weight: 2 - }); - graph.addUndirectedEdge('John', 'Thomas'); - - _assert["default"].strictEqual(graph.hasDirectedEdgeAttribute('John', 'Thomas', 'weight'), true); - - _assert["default"].strictEqual(graph.hasUndirectedEdgeAttribute('John', 'Thomas', 'weight'), false); - }, - 'it does not fail with typical prototypal properties.': function itDoesNotFailWithTypicalPrototypalProperties() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Martha']); - graph.addEdgeWithKey('J->M', 'John', 'Martha', { - weight: 10 - }); - - _assert["default"].strictEqual(graph.hasEdgeAttribute('J->M', 'toString'), false); - } - }, - '#.setAttribute': { - "it should correctly set the graph's attribute.": function itShouldCorrectlySetTheGraphSAttribute() { - var graph = new Graph(); - graph.setAttribute('name', 'graph'); - - _assert["default"].strictEqual(graph.getAttribute('name'), 'graph'); - } - }, - '#.setNodeAttribute': { - "it should correctly set the node's attribute.": function itShouldCorrectlySetTheNodeSAttribute() { - var graph = new Graph(); - graph.addNode('John', { - age: 20 - }); - graph.setNodeAttribute('John', 'age', 45); - - _assert["default"].strictEqual(graph.getNodeAttribute('John', 'age'), 45); - } - }, - '#.setEdgeAttribute': { - "it should correctly set the edge's attribute.": function itShouldCorrectlySetTheEdgeSAttribute() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Martha']); - var edge = graph.addEdge('John', 'Martha', { - weight: 3 - }); - graph.setEdgeAttribute(edge, 'weight', 40); - - _assert["default"].strictEqual(graph.getEdgeAttribute(edge, 'weight'), 40); - - graph.setEdgeAttribute('John', 'Martha', 'weight', 60); - - _assert["default"].strictEqual(graph.getEdgeAttribute(edge, 'weight'), 60); - }, - 'it should also work with typed edges.': function itShouldAlsoWorkWithTypedEdges() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - graph.addDirectedEdge('John', 'Thomas', { - weight: 0 - }); - graph.addUndirectedEdge('John', 'Thomas', { - weight: 0 - }); - graph.setDirectedEdgeAttribute('John', 'Thomas', 'weight', 2); - graph.setUndirectedEdgeAttribute('John', 'Thomas', 'weight', 3); - - _assert["default"].strictEqual(graph.getDirectedEdgeAttribute('John', 'Thomas', 'weight'), 2); - - _assert["default"].strictEqual(graph.getUndirectedEdgeAttribute('John', 'Thomas', 'weight'), 3); - } - }, - '#.updateAttribute': { - 'it should throw if the updater is not a function.': function itShouldThrowIfTheUpdaterIsNotAFunction() { - var graph = new Graph(); - graph.setAttribute('count', 0); - - _assert["default"]["throws"](function () { - graph.updateAttribute('count', { - hello: 'world' - }); - }, invalid()); - }, - "it should correctly set the graph's attribute.": function itShouldCorrectlySetTheGraphSAttribute() { - var graph = new Graph(); - graph.setAttribute('name', 'graph'); - graph.updateAttribute('name', function (name) { - return name + '1'; - }); - - _assert["default"].strictEqual(graph.getAttribute('name'), 'graph1'); - }, - 'the given value should be undefined if not found.': function theGivenValueShouldBeUndefinedIfNotFound() { - var graph = new Graph(); - - var updater = function updater(x) { - _assert["default"].strictEqual(x, undefined); - - return 'graph'; - }; - - graph.updateAttribute('name', updater); - - _assert["default"].strictEqual(graph.getAttribute('name'), 'graph'); - } - }, - '#.updateNodeAttribute': { - 'it should throw if given an invalid updater.': function itShouldThrowIfGivenAnInvalidUpdater() { - var graph = new Graph(); - graph.addNode('John', { - age: 20 - }); - - _assert["default"]["throws"](function () { - graph.updateNodeAttribute('John', 'age', { - hello: 'world' - }); - }, invalid()); - }, - 'it should throw if not enough arguments are provided.': function itShouldThrowIfNotEnoughArgumentsAreProvided() { - var graph = new Graph(); - graph.addNode('Lucy'); - - _assert["default"]["throws"](function () { - graph.updateNodeAttribute('Lucy', { - hello: 'world' - }); - }, invalid()); - }, - "it should correctly set the node's attribute.": function itShouldCorrectlySetTheNodeSAttribute() { - var graph = new Graph(); - graph.addNode('John', { - age: 20 - }); - graph.updateNodeAttribute('John', 'age', function (x) { - return x + 1; - }); - - _assert["default"].strictEqual(graph.getNodeAttribute('John', 'age'), 21); - }, - 'the given value should be undefined if not found.': function theGivenValueShouldBeUndefinedIfNotFound() { - var graph = new Graph(); - graph.addNode('John'); - - var updater = function updater(x) { - _assert["default"].strictEqual(x, undefined); - - return 10; - }; - - graph.updateNodeAttribute('John', 'age', updater); - - _assert["default"].strictEqual(graph.getNodeAttribute('John', 'age'), 10); - } - }, - '#.updateEdgeAttribute': { - 'it should throw if given an invalid updater.': function itShouldThrowIfGivenAnInvalidUpdater() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Martha']); - graph.addEdge('John', 'Martha', { - weight: 3 - }); - - _assert["default"]["throws"](function () { - graph.updateEdgeAttribute('John', 'Martha', 'weight', { - hello: 'world' - }); - }, invalid()); - }, - "it should correctly set the edge's attribute.": function itShouldCorrectlySetTheEdgeSAttribute() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Martha']); - var edge = graph.addEdge('John', 'Martha', { - weight: 3 - }); - graph.updateEdgeAttribute(edge, 'weight', function (x) { - return x + 1; - }); - - _assert["default"].strictEqual(graph.getEdgeAttribute(edge, 'weight'), 4); - - graph.updateEdgeAttribute('John', 'Martha', 'weight', function (x) { - return x + 2; - }); - - _assert["default"].strictEqual(graph.getEdgeAttribute(edge, 'weight'), 6); - }, - 'it should also work with typed edges.': function itShouldAlsoWorkWithTypedEdges() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - graph.addDirectedEdge('John', 'Thomas', { - weight: 0 - }); - graph.addUndirectedEdge('John', 'Thomas', { - weight: 0 - }); - graph.updateDirectedEdgeAttribute('John', 'Thomas', 'weight', function (x) { - return x + 2; - }); - graph.updateUndirectedEdgeAttribute('John', 'Thomas', 'weight', function (x) { - return x + 3; - }); - - _assert["default"].strictEqual(graph.getDirectedEdgeAttribute('John', 'Thomas', 'weight'), 2); - - _assert["default"].strictEqual(graph.getUndirectedEdgeAttribute('John', 'Thomas', 'weight'), 3); - }, - 'the given value should be undefined if not found.': function theGivenValueShouldBeUndefinedIfNotFound() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Martha']); - var edge = graph.addEdge('John', 'Martha'); - - var updater = function updater(x) { - _assert["default"].strictEqual(x, undefined); - - return 10; - }; - - graph.updateEdgeAttribute(edge, 'weight', updater); - - _assert["default"].strictEqual(graph.getEdgeAttribute(edge, 'weight'), 10); - } - }, - '#.removeAttribute': { - 'it should correctly remove the attribute.': function itShouldCorrectlyRemoveTheAttribute() { - var graph = new Graph(); - graph.setAttribute('name', 'graph'); - graph.removeAttribute('name'); - - _assert["default"].strictEqual(graph.hasAttribute('name'), false); - - _assert["default"].deepStrictEqual(graph.getAttributes(), {}); - } - }, - '#.removeNodeAttribute': { - 'it should correctly remove the attribute.': function itShouldCorrectlyRemoveTheAttribute() { - var graph = new Graph(); - graph.addNode('Martha', { - age: 34 - }); - graph.removeNodeAttribute('Martha', 'age'); - - _assert["default"].strictEqual(graph.hasNodeAttribute('Martha', 'age'), false); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes('Martha'), {}); - } - }, - '#.removeEdgeAttribute': { - 'it should correclty remove the attribute.': function itShouldCorrecltyRemoveTheAttribute() { - var graph = new Graph(); - - var _graph$mergeEdge6 = graph.mergeEdge('John', 'Martha', { - weight: 1, - size: 3 - }), - edge = _graph$mergeEdge6[0]; - - graph.removeEdgeAttribute('John', 'Martha', 'weight'); - graph.removeEdgeAttribute(edge, 'size'); - - _assert["default"].strictEqual(graph.hasEdgeAttribute(edge, 'weight'), false); - - _assert["default"].strictEqual(graph.hasEdgeAttribute(edge, 'size'), false); - - _assert["default"].deepStrictEqual(graph.getEdgeAttributes(edge), {}); - }, - 'it should also work with typed edges.': function itShouldAlsoWorkWithTypedEdges() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - graph.addDirectedEdge('John', 'Thomas', { - weight: 2 - }); - graph.addUndirectedEdge('John', 'Thomas', { - weight: 3 - }); - graph.removeDirectedEdgeAttribute('John', 'Thomas', 'weight'); - graph.removeUndirectedEdgeAttribute('John', 'Thomas', 'weight'); - - _assert["default"].strictEqual(graph.hasDirectedEdgeAttribute('John', 'Thomas', 'weight'), false); - - _assert["default"].strictEqual(graph.hasUndirectedEdgeAttribute('John', 'Thomas', 'weight'), false); - } - }, - '#.replaceAttribute': { - 'it should throw if given attributes are not a plain object.': function itShouldThrowIfGivenAttributesAreNotAPlainObject() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.replaceAttributes(true); - }, invalid()); - }, - 'it should correctly replace attributes.': function itShouldCorrectlyReplaceAttributes() { - var graph = new Graph(); - graph.setAttribute('name', 'graph'); - graph.replaceAttributes({ - name: 'other graph' - }); - - _assert["default"].deepStrictEqual(graph.getAttributes(), { - name: 'other graph' - }); - } - }, - '#.replaceNodeAttributes': { - 'it should throw if given attributes are not a plain object.': function itShouldThrowIfGivenAttributesAreNotAPlainObject() { - var graph = new Graph(); - graph.addNode('John'); - - _assert["default"]["throws"](function () { - graph.replaceNodeAttributes('John', true); - }, invalid()); - }, - 'it should correctly replace attributes.': function itShouldCorrectlyReplaceAttributes() { - var graph = new Graph(); - graph.addNode('John', { - age: 45 - }); - graph.replaceNodeAttributes('John', { - age: 23, - eyes: 'blue' - }); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes('John'), { - age: 23, - eyes: 'blue' - }); - } - }, - '#.replaceEdgeAttributes': { - 'it should throw if given attributes are not a plain object.': function itShouldThrowIfGivenAttributesAreNotAPlainObject() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Martha']); - var edge = graph.addEdge('John', 'Martha'); - - _assert["default"]["throws"](function () { - graph.replaceEdgeAttributes(edge, true); - }, invalid()); - }, - 'it should also work with typed edges.': function itShouldAlsoWorkWithTypedEdges() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - graph.addDirectedEdge('John', 'Thomas', { - test: 0 - }); - graph.addUndirectedEdge('John', 'Thomas', { - test: 0 - }); - graph.replaceDirectedEdgeAttributes('John', 'Thomas', { - weight: 2 - }); - graph.replaceUndirectedEdgeAttributes('John', 'Thomas', { - weight: 3 - }); - - _assert["default"].deepStrictEqual(graph.getDirectedEdgeAttributes('John', 'Thomas'), { - weight: 2 - }); - - _assert["default"].deepStrictEqual(graph.getUndirectedEdgeAttributes('John', 'Thomas'), { - weight: 3 - }); - }, - 'it should correctly replace attributes.': function itShouldCorrectlyReplaceAttributes() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Martha']); - var edge = graph.addEdge('John', 'Martha', { - weight: 1 - }); - graph.replaceEdgeAttributes(edge, { - weight: 4, - type: 'KNOWS' - }); - - _assert["default"].deepStrictEqual(graph.getEdgeAttributes(edge), { - weight: 4, - type: 'KNOWS' - }); - } - }, - '#.mergeAttributes': { - 'it should throw if given attributes are not a plain object.': function itShouldThrowIfGivenAttributesAreNotAPlainObject() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.mergeAttributes(true); - }, invalid()); - }, - 'it should correctly merge attributes.': function itShouldCorrectlyMergeAttributes() { - var graph = new Graph(); - graph.setAttribute('name', 'graph'); - graph.mergeAttributes({ - color: 'blue' - }); - - _assert["default"].deepStrictEqual(graph.getAttributes(), { - name: 'graph', - color: 'blue' - }); - } - }, - '#.mergeNodeAttributes': { - 'it should throw if given attributes are not a plain object.': function itShouldThrowIfGivenAttributesAreNotAPlainObject() { - var graph = new Graph(); - graph.addNode('John'); - - _assert["default"]["throws"](function () { - graph.mergeNodeAttributes('John', true); - }, invalid()); - }, - 'it should correctly merge attributes.': function itShouldCorrectlyMergeAttributes() { - var graph = new Graph(); - graph.addNode('John', { - age: 45 - }); - graph.mergeNodeAttributes('John', { - eyes: 'blue' - }); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes('John'), { - age: 45, - eyes: 'blue' - }); - } - }, - '#.mergeEdgeAttributes': { - 'it should throw if given attributes are not a plain object.': function itShouldThrowIfGivenAttributesAreNotAPlainObject() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Martha']); - var edge = graph.addEdge('John', 'Martha'); - - _assert["default"]["throws"](function () { - graph.mergeEdgeAttributes(edge, true); - }, invalid()); - }, - 'it should also work with typed edges.': function itShouldAlsoWorkWithTypedEdges() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - graph.addDirectedEdge('John', 'Thomas', { - test: 0 - }); - graph.addUndirectedEdge('John', 'Thomas', { - test: 0 - }); - graph.mergeDirectedEdgeAttributes('John', 'Thomas', { - weight: 2 - }); - graph.mergeUndirectedEdgeAttributes('John', 'Thomas', { - weight: 3 - }); - - _assert["default"].deepStrictEqual(graph.getDirectedEdgeAttributes('John', 'Thomas'), { - weight: 2, - test: 0 - }); - - _assert["default"].deepStrictEqual(graph.getUndirectedEdgeAttributes('John', 'Thomas'), { - weight: 3, - test: 0 - }); - }, - 'it should correctly merge attributes.': function itShouldCorrectlyMergeAttributes() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Martha']); - var edge = graph.addEdge('John', 'Martha', { - weight: 1 - }); - graph.mergeEdgeAttributes(edge, { - type: 'KNOWS' - }); - - _assert["default"].deepStrictEqual(graph.getEdgeAttributes(edge), { - weight: 1, - type: 'KNOWS' - }); - } - }, - '#.updateAttributes': { - 'it should throw if given updater is not a function.': function itShouldThrowIfGivenUpdaterIsNotAFunction() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.updateAttribute(true); - }, invalid()); - }, - 'it should correctly update attributes.': function itShouldCorrectlyUpdateAttributes() { - var graph = new Graph(); - graph.setAttribute('name', 'graph'); - graph.updateAttributes(function (attr) { - return _objectSpread(_objectSpread({}, attr), {}, { - color: 'blue' - }); - }); - - _assert["default"].deepStrictEqual(graph.getAttributes(), { - name: 'graph', - color: 'blue' - }); - } - }, - '#.updateNodeAttributes': { - 'it should throw if given updater is not a function': function itShouldThrowIfGivenUpdaterIsNotAFunction() { - var graph = new Graph(); - graph.addNode('John'); - - _assert["default"]["throws"](function () { - graph.updateNodeAttributes('John', true); - }, invalid()); - }, - 'it should correctly update attributes.': function itShouldCorrectlyUpdateAttributes() { - var graph = new Graph(); - graph.addNode('John', { - age: 45 - }); - graph.updateNodeAttributes('John', function (attr) { - return _objectSpread(_objectSpread({}, attr), {}, { - eyes: 'blue' - }); - }); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes('John'), { - age: 45, - eyes: 'blue' - }); - } - }, - '#.updateEdgeAttributes': { - 'it should throw if given updater is not a function.': function itShouldThrowIfGivenUpdaterIsNotAFunction() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Martha']); - var edge = graph.addEdge('John', 'Martha'); - - _assert["default"]["throws"](function () { - graph.updateEdgeAttributes(edge, true); - }, invalid()); - }, - 'it should also work with typed edges.': function itShouldAlsoWorkWithTypedEdges() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - graph.addDirectedEdge('John', 'Thomas', { - test: 0 - }); - graph.addUndirectedEdge('John', 'Thomas', { - test: 0 - }); - graph.updateDirectedEdgeAttributes('John', 'Thomas', function (attr) { - return _objectSpread(_objectSpread({}, attr), {}, { - weight: 2 - }); - }); - graph.updateUndirectedEdgeAttributes('John', 'Thomas', function (attr) { - return _objectSpread(_objectSpread({}, attr), {}, { - weight: 3 - }); - }); - - _assert["default"].deepStrictEqual(graph.getDirectedEdgeAttributes('John', 'Thomas'), { - weight: 2, - test: 0 - }); - - _assert["default"].deepStrictEqual(graph.getUndirectedEdgeAttributes('John', 'Thomas'), { - weight: 3, - test: 0 - }); - }, - 'it should correctly update attributes.': function itShouldCorrectlyUpdateAttributes() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Martha']); - var edge = graph.addEdge('John', 'Martha', { - weight: 1 - }); - graph.updateEdgeAttributes(edge, function (attr) { - return _objectSpread(_objectSpread({}, attr), {}, { - type: 'KNOWS' - }); - }); - - _assert["default"].deepStrictEqual(graph.getEdgeAttributes(edge), { - weight: 1, - type: 'KNOWS' - }); - } - }, - '#.updateEachNodeAttributes': { - 'it should throw when given invalid arguments.': function itShouldThrowWhenGivenInvalidArguments() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.updateEachNodeAttributes(null); - }, invalid()); - - _assert["default"]["throws"](function () { - graph.updateEachNodeAttributes(Function.prototype, 'test'); - }, invalid()); - - _assert["default"]["throws"](function () { - graph.updateEachNodeAttributes(Function.prototype, { - attributes: 'yes' - }); - }, invalid()); - }, - "it should update each node's attributes.": function itShouldUpdateEachNodeSAttributes() { - var graph = new Graph(); - graph.addNode('John', { - age: 34 - }); - graph.addNode('Mary', { - age: 56 - }); - graph.addNode('Suz', { - age: 13 - }); - graph.updateEachNodeAttributes(function (node, attr) { - return _objectSpread(_objectSpread({}, attr), {}, { - age: attr.age + 1 - }); - }); - - _assert["default"].deepStrictEqual(graph.nodes().map(function (n) { - return graph.getNodeAttributes(n); - }), [{ - age: 35 - }, { - age: 57 - }, { - age: 14 - }]); - } - }, - '#.updateEachEdgeAttributes': { - 'it should throw when given invalid arguments.': function itShouldThrowWhenGivenInvalidArguments() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.updateEachEdgeAttributes(null); - }, invalid()); - - _assert["default"]["throws"](function () { - graph.updateEachEdgeAttributes(Function.prototype, 'test'); - }, invalid()); - - _assert["default"]["throws"](function () { - graph.updateEachEdgeAttributes(Function.prototype, { - attributes: 'yes' - }); - }, invalid()); - }, - "it should update each node's attributes.": function itShouldUpdateEachNodeSAttributes() { - var graph = new Graph(); - graph.mergeEdgeWithKey(0, 'John', 'Lucy', { - weight: 1 - }); - graph.mergeEdgeWithKey(1, 'John', 'Mary', { - weight: 10 - }); - graph.updateEachEdgeAttributes(function (edge, attr, source, _t, _sa, _ta, undirected) { - _assert["default"].strictEqual(source, 'John'); - - _assert["default"].strictEqual(undirected, false); - - return _objectSpread(_objectSpread({}, attr), {}, { - weight: attr.weight + 1 - }); - }); - - _assert["default"].deepStrictEqual(graph.mapEdges(function (_, attr) { - return attr; - }), [{ - weight: 2 - }, { - weight: 11 - }]); - } - } - }); -} \ No newline at end of file diff --git a/libs/shared/graph-layouts/node_modules/graphology/specs/events.js b/libs/shared/graph-layouts/node_modules/graphology/specs/events.js deleted file mode 100644 index df9c4c44f..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/specs/events.js +++ /dev/null @@ -1,426 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = events; - -var _assert = _interopRequireDefault(require("assert")); - -var _helpers = require("./helpers"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var VALID_TYPES = new Set(['set', 'merge', 'replace', 'remove']); - -function events(Graph) { - return { - nodeAdded: { - 'it should fire when a node is added.': function itShouldFireWhenANodeIsAdded() { - var graph = new Graph(); - var handler = (0, _helpers.spy)(function (data) { - _assert["default"].strictEqual(data.key, 'John'); - - _assert["default"].deepStrictEqual(data.attributes, { - age: 34 - }); - }); - graph.on('nodeAdded', handler); - graph.addNode('John', { - age: 34 - }); - (0, _assert["default"])(handler.called); - } - }, - edgeAdded: { - 'it should fire when an edge is added.': function itShouldFireWhenAnEdgeIsAdded() { - var graph = new Graph(); - var handler = (0, _helpers.spy)(function (data) { - _assert["default"].strictEqual(data.key, 'J->T'); - - _assert["default"].deepStrictEqual(data.attributes, { - weight: 1 - }); - - _assert["default"].strictEqual(data.source, 'John'); - - _assert["default"].strictEqual(data.target, 'Thomas'); - - _assert["default"].strictEqual(data.undirected, false); - }); - graph.on('edgeAdded', handler); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - graph.addEdgeWithKey('J->T', 'John', 'Thomas', { - weight: 1 - }); - (0, _assert["default"])(handler.called); - } - }, - nodeDropped: { - 'it should fire when a node is dropped.': function itShouldFireWhenANodeIsDropped() { - var graph = new Graph(); - var handler = (0, _helpers.spy)(function (data) { - _assert["default"].strictEqual(data.key, 'John'); - - _assert["default"].deepStrictEqual(data.attributes, { - age: 34 - }); - }); - graph.on('nodeDropped', handler); - graph.addNode('John', { - age: 34 - }); - graph.dropNode('John'); - (0, _assert["default"])(handler.called); - } - }, - edgeDropped: { - 'it should fire when an edge is added.': function itShouldFireWhenAnEdgeIsAdded() { - var graph = new Graph(); - var handler = (0, _helpers.spy)(function (data) { - _assert["default"].strictEqual(data.key, 'J->T'); - - _assert["default"].deepStrictEqual(data.attributes, { - weight: 1 - }); - - _assert["default"].strictEqual(data.source, 'John'); - - _assert["default"].strictEqual(data.target, 'Thomas'); - - _assert["default"].strictEqual(data.undirected, false); - }); - graph.on('edgeDropped', handler); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - graph.addEdgeWithKey('J->T', 'John', 'Thomas', { - weight: 1 - }); - graph.dropEdge('J->T'); - (0, _assert["default"])(handler.called); - } - }, - cleared: { - 'it should fire when the graph is cleared.': function itShouldFireWhenTheGraphIsCleared() { - var graph = new Graph(); - var handler = (0, _helpers.spy)(); - graph.on('cleared', handler); - graph.clear(); - (0, _assert["default"])(handler.called); - } - }, - attributesUpdated: { - 'it should fire when a graph attribute is updated.': function itShouldFireWhenAGraphAttributeIsUpdated() { - var graph = new Graph(); - var handler = (0, _helpers.spy)(function (payload) { - (0, _assert["default"])(VALID_TYPES.has(payload.type)); - - if (payload.type === 'set') { - _assert["default"].strictEqual(payload.name, 'name'); - } else if (payload.type === 'remove') { - _assert["default"].strictEqual(payload.name, 'name'); - } else if (payload.type === 'merge') { - _assert["default"].deepStrictEqual(payload.data, { - author: 'John' - }); - } - - _assert["default"].deepStrictEqual(payload.attributes, graph.getAttributes()); - }); - graph.on('attributesUpdated', handler); - graph.setAttribute('name', 'Awesome graph'); - graph.replaceAttributes({ - name: 'Shitty graph' - }); - graph.mergeAttributes({ - author: 'John' - }); - graph.removeAttribute('name'); - - _assert["default"].strictEqual(handler.times, 4); - } - }, - nodeAttributesUpdated: { - "it should fire when a node's attributes are updated.": function itShouldFireWhenANodeSAttributesAreUpdated() { - var graph = new Graph(); - var handler = (0, _helpers.spy)(function (payload) { - _assert["default"].strictEqual(payload.key, 'John'); - - (0, _assert["default"])(VALID_TYPES.has(payload.type)); - - if (payload.type === 'set') { - _assert["default"].strictEqual(payload.name, 'age'); - } else if (payload.type === 'remove') { - _assert["default"].strictEqual(payload.name, 'eyes'); - } else if (payload.type === 'merge') { - _assert["default"].deepStrictEqual(payload.data, { - eyes: 'blue' - }); - } - - _assert["default"].strictEqual(payload.attributes, graph.getNodeAttributes(payload.key)); - }); - graph.on('nodeAttributesUpdated', handler); - graph.addNode('John'); - graph.setNodeAttribute('John', 'age', 34); - graph.replaceNodeAttributes('John', { - age: 56 - }); - graph.mergeNodeAttributes('John', { - eyes: 'blue' - }); - graph.removeNodeAttribute('John', 'eyes'); - - _assert["default"].strictEqual(handler.times, 4); - }, - 'it should fire when a node is merged.': function itShouldFireWhenANodeIsMerged() { - var graph = new Graph(); - var handler = (0, _helpers.spy)(function (payload) { - _assert["default"].deepStrictEqual(payload, { - type: 'merge', - key: 'John', - attributes: { - count: 2 - }, - data: { - count: 2 - } - }); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(payload.key), { - count: 2 - }); - }); - graph.on('nodeAttributesUpdated', handler); - graph.mergeNode('John', { - count: 1 - }); - graph.mergeNode('John', { - count: 2 - }); - - _assert["default"].strictEqual(handler.times, 1); - }, - 'it should fire when a node is updated.': function itShouldFireWhenANodeIsUpdated() { - var graph = new Graph(); - var handler = (0, _helpers.spy)(function (payload) { - _assert["default"].deepStrictEqual(payload, { - type: 'replace', - key: 'John', - attributes: { - count: 2 - } - }); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(payload.key), { - count: 2 - }); - }); - graph.on('nodeAttributesUpdated', handler); - graph.mergeNode('John', { - count: 1 - }); - graph.updateNode('John', function (attr) { - return _objectSpread(_objectSpread({}, attr), {}, { - count: attr.count + 1 - }); - }); - - _assert["default"].strictEqual(handler.times, 1); - } - }, - edgeAttributesUpdated: { - "it should fire when an edge's attributes are updated.": function itShouldFireWhenAnEdgeSAttributesAreUpdated() { - var graph = new Graph(); - var handler = (0, _helpers.spy)(function (payload) { - _assert["default"].strictEqual(payload.key, 'J->T'); - - (0, _assert["default"])(VALID_TYPES.has(payload.type)); - - if (payload.type === 'set') { - _assert["default"].strictEqual(payload.name, 'weight'); - } else if (payload.type === 'remove') { - _assert["default"].strictEqual(payload.name, 'type'); - } else if (payload.type === 'merge') { - _assert["default"].deepStrictEqual(payload.data, { - type: 'KNOWS' - }); - } - - _assert["default"].strictEqual(payload.attributes, graph.getEdgeAttributes(payload.key)); - }); - graph.on('edgeAttributesUpdated', handler); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - graph.addEdgeWithKey('J->T', 'John', 'Thomas'); - graph.setEdgeAttribute('J->T', 'weight', 34); - graph.replaceEdgeAttributes('J->T', { - weight: 56 - }); - graph.mergeEdgeAttributes('J->T', { - type: 'KNOWS' - }); - graph.removeEdgeAttribute('J->T', 'type'); - - _assert["default"].strictEqual(handler.times, 4); - }, - 'it should fire when an edge is merged.': function itShouldFireWhenAnEdgeIsMerged() { - var graph = new Graph(); - var handler = (0, _helpers.spy)(function (payload) { - _assert["default"].deepStrictEqual(payload, { - type: 'merge', - key: graph.edge('John', 'Mary'), - attributes: { - weight: 2 - }, - data: { - weight: 2 - } - }); - - _assert["default"].deepStrictEqual(graph.getEdgeAttributes(payload.key), { - weight: 2 - }); - }); - graph.on('edgeAttributesUpdated', handler); - graph.mergeEdge('John', 'Mary', { - weight: 1 - }); - graph.mergeEdge('John', 'Mary', { - weight: 2 - }); - - _assert["default"].strictEqual(handler.times, 1); - }, - 'it should fire when an edge is updated.': function itShouldFireWhenAnEdgeIsUpdated() { - var graph = new Graph(); - var handler = (0, _helpers.spy)(function (payload) { - _assert["default"].deepStrictEqual(payload, { - type: 'replace', - key: 'j->m', - attributes: { - weight: 2 - } - }); - - _assert["default"].deepStrictEqual(graph.getEdgeAttributes(payload.key), { - weight: 2 - }); - }); - graph.on('edgeAttributesUpdated', handler); - graph.mergeEdgeWithKey('j->m', 'John', 'Mary', { - weight: 1 - }); - graph.updateEdgeWithKey('j->m', 'John', 'Mary', function (attr) { - return _objectSpread(_objectSpread({}, attr), {}, { - weight: attr.weight + 1 - }); - }); - - _assert["default"].strictEqual(handler.times, 1); - } - }, - eachNodeAttributesUpdated: { - 'it should fire when using #.updateEachNodeAttributes.': function itShouldFireWhenUsingUpdateEachNodeAttributes() { - var graph = new Graph(); - graph.addNode('John', { - age: 34 - }); - graph.addNode('Mary', { - age: 56 - }); - graph.addNode('Suz', { - age: 13 - }); - var handler = (0, _helpers.spy)(function (payload) { - _assert["default"].strictEqual(payload.hints, null); - }); - graph.on('eachNodeAttributesUpdated', handler); - graph.updateEachNodeAttributes(function (node, attr) { - return _objectSpread(_objectSpread({}, attr), {}, { - age: attr.age + 1 - }); - }); - - _assert["default"].strictEqual(handler.times, 1); - }, - 'it should provide hints when user gave them.': function itShouldProvideHintsWhenUserGaveThem() { - var graph = new Graph(); - graph.addNode('John', { - age: 34 - }); - graph.addNode('Mary', { - age: 56 - }); - graph.addNode('Suz', { - age: 13 - }); - var handler = (0, _helpers.spy)(function (payload) { - _assert["default"].deepStrictEqual(payload.hints, { - attributes: ['age'] - }); - }); - graph.on('eachNodeAttributesUpdated', handler); - graph.updateEachNodeAttributes(function (node, attr) { - return _objectSpread(_objectSpread({}, attr), {}, { - age: attr.age + 1 - }); - }, { - attributes: ['age'] - }); - - _assert["default"].strictEqual(handler.times, 1); - } - }, - eachEdgeAttributesUpdated: { - 'it should fire when using #.updateEachEdgeAttributes.': function itShouldFireWhenUsingUpdateEachEdgeAttributes() { - var graph = new Graph(); - graph.mergeEdgeWithKey(0, 'John', 'Lucy', { - weight: 1 - }); - graph.mergeEdgeWithKey(1, 'John', 'Mary', { - weight: 10 - }); - var handler = (0, _helpers.spy)(function (payload) { - _assert["default"].strictEqual(payload.hints, null); - }); - graph.on('eachEdgeAttributesUpdated', handler); - graph.updateEachEdgeAttributes(function (node, attr) { - return _objectSpread(_objectSpread({}, attr), {}, { - age: attr.weight + 1 - }); - }); - - _assert["default"].strictEqual(handler.times, 1); - }, - 'it should provide hints when user gave them.': function itShouldProvideHintsWhenUserGaveThem() { - var graph = new Graph(); - graph.mergeEdgeWithKey(0, 'John', 'Lucy', { - weight: 1 - }); - graph.mergeEdgeWithKey(1, 'John', 'Mary', { - weight: 10 - }); - var handler = (0, _helpers.spy)(function (payload) { - _assert["default"].deepStrictEqual(payload.hints, { - attributes: ['weight'] - }); - }); - graph.on('eachEdgeAttributesUpdated', handler); - graph.updateEachEdgeAttributes(function (node, attr) { - return _objectSpread(_objectSpread({}, attr), {}, { - weight: attr.weight + 1 - }); - }, { - attributes: ['weight'] - }); - - _assert["default"].strictEqual(handler.times, 1); - } - } - }; -} \ No newline at end of file diff --git a/libs/shared/graph-layouts/node_modules/graphology/specs/helpers.js b/libs/shared/graph-layouts/node_modules/graphology/specs/helpers.js deleted file mode 100644 index 5198d01d9..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/specs/helpers.js +++ /dev/null @@ -1,101 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports.addNodesFrom = addNodesFrom; -exports.capitalize = capitalize; -exports.deepMerge = deepMerge; -exports.sameMembers = sameMembers; -exports.spy = spy; - -function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } - -/** - * Graphology Specs Helpers - * ========================= - * - * Miscellaneous helpers to test more easily. - */ - -/** - * Capitalize function. - */ -function capitalize(string) { - return string[0].toUpperCase() + string.slice(1); -} -/** - * Simplistic deep merger function. - */ - - -function deepMerge() { - for (var _len = arguments.length, objects = new Array(_len), _key = 0; _key < _len; _key++) { - objects[_key] = arguments[_key]; - } - - var o = objects[0]; - var t, i, l, k; - - for (i = 1, l = objects.length; i < l; i++) { - t = objects[i]; - - for (k in t) { - if (_typeof(t[k]) === 'object') { - o[k] = deepMerge(o[k] || {}, t[k]); - } else { - o[k] = t[k]; - } - } - } - - return o; -} -/** - * Checking that two arrays have the same members. - */ - - -function sameMembers(a1, a2) { - if (a1.length !== a2.length) return false; - var set = new Set(a1); - - for (var i = 0, l = a2.length; i < l; i++) { - if (!set.has(a2[i])) return false; - } - - return true; -} -/** - * Function spying on the execution of the provided function to ease some - * tests, notably related to event handling. - * - * @param {function} target - Target function. - * @param {function} - The spy. - */ - - -function spy(target) { - var fn = function fn() { - fn.called = true; - fn.times++; - if (typeof target === 'function') return target.apply(null, arguments); - }; - - fn.called = false; - fn.times = 0; - return fn; -} -/** - * Function adding multiple nodes from an array to the given graph. - * - * @param {Graph} graph - Target graph. - * @param {array} nodes - Node array. - */ - - -function addNodesFrom(graph, nodes) { - nodes.forEach(function (node) { - graph.addNode(node); - }); -} \ No newline at end of file diff --git a/libs/shared/graph-layouts/node_modules/graphology/specs/index.js b/libs/shared/graph-layouts/node_modules/graphology/specs/index.js deleted file mode 100644 index 18b6595fc..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/specs/index.js +++ /dev/null @@ -1,78 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = specs; - -var _instantiation = _interopRequireDefault(require("./instantiation")); - -var _properties = _interopRequireDefault(require("./properties")); - -var _read = _interopRequireDefault(require("./read")); - -var _mutation = _interopRequireDefault(require("./mutation")); - -var _attributes = _interopRequireDefault(require("./attributes")); - -var _iteration = _interopRequireDefault(require("./iteration")); - -var _serialization = _interopRequireDefault(require("./serialization")); - -var _events = _interopRequireDefault(require("./events")); - -var _utils = _interopRequireDefault(require("./utils")); - -var _known = _interopRequireDefault(require("./known")); - -var _misc = _interopRequireDefault(require("./misc")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -/** - * Graphology Specs - * ================= - * - * Unit tests factory taking the Graph object implementation. - */ -var createErrorChecker = function createErrorChecker(name) { - return function () { - return function (error) { - return error && error.name === name; - }; - }; -}; -/** - * Returning the unit tests to run. - * - * @param {string} path - Path to the implementation (should be absolute). - * @return {object} - The tests to run with Mocha. - */ - - -function specs(Graph, implementation) { - var errors = [['invalid', 'InvalidArgumentsGraphError'], ['notFound', 'NotFoundGraphError'], ['usage', 'UsageGraphError']]; // Building error checkers - - var errorCheckers = {}; - errors.forEach(function (_ref) { - var fn = _ref[0], - name = _ref[1]; - return errorCheckers[fn] = createErrorChecker(name); - }); - var tests = { - Basic: { - Instantiation: (0, _instantiation["default"])(Graph, implementation, errorCheckers), - Properties: (0, _properties["default"])(Graph, errorCheckers), - Mutation: (0, _mutation["default"])(Graph, errorCheckers), - Read: (0, _read["default"])(Graph, errorCheckers), - Attributes: (0, _attributes["default"])(Graph, errorCheckers), - Iteration: (0, _iteration["default"])(Graph, errorCheckers), - Serialization: (0, _serialization["default"])(Graph, errorCheckers), - Events: (0, _events["default"])(Graph), - Utils: (0, _utils["default"])(Graph, errorCheckers), - 'Known Methods': (0, _known["default"])(Graph, errorCheckers), - Miscellaneous: (0, _misc["default"])(Graph) - } - }; - return tests; -} \ No newline at end of file diff --git a/libs/shared/graph-layouts/node_modules/graphology/specs/instantiation.js b/libs/shared/graph-layouts/node_modules/graphology/specs/instantiation.js deleted file mode 100644 index 45945a419..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/specs/instantiation.js +++ /dev/null @@ -1,211 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = instantiation; - -var _assert = _interopRequireDefault(require("assert")); - -var _helpers = require("./helpers"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -/* eslint no-unused-vars: 0 */ - -/** - * Graphology Instantiation Specs - * =============================== - * - * Testing the instantiation of the graph. - */ -var CONSTRUCTORS = ['DirectedGraph', 'UndirectedGraph', 'MultiGraph', 'MultiDirectedGraph', 'MultiUndirectedGraph']; -var OPTIONS = [{ - multi: false, - type: 'directed' -}, { - multi: false, - type: 'undirected' -}, { - multi: true, - type: 'mixed' -}, { - multi: true, - type: 'directed' -}, { - multi: true, - type: 'undirected' -}]; - -function instantiation(Graph, implementation, checkers) { - var invalid = checkers.invalid; - return { - 'Static #.from method': { - 'it should be possible to create a Graph from a Graph instance.': function itShouldBePossibleToCreateAGraphFromAGraphInstance() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - graph.addEdge('John', 'Thomas'); - var other = Graph.from(graph); - - _assert["default"].deepStrictEqual(graph.nodes(), other.nodes()); - - _assert["default"].deepStrictEqual(graph.edges(), other.edges()); - }, - 'it should be possible to create a Graph from a serialized graph': function itShouldBePossibleToCreateAGraphFromASerializedGraph() { - var graph = Graph.from({ - nodes: [{ - key: 'John' - }, { - key: 'Thomas' - }], - edges: [{ - source: 'John', - target: 'Thomas' - }] - }); - - _assert["default"].deepStrictEqual(graph.nodes(), ['John', 'Thomas']); - - _assert["default"].strictEqual(graph.hasEdge('John', 'Thomas'), true); - }, - 'it should be possible to provide options.': function itShouldBePossibleToProvideOptions() { - var graph = Graph.from({ - node: [{ - key: 'John' - }], - attributes: { - name: 'Awesome graph' - } - }, { - type: 'directed' - }); - - _assert["default"].strictEqual(graph.type, 'directed'); - - _assert["default"].strictEqual(graph.getAttribute('name'), 'Awesome graph'); - }, - 'it should be possible to take options from the serialized format.': function itShouldBePossibleToTakeOptionsFromTheSerializedFormat() { - var graph = Graph.from({ - node: [{ - key: 'John' - }], - attributes: { - name: 'Awesome graph' - }, - options: { - type: 'directed', - multi: true - } - }); - - _assert["default"].strictEqual(graph.type, 'directed'); - - _assert["default"].strictEqual(graph.multi, true); - - _assert["default"].strictEqual(graph.getAttribute('name'), 'Awesome graph'); - }, - 'given options should take precedence over the serialization ones.': function givenOptionsShouldTakePrecedenceOverTheSerializationOnes() { - var graph = Graph.from({ - node: [{ - key: 'John' - }], - attributes: { - name: 'Awesome graph' - }, - options: { - type: 'directed', - multi: true - } - }, { - type: 'undirected' - }); - - _assert["default"].strictEqual(graph.type, 'undirected'); - - _assert["default"].strictEqual(graph.multi, true); - - _assert["default"].strictEqual(graph.getAttribute('name'), 'Awesome graph'); - } - }, - Options: { - /** - * allowSelfLoops - */ - allowSelfLoops: { - 'providing a non-boolean value should throw.': function providingANonBooleanValueShouldThrow() { - _assert["default"]["throws"](function () { - var graph = new Graph({ - allowSelfLoops: 'test' - }); - }, invalid()); - } - }, - - /** - * multi - */ - multi: { - 'providing a non-boolean value should throw.': function providingANonBooleanValueShouldThrow() { - _assert["default"]["throws"](function () { - var graph = new Graph({ - multi: 'test' - }); - }, invalid()); - } - }, - - /** - * type - */ - type: { - 'providing an invalid type should throw.': function providingAnInvalidTypeShouldThrow() { - _assert["default"]["throws"](function () { - var graph = new Graph({ - type: 'test' - }); - }, invalid()); - } - } - }, - Constructors: { - 'all alternative constructors should be available.': function allAlternativeConstructorsShouldBeAvailable() { - CONSTRUCTORS.forEach(function (name) { - return (0, _assert["default"])(name in implementation); - }); - }, - 'alternative constructors should have the correct options.': function alternativeConstructorsShouldHaveTheCorrectOptions() { - CONSTRUCTORS.forEach(function (name, index) { - var graph = new implementation[name](); - var _OPTIONS$index = OPTIONS[index], - multi = _OPTIONS$index.multi, - type = _OPTIONS$index.type; - - _assert["default"].strictEqual(graph.multi, multi); - - _assert["default"].strictEqual(graph.type, type); - }); - }, - 'alternative constructors should throw if given inconsistent options.': function alternativeConstructorsShouldThrowIfGivenInconsistentOptions() { - CONSTRUCTORS.forEach(function (name, index) { - var _OPTIONS$index2 = OPTIONS[index], - multi = _OPTIONS$index2.multi, - type = _OPTIONS$index2.type; - - _assert["default"]["throws"](function () { - var graph = new implementation[name]({ - multi: !multi - }); - }, invalid()); - - if (type === 'mixed') return; - - _assert["default"]["throws"](function () { - var graph = new implementation[name]({ - type: type === 'directed' ? 'undirected' : 'directed' - }); - }, invalid()); - }); - } - } - }; -} \ No newline at end of file diff --git a/libs/shared/graph-layouts/node_modules/graphology/specs/iteration/edges.js b/libs/shared/graph-layouts/node_modules/graphology/specs/iteration/edges.js deleted file mode 100644 index 8210ea7f2..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/specs/iteration/edges.js +++ /dev/null @@ -1,894 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = edgesIteration; - -var _assert = _interopRequireDefault(require("assert")); - -var _take = _interopRequireDefault(require("obliterator/take")); - -var _map = _interopRequireDefault(require("obliterator/map")); - -var _helpers = require("../helpers"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var METHODS = ['edges', 'inEdges', 'outEdges', 'inboundEdges', 'outboundEdges', 'directedEdges', 'undirectedEdges']; - -function edgesIteration(Graph, checkers) { - var invalid = checkers.invalid, - notFound = checkers.notFound; - var graph = new Graph({ - multi: true - }); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas', 'Martha', 'Roger', 'Catherine', 'Alone', 'Forever']); - graph.replaceNodeAttributes('John', { - age: 13 - }); - graph.replaceNodeAttributes('Martha', { - age: 15 - }); - graph.addDirectedEdgeWithKey('J->T', 'John', 'Thomas', { - weight: 14 - }); - graph.addDirectedEdgeWithKey('J->M', 'John', 'Martha'); - graph.addDirectedEdgeWithKey('C->J', 'Catherine', 'John'); - graph.addUndirectedEdgeWithKey('M<->R', 'Martha', 'Roger'); - graph.addUndirectedEdgeWithKey('M<->J', 'Martha', 'John'); - graph.addUndirectedEdgeWithKey('J<->R', 'John', 'Roger'); - graph.addUndirectedEdgeWithKey('T<->M', 'Thomas', 'Martha'); - var ALL_EDGES = ['J->T', 'J->M', 'C->J', 'M<->R', 'M<->J', 'J<->R', 'T<->M']; - var ALL_DIRECTED_EDGES = ['J->T', 'J->M', 'C->J']; - var ALL_UNDIRECTED_EDGES = ['M<->R', 'M<->J', 'J<->R', 'T<->M']; - var TEST_DATA = { - edges: { - all: ALL_EDGES, - node: { - key: 'John', - edges: ['C->J', 'J->T', 'J->M', 'M<->J', 'J<->R'] - }, - path: { - source: 'John', - target: 'Martha', - edges: ['J->M', 'M<->J'] - } - }, - inEdges: { - all: ALL_DIRECTED_EDGES, - node: { - key: 'John', - edges: ['C->J'] - }, - path: { - source: 'John', - target: 'Martha', - edges: [] - } - }, - outEdges: { - all: ALL_DIRECTED_EDGES, - node: { - key: 'John', - edges: ['J->T', 'J->M'] - }, - path: { - source: 'John', - target: 'Martha', - edges: ['J->M'] - } - }, - inboundEdges: { - all: ALL_DIRECTED_EDGES.concat(ALL_UNDIRECTED_EDGES), - node: { - key: 'John', - edges: ['C->J', 'M<->J', 'J<->R'] - }, - path: { - source: 'John', - target: 'Martha', - edges: ['M<->J'] - } - }, - outboundEdges: { - all: ALL_DIRECTED_EDGES.concat(ALL_UNDIRECTED_EDGES), - node: { - key: 'John', - edges: ['J->T', 'J->M', 'M<->J', 'J<->R'] - }, - path: { - source: 'John', - target: 'Martha', - edges: ['J->M', 'M<->J'] - } - }, - directedEdges: { - all: ALL_DIRECTED_EDGES, - node: { - key: 'John', - edges: ['C->J', 'J->T', 'J->M'] - }, - path: { - source: 'John', - target: 'Martha', - edges: ['J->M'] - } - }, - undirectedEdges: { - all: ALL_UNDIRECTED_EDGES, - node: { - key: 'John', - edges: ['M<->J', 'J<->R'] - }, - path: { - source: 'John', - target: 'Martha', - edges: ['M<->J'] - } - } - }; - - function commonTests(name) { - return _defineProperty({}, '#.' + name, { - 'it should throw if too many arguments are provided.': function itShouldThrowIfTooManyArgumentsAreProvided() { - _assert["default"]["throws"](function () { - graph[name](1, 2, 3); - }, invalid()); - }, - 'it should throw when the node is not found.': function itShouldThrowWhenTheNodeIsNotFound() { - _assert["default"]["throws"](function () { - graph[name]('Test'); - }, notFound()); - }, - 'it should throw if either source or target is not found.': function itShouldThrowIfEitherSourceOrTargetIsNotFound() { - _assert["default"]["throws"](function () { - graph[name]('Test', 'Alone'); - }, notFound()); - - _assert["default"]["throws"](function () { - graph[name]('Alone', 'Test'); - }, notFound()); - } - }); - } - - function specificTests(name, data) { - var _ref2; - - var capitalized = name[0].toUpperCase() + name.slice(1, -1); - var iteratorName = name.slice(0, -1) + 'Entries'; - var forEachName = 'forEach' + capitalized; - var findName = 'find' + capitalized; - var mapName = 'map' + capitalized + 's'; - var filterName = 'filter' + capitalized + 's'; - var reduceName = 'reduce' + capitalized + 's'; - var someName = 'some' + capitalized; - var everyName = 'every' + capitalized; - return _ref2 = {}, _defineProperty(_ref2, '#.' + name, { - 'it should return all the relevant edges.': function itShouldReturnAllTheRelevantEdges() { - var edges = graph[name]().sort(); - - _assert["default"].deepStrictEqual(edges, data.all.slice().sort()); - }, - "it should return a node's relevant edges.": function itShouldReturnANodeSRelevantEdges() { - var edges = graph[name](data.node.key); - - _assert["default"].deepStrictEqual(edges, data.node.edges); - - _assert["default"].deepStrictEqual(graph[name]('Alone'), []); - }, - 'it should return all the relevant edges between source & target.': function itShouldReturnAllTheRelevantEdgesBetweenSourceTarget() { - var edges = graph[name](data.path.source, data.path.target); - (0, _assert["default"])((0, _helpers.sameMembers)(edges, data.path.edges)); - - _assert["default"].deepStrictEqual(graph[name]('Forever', 'Alone'), []); - } - }), _defineProperty(_ref2, '#.' + forEachName, { - 'it should possible to use callback iterators.': function itShouldPossibleToUseCallbackIterators() { - var edges = []; - graph[forEachName](function (key, attributes, source, target, sA, tA, u) { - edges.push(key); - - _assert["default"].deepStrictEqual(attributes, key === 'J->T' ? { - weight: 14 - } : {}); - - _assert["default"].strictEqual(source, graph.source(key)); - - _assert["default"].strictEqual(target, graph.target(key)); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(source), sA); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(target), tA); - - _assert["default"].strictEqual(graph.isUndirected(key), u); - }); - edges.sort(); - - _assert["default"].deepStrictEqual(edges, data.all.slice().sort()); - }, - "it should be possible to use callback iterators over a node's relevant edges.": function itShouldBePossibleToUseCallbackIteratorsOverANodeSRelevantEdges() { - var edges = []; - graph[forEachName](data.node.key, function (key, attributes, source, target, sA, tA, u) { - edges.push(key); - - _assert["default"].deepStrictEqual(attributes, key === 'J->T' ? { - weight: 14 - } : {}); - - _assert["default"].strictEqual(source, graph.source(key)); - - _assert["default"].strictEqual(target, graph.target(key)); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(source), sA); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(target), tA); - - _assert["default"].strictEqual(graph.isUndirected(key), u); - }); - edges.sort(); - - _assert["default"].deepStrictEqual(edges, data.node.edges.slice().sort()); - }, - 'it should be possible to use callback iterators over all the relevant edges between source & target.': function itShouldBePossibleToUseCallbackIteratorsOverAllTheRelevantEdgesBetweenSourceTarget() { - var edges = []; - graph[forEachName](data.path.source, data.path.target, function (key, attributes, source, target, sA, tA, u) { - edges.push(key); - - _assert["default"].deepStrictEqual(attributes, key === 'J->T' ? { - weight: 14 - } : {}); - - _assert["default"].strictEqual(source, graph.source(key)); - - _assert["default"].strictEqual(target, graph.target(key)); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(source), sA); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(target), tA); - - _assert["default"].strictEqual(graph.isUndirected(key), u); - }); - (0, _assert["default"])((0, _helpers.sameMembers)(edges, data.path.edges)); - } - }), _defineProperty(_ref2, '#.' + mapName, { - 'it should possible to map edges.': function itShouldPossibleToMapEdges() { - var result = graph[mapName](function (key) { - return key; - }); - result.sort(); - - _assert["default"].deepStrictEqual(result, data.all.slice().sort()); - }, - "it should be possible to map a node's relevant edges.": function itShouldBePossibleToMapANodeSRelevantEdges() { - var result = graph[mapName](data.node.key, function (key) { - return key; - }); - result.sort(); - - _assert["default"].deepStrictEqual(result, data.node.edges.slice().sort()); - }, - 'it should be possible to map the relevant edges between source & target.': function itShouldBePossibleToMapTheRelevantEdgesBetweenSourceTarget() { - var result = graph[mapName](data.path.source, data.path.target, function (key) { - return key; - }); - result.sort(); - (0, _assert["default"])((0, _helpers.sameMembers)(result, data.path.edges)); - } - }), _defineProperty(_ref2, '#.' + filterName, { - 'it should possible to filter edges.': function itShouldPossibleToFilterEdges() { - var result = graph[filterName](function (key) { - return data.all.includes(key); - }); - result.sort(); - - _assert["default"].deepStrictEqual(result, data.all.slice().sort()); - }, - "it should be possible to filter a node's relevant edges.": function itShouldBePossibleToFilterANodeSRelevantEdges() { - var result = graph[filterName](data.node.key, function (key) { - return data.all.includes(key); - }); - result.sort(); - - _assert["default"].deepStrictEqual(result, data.node.edges.slice().sort()); - }, - 'it should be possible to filter the relevant edges between source & target.': function itShouldBePossibleToFilterTheRelevantEdgesBetweenSourceTarget() { - var result = graph[filterName](data.path.source, data.path.target, function (key) { - return data.all.includes(key); - }); - result.sort(); - (0, _assert["default"])((0, _helpers.sameMembers)(result, data.path.edges)); - } - }), _defineProperty(_ref2, '#.' + reduceName, { - 'it should throw when given bad arguments.': function itShouldThrowWhenGivenBadArguments() { - _assert["default"]["throws"](function () { - graph[reduceName]('test'); - }, invalid()); - - _assert["default"]["throws"](function () { - graph[reduceName](1, 2, 3, 4, 5); - }, invalid()); - - _assert["default"]["throws"](function () { - graph[reduceName]('notafunction', 0); - }, TypeError); - - _assert["default"]["throws"](function () { - graph[reduceName]('test', function () { - return true; - }); - }, invalid()); - }, - 'it should possible to reduce edges.': function itShouldPossibleToReduceEdges() { - var result = graph[reduceName](function (x) { - return x + 1; - }, 0); - - _assert["default"].strictEqual(result, data.all.length); - }, - "it should be possible to reduce a node's relevant edges.": function itShouldBePossibleToReduceANodeSRelevantEdges() { - var result = graph[reduceName](data.node.key, function (x) { - return x + 1; - }, 0); - - _assert["default"].strictEqual(result, data.node.edges.length); - }, - 'it should be possible to reduce the relevant edges between source & target.': function itShouldBePossibleToReduceTheRelevantEdgesBetweenSourceTarget() { - var result = graph[reduceName](data.path.source, data.path.target, function (x) { - return x + 1; - }, 0); - - _assert["default"].strictEqual(result, data.path.edges.length); - } - }), _defineProperty(_ref2, '#.' + findName, { - 'it should possible to find an edge.': function itShouldPossibleToFindAnEdge() { - var edges = []; - var found = graph[findName](function (key, attributes, source, target, sA, tA, u) { - edges.push(key); - - _assert["default"].deepStrictEqual(attributes, key === 'J->T' ? { - weight: 14 - } : {}); - - _assert["default"].strictEqual(source, graph.source(key)); - - _assert["default"].strictEqual(target, graph.target(key)); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(source), sA); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(target), tA); - - _assert["default"].strictEqual(graph.isUndirected(key), u); - - return true; - }); - - _assert["default"].strictEqual(found, edges[0]); - - _assert["default"].strictEqual(edges.length, 1); - - found = graph[findName](function () { - return false; - }); - - _assert["default"].strictEqual(found, undefined); - }, - "it should be possible to find a node's edge.": function itShouldBePossibleToFindANodeSEdge() { - var edges = []; - var found = graph[findName](data.node.key, function (key, attributes, source, target, sA, tA, u) { - edges.push(key); - - _assert["default"].deepStrictEqual(attributes, key === 'J->T' ? { - weight: 14 - } : {}); - - _assert["default"].strictEqual(source, graph.source(key)); - - _assert["default"].strictEqual(target, graph.target(key)); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(source), sA); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(target), tA); - - _assert["default"].strictEqual(graph.isUndirected(key), u); - - return true; - }); - - _assert["default"].strictEqual(found, edges[0]); - - _assert["default"].strictEqual(edges.length, 1); - - found = graph[findName](data.node.key, function () { - return false; - }); - - _assert["default"].strictEqual(found, undefined); - }, - 'it should be possible to find an edge between source & target.': function itShouldBePossibleToFindAnEdgeBetweenSourceTarget() { - var edges = []; - var found = graph[findName](data.path.source, data.path.target, function (key, attributes, source, target, sA, tA, u) { - edges.push(key); - - _assert["default"].deepStrictEqual(attributes, key === 'J->T' ? { - weight: 14 - } : {}); - - _assert["default"].strictEqual(source, graph.source(key)); - - _assert["default"].strictEqual(target, graph.target(key)); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(source), sA); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(target), tA); - - _assert["default"].strictEqual(graph.isUndirected(key), u); - - return true; - }); - - _assert["default"].strictEqual(found, edges[0]); - - _assert["default"].strictEqual(edges.length, graph[name](data.path.source, data.path.target).length ? 1 : 0); - - found = graph[findName](data.path.source, data.path.target, function () { - return false; - }); - - _assert["default"].strictEqual(found, undefined); - } - }), _defineProperty(_ref2, '#.' + someName, { - 'it should possible to assert whether any edge matches a predicate.': function itShouldPossibleToAssertWhetherAnyEdgeMatchesAPredicate() { - var edges = []; - var found = graph[someName](function (key, attributes, source, target, sA, tA, u) { - edges.push(key); - - _assert["default"].deepStrictEqual(attributes, key === 'J->T' ? { - weight: 14 - } : {}); - - _assert["default"].strictEqual(source, graph.source(key)); - - _assert["default"].strictEqual(target, graph.target(key)); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(source), sA); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(target), tA); - - _assert["default"].strictEqual(graph.isUndirected(key), u); - - return true; - }); - - _assert["default"].strictEqual(found, true); - - _assert["default"].strictEqual(edges.length, 1); - - found = graph[someName](function () { - return false; - }); - - _assert["default"].strictEqual(found, false); - }, - "it should possible to assert whether any node's edge matches a predicate.": function itShouldPossibleToAssertWhetherAnyNodeSEdgeMatchesAPredicate() { - var edges = []; - var found = graph[someName](data.node.key, function (key, attributes, source, target, sA, tA, u) { - edges.push(key); - - _assert["default"].deepStrictEqual(attributes, key === 'J->T' ? { - weight: 14 - } : {}); - - _assert["default"].strictEqual(source, graph.source(key)); - - _assert["default"].strictEqual(target, graph.target(key)); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(source), sA); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(target), tA); - - _assert["default"].strictEqual(graph.isUndirected(key), u); - - return true; - }); - - _assert["default"].strictEqual(found, true); - - _assert["default"].strictEqual(edges.length, 1); - - found = graph[someName](data.node.key, function () { - return false; - }); - - _assert["default"].strictEqual(found, false); - }, - 'it should possible to assert whether any edge between source & target matches a predicate.': function itShouldPossibleToAssertWhetherAnyEdgeBetweenSourceTargetMatchesAPredicate() { - var edges = []; - var found = graph[someName](data.path.source, data.path.target, function (key, attributes, source, target, sA, tA, u) { - edges.push(key); - - _assert["default"].deepStrictEqual(attributes, key === 'J->T' ? { - weight: 14 - } : {}); - - _assert["default"].strictEqual(source, graph.source(key)); - - _assert["default"].strictEqual(target, graph.target(key)); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(source), sA); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(target), tA); - - _assert["default"].strictEqual(graph.isUndirected(key), u); - - return true; - }); - - _assert["default"].strictEqual(found, graph[name](data.path.source, data.path.target).length !== 0); - - _assert["default"].strictEqual(edges.length, graph[name](data.path.source, data.path.target).length ? 1 : 0); - - found = graph[someName](data.path.source, data.path.target, function () { - return false; - }); - - _assert["default"].strictEqual(found, false); - }, - 'it should always return false on empty sets.': function itShouldAlwaysReturnFalseOnEmptySets() { - var empty = new Graph(); - - _assert["default"].strictEqual(empty[someName](function () { - return true; - }), false); - } - }), _defineProperty(_ref2, '#.' + everyName, { - 'it should possible to assert whether all edges matches a predicate.': function itShouldPossibleToAssertWhetherAllEdgesMatchesAPredicate() { - var edges = []; - var found = graph[everyName](function (key, attributes, source, target, sA, tA, u) { - edges.push(key); - - _assert["default"].deepStrictEqual(attributes, key === 'J->T' ? { - weight: 14 - } : {}); - - _assert["default"].strictEqual(source, graph.source(key)); - - _assert["default"].strictEqual(target, graph.target(key)); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(source), sA); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(target), tA); - - _assert["default"].strictEqual(graph.isUndirected(key), u); - - return true; - }); - - _assert["default"].strictEqual(found, true); - - found = graph[everyName](function () { - return false; - }); - - _assert["default"].strictEqual(found, false); - }, - "it should possible to assert whether all of a node's edges matches a predicate.": function itShouldPossibleToAssertWhetherAllOfANodeSEdgesMatchesAPredicate() { - var edges = []; - var found = graph[everyName](data.node.key, function (key, attributes, source, target, sA, tA, u) { - edges.push(key); - - _assert["default"].deepStrictEqual(attributes, key === 'J->T' ? { - weight: 14 - } : {}); - - _assert["default"].strictEqual(source, graph.source(key)); - - _assert["default"].strictEqual(target, graph.target(key)); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(source), sA); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(target), tA); - - _assert["default"].strictEqual(graph.isUndirected(key), u); - - return true; - }); - - _assert["default"].strictEqual(found, true); - - found = graph[everyName](data.node.key, function () { - return false; - }); - - _assert["default"].strictEqual(found, false); - }, - 'it should possible to assert whether all edges between source & target matches a predicate.': function itShouldPossibleToAssertWhetherAllEdgesBetweenSourceTargetMatchesAPredicate() { - var edges = []; - var found = graph[everyName](data.path.source, data.path.target, function (key, attributes, source, target, sA, tA, u) { - edges.push(key); - - _assert["default"].deepStrictEqual(attributes, key === 'J->T' ? { - weight: 14 - } : {}); - - _assert["default"].strictEqual(source, graph.source(key)); - - _assert["default"].strictEqual(target, graph.target(key)); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(source), sA); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(target), tA); - - _assert["default"].strictEqual(graph.isUndirected(key), u); - - return true; - }); - var isEmpty = graph[name](data.path.source, data.path.target).length === 0; - - _assert["default"].strictEqual(found, true); - - found = graph[everyName](data.path.source, data.path.target, function () { - return false; - }); - - _assert["default"].strictEqual(found, isEmpty ? true : false); - }, - 'it should always return true on empty sets.': function itShouldAlwaysReturnTrueOnEmptySets() { - var empty = new Graph(); - - _assert["default"].strictEqual(empty[everyName](function () { - return true; - }), true); - } - }), _defineProperty(_ref2, '#.' + iteratorName, { - 'it should be possible to return an iterator over the relevant edges.': function itShouldBePossibleToReturnAnIteratorOverTheRelevantEdges() { - var iterator = graph[iteratorName](); - - _assert["default"].deepStrictEqual((0, _take["default"])(iterator), data.all.map(function (edge) { - var _graph$extremities = graph.extremities(edge), - source = _graph$extremities[0], - target = _graph$extremities[1]; - - return { - edge: edge, - attributes: graph.getEdgeAttributes(edge), - source: source, - target: target, - sourceAttributes: graph.getNodeAttributes(source), - targetAttributes: graph.getNodeAttributes(target), - undirected: graph.isUndirected(edge) - }; - })); - }, - "it should be possible to return an iterator over a node's relevant edges.": function itShouldBePossibleToReturnAnIteratorOverANodeSRelevantEdges() { - var iterator = graph[iteratorName](data.node.key); - - _assert["default"].deepStrictEqual((0, _take["default"])(iterator), data.node.edges.map(function (edge) { - var _graph$extremities2 = graph.extremities(edge), - source = _graph$extremities2[0], - target = _graph$extremities2[1]; - - return { - edge: edge, - attributes: graph.getEdgeAttributes(edge), - source: source, - target: target, - sourceAttributes: graph.getNodeAttributes(source), - targetAttributes: graph.getNodeAttributes(target), - undirected: graph.isUndirected(edge) - }; - })); - }, - 'it should be possible to return an iterator over relevant edges between source & target.': function itShouldBePossibleToReturnAnIteratorOverRelevantEdgesBetweenSourceTarget() { - var iterator = graph[iteratorName](data.path.source, data.path.target); - - _assert["default"].deepStrictEqual((0, _take["default"])(iterator), data.path.edges.map(function (edge) { - var _graph$extremities3 = graph.extremities(edge), - source = _graph$extremities3[0], - target = _graph$extremities3[1]; - - return { - edge: edge, - attributes: graph.getEdgeAttributes(edge), - source: source, - target: target, - sourceAttributes: graph.getNodeAttributes(source), - targetAttributes: graph.getNodeAttributes(target), - undirected: graph.isUndirected(edge) - }; - })); - } - }), _ref2; - } - - var tests = { - Miscellaneous: { - 'simple graph indices should work.': function simpleGraphIndicesShouldWork() { - var simpleGraph = new Graph(); - (0, _helpers.addNodesFrom)(simpleGraph, [1, 2, 3, 4]); - simpleGraph.addEdgeWithKey('1->2', 1, 2); - simpleGraph.addEdgeWithKey('1->3', 1, 3); - simpleGraph.addEdgeWithKey('1->4', 1, 4); - - _assert["default"].deepStrictEqual(simpleGraph.edges(1), ['1->2', '1->3', '1->4']); - }, - 'it should also work with typed graphs.': function itShouldAlsoWorkWithTypedGraphs() { - var undirected = new Graph({ - type: 'undirected' - }), - directed = new Graph({ - type: 'directed' - }); - undirected.mergeEdgeWithKey('1--2', 1, 2); - directed.mergeEdgeWithKey('1->2', 1, 2); - - _assert["default"].deepStrictEqual(undirected.edges(1, 2), ['1--2']); - - _assert["default"].deepStrictEqual(directed.edges(1, 2), ['1->2']); - }, - 'self loops should appear when using #.inEdges and should appear only once with #.edges.': function selfLoopsShouldAppearWhenUsingInEdgesAndShouldAppearOnlyOnceWithEdges() { - var directed = new Graph({ - type: 'directed' - }); - directed.addNode('Lucy'); - directed.addEdgeWithKey('Lucy', 'Lucy', 'Lucy'); - - _assert["default"].deepStrictEqual(directed.inEdges('Lucy'), ['Lucy']); - - _assert["default"].deepStrictEqual(Array.from(directed.inEdgeEntries('Lucy')).map(function (x) { - return x.edge; - }), ['Lucy']); - - var edges = []; - directed.forEachInEdge('Lucy', function (edge) { - edges.push(edge); - }); - - _assert["default"].deepStrictEqual(edges, ['Lucy']); - - _assert["default"].deepStrictEqual(directed.edges('Lucy'), ['Lucy']); - - edges = []; - directed.forEachEdge('Lucy', function (edge) { - edges.push(edge); - }); - - _assert["default"].deepStrictEqual(edges, ['Lucy']); - - _assert["default"].deepStrictEqual(Array.from(directed.edgeEntries('Lucy')).map(function (x) { - return x.edge; - }), ['Lucy']); - }, - 'it should be possible to retrieve self loops.': function itShouldBePossibleToRetrieveSelfLoops() { - var loopy = new Graph(); - loopy.addNode('John'); - loopy.addEdgeWithKey('d', 'John', 'John'); - loopy.addUndirectedEdgeWithKey('u', 'John', 'John'); - - _assert["default"].deepStrictEqual(new Set(loopy.edges('John', 'John')), new Set(['d', 'u'])); - - _assert["default"].deepStrictEqual(loopy.directedEdges('John', 'John'), ['d']); - - _assert["default"].deepStrictEqual(loopy.undirectedEdges('John', 'John'), ['u']); - - var edges = []; - loopy.forEachDirectedEdge('John', 'John', function (edge) { - edges.push(edge); - }); - - _assert["default"].deepStrictEqual(edges, ['d']); - - edges = []; - loopy.forEachUndirectedEdge('John', 'John', function (edge) { - edges.push(edge); - }); - - _assert["default"].deepStrictEqual(edges, ['u']); - }, - 'self loops in multi graphs should work properly (#352).': function selfLoopsInMultiGraphsShouldWorkProperly352() { - var loopy = new Graph({ - multi: true - }); - loopy.addNode('n'); - loopy.addEdgeWithKey('e1', 'n', 'n'); - loopy.addEdgeWithKey('e2', 'n', 'n'); - loopy.addUndirectedEdgeWithKey('e3', 'n', 'n'); // Arrays - - _assert["default"].deepStrictEqual(loopy.edges('n'), ['e2', 'e1', 'e3']); - - _assert["default"].deepStrictEqual(loopy.outboundEdges('n'), ['e2', 'e1', 'e3']); - - _assert["default"].deepStrictEqual(loopy.inboundEdges('n'), ['e2', 'e1', 'e3']); - - _assert["default"].deepStrictEqual(loopy.outEdges('n'), ['e2', 'e1']); - - _assert["default"].deepStrictEqual(loopy.inEdges('n'), ['e2', 'e1']); - - _assert["default"].deepStrictEqual(loopy.undirectedEdges('n'), ['e3']); - - _assert["default"].deepStrictEqual(loopy.directedEdges('n'), ['e2', 'e1']); - - _assert["default"].deepStrictEqual(loopy.edges('n', 'n'), ['e2', 'e1', 'e3']); - - _assert["default"].deepStrictEqual(loopy.outboundEdges('n', 'n'), ['e2', 'e1', 'e3']); - - _assert["default"].deepStrictEqual(loopy.inboundEdges('n', 'n'), ['e2', 'e1', 'e3']); - - _assert["default"].deepStrictEqual(loopy.outEdges('n', 'n'), ['e2', 'e1']); - - _assert["default"].deepStrictEqual(loopy.inEdges('n', 'n'), ['e2', 'e1']); - - _assert["default"].deepStrictEqual(loopy.undirectedEdges('n', 'n'), ['e3']); - - _assert["default"].deepStrictEqual(loopy.directedEdges('n', 'n'), ['e2', 'e1']); // Iterators - - - var mapKeys = function mapKeys(it) { - return (0, _take["default"])((0, _map["default"])(it, function (e) { - return e.edge; - })); - }; - - _assert["default"].deepStrictEqual(mapKeys(loopy.edgeEntries('n')), ['e2', 'e1', 'e3']); - - _assert["default"].deepStrictEqual(mapKeys(loopy.outboundEdgeEntries('n')), ['e2', 'e1', 'e3']); - - _assert["default"].deepStrictEqual(mapKeys(loopy.inboundEdgeEntries('n')), ['e2', 'e1', 'e3']); - - _assert["default"].deepStrictEqual(mapKeys(loopy.outEdgeEntries('n')), ['e2', 'e1']); - - _assert["default"].deepStrictEqual(mapKeys(loopy.inEdgeEntries('n')), ['e2', 'e1']); - - _assert["default"].deepStrictEqual(mapKeys(loopy.undirectedEdgeEntries('n')), ['e3']); - - _assert["default"].deepStrictEqual(mapKeys(loopy.directedEdgeEntries('n')), ['e2', 'e1']); - - _assert["default"].deepStrictEqual(mapKeys(loopy.edgeEntries('n', 'n')), ['e2', 'e1', 'e3']); - - _assert["default"].deepStrictEqual(mapKeys(loopy.outboundEdgeEntries('n', 'n')), ['e2', 'e1', 'e3']); - - _assert["default"].deepStrictEqual(mapKeys(loopy.inboundEdgeEntries('n', 'n')), ['e2', 'e1', 'e3']); - - _assert["default"].deepStrictEqual(mapKeys(loopy.outEdgeEntries('n', 'n')), ['e2', 'e1']); - - _assert["default"].deepStrictEqual(mapKeys(loopy.inEdgeEntries('n', 'n')), ['e2', 'e1']); - - _assert["default"].deepStrictEqual(mapKeys(loopy.undirectedEdgeEntries('n', 'n')), ['e3']); - - _assert["default"].deepStrictEqual(mapKeys(loopy.directedEdgeEntries('n', 'n')), ['e2', 'e1']); - }, - 'findOutboundEdge should work on multigraphs (#319).': function findOutboundEdgeShouldWorkOnMultigraphs319() { - var loopy = new Graph({ - multi: true - }); - loopy.mergeEdgeWithKey('e1', 'n', 'm'); - loopy.mergeEdgeWithKey('e2', 'n', 'n'); - - _assert["default"].strictEqual(loopy.findOutboundEdge(function (_e, _a, s, t) { - return s === t; - }), 'e2'); - - _assert["default"].strictEqual(loopy.findOutboundEdge('n', function (_e, _a, s, t) { - return s === t; - }), 'e2'); - - _assert["default"].strictEqual(loopy.findOutboundEdge('n', 'n', function (_e, _a, s, t) { - return s === t; - }), 'e2'); - } - } - }; // Common tests - - METHODS.forEach(function (name) { - return (0, _helpers.deepMerge)(tests, commonTests(name)); - }); // Specific tests - - for (var name in TEST_DATA) { - (0, _helpers.deepMerge)(tests, specificTests(name, TEST_DATA[name])); - } - - return tests; -} \ No newline at end of file diff --git a/libs/shared/graph-layouts/node_modules/graphology/specs/iteration/index.js b/libs/shared/graph-layouts/node_modules/graphology/specs/iteration/index.js deleted file mode 100644 index bf2e892c5..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/specs/iteration/index.js +++ /dev/null @@ -1,161 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = iteration; - -var _assert = _interopRequireDefault(require("assert")); - -var _nodes = _interopRequireDefault(require("./nodes")); - -var _edges = _interopRequireDefault(require("./edges")); - -var _neighbors = _interopRequireDefault(require("./neighbors")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -/** - * Graphology Iteration Specs - * =========================== - * - * Testing the iteration-related methods of the graph. - */ -function iteration(Graph, checkers) { - return { - Adjacency: { - '#.forEachAdjacencyEntry': { - 'it should iterate over the relevant elements.': function itShouldIterateOverTheRelevantElements() { - function test(multi) { - var graph = new Graph({ - multi: multi - }); - graph.addNode('John', { - hello: 'world' - }); - - var _graph$mergeUndirecte = graph.mergeUndirectedEdge('John', 'Mary', { - weight: 3 - }), - e1 = _graph$mergeUndirecte[0]; - - graph.mergeUndirectedEdge('Thomas', 'John'); - graph.mergeDirectedEdge('John', 'Thomas'); - var count = 0; - graph.forEachAdjacencyEntry(function (node, neighbor, attr, neighborAttr, edge, edgeAttr, undirected) { - count++; - - if (node === 'John') { - _assert["default"].deepStrictEqual(attr, { - hello: 'world' - }); - } else { - _assert["default"].deepStrictEqual(attr, {}); - } - - if (neighbor === 'John') { - _assert["default"].deepStrictEqual(neighborAttr, { - hello: 'world' - }); - } else { - _assert["default"].deepStrictEqual(neighborAttr, {}); - } - - if (edge === e1) { - _assert["default"].deepStrictEqual(edgeAttr, { - weight: 3 - }); - } else { - _assert["default"].deepStrictEqual(edgeAttr, {}); - } - - _assert["default"].strictEqual(graph.isUndirected(edge), undirected); - }); - - _assert["default"].strictEqual(count, graph.directedSize + graph.undirectedSize * 2); - - graph.addNode('Disconnected'); - count = 0; - graph.forEachAdjacencyEntryWithOrphans(function (node, neighbor, attr, neighborAttr, edge, edgeAttr, undirected) { - count++; - if (node !== 'Disconnected') return; - - _assert["default"].strictEqual(neighbor, null); - - _assert["default"].strictEqual(neighborAttr, null); - - _assert["default"].strictEqual(edge, null); - - _assert["default"].strictEqual(edgeAttr, null); - - _assert["default"].strictEqual(undirected, null); - }, true); - - _assert["default"].strictEqual(count, graph.directedSize + graph.undirectedSize * 2 + 1); - } - - test(false); - test(true); - } - }, - '#.forEachAssymetricAdjacencyEntry': { - 'it should iterate over the relevant elements.': function itShouldIterateOverTheRelevantElements() { - function test(multi) { - var graph = new Graph({ - multi: multi - }); - graph.addNode('John', { - hello: 'world' - }); - graph.mergeUndirectedEdge('John', 'Mary', { - weight: 3 - }); - graph.mergeUndirectedEdge('Thomas', 'John'); - graph.mergeDirectedEdge('John', 'Thomas'); - var edges = []; - graph.forEachAssymetricAdjacencyEntry(function (node, neighbor, attr, neighborAttr, edge, edgeAttr, undirected) { - if (undirected) { - _assert["default"].strictEqual(node < neighbor, true); - } - - edges.push(edge); - }); - - _assert["default"].strictEqual(edges.length, graph.directedSize + graph.undirectedSize); - - _assert["default"].deepStrictEqual(new Set(edges).size, edges.length); - - graph.addNode('Disconnected'); - var count = 0; - var nulls = 0; - graph.forEachAssymetricAdjacencyEntryWithOrphans(function (node, neighbor, attr, neighborAttr, edge, edgeAttr, undirected) { - count++; - if (neighbor) return; - nulls++; - - _assert["default"].strictEqual(neighbor, null); - - _assert["default"].strictEqual(neighborAttr, null); - - _assert["default"].strictEqual(edge, null); - - _assert["default"].strictEqual(edgeAttr, null); - - _assert["default"].strictEqual(undirected, null); - }, true); - - _assert["default"].strictEqual(count, graph.directedSize + graph.undirectedSize + 3); - - _assert["default"].strictEqual(nulls, 3); - } - - test(false); - test(true); - } - } - }, - Nodes: (0, _nodes["default"])(Graph, checkers), - Edges: (0, _edges["default"])(Graph, checkers), - Neighbors: (0, _neighbors["default"])(Graph, checkers) - }; -} \ No newline at end of file diff --git a/libs/shared/graph-layouts/node_modules/graphology/specs/iteration/neighbors.js b/libs/shared/graph-layouts/node_modules/graphology/specs/iteration/neighbors.js deleted file mode 100644 index 7948bd77c..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/specs/iteration/neighbors.js +++ /dev/null @@ -1,284 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = neighborsIteration; - -var _assert = _interopRequireDefault(require("assert")); - -var _take = _interopRequireDefault(require("obliterator/take")); - -var _helpers = require("../helpers"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -var METHODS = ['neighbors', 'inNeighbors', 'outNeighbors', 'inboundNeighbors', 'outboundNeighbors', 'directedNeighbors', 'undirectedNeighbors']; - -function neighborsIteration(Graph, checkers) { - var notFound = checkers.notFound, - invalid = checkers.invalid; - var graph = new Graph({ - multi: true - }); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas', 'Martha', 'Roger', 'Catherine', 'Alone', 'Forever']); - graph.replaceNodeAttributes('John', { - age: 34 - }); - graph.replaceNodeAttributes('Martha', { - age: 35 - }); - graph.addDirectedEdgeWithKey('J->T', 'John', 'Thomas'); - graph.addDirectedEdgeWithKey('J->M', 'John', 'Martha'); - graph.addDirectedEdgeWithKey('C->J', 'Catherine', 'John'); - graph.addUndirectedEdgeWithKey('M<->R', 'Martha', 'Roger'); - graph.addUndirectedEdgeWithKey('M<->J', 'Martha', 'John'); - graph.addUndirectedEdgeWithKey('J<->R', 'John', 'Roger'); - graph.addUndirectedEdgeWithKey('T<->M', 'Thomas', 'Martha'); - var TEST_DATA = { - neighbors: { - node: { - key: 'John', - neighbors: ['Catherine', 'Thomas', 'Martha', 'Roger'] - } - }, - inNeighbors: { - node: { - key: 'John', - neighbors: ['Catherine'] - } - }, - outNeighbors: { - node: { - key: 'John', - neighbors: ['Thomas', 'Martha'] - } - }, - inboundNeighbors: { - node: { - key: 'John', - neighbors: ['Catherine', 'Martha', 'Roger'] - } - }, - outboundNeighbors: { - node: { - key: 'John', - neighbors: ['Thomas', 'Martha', 'Roger'] - } - }, - directedNeighbors: { - node: { - key: 'John', - neighbors: ['Catherine', 'Thomas', 'Martha'] - } - }, - undirectedNeighbors: { - node: { - key: 'John', - neighbors: ['Martha', 'Roger'] - } - } - }; - - function commonTests(name) { - return _defineProperty({}, '#.' + name, { - 'it should throw when the node is not found.': function itShouldThrowWhenTheNodeIsNotFound() { - _assert["default"]["throws"](function () { - graph[name]('Test'); - }, notFound()); - - if (~name.indexOf('count')) return; - - _assert["default"]["throws"](function () { - graph[name]('Test', 'SecondTest'); - }, notFound()); - } - }); - } - - function specificTests(name, data) { - var _ref2; - - var capitalized = name[0].toUpperCase() + name.slice(1, -1); - var forEachName = 'forEach' + capitalized; - var findName = 'find' + capitalized; - var iteratorName = name.slice(0, -1) + 'Entries'; - var areName = 'are' + capitalized + 's'; - var mapName = 'map' + capitalized + 's'; - var filterName = 'filter' + capitalized + 's'; - var reduceName = 'reduce' + capitalized + 's'; - var someName = 'some' + capitalized; - var everyName = 'every' + capitalized; - return _ref2 = {}, _defineProperty(_ref2, '#.' + name, { - 'it should return the correct neighbors array.': function itShouldReturnTheCorrectNeighborsArray() { - var neighbors = graph[name](data.node.key); - - _assert["default"].deepStrictEqual(neighbors, data.node.neighbors); - - _assert["default"].deepStrictEqual(graph[name]('Alone'), []); - } - }), _defineProperty(_ref2, '#.' + forEachName, { - 'it should be possible to iterate over neighbors using a callback.': function itShouldBePossibleToIterateOverNeighborsUsingACallback() { - var neighbors = []; - graph[forEachName](data.node.key, function (target, attrs) { - neighbors.push(target); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(target), attrs); - - _assert["default"].strictEqual(graph[areName](data.node.key, target), true); - }); - - _assert["default"].deepStrictEqual(neighbors, data.node.neighbors); - } - }), _defineProperty(_ref2, '#.' + mapName, { - 'it should be possible to map neighbors using a callback.': function itShouldBePossibleToMapNeighborsUsingACallback() { - var result = graph[mapName](data.node.key, function (target) { - return target; - }); - - _assert["default"].deepStrictEqual(result, data.node.neighbors); - } - }), _defineProperty(_ref2, '#.' + filterName, { - 'it should be possible to filter neighbors using a callback.': function itShouldBePossibleToFilterNeighborsUsingACallback() { - var result = graph[filterName](data.node.key, function () { - return true; - }); - - _assert["default"].deepStrictEqual(result, data.node.neighbors); - - result = graph[filterName](data.node.key, function () { - return false; - }); - - _assert["default"].deepStrictEqual(result, []); - } - }), _defineProperty(_ref2, '#.' + reduceName, { - 'it sould throw if not given an initial value.': function itSouldThrowIfNotGivenAnInitialValue() { - _assert["default"]["throws"](function () { - graph[reduceName]('node', function () { - return true; - }); - }, invalid()); - }, - 'it should be possible to reduce neighbors using a callback.': function itShouldBePossibleToReduceNeighborsUsingACallback() { - var result = graph[reduceName](data.node.key, function (acc, key) { - return acc.concat(key); - }, []); - - _assert["default"].deepStrictEqual(result, data.node.neighbors); - } - }), _defineProperty(_ref2, '#.' + findName, { - 'it should be possible to find neighbors.': function itShouldBePossibleToFindNeighbors() { - var neighbors = []; - var found = graph[findName](data.node.key, function (target, attrs) { - neighbors.push(target); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes(target), attrs); - - _assert["default"].strictEqual(graph[areName](data.node.key, target), true); - - return true; - }); - - _assert["default"].strictEqual(found, neighbors[0]); - - _assert["default"].deepStrictEqual(neighbors, data.node.neighbors.slice(0, 1)); - - found = graph[findName](data.node.key, function () { - return false; - }); - - _assert["default"].strictEqual(found, undefined); - } - }), _defineProperty(_ref2, '#.' + someName, { - 'it should always return false on empty set.': function itShouldAlwaysReturnFalseOnEmptySet() { - var loneGraph = new Graph(); - loneGraph.addNode('alone'); - - _assert["default"].strictEqual(loneGraph[someName]('alone', function () { - return true; - }), false); - }, - 'it should be possible to assert whether any neighbor matches a predicate.': function itShouldBePossibleToAssertWhetherAnyNeighborMatchesAPredicate() { - _assert["default"].strictEqual(graph[someName](data.node.key, function () { - return true; - }), data.node.neighbors.length > 0); - } - }), _defineProperty(_ref2, '#.' + everyName, { - 'it should always return true on empty set.': function itShouldAlwaysReturnTrueOnEmptySet() { - var loneGraph = new Graph(); - loneGraph.addNode('alone'); - - _assert["default"].strictEqual(loneGraph[everyName]('alone', function () { - return true; - }), true); - }, - 'it should be possible to assert whether any neighbor matches a predicate.': function itShouldBePossibleToAssertWhetherAnyNeighborMatchesAPredicate() { - _assert["default"].strictEqual(graph[everyName](data.node.key, function () { - return true; - }), data.node.neighbors.length > 0); - } - }), _defineProperty(_ref2, '#.' + iteratorName, { - 'it should be possible to create an iterator over neighbors.': function itShouldBePossibleToCreateAnIteratorOverNeighbors() { - var iterator = graph[iteratorName](data.node.key); - - _assert["default"].deepStrictEqual((0, _take["default"])(iterator), data.node.neighbors.map(function (neighbor) { - return { - neighbor: neighbor, - attributes: graph.getNodeAttributes(neighbor) - }; - })); - } - }), _ref2; - } - - var tests = { - Miscellaneous: { - 'self loops should appear when using #.inNeighbors and should appear only once with #.neighbors.': function selfLoopsShouldAppearWhenUsingInNeighborsAndShouldAppearOnlyOnceWithNeighbors() { - var directed = new Graph({ - type: 'directed' - }); - directed.addNode('Lucy'); - directed.addEdgeWithKey('test', 'Lucy', 'Lucy'); - - _assert["default"].deepStrictEqual(directed.inNeighbors('Lucy'), ['Lucy']); - - _assert["default"].deepStrictEqual(Array.from(directed.inNeighborEntries('Lucy')).map(function (x) { - return x.neighbor; - }), ['Lucy']); - - var neighbors = []; - directed.forEachInNeighbor('Lucy', function (neighbor) { - neighbors.push(neighbor); - }); - - _assert["default"].deepStrictEqual(neighbors, ['Lucy']); - - _assert["default"].deepStrictEqual(directed.neighbors('Lucy'), ['Lucy']); - - neighbors = []; - directed.forEachNeighbor('Lucy', function (neighbor) { - neighbors.push(neighbor); - }); - - _assert["default"].deepStrictEqual(neighbors, ['Lucy']); - - _assert["default"].deepStrictEqual(Array.from(directed.neighborEntries('Lucy')).map(function (x) { - return x.neighbor; - }), ['Lucy']); - } - } - }; // Common tests - - METHODS.forEach(function (name) { - return (0, _helpers.deepMerge)(tests, commonTests(name)); - }); // Specific tests - - for (var name in TEST_DATA) { - (0, _helpers.deepMerge)(tests, specificTests(name, TEST_DATA[name])); - } - - return tests; -} \ No newline at end of file diff --git a/libs/shared/graph-layouts/node_modules/graphology/specs/iteration/nodes.js b/libs/shared/graph-layouts/node_modules/graphology/specs/iteration/nodes.js deleted file mode 100644 index 33298820d..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/specs/iteration/nodes.js +++ /dev/null @@ -1,248 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = nodesIteration; - -var _assert = _interopRequireDefault(require("assert")); - -var _helpers = require("../helpers"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -/** - * Graphology Nodes Iteration Specs - * ================================= - * - * Testing the nodes iteration-related methods of the graph. - */ -function nodesIteration(Graph, checkers) { - var invalid = checkers.invalid; - return { - '#.nodes': { - 'it should return the list of nodes of the graph.': function itShouldReturnTheListOfNodesOfTheGraph() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['one', 'two', 'three']); - - _assert["default"].deepStrictEqual(graph.nodes(), ['one', 'two', 'three']); - } - }, - '#.forEachNode': { - 'it should throw if given callback is not a function.': function itShouldThrowIfGivenCallbackIsNotAFunction() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.forEachNode(null); - }, invalid()); - }, - 'it should be possible to iterate over nodes and their attributes.': function itShouldBePossibleToIterateOverNodesAndTheirAttributes() { - var graph = new Graph(); - graph.addNode('John', { - age: 34 - }); - graph.addNode('Martha', { - age: 33 - }); - var count = 0; - graph.forEachNode(function (key, attributes) { - _assert["default"].strictEqual(key, count ? 'Martha' : 'John'); - - _assert["default"].deepStrictEqual(attributes, count ? { - age: 33 - } : { - age: 34 - }); - - count++; - }); - - _assert["default"].strictEqual(count, 2); - } - }, - '#.findNode': { - 'it should throw if given callback is not a function.': function itShouldThrowIfGivenCallbackIsNotAFunction() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.findNode(null); - }, invalid()); - }, - 'it should be possible to find a node in the graph.': function itShouldBePossibleToFindANodeInTheGraph() { - var graph = new Graph(); - graph.addNode('John', { - age: 34 - }); - graph.addNode('Martha', { - age: 33 - }); - var count = 0; - var found = graph.findNode(function (key, attributes) { - _assert["default"].strictEqual(key, 'John'); - - _assert["default"].deepStrictEqual(attributes, { - age: 34 - }); - - count++; - if (key === 'John') return true; - }); - - _assert["default"].strictEqual(found, 'John'); - - _assert["default"].strictEqual(count, 1); - - found = graph.findNode(function () { - return false; - }); - - _assert["default"].strictEqual(found, undefined); - } - }, - '#.mapNodes': { - 'it should be possible to map nodes.': function itShouldBePossibleToMapNodes() { - var graph = new Graph(); - graph.addNode('one', { - weight: 2 - }); - graph.addNode('two', { - weight: 3 - }); - var result = graph.mapNodes(function (node, attr) { - return attr.weight * 2; - }); - - _assert["default"].deepStrictEqual(result, [4, 6]); - } - }, - '#.someNode': { - 'it should always return false on empty sets.': function itShouldAlwaysReturnFalseOnEmptySets() { - var graph = new Graph(); - - _assert["default"].strictEqual(graph.someNode(function () { - return true; - }), false); - }, - 'it should be possible to find if some node matches a predicate.': function itShouldBePossibleToFindIfSomeNodeMatchesAPredicate() { - var graph = new Graph(); - graph.addNode('one', { - weight: 2 - }); - graph.addNode('two', { - weight: 3 - }); - - _assert["default"].strictEqual(graph.someNode(function (node, attr) { - return attr.weight > 6; - }), false); - - _assert["default"].strictEqual(graph.someNode(function (node, attr) { - return attr.weight > 2; - }), true); - } - }, - '#.everyNode': { - 'it should always return true on empty sets.': function itShouldAlwaysReturnTrueOnEmptySets() { - var graph = new Graph(); - - _assert["default"].strictEqual(graph.everyNode(function () { - return true; - }), true); - }, - 'it should be possible to find if all node matches a predicate.': function itShouldBePossibleToFindIfAllNodeMatchesAPredicate() { - var graph = new Graph(); - graph.addNode('one', { - weight: 2 - }); - graph.addNode('two', { - weight: 3 - }); - - _assert["default"].strictEqual(graph.everyNode(function (node, attr) { - return attr.weight > 2; - }), false); - - _assert["default"].strictEqual(graph.everyNode(function (node, attr) { - return attr.weight > 1; - }), true); - } - }, - '#.filterNodes': { - 'it should be possible to filter nodes.': function itShouldBePossibleToFilterNodes() { - var graph = new Graph(); - graph.addNode('one', { - weight: 2 - }); - graph.addNode('two', { - weight: 3 - }); - graph.addNode('three', { - weight: 4 - }); - var result = graph.filterNodes(function (node, _ref) { - var weight = _ref.weight; - return weight >= 3; - }); - - _assert["default"].deepStrictEqual(result, ['two', 'three']); - } - }, - '#.reduceNodes': { - 'it should throw if initial value is not given.': function itShouldThrowIfInitialValueIsNotGiven() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.reduceNodes(function (x, _, attr) { - return x + attr.weight; - }); - }, invalid()); - }, - 'it should be possible to reduce nodes.': function itShouldBePossibleToReduceNodes() { - var graph = new Graph(); - graph.addNode('one', { - weight: 2 - }); - graph.addNode('two', { - weight: 3 - }); - graph.addNode('three', { - weight: 4 - }); - var result = graph.reduceNodes(function (x, _, attr) { - return x + attr.weight; - }, 0); - - _assert["default"].strictEqual(result, 9); - } - }, - '#.nodeEntries': { - 'it should be possible to create a nodes iterator.': function itShouldBePossibleToCreateANodesIterator() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['one', 'two', 'three']); - graph.replaceNodeAttributes('two', { - hello: 'world' - }); - var iterator = graph.nodeEntries(); - - _assert["default"].deepStrictEqual(iterator.next().value, { - node: 'one', - attributes: {} - }); - - _assert["default"].deepStrictEqual(iterator.next().value, { - node: 'two', - attributes: { - hello: 'world' - } - }); - - _assert["default"].deepStrictEqual(iterator.next().value, { - node: 'three', - attributes: {} - }); - - _assert["default"].strictEqual(iterator.next().done, true); - } - } - }; -} \ No newline at end of file diff --git a/libs/shared/graph-layouts/node_modules/graphology/specs/known.js b/libs/shared/graph-layouts/node_modules/graphology/specs/known.js deleted file mode 100644 index 040ffb036..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/specs/known.js +++ /dev/null @@ -1,50 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = knownMethods; - -var _assert = _interopRequireDefault(require("assert")); - -var _helpers = require("./helpers"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -/** - * Graphology Known Methods Specs - * =============================== - * - * Testing the known methods of the graph. - */ -function knownMethods(Graph) { - return { - '#.toJSON': { - 'it should return the serialized graph.': function itShouldReturnTheSerializedGraph() { - var graph = new Graph({ - multi: true - }); - (0, _helpers.addNodesFrom)(graph, ['John', 'Jack', 'Martha']); - graph.setNodeAttribute('John', 'age', 34); - graph.addEdgeWithKey('J->J•1', 'John', 'Jack'); - graph.addEdgeWithKey('J->J•2', 'John', 'Jack', { - weight: 2 - }); - graph.addEdgeWithKey('J->J•3', 'John', 'Jack'); - graph.addUndirectedEdgeWithKey('J<->J•1', 'John', 'Jack'); - graph.addUndirectedEdgeWithKey('J<->J•2', 'John', 'Jack', { - weight: 3 - }); - - _assert["default"].deepStrictEqual(graph.toJSON(), graph["export"]()); - } - }, - '#.toString': { - 'it should return "[object Graph]".': function itShouldReturnObjectGraph() { - var graph = new Graph(); - - _assert["default"].strictEqual(graph.toString(), '[object Graph]'); - } - } - }; -} \ No newline at end of file diff --git a/libs/shared/graph-layouts/node_modules/graphology/specs/misc.js b/libs/shared/graph-layouts/node_modules/graphology/specs/misc.js deleted file mode 100644 index c0044b1a2..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/specs/misc.js +++ /dev/null @@ -1,112 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = misc; - -var _assert = _interopRequireDefault(require("assert")); - -var _helpers = require("./helpers"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -/** - * Graphology Misc Specs - * ====================== - * - * Testing the miscellaneous things about the graph. - */ -function misc(Graph) { - return { - Structure: { - 'a simple mixed graph can have A->B, B->A & A<->B': function aSimpleMixedGraphCanHaveABBAAB() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['Audrey', 'Benjamin']); - - _assert["default"].doesNotThrow(function () { - graph.addEdge('Audrey', 'Benjamin'); - graph.addEdge('Benjamin', 'Audrey'); - graph.addUndirectedEdge('Benjamin', 'Audrey'); - }); - }, - 'deleting the last edge between A & B should correctly clear neighbor index.': function deletingTheLastEdgeBetweenABShouldCorrectlyClearNeighborIndex() { - var graph = new Graph({ - multi: true - }); - graph.addNode('A'); - graph.addNode('B'); - graph.addEdge('A', 'B'); - graph.addEdge('A', 'B'); - graph.forEachEdge('A', function (edge) { - return graph.dropEdge(edge); - }); - - _assert["default"].deepStrictEqual(graph.neighbors('A'), []); - - _assert["default"].deepStrictEqual(graph.neighbors('B'), []); - }, - 'exhaustive deletion use-cases should not break doubly-linked lists implementation of multigraph edge storage.': function exhaustiveDeletionUseCasesShouldNotBreakDoublyLinkedListsImplementationOfMultigraphEdgeStorage() { - var graph = new Graph({ - multi: true - }); - graph.mergeEdgeWithKey('1', 'A', 'B'); - graph.mergeEdgeWithKey('2', 'A', 'B'); - graph.mergeEdgeWithKey('3', 'A', 'B'); - graph.mergeEdgeWithKey('4', 'A', 'B'); - graph.dropEdge('1'); - graph.dropEdge('2'); - graph.dropEdge('3'); - graph.dropEdge('4'); - - _assert["default"].strictEqual(graph.size, 0); - - _assert["default"].strictEqual(graph.areNeighbors('A', 'B'), false); - - graph.mergeEdgeWithKey('1', 'A', 'B'); - graph.mergeEdgeWithKey('2', 'A', 'B'); - graph.mergeEdgeWithKey('3', 'A', 'B'); - graph.mergeEdgeWithKey('4', 'A', 'B'); - - _assert["default"].strictEqual(graph.size, 4); - - _assert["default"].strictEqual(graph.areNeighbors('A', 'B'), true); - - graph.dropEdge('2'); - graph.dropEdge('3'); - - _assert["default"].strictEqual(graph.size, 2); - - _assert["default"].strictEqual(graph.areNeighbors('A', 'B'), true); - - graph.dropEdge('4'); - graph.dropEdge('1'); - - _assert["default"].strictEqual(graph.size, 0); - - _assert["default"].strictEqual(graph.areNeighbors('A', 'B'), false); - } - }, - 'Key coercion': { - 'keys should be correctly coerced to strings.': function keysShouldBeCorrectlyCoercedToStrings() { - var graph = new Graph(); - graph.addNode(1); - graph.addNode('2'); - - _assert["default"].strictEqual(graph.hasNode(1), true); - - _assert["default"].strictEqual(graph.hasNode('1'), true); - - _assert["default"].strictEqual(graph.hasNode(2), true); - - _assert["default"].strictEqual(graph.hasNode('2'), true); - - graph.addEdgeWithKey(3, 1, 2); - - _assert["default"].strictEqual(graph.hasEdge(3), true); - - _assert["default"].strictEqual(graph.hasEdge('3'), true); - } - } - }; -} \ No newline at end of file diff --git a/libs/shared/graph-layouts/node_modules/graphology/specs/mutation.js b/libs/shared/graph-layouts/node_modules/graphology/specs/mutation.js deleted file mode 100644 index c6a114c1b..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/specs/mutation.js +++ /dev/null @@ -1,883 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = mutation; - -var _assert = _interopRequireDefault(require("assert")); - -var _helpers = require("./helpers"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } - -function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } - -function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } - -function mutation(Graph, checkers) { - var invalid = checkers.invalid, - notFound = checkers.notFound, - usage = checkers.usage; - return { - '#.addNode': { - 'it should throw if given attributes is not an object.': function itShouldThrowIfGivenAttributesIsNotAnObject() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.addNode('test', true); - }, invalid()); - }, - 'it should throw if the given node already exist.': function itShouldThrowIfTheGivenNodeAlreadyExist() { - var graph = new Graph(); - graph.addNode('Martha'); - - _assert["default"]["throws"](function () { - graph.addNode('Martha'); - }, usage()); - }, - 'it should return the added node.': function itShouldReturnTheAddedNode() { - var graph = new Graph(); - - _assert["default"].strictEqual(graph.addNode('John'), 'John'); - } - }, - '#.mergeNode': { - 'it should add the node if it does not exist yet.': function itShouldAddTheNodeIfItDoesNotExistYet() { - var graph = new Graph(); - graph.mergeNode('John'); - - _assert["default"].deepStrictEqual(graph.nodes(), ['John']); - }, - 'it should do nothing if the node already exists.': function itShouldDoNothingIfTheNodeAlreadyExists() { - var graph = new Graph(); - graph.addNode('John'); - graph.mergeNode('John'); - - _assert["default"].deepStrictEqual(graph.nodes(), ['John']); - }, - 'it should merge the attributes.': function itShouldMergeTheAttributes() { - var graph = new Graph(); - graph.addNode('John', { - eyes: 'blue' - }); - graph.mergeNode('John', { - age: 15 - }); - - _assert["default"].deepStrictEqual(graph.nodes(), ['John']); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes('John'), { - eyes: 'blue', - age: 15 - }); - }, - 'it should coerce keys to string.': function itShouldCoerceKeysToString() { - var graph = new Graph(); - graph.addNode(4); - - _assert["default"].doesNotThrow(function () { - return graph.mergeNode(4); - }); - }, - 'it should return useful information.': function itShouldReturnUsefulInformation() { - var graph = new Graph(); - - var _graph$mergeNode = graph.mergeNode('Jack'), - key = _graph$mergeNode[0], - wasAdded = _graph$mergeNode[1]; - - _assert["default"].strictEqual(key, 'Jack'); - - _assert["default"].strictEqual(wasAdded, true); - - var _graph$mergeNode2 = graph.mergeNode('Jack'); - - key = _graph$mergeNode2[0]; - wasAdded = _graph$mergeNode2[1]; - - _assert["default"].strictEqual(key, 'Jack'); - - _assert["default"].strictEqual(wasAdded, false); - } - }, - '#.updateNode': { - 'it should add the node if it does not exist yet.': function itShouldAddTheNodeIfItDoesNotExistYet() { - var graph = new Graph(); - graph.updateNode('John'); - - _assert["default"].deepStrictEqual(graph.nodes(), ['John']); - }, - 'it should do nothing if the node already exists.': function itShouldDoNothingIfTheNodeAlreadyExists() { - var graph = new Graph(); - graph.addNode('John'); - graph.updateNode('John'); - - _assert["default"].deepStrictEqual(graph.nodes(), ['John']); - }, - 'it should update the attributes.': function itShouldUpdateTheAttributes() { - var graph = new Graph(); - graph.addNode('John', { - eyes: 'blue', - count: 1 - }); - graph.updateNode('John', function (attr) { - return _objectSpread(_objectSpread({}, attr), {}, { - count: attr.count + 1 - }); - }); - - _assert["default"].deepStrictEqual(graph.nodes(), ['John']); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes('John'), { - eyes: 'blue', - count: 2 - }); - }, - 'it should be possible to start from blank attributes.': function itShouldBePossibleToStartFromBlankAttributes() { - var graph = new Graph(); - graph.updateNode('John', function () { - return { - count: 2 - }; - }); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes('John'), { - count: 2 - }); - }, - 'it should coerce keys to string.': function itShouldCoerceKeysToString() { - var graph = new Graph(); - graph.addNode(4); - - _assert["default"].doesNotThrow(function () { - return graph.updateNode(4); - }); - }, - 'it should return useful information.': function itShouldReturnUsefulInformation() { - var graph = new Graph(); - - var _graph$updateNode = graph.updateNode('Jack'), - key = _graph$updateNode[0], - wasAdded = _graph$updateNode[1]; - - _assert["default"].strictEqual(key, 'Jack'); - - _assert["default"].strictEqual(wasAdded, true); - - var _graph$updateNode2 = graph.updateNode('Jack'); - - key = _graph$updateNode2[0]; - wasAdded = _graph$updateNode2[1]; - - _assert["default"].strictEqual(key, 'Jack'); - - _assert["default"].strictEqual(wasAdded, false); - } - }, - '#.addDirectedEdge': { - 'it should throw if given attributes is not an object.': function itShouldThrowIfGivenAttributesIsNotAnObject() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.addDirectedEdge('source', 'target', true); - }, invalid()); - }, - 'it should throw if the graph is undirected.': function itShouldThrowIfTheGraphIsUndirected() { - var graph = new Graph({ - type: 'undirected' - }); - - _assert["default"]["throws"](function () { - graph.addDirectedEdge('source', 'target'); - }, usage()); - }, - 'it should throw if either the source or the target does not exist.': function itShouldThrowIfEitherTheSourceOrTheTargetDoesNotExist() { - var graph = new Graph(); - graph.addNode('Martha'); - - _assert["default"]["throws"](function () { - graph.addDirectedEdge('Thomas', 'Eric'); - }, notFound()); - - _assert["default"]["throws"](function () { - graph.addDirectedEdge('Martha', 'Eric'); - }, notFound()); - }, - 'it should throw if the edge is a loop and the graph does not allow it.': function itShouldThrowIfTheEdgeIsALoopAndTheGraphDoesNotAllowIt() { - var graph = new Graph({ - allowSelfLoops: false - }); - graph.addNode('Thomas'); - - _assert["default"]["throws"](function () { - graph.addDirectedEdge('Thomas', 'Thomas'); - }, usage()); - }, - 'it should be possible to add self loops.': function itShouldBePossibleToAddSelfLoops() { - var graph = new Graph(); - graph.addNode('Thomas'); - var loop = graph.addDirectedEdge('Thomas', 'Thomas'); - - _assert["default"].deepStrictEqual(graph.extremities(loop), ['Thomas', 'Thomas']); - }, - 'it should throw if the graph is not multi & we try to add twice the same edge.': function itShouldThrowIfTheGraphIsNotMultiWeTryToAddTwiceTheSameEdge() { - var graph = new Graph(); - graph.addNode('Thomas'); - graph.addNode('Martha'); - graph.addDirectedEdge('Thomas', 'Martha'); - - _assert["default"]["throws"](function () { - graph.addDirectedEdge('Thomas', 'Martha'); - }, usage()); - - _assert["default"]["throws"](function () { - graph.addDirectedEdgeWithKey('T->M', 'Thomas', 'Martha'); - }, usage()); - }, - "it should return the generated edge's key.": function itShouldReturnTheGeneratedEdgeSKey() { - var graph = new Graph(); - graph.addNode('Thomas'); - graph.addNode('Martha'); - var edge = graph.addDirectedEdge('Thomas', 'Martha'); - (0, _assert["default"])(typeof edge === 'string' || typeof edge === 'number'); - (0, _assert["default"])(!(edge instanceof Graph)); - } - }, - '#.addEdge': { - 'it should add a directed edge if the graph is directed or mixed.': function itShouldAddADirectedEdgeIfTheGraphIsDirectedOrMixed() { - var graph = new Graph(), - directedGraph = new Graph({ - type: 'directed' - }); - graph.addNode('John'); - graph.addNode('Martha'); - var mixedEdge = graph.addEdge('John', 'Martha'); - directedGraph.addNode('John'); - directedGraph.addNode('Martha'); - var directedEdge = directedGraph.addEdge('John', 'Martha'); - (0, _assert["default"])(graph.isDirected(mixedEdge)); - (0, _assert["default"])(directedGraph.isDirected(directedEdge)); - }, - 'it should add an undirected edge if the graph is undirected.': function itShouldAddAnUndirectedEdgeIfTheGraphIsUndirected() { - var graph = new Graph({ - type: 'undirected' - }); - graph.addNode('John'); - graph.addNode('Martha'); - var edge = graph.addEdge('John', 'Martha'); - (0, _assert["default"])(graph.isUndirected(edge)); - } - }, - '#.addDirectedEdgeWithKey': { - 'it should throw if an edge with the same key already exists.': function itShouldThrowIfAnEdgeWithTheSameKeyAlreadyExists() { - var graph = new Graph(); - graph.addNode('Thomas'); - graph.addNode('Martha'); - graph.addDirectedEdgeWithKey('T->M', 'Thomas', 'Martha'); - - _assert["default"]["throws"](function () { - graph.addDirectedEdgeWithKey('T->M', 'Thomas', 'Martha'); - }, usage()); - - _assert["default"]["throws"](function () { - graph.addUndirectedEdgeWithKey('T->M', 'Thomas', 'Martha'); - }, usage()); - } - }, - '#.addUndirectedEdgeWithKey': { - 'it should throw if an edge with the same key already exists.': function itShouldThrowIfAnEdgeWithTheSameKeyAlreadyExists() { - var graph = new Graph(); - graph.addNode('Thomas'); - graph.addNode('Martha'); - graph.addUndirectedEdgeWithKey('T<->M', 'Thomas', 'Martha'); - - _assert["default"]["throws"](function () { - graph.addUndirectedEdgeWithKey('T<->M', 'Thomas', 'Martha'); - }, usage()); - - _assert["default"]["throws"](function () { - graph.addDirectedEdgeWithKey('T<->M', 'Thomas', 'Martha'); - }, usage()); - } - }, - '#.addEdgeWithKey': { - 'it should add a directed edge if the graph is directed or mixed.': function itShouldAddADirectedEdgeIfTheGraphIsDirectedOrMixed() { - var graph = new Graph(), - directedGraph = new Graph({ - type: 'directed' - }); - graph.addNode('John'); - graph.addNode('Martha'); - var mixedEdge = graph.addEdgeWithKey('J->M', 'John', 'Martha'); - directedGraph.addNode('John'); - directedGraph.addNode('Martha'); - var directedEdge = directedGraph.addEdgeWithKey('J->M', 'John', 'Martha'); - (0, _assert["default"])(graph.isDirected(mixedEdge)); - (0, _assert["default"])(directedGraph.isDirected(directedEdge)); - }, - 'it should add an undirected edge if the graph is undirected.': function itShouldAddAnUndirectedEdgeIfTheGraphIsUndirected() { - var graph = new Graph({ - type: 'undirected' - }); - graph.addNode('John'); - graph.addNode('Martha'); - var edge = graph.addEdgeWithKey('J<->M', 'John', 'Martha'); - (0, _assert["default"])(graph.isUndirected(edge)); - } - }, - '#.mergeEdge': { - 'it should add the edge if it does not yet exist.': function itShouldAddTheEdgeIfItDoesNotYetExist() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Martha']); - graph.mergeEdge('John', 'Martha'); - - _assert["default"].strictEqual(graph.size, 1); - - _assert["default"].strictEqual(graph.hasEdge('John', 'Martha'), true); - }, - 'it should do nothing if the edge already exists.': function itShouldDoNothingIfTheEdgeAlreadyExists() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Martha']); - graph.addEdge('John', 'Martha'); - graph.mergeEdge('John', 'Martha'); - - _assert["default"].strictEqual(graph.size, 1); - - _assert["default"].strictEqual(graph.hasEdge('John', 'Martha'), true); - }, - 'it should merge existing attributes if any.': function itShouldMergeExistingAttributesIfAny() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Martha']); - graph.addEdge('John', 'Martha', { - type: 'KNOWS' - }); - graph.mergeEdge('John', 'Martha', { - weight: 2 - }); - - _assert["default"].strictEqual(graph.size, 1); - - _assert["default"].strictEqual(graph.hasEdge('John', 'Martha'), true); - - _assert["default"].deepStrictEqual(graph.getEdgeAttributes('John', 'Martha'), { - type: 'KNOWS', - weight: 2 - }); - }, - 'it should add missing nodes in the path.': function itShouldAddMissingNodesInThePath() { - var graph = new Graph(); - graph.mergeEdge('John', 'Martha'); - - _assert["default"].strictEqual(graph.order, 2); - - _assert["default"].strictEqual(graph.size, 1); - - _assert["default"].deepStrictEqual(graph.nodes(), ['John', 'Martha']); - }, - 'it should throw in case of inconsistencies.': function itShouldThrowInCaseOfInconsistencies() { - var graph = new Graph(); - graph.mergeEdgeWithKey('J->M', 'John', 'Martha'); - - _assert["default"]["throws"](function () { - graph.mergeEdgeWithKey('J->M', 'John', 'Thomas'); - }, usage()); - }, - 'it should be able to merge undirected edges in both directions.': function itShouldBeAbleToMergeUndirectedEdgesInBothDirections() { - _assert["default"].doesNotThrow(function () { - var graph = new Graph(); - graph.mergeUndirectedEdgeWithKey('J<->M', 'John', 'Martha'); - graph.mergeUndirectedEdgeWithKey('J<->M', 'John', 'Martha'); - graph.mergeUndirectedEdgeWithKey('J<->M', 'Martha', 'John'); - }, usage()); - }, - 'it should distinguish between typed edges.': function itShouldDistinguishBetweenTypedEdges() { - var graph = new Graph(); - graph.mergeEdge('John', 'Martha', { - type: 'LIKES' - }); - graph.mergeUndirectedEdge('John', 'Martha', { - weight: 34 - }); - - _assert["default"].strictEqual(graph.size, 2); - }, - 'it should be possible to merge a self loop.': function itShouldBePossibleToMergeASelfLoop() { - var graph = new Graph(); - graph.mergeEdge('John', 'John', { - type: 'IS' - }); - - _assert["default"].strictEqual(graph.order, 1); - - _assert["default"].strictEqual(graph.size, 1); - }, - 'it should return useful information.': function itShouldReturnUsefulInformation() { - var graph = new Graph(); - var info = graph.mergeEdge('John', 'Jack'); - - _assert["default"].deepStrictEqual(info, [graph.edge('John', 'Jack'), true, true, true]); - - info = graph.mergeEdge('John', 'Jack'); - - _assert["default"].deepStrictEqual(info, [graph.edge('John', 'Jack'), false, false, false]); - - graph.addNode('Mary'); - info = graph.mergeEdge('Mary', 'Sue'); - - _assert["default"].deepStrictEqual(info, [graph.edge('Mary', 'Sue'), true, false, true]); - - info = graph.mergeEdge('Gwladys', 'Mary'); - - _assert["default"].deepStrictEqual(info, [graph.edge('Gwladys', 'Mary'), true, true, false]); - - graph.addNode('Quintin'); - info = graph.mergeEdge('Quintin', 'Mary'); - - _assert["default"].deepStrictEqual(info, [graph.edge('Quintin', 'Mary'), true, false, false]); - } - }, - '#.updateEdge': { - 'it should add the edge if it does not yet exist.': function itShouldAddTheEdgeIfItDoesNotYetExist() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Martha']); - graph.updateEdge('John', 'Martha'); - - _assert["default"].strictEqual(graph.size, 1); - - _assert["default"].strictEqual(graph.hasEdge('John', 'Martha'), true); - }, - 'it should do nothing if the edge already exists.': function itShouldDoNothingIfTheEdgeAlreadyExists() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Martha']); - graph.addEdge('John', 'Martha'); - graph.updateEdge('John', 'Martha'); - - _assert["default"].strictEqual(graph.size, 1); - - _assert["default"].strictEqual(graph.hasEdge('John', 'Martha'), true); - }, - 'it should be possible to start from blank attributes.': function itShouldBePossibleToStartFromBlankAttributes() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Martha']); - graph.updateEdge('John', 'Martha', function (attr) { - return _objectSpread(_objectSpread({}, attr), {}, { - weight: 3 - }); - }); - - _assert["default"].strictEqual(graph.size, 1); - - _assert["default"].strictEqual(graph.hasEdge('John', 'Martha'), true); - - _assert["default"].deepStrictEqual(graph.getEdgeAttributes('John', 'Martha'), { - weight: 3 - }); - }, - 'it should update existing attributes if any.': function itShouldUpdateExistingAttributesIfAny() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Martha']); - graph.addEdge('John', 'Martha', { - type: 'KNOWS' - }); - graph.updateEdge('John', 'Martha', function (attr) { - return _objectSpread(_objectSpread({}, attr), {}, { - weight: 2 - }); - }); - - _assert["default"].strictEqual(graph.size, 1); - - _assert["default"].strictEqual(graph.hasEdge('John', 'Martha'), true); - - _assert["default"].deepStrictEqual(graph.getEdgeAttributes('John', 'Martha'), { - type: 'KNOWS', - weight: 2 - }); - }, - 'it should add missing nodes in the path.': function itShouldAddMissingNodesInThePath() { - var graph = new Graph(); - graph.updateEdge('John', 'Martha'); - - _assert["default"].strictEqual(graph.order, 2); - - _assert["default"].strictEqual(graph.size, 1); - - _assert["default"].deepStrictEqual(graph.nodes(), ['John', 'Martha']); - }, - 'it should throw in case of inconsistencies.': function itShouldThrowInCaseOfInconsistencies() { - var graph = new Graph(); - graph.updateEdgeWithKey('J->M', 'John', 'Martha'); - - _assert["default"]["throws"](function () { - graph.updateEdgeWithKey('J->M', 'John', 'Thomas'); - }, usage()); - }, - 'it should distinguish between typed edges.': function itShouldDistinguishBetweenTypedEdges() { - var graph = new Graph(); - graph.updateEdge('John', 'Martha', function () { - return { - type: 'LIKES' - }; - }); - graph.updateUndirectedEdge('John', 'Martha', function () { - return { - weight: 34 - }; - }); - - _assert["default"].strictEqual(graph.size, 2); - }, - 'it should be possible to merge a self loop.': function itShouldBePossibleToMergeASelfLoop() { - var graph = new Graph(); - graph.updateEdge('John', 'John', function () { - return { - type: 'IS' - }; - }); - - _assert["default"].strictEqual(graph.order, 1); - - _assert["default"].strictEqual(graph.size, 1); - }, - 'it should return useful information.': function itShouldReturnUsefulInformation() { - var graph = new Graph(); - var info = graph.updateEdge('John', 'Jack'); - - _assert["default"].deepStrictEqual(info, [graph.edge('John', 'Jack'), true, true, true]); - - info = graph.updateEdge('John', 'Jack'); - - _assert["default"].deepStrictEqual(info, [graph.edge('John', 'Jack'), false, false, false]); - - graph.addNode('Mary'); - info = graph.updateEdge('Mary', 'Sue'); - - _assert["default"].deepStrictEqual(info, [graph.edge('Mary', 'Sue'), true, false, true]); - - info = graph.updateEdge('Gwladys', 'Mary'); - - _assert["default"].deepStrictEqual(info, [graph.edge('Gwladys', 'Mary'), true, true, false]); - - graph.addNode('Quintin'); - info = graph.updateEdge('Quintin', 'Mary'); - - _assert["default"].deepStrictEqual(info, [graph.edge('Quintin', 'Mary'), true, false, false]); - } - }, - '#.dropEdge': { - 'it should throw if the edge or nodes in the path are not found in the graph.': function itShouldThrowIfTheEdgeOrNodesInThePathAreNotFoundInTheGraph() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Martha']); - - _assert["default"]["throws"](function () { - graph.dropEdge('Test'); - }, notFound()); - - _assert["default"]["throws"](function () { - graph.dropEdge('Forever', 'Alone'); - }, notFound()); - - _assert["default"]["throws"](function () { - graph.dropEdge('John', 'Test'); - }, notFound()); - - _assert["default"]["throws"](function () { - graph.dropEdge('John', 'Martha'); - }, notFound()); - }, - 'it should correctly remove the given edge from the graph.': function itShouldCorrectlyRemoveTheGivenEdgeFromTheGraph() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Margaret']); - var edge = graph.addEdge('John', 'Margaret'); - graph.dropEdge(edge); - - _assert["default"].strictEqual(graph.order, 2); - - _assert["default"].strictEqual(graph.size, 0); - - _assert["default"].strictEqual(graph.degree('John'), 0); - - _assert["default"].strictEqual(graph.degree('Margaret'), 0); - - _assert["default"].strictEqual(graph.hasEdge(edge), false); - - _assert["default"].strictEqual(graph.hasDirectedEdge('John', 'Margaret'), false); - }, - 'it should be possible to remove an edge using source & target.': function itShouldBePossibleToRemoveAnEdgeUsingSourceTarget() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Margaret']); - graph.addEdge('John', 'Margaret'); - graph.dropEdge('John', 'Margaret'); - - _assert["default"].strictEqual(graph.order, 2); - - _assert["default"].strictEqual(graph.size, 0); - - _assert["default"].strictEqual(graph.degree('John'), 0); - - _assert["default"].strictEqual(graph.degree('Margaret'), 0); - - _assert["default"].strictEqual(graph.hasEdge('John', 'Margaret'), false); - - _assert["default"].strictEqual(graph.hasDirectedEdge('John', 'Margaret'), false); - }, - 'it should work with self loops.': function itShouldWorkWithSelfLoops() { - var graph = new Graph(); - graph.mergeEdge('John', 'John'); - graph.dropEdge('John', 'John'); - - _assert["default"].deepStrictEqual(graph.edges(), []); - - _assert["default"].deepStrictEqual(graph.edges('John'), []); - - _assert["default"].strictEqual(graph.size, 0); - - var multiGraph = new Graph({ - multi: true - }); - multiGraph.mergeEdgeWithKey('j', 'John', 'John'); - multiGraph.mergeEdgeWithKey('k', 'John', 'John'); - multiGraph.dropEdge('j'); - - _assert["default"].deepStrictEqual(multiGraph.edges(), ['k']); - - _assert["default"].deepStrictEqual(multiGraph.edges('John'), ['k']); - - _assert["default"].strictEqual(multiGraph.size, 1); - } - }, - '#.dropNode': { - 'it should throw if the edge is not found in the graph.': function itShouldThrowIfTheEdgeIsNotFoundInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.dropNode('Test'); - }, notFound()); - }, - 'it should correctly remove the given node from the graph.': function itShouldCorrectlyRemoveTheGivenNodeFromTheGraph() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Margaret']); - var edge = graph.addEdge('John', 'Margaret'); - graph.mergeEdge('Jack', 'Trudy'); - graph.dropNode('Margaret'); - - _assert["default"].strictEqual(graph.order, 3); - - _assert["default"].strictEqual(graph.size, 1); - - _assert["default"].strictEqual(graph.hasNode('Margaret'), false); - - _assert["default"].strictEqual(graph.hasEdge(edge), false); - - _assert["default"].strictEqual(graph.degree('John'), 0); - - _assert["default"].strictEqual(graph.hasDirectedEdge('John', 'Margaret'), false); - }, - 'it should also work with mixed, multi graphs and self loops.': function itShouldAlsoWorkWithMixedMultiGraphsAndSelfLoops() { - var graph = new Graph({ - multi: true - }); - graph.mergeEdge('A', 'B'); - graph.mergeEdge('A', 'B'); - graph.mergeEdge('B', 'A'); - graph.mergeEdge('A', 'B'); - graph.mergeEdge('A', 'A'); - graph.mergeUndirectedEdge('A', 'B'); - graph.mergeUndirectedEdge('A', 'B'); - graph.mergeUndirectedEdge('A', 'A'); - var copy = graph.copy(); - graph.dropNode('B'); - - _assert["default"].strictEqual(graph.size, 2); - - _assert["default"].strictEqual(graph.directedSelfLoopCount, 1); - - _assert["default"].strictEqual(graph.undirectedSelfLoopCount, 1); - - copy.dropNode('A'); - - _assert["default"].strictEqual(copy.size, 0); - - _assert["default"].strictEqual(copy.directedSelfLoopCount, 0); - - _assert["default"].strictEqual(copy.undirectedSelfLoopCount, 0); - }, - 'it should also coerce keys as strings.': function itShouldAlsoCoerceKeysAsStrings() { - function Key(name) { - this.name = name; - } - - Key.prototype.toString = function () { - return this.name; - }; - - var graph = new Graph(); - var key = new Key('test'); - graph.addNode(key); - graph.dropNode(key); - - _assert["default"].strictEqual(graph.order, 0); - - _assert["default"].strictEqual(graph.hasNode(key), false); - } - }, - '#.dropDirectedEdge': { - 'it should throw if given incorrect arguments.': function itShouldThrowIfGivenIncorrectArguments() { - _assert["default"]["throws"](function () { - var graph = new Graph({ - multi: true - }); - graph.mergeEdge('a', 'b'); - graph.dropDirectedEdge('a', 'b'); - }, usage()); - - _assert["default"]["throws"](function () { - var graph = new Graph({ - multi: true - }); - graph.mergeEdgeWithKey('1', 'a', 'b'); - graph.dropDirectedEdge('1'); - }, usage()); - - _assert["default"]["throws"](function () { - var graph = new Graph(); - graph.dropDirectedEdge('a', 'b'); - }, notFound()); - }, - 'it should correctly drop the relevant edge.': function itShouldCorrectlyDropTheRelevantEdge() { - var graph = new Graph(); - graph.mergeUndirectedEdge('a', 'b'); - graph.mergeDirectedEdge('a', 'b'); - graph.dropDirectedEdge('a', 'b'); - - _assert["default"].strictEqual(graph.directedSize, 0); - - _assert["default"].strictEqual(graph.hasDirectedEdge('a', 'b'), false); - - _assert["default"].strictEqual(graph.hasUndirectedEdge('a', 'b'), true); - } - }, - '#.dropUndirectedEdge': { - 'it should throw if given incorrect arguments.': function itShouldThrowIfGivenIncorrectArguments() { - _assert["default"]["throws"](function () { - var graph = new Graph({ - multi: true, - type: 'undirected' - }); - graph.mergeEdge('a', 'b'); - graph.dropUndirectedEdge('a', 'b'); - }, usage()); - - _assert["default"]["throws"](function () { - var graph = new Graph({ - multi: true, - type: 'undirected' - }); - graph.mergeEdgeWithKey('1', 'a', 'b'); - graph.dropUndirectedEdge('1'); - }, usage()); - - _assert["default"]["throws"](function () { - var graph = new Graph({ - type: 'undirected' - }); - graph.dropUndirectedEdge('a', 'b'); - }, notFound()); - }, - 'it should correctly drop the relevant edge.': function itShouldCorrectlyDropTheRelevantEdge() { - var graph = new Graph(); - graph.mergeUndirectedEdge('a', 'b'); - graph.mergeDirectedEdge('a', 'b'); - graph.dropUndirectedEdge('a', 'b'); - - _assert["default"].strictEqual(graph.undirectedSize, 0); - - _assert["default"].strictEqual(graph.hasUndirectedEdge('a', 'b'), false); - - _assert["default"].strictEqual(graph.hasDirectedEdge('a', 'b'), true); - } - }, - '#.clear': { - 'it should empty the graph.': function itShouldEmptyTheGraph() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['Lindsay', 'Martha']); - var edge = graph.addEdge('Lindsay', 'Martha'); - graph.clear(); - - _assert["default"].strictEqual(graph.order, 0); - - _assert["default"].strictEqual(graph.size, 0); - - _assert["default"].strictEqual(graph.hasNode('Lindsay'), false); - - _assert["default"].strictEqual(graph.hasNode('Martha'), false); - - _assert["default"].strictEqual(graph.hasEdge(edge), false); - }, - 'it should be possible to use the graph normally afterwards.': function itShouldBePossibleToUseTheGraphNormallyAfterwards() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['Lindsay', 'Martha']); - graph.addEdge('Lindsay', 'Martha'); - graph.clear(); - (0, _helpers.addNodesFrom)(graph, ['Lindsay', 'Martha']); - var edge = graph.addEdge('Lindsay', 'Martha'); - - _assert["default"].strictEqual(graph.order, 2); - - _assert["default"].strictEqual(graph.size, 1); - - _assert["default"].strictEqual(graph.hasNode('Lindsay'), true); - - _assert["default"].strictEqual(graph.hasNode('Martha'), true); - - _assert["default"].strictEqual(graph.hasEdge(edge), true); - } - }, - '#.clearEdges': { - 'it should drop every edge from the graph.': function itShouldDropEveryEdgeFromTheGraph() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['Lindsay', 'Martha']); - var edge = graph.addEdge('Lindsay', 'Martha'); - graph.clearEdges(); - - _assert["default"].strictEqual(graph.order, 2); - - _assert["default"].strictEqual(graph.size, 0); - - _assert["default"].strictEqual(graph.hasNode('Lindsay'), true); - - _assert["default"].strictEqual(graph.hasNode('Martha'), true); - - _assert["default"].strictEqual(graph.hasEdge(edge), false); - }, - 'it should properly reset instance counters.': function itShouldProperlyResetInstanceCounters() { - var graph = new Graph(); - graph.mergeEdge(0, 1); - - _assert["default"].strictEqual(graph.directedSize, 1); - - graph.clearEdges(); - - _assert["default"].strictEqual(graph.directedSize, 0); - - graph.mergeEdge(0, 1); - graph.clear(); - - _assert["default"].strictEqual(graph.directedSize, 0); - }, - 'it should properly clear node indices, regarding self loops notably.': function itShouldProperlyClearNodeIndicesRegardingSelfLoopsNotably() { - var graph = new Graph(); - graph.mergeEdge(1, 1); - - _assert["default"].strictEqual(graph.degree(1), 2); - - graph.clearEdges(); - - _assert["default"].strictEqual(graph.degree(1), 0); - } - } - }; -} \ No newline at end of file diff --git a/libs/shared/graph-layouts/node_modules/graphology/specs/properties.js b/libs/shared/graph-layouts/node_modules/graphology/specs/properties.js deleted file mode 100644 index 4babe3dc5..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/specs/properties.js +++ /dev/null @@ -1,214 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = properties; - -var _assert = _interopRequireDefault(require("assert")); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); } - -var PROPERTIES = ['order', 'size', 'directedSize', 'undirectedSize', 'type', 'multi', 'allowSelfLoops', 'implementation', 'selfLoopCount', 'directedSelfLoopCount', 'undirectedSelfLoopCount']; - -function properties(Graph) { - return { - /** - * Regarding all properties. - */ - misc: { - 'all expected properties should be set.': function allExpectedPropertiesShouldBeSet() { - var graph = new Graph(); - PROPERTIES.forEach(function (property) { - (0, _assert["default"])(property in graph, property); - }); - }, - 'properties should be read-only.': function propertiesShouldBeReadOnly() { - var graph = new Graph(); // Attempting to mutate the properties - - PROPERTIES.forEach(function (property) { - _assert["default"]["throws"](function () { - graph[property] = 'test'; - }, TypeError); - }); - } - }, - - /** - * Order. - */ - '#.order': { - 'it should be 0 if the graph is empty.': function itShouldBe0IfTheGraphIsEmpty() { - var graph = new Graph(); - - _assert["default"].strictEqual(graph.order, 0); - }, - 'adding nodes should increase order.': function addingNodesShouldIncreaseOrder() { - var graph = new Graph(); - graph.addNode('John'); - graph.addNode('Jack'); - - _assert["default"].strictEqual(graph.order, 2); - } - }, - - /** - * Size. - */ - '#.size': { - 'it should be 0 if the graph is empty.': function itShouldBe0IfTheGraphIsEmpty() { - var graph = new Graph(); - - _assert["default"].strictEqual(graph.size, 0); - }, - 'adding & dropping edges should affect size.': function addingDroppingEdgesShouldAffectSize() { - var graph = new Graph(); - graph.addNode('John'); - graph.addNode('Jack'); - graph.addDirectedEdge('John', 'Jack'); - - _assert["default"].strictEqual(graph.size, 1); - - graph.dropEdge('John', 'Jack'); - - _assert["default"].strictEqual(graph.size, 0); - } - }, - - /** - * Directed Size. - */ - '#.directedSize': { - 'it should be 0 if the graph is empty.': function itShouldBe0IfTheGraphIsEmpty() { - var graph = new Graph(); - - _assert["default"].strictEqual(graph.directedSize, 0); - }, - 'adding & dropping edges should affect directed size.': function addingDroppingEdgesShouldAffectDirectedSize() { - var graph = new Graph(); - graph.addNode('John'); - graph.addNode('Jack'); - var directedEdge = graph.addDirectedEdge('John', 'Jack'); - - _assert["default"].strictEqual(graph.directedSize, 1); - - var undirectedEdge = graph.addUndirectedEdge('John', 'Jack'); - - _assert["default"].strictEqual(graph.directedSize, 1); - - graph.dropEdge(directedEdge); - - _assert["default"].strictEqual(graph.directedSize, 0); - - graph.dropEdge(undirectedEdge); - - _assert["default"].strictEqual(graph.directedSize, 0); - } - }, - - /** - * Undirected Size. - */ - '#.undirectedSize': { - 'it should be 0 if the graph is empty.': function itShouldBe0IfTheGraphIsEmpty() { - var graph = new Graph(); - - _assert["default"].strictEqual(graph.undirectedSize, 0); - }, - 'adding & dropping edges should affect undirected size.': function addingDroppingEdgesShouldAffectUndirectedSize() { - var graph = new Graph(); - graph.addNode('John'); - graph.addNode('Jack'); - var directedEdge = graph.addDirectedEdge('John', 'Jack'); - - _assert["default"].strictEqual(graph.undirectedSize, 0); - - var undirectedEdge = graph.addUndirectedEdge('John', 'Jack'); - - _assert["default"].strictEqual(graph.undirectedSize, 1); - - graph.dropEdge(directedEdge); - - _assert["default"].strictEqual(graph.undirectedSize, 1); - - graph.dropEdge(undirectedEdge); - - _assert["default"].strictEqual(graph.undirectedSize, 0); - } - }, - - /** - * Multi. - */ - '#.multi': { - 'it should be false by default.': function itShouldBeFalseByDefault() { - var graph = new Graph(); - - _assert["default"].strictEqual(graph.multi, false); - } - }, - - /** - * Type. - */ - '#.type': { - 'it should be "mixed" by default.': function itShouldBeMixedByDefault() { - var graph = new Graph(); - - _assert["default"].strictEqual(graph.type, 'mixed'); - } - }, - - /** - * Self loops. - */ - '#.allowSelfLoops': { - 'it should be true by default.': function itShouldBeTrueByDefault() { - var graph = new Graph(); - - _assert["default"].strictEqual(graph.allowSelfLoops, true); - } - }, - - /** - * Implementation. - */ - '#.implementation': { - 'it should exist and be a string.': function itShouldExistAndBeAString() { - var graph = new Graph(); - - _assert["default"].strictEqual(_typeof(graph.implementation), 'string'); - } - }, - - /** - * Self Loop Count. - */ - '#.selfLoopCount': { - 'it should exist and be correct.': function itShouldExistAndBeCorrect() { - var graph = new Graph(); - graph.mergeDirectedEdge('John', 'John'); - graph.mergeDirectedEdge('Lucy', 'Lucy'); - graph.mergeUndirectedEdge('Joana', 'Joana'); - - _assert["default"].strictEqual(graph.selfLoopCount, 3); - - _assert["default"].strictEqual(graph.directedSelfLoopCount, 2); - - _assert["default"].strictEqual(graph.undirectedSelfLoopCount, 1); - - graph.forEachEdge(function (edge) { - return graph.dropEdge(edge); - }); - - _assert["default"].strictEqual(graph.selfLoopCount, 0); - - _assert["default"].strictEqual(graph.directedSelfLoopCount, 0); - - _assert["default"].strictEqual(graph.undirectedSelfLoopCount, 0); - } - } - }; -} \ No newline at end of file diff --git a/libs/shared/graph-layouts/node_modules/graphology/specs/read.js b/libs/shared/graph-layouts/node_modules/graphology/specs/read.js deleted file mode 100644 index afe9f1c66..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/specs/read.js +++ /dev/null @@ -1,909 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = read; - -var _assert = _interopRequireDefault(require("assert")); - -var _helpers = require("./helpers"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -/** - * Graphology Read Specs - * ====================== - * - * Testing the read methods of the graph. - */ -function read(Graph, checkers) { - var invalid = checkers.invalid, - notFound = checkers.notFound, - usage = checkers.usage; - return { - '#.hasNode': { - 'it should correctly return whether the given node is found in the graph.': function itShouldCorrectlyReturnWhetherTheGivenNodeIsFoundInTheGraph() { - var graph = new Graph(); - - _assert["default"].strictEqual(graph.hasNode('John'), false); - - graph.addNode('John'); - - _assert["default"].strictEqual(graph.hasNode('John'), true); - } - }, - '#.hasDirectedEdge': { - 'it should throw if invalid arguments are provided.': function itShouldThrowIfInvalidArgumentsAreProvided() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.hasDirectedEdge(1, 2, 3); - }, invalid()); - }, - 'it should correctly return whether a matching edge exists in the graph.': function itShouldCorrectlyReturnWhetherAMatchingEdgeExistsInTheGraph() { - var graph = new Graph(); - graph.addNode('Martha'); - graph.addNode('Catherine'); - graph.addNode('John'); - graph.addDirectedEdgeWithKey('M->C', 'Martha', 'Catherine'); - graph.addUndirectedEdgeWithKey('C<->J', 'Catherine', 'John'); - - _assert["default"].strictEqual(graph.hasDirectedEdge('M->C'), true); - - _assert["default"].strictEqual(graph.hasDirectedEdge('C<->J'), false); - - _assert["default"].strictEqual(graph.hasDirectedEdge('test'), false); - - _assert["default"].strictEqual(graph.hasDirectedEdge('Martha', 'Catherine'), true); - - _assert["default"].strictEqual(graph.hasDirectedEdge('Martha', 'Thomas'), false); - - _assert["default"].strictEqual(graph.hasDirectedEdge('Catherine', 'John'), false); - - _assert["default"].strictEqual(graph.hasDirectedEdge('John', 'Catherine'), false); - }, - 'it should work with self loops.': function itShouldWorkWithSelfLoops() { - var graph = new Graph(); - graph.mergeDirectedEdge('Lucy', 'Lucy'); - - _assert["default"].strictEqual(graph.hasDirectedEdge('Lucy', 'Lucy'), true); - - _assert["default"].strictEqual(graph.hasUndirectedEdge('Lucy', 'Lucy'), false); - } - }, - '#.hasUndirectedEdge': { - 'it should throw if invalid arguments are provided.': function itShouldThrowIfInvalidArgumentsAreProvided() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.hasUndirectedEdge(1, 2, 3); - }, invalid()); - }, - 'it should correctly return whether a matching edge exists in the graph.': function itShouldCorrectlyReturnWhetherAMatchingEdgeExistsInTheGraph() { - var graph = new Graph(); - graph.addNode('Martha'); - graph.addNode('Catherine'); - graph.addNode('John'); - graph.addDirectedEdgeWithKey('M->C', 'Martha', 'Catherine'); - graph.addUndirectedEdgeWithKey('C<->J', 'Catherine', 'John'); - - _assert["default"].strictEqual(graph.hasUndirectedEdge('M->C'), false); - - _assert["default"].strictEqual(graph.hasUndirectedEdge('C<->J'), true); - - _assert["default"].strictEqual(graph.hasUndirectedEdge('test'), false); - - _assert["default"].strictEqual(graph.hasUndirectedEdge('Martha', 'Catherine'), false); - - _assert["default"].strictEqual(graph.hasUndirectedEdge('Martha', 'Thomas'), false); - - _assert["default"].strictEqual(graph.hasUndirectedEdge('Catherine', 'John'), true); - - _assert["default"].strictEqual(graph.hasUndirectedEdge('John', 'Catherine'), true); - }, - 'it should work with self loops.': function itShouldWorkWithSelfLoops() { - var graph = new Graph(); - graph.mergeUndirectedEdge('Lucy', 'Lucy'); - - _assert["default"].strictEqual(graph.hasDirectedEdge('Lucy', 'Lucy'), false); - - _assert["default"].strictEqual(graph.hasUndirectedEdge('Lucy', 'Lucy'), true); - } - }, - '#.hasEdge': { - 'it should throw if invalid arguments are provided.': function itShouldThrowIfInvalidArgumentsAreProvided() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.hasEdge(1, 2, 3); - }, invalid()); - }, - 'it should correctly return whether a matching edge exists in the graph.': function itShouldCorrectlyReturnWhetherAMatchingEdgeExistsInTheGraph() { - var graph = new Graph(); - graph.addNode('Martha'); - graph.addNode('Catherine'); - graph.addNode('John'); - graph.addDirectedEdgeWithKey('M->C', 'Martha', 'Catherine'); - graph.addUndirectedEdgeWithKey('C<->J', 'Catherine', 'John'); - - _assert["default"].strictEqual(graph.hasEdge('M->C'), true); - - _assert["default"].strictEqual(graph.hasEdge('C<->J'), true); - - _assert["default"].strictEqual(graph.hasEdge('test'), false); - - _assert["default"].strictEqual(graph.hasEdge('Martha', 'Catherine'), true); - - _assert["default"].strictEqual(graph.hasEdge('Martha', 'Thomas'), false); - - _assert["default"].strictEqual(graph.hasEdge('Catherine', 'John'), true); - - _assert["default"].strictEqual(graph.hasEdge('John', 'Catherine'), true); - }, - 'it should work properly with typed graphs.': function itShouldWorkProperlyWithTypedGraphs() { - var directedGraph = new Graph({ - type: 'directed' - }), - undirectedGraph = new Graph({ - type: 'undirected' - }); - (0, _helpers.addNodesFrom)(directedGraph, [1, 2]); - (0, _helpers.addNodesFrom)(undirectedGraph, [1, 2]); - - _assert["default"].strictEqual(directedGraph.hasEdge(1, 2), false); - - _assert["default"].strictEqual(undirectedGraph.hasEdge(1, 2), false); - }, - 'it should work with self loops.': function itShouldWorkWithSelfLoops() { - var graph = new Graph(); - graph.mergeUndirectedEdge('Lucy', 'Lucy'); - - _assert["default"].strictEqual(graph.hasDirectedEdge('Lucy', 'Lucy'), false); - - _assert["default"].strictEqual(graph.hasUndirectedEdge('Lucy', 'Lucy'), true); - - _assert["default"].strictEqual(graph.hasEdge('Lucy', 'Lucy'), true); - } - }, - '#.directedEdge': { - 'it should throw if invalid arguments are provided.': function itShouldThrowIfInvalidArgumentsAreProvided() { - var graph = new Graph(), - multiGraph = new Graph({ - multi: true - }); - graph.addNode('John'); - - _assert["default"]["throws"](function () { - multiGraph.directedEdge(1, 2); - }, usage()); - - _assert["default"]["throws"](function () { - graph.directedEdge('Jack', 'John'); - }, notFound()); - - _assert["default"]["throws"](function () { - graph.directedEdge('John', 'Jack'); - }, notFound()); - }, - 'it should return the correct edge.': function itShouldReturnTheCorrectEdge() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['Jack', 'Lucy']); - graph.addDirectedEdgeWithKey('J->L', 'Jack', 'Lucy'); - graph.addUndirectedEdgeWithKey('J<->L', 'Jack', 'Lucy'); - - _assert["default"].strictEqual(graph.directedEdge('Lucy', 'Jack'), undefined); - - _assert["default"].strictEqual(graph.directedEdge('Jack', 'Lucy'), 'J->L'); - - var undirectedGraph = new Graph({ - type: 'undirected' - }); - undirectedGraph.mergeEdge('Jack', 'Lucy'); - - _assert["default"].strictEqual(undirectedGraph.directedEdge('Jack', 'Lucy'), undefined); - }, - 'it should return the correct self loop.': function itShouldReturnTheCorrectSelfLoop() { - var graph = new Graph(); - graph.addNode('John'); - graph.addEdgeWithKey('d', 'John', 'John'); - graph.addUndirectedEdgeWithKey('u', 'John', 'John'); - - _assert["default"].strictEqual(graph.directedEdge('John', 'John'), 'd'); - } - }, - '#.undirectedEdge': { - 'it should throw if invalid arguments are provided.': function itShouldThrowIfInvalidArgumentsAreProvided() { - var graph = new Graph(), - multiGraph = new Graph({ - multi: true - }); - graph.addNode('John'); - - _assert["default"]["throws"](function () { - multiGraph.undirectedEdge(1, 2); - }, usage()); - - _assert["default"]["throws"](function () { - graph.undirectedEdge('Jack', 'John'); - }, notFound()); - - _assert["default"]["throws"](function () { - graph.undirectedEdge('John', 'Jack'); - }, notFound()); - }, - 'it should return the correct edge.': function itShouldReturnTheCorrectEdge() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['Jack', 'Lucy']); - graph.addDirectedEdgeWithKey('J->L', 'Jack', 'Lucy'); - graph.addUndirectedEdgeWithKey('J<->L', 'Jack', 'Lucy'); - - _assert["default"].strictEqual(graph.undirectedEdge('Lucy', 'Jack'), 'J<->L'); - - _assert["default"].strictEqual(graph.undirectedEdge('Jack', 'Lucy'), 'J<->L'); - - var directedGraph = new Graph({ - type: 'directed' - }); - directedGraph.mergeEdge('Jack', 'Lucy'); - - _assert["default"].strictEqual(directedGraph.undirectedEdge('Jack', 'Lucy'), undefined); - }, - 'it should return the correct self loop.': function itShouldReturnTheCorrectSelfLoop() { - var graph = new Graph(); - graph.addNode('John'); - graph.addEdgeWithKey('d', 'John', 'John'); - graph.addUndirectedEdgeWithKey('u', 'John', 'John'); - - _assert["default"].strictEqual(graph.undirectedEdge('John', 'John'), 'u'); - } - }, - '#.edge': { - 'it should throw if invalid arguments are provided.': function itShouldThrowIfInvalidArgumentsAreProvided() { - var graph = new Graph(), - multiGraph = new Graph({ - multi: true - }); - graph.addNode('John'); - - _assert["default"]["throws"](function () { - multiGraph.edge(1, 2); - }, usage()); - - _assert["default"]["throws"](function () { - graph.edge('Jack', 'John'); - }, notFound()); - - _assert["default"]["throws"](function () { - graph.edge('John', 'Jack'); - }, notFound()); - }, - 'it should return the correct edge.': function itShouldReturnTheCorrectEdge() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['Jack', 'Lucy']); - graph.addDirectedEdgeWithKey('J->L', 'Jack', 'Lucy'); - graph.addUndirectedEdgeWithKey('J<->L', 'Jack', 'Lucy'); - - _assert["default"].strictEqual(graph.edge('Lucy', 'Jack'), 'J<->L'); - - _assert["default"].strictEqual(graph.edge('Jack', 'Lucy'), 'J->L'); - }, - 'it should return the correct self loop.': function itShouldReturnTheCorrectSelfLoop() { - var graph = new Graph(); - graph.addNode('John'); - graph.addEdgeWithKey('d', 'John', 'John'); - graph.addUndirectedEdgeWithKey('u', 'John', 'John'); - - _assert["default"].strictEqual(graph.edge('John', 'John'), 'd'); - } - }, - '#.areDirectedNeighbors': { - 'it should throw if node is not in the graph.': function itShouldThrowIfNodeIsNotInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.areDirectedNeighbors('source', 'target'); - }, notFound()); - }, - 'it should correctly return whether two nodes are neighbors.': function itShouldCorrectlyReturnWhetherTwoNodesAreNeighbors() { - var graph = new Graph(); - graph.mergeDirectedEdge('Mary', 'Joseph'); - graph.mergeUndirectedEdge('Martha', 'Mary'); - - _assert["default"].strictEqual(graph.areDirectedNeighbors('Mary', 'Joseph'), true); - - _assert["default"].strictEqual(graph.areDirectedNeighbors('Joseph', 'Mary'), true); - - _assert["default"].strictEqual(graph.areDirectedNeighbors('Martha', 'Mary'), false); - - var undirectedGraph = new Graph({ - type: 'undirected' - }); - undirectedGraph.mergeEdge('Mary', 'Martha'); - - _assert["default"].strictEqual(undirectedGraph.areDirectedNeighbors('Mary', 'Martha'), false); - } - }, - '#.areInNeighbors': { - 'it should throw if node is not in the graph.': function itShouldThrowIfNodeIsNotInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.areInNeighbors('source', 'target'); - }, notFound()); - }, - 'it should correctly return whether two nodes are neighbors.': function itShouldCorrectlyReturnWhetherTwoNodesAreNeighbors() { - var graph = new Graph(); - graph.mergeDirectedEdge('Mary', 'Joseph'); - graph.mergeUndirectedEdge('Martha', 'Mary'); - - _assert["default"].strictEqual(graph.areInNeighbors('Mary', 'Joseph'), false); - - _assert["default"].strictEqual(graph.areInNeighbors('Joseph', 'Mary'), true); - - _assert["default"].strictEqual(graph.areInNeighbors('Martha', 'Mary'), false); - - var undirectedGraph = new Graph({ - type: 'undirected' - }); - undirectedGraph.mergeEdge('Mary', 'Martha'); - - _assert["default"].strictEqual(undirectedGraph.areInNeighbors('Mary', 'Martha'), false); - } - }, - '#.areOutNeighbors': { - 'it should throw if node is not in the graph.': function itShouldThrowIfNodeIsNotInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.areOutNeighbors('source', 'target'); - }, notFound()); - }, - 'it should correctly return whether two nodes are neighbors.': function itShouldCorrectlyReturnWhetherTwoNodesAreNeighbors() { - var graph = new Graph(); - graph.mergeDirectedEdge('Mary', 'Joseph'); - graph.mergeUndirectedEdge('Martha', 'Mary'); - - _assert["default"].strictEqual(graph.areOutNeighbors('Mary', 'Joseph'), true); - - _assert["default"].strictEqual(graph.areOutNeighbors('Joseph', 'Mary'), false); - - _assert["default"].strictEqual(graph.areOutNeighbors('Martha', 'Mary'), false); - - var undirectedGraph = new Graph({ - type: 'undirected' - }); - undirectedGraph.mergeEdge('Mary', 'Martha'); - - _assert["default"].strictEqual(undirectedGraph.areOutNeighbors('Mary', 'Martha'), false); - } - }, - '#.areOutboundNeighbors': { - 'it should throw if node is not in the graph.': function itShouldThrowIfNodeIsNotInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.areOutboundNeighbors('source', 'target'); - }, notFound()); - }, - 'it should correctly return whether two nodes are neighbors.': function itShouldCorrectlyReturnWhetherTwoNodesAreNeighbors() { - var graph = new Graph(); - graph.mergeDirectedEdge('Mary', 'Joseph'); - graph.mergeUndirectedEdge('Martha', 'Mary'); - - _assert["default"].strictEqual(graph.areOutboundNeighbors('Mary', 'Joseph'), true); - - _assert["default"].strictEqual(graph.areOutboundNeighbors('Joseph', 'Mary'), false); - - _assert["default"].strictEqual(graph.areOutboundNeighbors('Martha', 'Mary'), true); - - var undirectedGraph = new Graph({ - type: 'undirected' - }); - undirectedGraph.mergeEdge('Mary', 'Martha'); - - _assert["default"].strictEqual(undirectedGraph.areOutboundNeighbors('Mary', 'Martha'), true); - } - }, - '#.areInboundNeighbors': { - 'it should throw if node is not in the graph.': function itShouldThrowIfNodeIsNotInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.areInboundNeighbors('source', 'target'); - }, notFound()); - }, - 'it should correctly return whether two nodes are neighbors.': function itShouldCorrectlyReturnWhetherTwoNodesAreNeighbors() { - var graph = new Graph(); - graph.mergeDirectedEdge('Mary', 'Joseph'); - graph.mergeUndirectedEdge('Martha', 'Mary'); - - _assert["default"].strictEqual(graph.areInboundNeighbors('Mary', 'Joseph'), false); - - _assert["default"].strictEqual(graph.areInboundNeighbors('Joseph', 'Mary'), true); - - _assert["default"].strictEqual(graph.areInboundNeighbors('Martha', 'Mary'), true); - - var undirectedGraph = new Graph({ - type: 'undirected' - }); - undirectedGraph.mergeEdge('Mary', 'Martha'); - - _assert["default"].strictEqual(undirectedGraph.areInboundNeighbors('Mary', 'Martha'), true); - } - }, - '#.areUndirectedNeighbors': { - 'it should throw if node is not in the graph.': function itShouldThrowIfNodeIsNotInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.areUndirectedNeighbors('source', 'target'); - }, notFound()); - }, - 'it should correctly return whether two nodes are neighbors.': function itShouldCorrectlyReturnWhetherTwoNodesAreNeighbors() { - var graph = new Graph(); - graph.mergeDirectedEdge('Mary', 'Joseph'); - graph.mergeUndirectedEdge('Martha', 'Mary'); - - _assert["default"].strictEqual(graph.areUndirectedNeighbors('Mary', 'Joseph'), false); - - _assert["default"].strictEqual(graph.areUndirectedNeighbors('Joseph', 'Mary'), false); - - _assert["default"].strictEqual(graph.areUndirectedNeighbors('Martha', 'Mary'), true); - - var directedGraph = new Graph({ - type: 'directed' - }); - directedGraph.mergeEdge('Mary', 'Martha'); - - _assert["default"].strictEqual(directedGraph.areUndirectedNeighbors('Mary', 'Martha'), false); - } - }, - '#.areNeighbors': { - 'it should throw if node is not in the graph.': function itShouldThrowIfNodeIsNotInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.areNeighbors('source', 'target'); - }, notFound()); - }, - 'it should correctly return whether two nodes are neighbors.': function itShouldCorrectlyReturnWhetherTwoNodesAreNeighbors() { - var graph = new Graph(); - graph.mergeDirectedEdge('Mary', 'Joseph'); - graph.mergeUndirectedEdge('Martha', 'Mary'); - - _assert["default"].strictEqual(graph.areNeighbors('Mary', 'Joseph'), true); - - _assert["default"].strictEqual(graph.areNeighbors('Joseph', 'Mary'), true); - - _assert["default"].strictEqual(graph.areNeighbors('Martha', 'Mary'), true); - - _assert["default"].strictEqual(graph.areNeighbors('Joseph', 'Martha'), false); - - var undirectedGraph = new Graph({ - type: 'undirected' - }); - undirectedGraph.mergeEdge('Mary', 'Martha'); - - _assert["default"].strictEqual(undirectedGraph.areNeighbors('Mary', 'Martha'), true); - } - }, - '#.source': { - 'it should throw if the edge is not in the graph.': function itShouldThrowIfTheEdgeIsNotInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.source('test'); - }, notFound()); - }, - 'it should return the correct source.': function itShouldReturnTheCorrectSource() { - var graph = new Graph(); - graph.addNode('John'); - graph.addNode('Martha'); - var edge = graph.addDirectedEdge('John', 'Martha'); - - _assert["default"].strictEqual(graph.source(edge), 'John'); - } - }, - '#.target': { - 'it should throw if the edge is not in the graph.': function itShouldThrowIfTheEdgeIsNotInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.target('test'); - }, notFound()); - }, - 'it should return the correct target.': function itShouldReturnTheCorrectTarget() { - var graph = new Graph(); - graph.addNode('John'); - graph.addNode('Martha'); - var edge = graph.addDirectedEdge('John', 'Martha'); - - _assert["default"].strictEqual(graph.target(edge), 'Martha'); - } - }, - '#.extremities': { - 'it should throw if the edge is not in the graph.': function itShouldThrowIfTheEdgeIsNotInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.extremities('test'); - }, notFound()); - }, - 'it should return the correct extremities.': function itShouldReturnTheCorrectExtremities() { - var graph = new Graph(); - graph.addNode('John'); - graph.addNode('Martha'); - var edge = graph.addDirectedEdge('John', 'Martha'); - - _assert["default"].deepStrictEqual(graph.extremities(edge), ['John', 'Martha']); - } - }, - '#.opposite': { - 'it should throw if either the node or the edge is not found in the graph.': function itShouldThrowIfEitherTheNodeOrTheEdgeIsNotFoundInTheGraph() { - var graph = new Graph(); - graph.addNode('Thomas'); - - _assert["default"]["throws"](function () { - graph.opposite('Jeremy', 'T->J'); - }, notFound()); - - _assert["default"]["throws"](function () { - graph.opposite('Thomas', 'T->J'); - }, notFound()); - }, - 'it should throw if the node & the edge are not related.': function itShouldThrowIfTheNodeTheEdgeAreNotRelated() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['Thomas', 'Isabella', 'Estelle']); - graph.addEdgeWithKey('I->E', 'Isabella', 'Estelle'); - - _assert["default"]["throws"](function () { - graph.opposite('Thomas', 'I->E'); - }, notFound()); - }, - 'it should return the correct node.': function itShouldReturnTheCorrectNode() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['Thomas', 'Estelle']); - var edge = graph.addEdge('Thomas', 'Estelle'); - - _assert["default"].strictEqual(graph.opposite('Thomas', edge), 'Estelle'); - } - }, - '#.hasExtremity': { - 'it should throw if either the edge is not found in the graph.': function itShouldThrowIfEitherTheEdgeIsNotFoundInTheGraph() { - var graph = new Graph(); - graph.mergeEdge('Thomas', 'Laura'); - - _assert["default"]["throws"](function () { - graph.hasExtremity('inexisting-edge', 'Thomas'); - }, notFound()); - }, - 'it should return the correct answer.': function itShouldReturnTheCorrectAnswer() { - var graph = new Graph(); - graph.addNode('Jack'); - - var _graph$mergeEdge = graph.mergeEdge('Thomas', 'Estelle'), - edge = _graph$mergeEdge[0]; - - _assert["default"].strictEqual(graph.hasExtremity(edge, 'Thomas'), true); - - _assert["default"].strictEqual(graph.hasExtremity(edge, 'Estelle'), true); - - _assert["default"].strictEqual(graph.hasExtremity(edge, 'Jack'), false); - - _assert["default"].strictEqual(graph.hasExtremity(edge, 'Who?'), false); - } - }, - '#.isDirected': { - 'it should throw if the edge is not in the graph.': function itShouldThrowIfTheEdgeIsNotInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.isDirected('test'); - }, notFound()); - }, - 'it should correctly return whether the edge is directed or not.': function itShouldCorrectlyReturnWhetherTheEdgeIsDirectedOrNot() { - var graph = new Graph(); - graph.addNode('John'); - graph.addNode('Rachel'); - graph.addNode('Suzan'); - var directedEdge = graph.addDirectedEdge('John', 'Rachel'), - undirectedEdge = graph.addUndirectedEdge('Rachel', 'Suzan'); - - _assert["default"].strictEqual(graph.isDirected(directedEdge), true); - - _assert["default"].strictEqual(graph.isDirected(undirectedEdge), false); - } - }, - '#.isUndirected': { - 'it should throw if the edge is not in the graph.': function itShouldThrowIfTheEdgeIsNotInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.isUndirected('test'); - }, notFound()); - }, - 'it should correctly return whether the edge is undirected or not.': function itShouldCorrectlyReturnWhetherTheEdgeIsUndirectedOrNot() { - var graph = new Graph(); - graph.addNode('John'); - graph.addNode('Rachel'); - graph.addNode('Suzan'); - var directedEdge = graph.addDirectedEdge('John', 'Rachel'), - undirectedEdge = graph.addUndirectedEdge('Rachel', 'Suzan'); - - _assert["default"].strictEqual(graph.isUndirected(directedEdge), false); - - _assert["default"].strictEqual(graph.isUndirected(undirectedEdge), true); - } - }, - '#.isSelfLoop': { - 'it should throw if the edge is not in the graph.': function itShouldThrowIfTheEdgeIsNotInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.isSelfLoop('test'); - }, notFound()); - }, - 'it should correctly return whether the edge is a self-loop or not.': function itShouldCorrectlyReturnWhetherTheEdgeIsASelfLoopOrNot() { - var graph = new Graph(); - graph.addNode('John'); - graph.addNode('Rachel'); - var selfLoop = graph.addDirectedEdge('John', 'John'), - edge = graph.addUndirectedEdge('John', 'Rachel'); - - _assert["default"].strictEqual(graph.isSelfLoop(selfLoop), true); - - _assert["default"].strictEqual(graph.isSelfLoop(edge), false); - } - }, - Degree: { - '#.inDegree': { - 'it should throw if the node is not found in the graph.': function itShouldThrowIfTheNodeIsNotFoundInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.inDegree('Test'); - }, notFound()); - }, - 'it should return the correct in degree.': function itShouldReturnTheCorrectInDegree() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['Helen', 'Sue', 'William', 'John']); - graph.addDirectedEdge('Helen', 'Sue'); - graph.addDirectedEdge('William', 'Sue'); - - _assert["default"].strictEqual(graph.inDegree('Sue'), 2); - - graph.addDirectedEdge('Sue', 'Sue'); - - _assert["default"].strictEqual(graph.inDegree('Sue'), 3); - - _assert["default"].strictEqual(graph.inDegreeWithoutSelfLoops('Sue'), 2); - }, - 'it should always return 0 in an undirected graph.': function itShouldAlwaysReturn0InAnUndirectedGraph() { - var graph = new Graph({ - type: 'undirected' - }); - (0, _helpers.addNodesFrom)(graph, ['Helen', 'Sue']); - graph.addEdge('Helen', 'Sue'); - - _assert["default"].strictEqual(graph.inDegree('Helen'), 0); - } - }, - '#.inboundDegree': { - 'it should throw if the node is not found in the graph.': function itShouldThrowIfTheNodeIsNotFoundInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.inboundDegree('Test'); - }, notFound()); - }, - 'it should return the correct in degree.': function itShouldReturnTheCorrectInDegree() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['Helen', 'Sue', 'William', 'John']); - graph.addDirectedEdge('Helen', 'Sue'); - graph.addDirectedEdge('William', 'Sue'); - graph.addUndirectedEdge('Helen', 'Sue'); - - _assert["default"].strictEqual(graph.inboundDegree('Sue'), 3); - - graph.addDirectedEdge('Sue', 'Sue'); - - _assert["default"].strictEqual(graph.inboundDegree('Sue'), 4); - - _assert["default"].strictEqual(graph.inboundDegreeWithoutSelfLoops('Sue'), 3); - }, - 'it should always the undirected degree in an undirected graph.': function itShouldAlwaysTheUndirectedDegreeInAnUndirectedGraph() { - var graph = new Graph({ - type: 'undirected' - }); - (0, _helpers.addNodesFrom)(graph, ['Helen', 'Sue']); - graph.addEdge('Helen', 'Sue'); - - _assert["default"].strictEqual(graph.inboundDegree('Helen'), 1); - } - }, - '#.outDegree': { - 'it should throw if the node is not found in the graph.': function itShouldThrowIfTheNodeIsNotFoundInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.outDegree('Test'); - }, notFound()); - }, - 'it should return the correct out degree.': function itShouldReturnTheCorrectOutDegree() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['Helen', 'Sue', 'William', 'John']); - graph.addDirectedEdge('Helen', 'Sue'); - graph.addDirectedEdge('Helen', 'William'); - - _assert["default"].strictEqual(graph.outDegree('Helen'), 2); - - graph.addDirectedEdge('Helen', 'Helen'); - - _assert["default"].strictEqual(graph.outDegree('Helen'), 3); - - _assert["default"].strictEqual(graph.outDegreeWithoutSelfLoops('Helen'), 2); - }, - 'it should always return 0 in an undirected graph.': function itShouldAlwaysReturn0InAnUndirectedGraph() { - var graph = new Graph({ - type: 'undirected' - }); - (0, _helpers.addNodesFrom)(graph, ['Helen', 'Sue']); - graph.addEdge('Helen', 'Sue'); - - _assert["default"].strictEqual(graph.outDegree('Sue'), 0); - } - }, - '#.outboundDegree': { - 'it should throw if the node is not found in the graph.': function itShouldThrowIfTheNodeIsNotFoundInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.outboundDegree('Test'); - }, notFound()); - }, - 'it should return the correct out degree.': function itShouldReturnTheCorrectOutDegree() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['Helen', 'Sue', 'William', 'John']); - graph.addDirectedEdge('Helen', 'Sue'); - graph.addDirectedEdge('Helen', 'William'); - graph.addUndirectedEdge('Helen', 'Sue'); - - _assert["default"].strictEqual(graph.outboundDegree('Helen'), 3); - - graph.addDirectedEdge('Helen', 'Helen'); - - _assert["default"].strictEqual(graph.outboundDegree('Helen'), 4); - - _assert["default"].strictEqual(graph.outboundDegreeWithoutSelfLoops('Helen'), 3); - }, - 'it should always the undirected degree in an undirected graph.': function itShouldAlwaysTheUndirectedDegreeInAnUndirectedGraph() { - var graph = new Graph({ - type: 'undirected' - }); - (0, _helpers.addNodesFrom)(graph, ['Helen', 'Sue']); - graph.addEdge('Helen', 'Sue'); - - _assert["default"].strictEqual(graph.outboundDegree('Sue'), 1); - } - }, - '#.directedDegree': { - 'it should throw if the node is not found in the graph.': function itShouldThrowIfTheNodeIsNotFoundInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.directedDegree('Test'); - }, notFound()); - }, - 'it should return the correct directed degree.': function itShouldReturnTheCorrectDirectedDegree() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['Helen', 'Sue', 'William', 'John', 'Martha']); - graph.addDirectedEdge('Helen', 'Sue'); - graph.addDirectedEdge('Helen', 'William'); - graph.addDirectedEdge('Martha', 'Helen'); - graph.addUndirectedEdge('Helen', 'John'); - - _assert["default"].strictEqual(graph.directedDegree('Helen'), 3); - - _assert["default"].strictEqual(graph.directedDegree('Helen'), graph.inDegree('Helen') + graph.outDegree('Helen')); - - graph.addDirectedEdge('Helen', 'Helen'); - - _assert["default"].strictEqual(graph.directedDegree('Helen'), 5); - - _assert["default"].strictEqual(graph.directedDegreeWithoutSelfLoops('Helen'), 3); - }, - 'it should always return 0 in an undirected graph.': function itShouldAlwaysReturn0InAnUndirectedGraph() { - var graph = new Graph({ - type: 'undirected' - }); - (0, _helpers.addNodesFrom)(graph, ['Helen', 'Sue']); - graph.addEdge('Helen', 'Sue'); - - _assert["default"].strictEqual(graph.inDegree('Helen'), 0); - } - }, - '#.undirectedDegree': { - 'it should throw if the node is not found in the graph.': function itShouldThrowIfTheNodeIsNotFoundInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.undirectedDegree('Test'); - }, notFound()); - }, - 'it should return the correct undirected degree.': function itShouldReturnTheCorrectUndirectedDegree() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['Helen', 'Sue', 'William', 'John']); - graph.addDirectedEdge('Helen', 'Sue'); - graph.addDirectedEdge('Helen', 'William'); - graph.addUndirectedEdge('Helen', 'John'); - - _assert["default"].strictEqual(graph.undirectedDegree('Helen'), 1); - - graph.addUndirectedEdge('Helen', 'Helen'); - - _assert["default"].strictEqual(graph.undirectedDegree('Helen'), 3); - - _assert["default"].strictEqual(graph.undirectedDegreeWithoutSelfLoops('Helen'), 1); - }, - 'it should always return 0 in a directed graph.': function itShouldAlwaysReturn0InADirectedGraph() { - var graph = new Graph({ - type: 'directed' - }); - (0, _helpers.addNodesFrom)(graph, ['Helen', 'Sue']); - graph.addEdge('Helen', 'Sue'); - - _assert["default"].strictEqual(graph.undirectedDegree('Helen'), 0); - } - }, - '#.degree': { - 'it should throw if the node is not found in the graph.': function itShouldThrowIfTheNodeIsNotFoundInTheGraph() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph.degree('Test'); - }, notFound()); - }, - 'it should return the correct degree.': function itShouldReturnTheCorrectDegree() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['Helen', 'Sue', 'William', 'John', 'Martha']); - graph.addDirectedEdge('Helen', 'Sue'); - graph.addDirectedEdge('Helen', 'William'); - graph.addDirectedEdge('Martha', 'Helen'); - graph.addUndirectedEdge('Helen', 'John'); - - _assert["default"].strictEqual(graph.degree('Helen'), 4); - - _assert["default"].strictEqual(graph.degree('Helen'), graph.directedDegree('Helen') + graph.undirectedDegree('Helen')); - - graph.addUndirectedEdge('Helen', 'Helen'); - - _assert["default"].strictEqual(graph.degree('Helen'), 6); - - _assert["default"].strictEqual(graph.degreeWithoutSelfLoops('Helen'), 4); - } - }, - 'it should also work with typed graphs.': function itShouldAlsoWorkWithTypedGraphs() { - var directedGraph = new Graph({ - type: 'directed' - }), - undirectedGraph = new Graph({ - type: 'undirected' - }); - (0, _helpers.addNodesFrom)(directedGraph, [1, 2]); - (0, _helpers.addNodesFrom)(undirectedGraph, [1, 2]); - - _assert["default"].strictEqual(directedGraph.degree(1), 0); - - _assert["default"].strictEqual(undirectedGraph.degree(1), 0); - - directedGraph.addDirectedEdge(1, 2); - undirectedGraph.addUndirectedEdge(1, 2); - - _assert["default"].strictEqual(directedGraph.degree(1), 1); - - _assert["default"].strictEqual(undirectedGraph.degree(1), 1); - } - } - }; -} \ No newline at end of file diff --git a/libs/shared/graph-layouts/node_modules/graphology/specs/serialization.js b/libs/shared/graph-layouts/node_modules/graphology/specs/serialization.js deleted file mode 100644 index fc9318ae9..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/specs/serialization.js +++ /dev/null @@ -1,171 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = serialization; - -var _assert = _interopRequireDefault(require("assert")); - -var _helpers = require("./helpers"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -/** - * Graphology Serializaton Specs - * ============================== - * - * Testing the serialization methods of the graph. - */ -function serialization(Graph, checkers) { - var invalid = checkers.invalid, - notFound = checkers.notFound; - return { - '#.export': { - 'it should correctly return the serialized graph.': function itShouldCorrectlyReturnTheSerializedGraph() { - var graph = new Graph({ - multi: true - }); - graph.setAttribute('name', 'graph'); - (0, _helpers.addNodesFrom)(graph, ['John', 'Jack', 'Martha']); - graph.setNodeAttribute('John', 'age', 34); - graph.addEdgeWithKey('J->J•1', 'John', 'Jack'); - graph.addEdgeWithKey('J->J•2', 'John', 'Jack', { - weight: 2 - }); - graph.addEdgeWithKey('J->J•3', 'John', 'Jack'); - graph.addUndirectedEdgeWithKey('J<->J•1', 'John', 'Jack'); - graph.addUndirectedEdgeWithKey('J<->J•2', 'John', 'Jack', { - weight: 3 - }); - - _assert["default"].deepStrictEqual(graph["export"](), { - attributes: { - name: 'graph' - }, - nodes: [{ - key: 'John', - attributes: { - age: 34 - } - }, { - key: 'Jack' - }, { - key: 'Martha' - }], - edges: [{ - key: 'J->J•1', - source: 'John', - target: 'Jack' - }, { - key: 'J->J•2', - source: 'John', - target: 'Jack', - attributes: { - weight: 2 - } - }, { - key: 'J->J•3', - source: 'John', - target: 'Jack' - }, { - key: 'J<->J•1', - source: 'John', - target: 'Jack', - undirected: true - }, { - key: 'J<->J•2', - source: 'John', - target: 'Jack', - attributes: { - weight: 3 - }, - undirected: true - }], - options: { - allowSelfLoops: true, - multi: true, - type: 'mixed' - } - }); - } - }, - '#.import': { - 'it should throw if the given data is invalid.': function itShouldThrowIfTheGivenDataIsInvalid() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph["import"](true); - }, invalid()); - }, - 'it should be possible to import a graph instance.': function itShouldBePossibleToImportAGraphInstance() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - graph.addEdge('John', 'Thomas'); - var other = new Graph(); - other["import"](graph); - - _assert["default"].deepStrictEqual(graph.nodes(), other.nodes()); - - _assert["default"].deepStrictEqual(graph.edges(), other.edges()); - }, - 'it should be possible to import a serialized graph.': function itShouldBePossibleToImportASerializedGraph() { - var graph = new Graph(); - graph["import"]({ - nodes: [{ - key: 'John' - }, { - key: 'Thomas' - }], - edges: [{ - source: 'John', - target: 'Thomas' - }] - }); - - _assert["default"].deepStrictEqual(graph.nodes(), ['John', 'Thomas']); - - _assert["default"].strictEqual(graph.hasEdge('John', 'Thomas'), true); - }, - 'it should be possible to import only edges when merging.': function itShouldBePossibleToImportOnlyEdgesWhenMerging() { - var graph = new Graph(); - graph["import"]({ - edges: [{ - source: 'John', - target: 'Thomas' - }] - }, true); - - _assert["default"].deepStrictEqual(graph.nodes(), ['John', 'Thomas']); - - _assert["default"].strictEqual(graph.size, 1); - - _assert["default"].strictEqual(graph.hasEdge('John', 'Thomas'), true); - }, - 'it should be possible to import attributes.': function itShouldBePossibleToImportAttributes() { - var graph = new Graph(); - graph["import"]({ - attributes: { - name: 'graph' - } - }); - - _assert["default"].deepStrictEqual(graph.getAttributes(), { - name: 'graph' - }); - }, - 'it should throw if nodes are absent, edges are present and we merge.': function itShouldThrowIfNodesAreAbsentEdgesArePresentAndWeMerge() { - var graph = new Graph(); - - _assert["default"]["throws"](function () { - graph["import"]({ - edges: [{ - source: '1', - target: '2' - }] - }); - }, notFound()); - } - } - }; -} \ No newline at end of file diff --git a/libs/shared/graph-layouts/node_modules/graphology/specs/utils.js b/libs/shared/graph-layouts/node_modules/graphology/specs/utils.js deleted file mode 100644 index 6b7158a8a..000000000 --- a/libs/shared/graph-layouts/node_modules/graphology/specs/utils.js +++ /dev/null @@ -1,249 +0,0 @@ -"use strict"; - -Object.defineProperty(exports, "__esModule", { - value: true -}); -exports["default"] = utils; - -var _assert = _interopRequireDefault(require("assert")); - -var _helpers = require("./helpers"); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - -/** - * Graphology Utils Specs - * ======================= - * - * Testing the utils methods. - */ -var PROPERTIES = ['type', 'multi', 'map', 'selfLoops']; - -function utils(Graph, checkers) { - var usage = checkers.usage; - return { - '#.nullCopy': { - 'it should create an null copy of the graph.': function itShouldCreateAnNullCopyOfTheGraph() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - graph.addEdge('John', 'Thomas'); - var copy = graph.nullCopy(); - - _assert["default"].deepStrictEqual(copy.nodes(), []); - - _assert["default"].strictEqual(copy.order, 0); - - _assert["default"].strictEqual(copy.size, 0); - - PROPERTIES.forEach(function (property) { - _assert["default"].strictEqual(graph[property], copy[property]); - }); - }, - 'it should be possible to pass options to merge.': function itShouldBePossibleToPassOptionsToMerge() { - var graph = new Graph({ - type: 'directed' - }); - var copy = graph.nullCopy({ - type: 'undirected' - }); - - _assert["default"].strictEqual(copy.type, 'undirected'); - - _assert["default"]["throws"](function () { - copy.addDirectedEdge('one', 'two'); - }, /addDirectedEdge/); - }, - 'copying the graph should conserve its attributes.': function copyingTheGraphShouldConserveItsAttributes() { - var graph = new Graph(); - graph.setAttribute('title', 'The Graph'); - var copy = graph.nullCopy(); - - _assert["default"].deepStrictEqual(graph.getAttributes(), copy.getAttributes()); - } - }, - '#.emptyCopy': { - 'it should create an empty copy of the graph.': function itShouldCreateAnEmptyCopyOfTheGraph() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - graph.addEdge('John', 'Thomas'); - var copy = graph.emptyCopy(); - - _assert["default"].deepStrictEqual(copy.nodes(), ['John', 'Thomas']); - - _assert["default"].strictEqual(copy.order, 2); - - _assert["default"].strictEqual(copy.size, 0); - - PROPERTIES.forEach(function (property) { - _assert["default"].strictEqual(graph[property], copy[property]); - }); - copy.mergeEdge('Mary', 'Thomas'); - copy.setNodeAttribute('John', 'age', 32); - - _assert["default"].strictEqual(copy.order, 3); - - _assert["default"].strictEqual(copy.size, 1); - - _assert["default"].deepStrictEqual(copy.getNodeAttributes('John'), { - age: 32 - }); - - _assert["default"].deepStrictEqual(graph.getNodeAttributes('John'), {}); - }, - 'it should be possible to pass options to merge.': function itShouldBePossibleToPassOptionsToMerge() { - var graph = new Graph({ - type: 'directed' - }); - var copy = graph.emptyCopy({ - type: 'undirected' - }); - - _assert["default"].strictEqual(copy.type, 'undirected'); - - _assert["default"]["throws"](function () { - copy.addDirectedEdge('one', 'two'); - }, /addDirectedEdge/); - }, - 'copying the graph should conserve its attributes.': function copyingTheGraphShouldConserveItsAttributes() { - var graph = new Graph(); - graph.setAttribute('title', 'The Graph'); - var copy = graph.emptyCopy(); - - _assert["default"].deepStrictEqual(graph.getAttributes(), copy.getAttributes()); - } - }, - '#.copy': { - 'it should create a full copy of the graph.': function itShouldCreateAFullCopyOfTheGraph() { - var graph = new Graph(); - (0, _helpers.addNodesFrom)(graph, ['John', 'Thomas']); - graph.addEdge('John', 'Thomas'); - var copy = graph.copy(); - - _assert["default"].deepStrictEqual(copy.nodes(), graph.nodes()); - - _assert["default"].deepStrictEqual(copy.edges(), graph.edges()); - - _assert["default"].strictEqual(copy.order, 2); - - _assert["default"].strictEqual(copy.size, 1); - - PROPERTIES.forEach(function (property) { - _assert["default"].strictEqual(graph[property], graph[property]); - }); - }, - 'it should not break when copying a graph with wrangled edge ids (issue #213).': function itShouldNotBreakWhenCopyingAGraphWithWrangledEdgeIdsIssue213() { - var graph = new Graph(); - graph.addNode('n0'); - graph.addNode('n1'); - graph.addNode('n2'); - graph.addNode('n3'); - graph.addEdge('n0', 'n1'); - graph.addEdge('n1', 'n2'); - graph.addEdge('n2', 'n3'); - graph.addEdge('n3', 'n0'); - - _assert["default"].doesNotThrow(function () { - graph.copy(); - }); // Do surgery on second edge - - - var edgeToSplit = graph.edge('n1', 'n2'); - var newNode = 'n12'; - graph.addNode(newNode); - graph.dropEdge('n1', 'n2'); - graph.addEdge('n1', newNode); - graph.addEdgeWithKey(edgeToSplit, newNode, 'n2'); - var copy = graph.copy(); - - _assert["default"].deepStrictEqual(new Set(graph.nodes()), new Set(copy.nodes())); - - _assert["default"].deepStrictEqual(new Set(graph.edges()), new Set(copy.edges())); - - _assert["default"].notStrictEqual(graph.getNodeAttributes('n1'), copy.getNodeAttributes('n1')); - - _assert["default"].doesNotThrow(function () { - copy.addEdge('n0', 'n12'); - }); - }, - 'it should not break on adversarial inputs.': function itShouldNotBreakOnAdversarialInputs() { - var graph = new Graph(); - graph.mergeEdge(0, 1); - graph.mergeEdge(1, 2); - graph.mergeEdge(2, 0); - var copy = graph.copy(); - copy.mergeEdge(3, 4); - var serializedCopy = Graph.from(graph["export"]()); - - _assert["default"].doesNotThrow(function () { - serializedCopy.mergeEdge(3, 4); - }); - - _assert["default"].strictEqual(serializedCopy.size, 4); - }, - 'copying the graph should conserve its attributes.': function copyingTheGraphShouldConserveItsAttributes() { - var graph = new Graph(); - graph.setAttribute('title', 'The Graph'); - var copy = graph.copy(); - - _assert["default"].deepStrictEqual(graph.getAttributes(), copy.getAttributes()); - }, - 'it should be possible to upgrade a graph.': function itShouldBePossibleToUpgradeAGraph() { - var strict = new Graph({ - type: 'directed', - allowSelfLoops: false - }); - var loose = new Graph({ - multi: true - }); - - _assert["default"].strictEqual(strict.copy({ - type: 'directed' - }).type, 'directed'); - - _assert["default"].strictEqual(strict.copy({ - multi: false - }).multi, false); - - _assert["default"].strictEqual(strict.copy({ - allowSelfLoops: false - }).allowSelfLoops, false); - - _assert["default"].strictEqual(strict.copy({ - type: 'mixed' - }).type, 'mixed'); - - _assert["default"].strictEqual(strict.copy({ - multi: true - }).multi, true); - - _assert["default"].strictEqual(strict.copy({ - allowSelfLoops: true - }).allowSelfLoops, true); - - _assert["default"]["throws"](function () { - strict.copy({ - type: 'undirected' - }); - }, usage()); - - _assert["default"]["throws"](function () { - loose.copy({ - type: 'undirected' - }); - }, usage()); - - _assert["default"]["throws"](function () { - loose.copy({ - multi: false - }); - }, usage()); - - _assert["default"]["throws"](function () { - loose.copy({ - allowSelfLoops: false - }); - }, usage()); - } - } - }; -} \ No newline at end of file diff --git a/libs/shared/graph-layouts/node_modules/obliterator/LICENSE.txt b/libs/shared/graph-layouts/node_modules/obliterator/LICENSE.txt deleted file mode 100644 index df12ee58e..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/LICENSE.txt +++ /dev/null @@ -1,21 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2017-2021 Guillaume Plique (Yomguithereal) - -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. diff --git a/libs/shared/graph-layouts/node_modules/obliterator/README.md b/libs/shared/graph-layouts/node_modules/obliterator/README.md deleted file mode 100644 index 8f3fc6656..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/README.md +++ /dev/null @@ -1,415 +0,0 @@ -[](https://github.com/Yomguithereal/obliterator/actions) - -# Obliterator - -Obliterator is a dead simple JavaScript/TypeScript library providing miscellaneous higher-order iterator/iterable functions such as combining two or more iterators into a single one. - -Note that when possible, `obliterator` also consider sequences such as arrays, strings etc. as valid iterables (although they are not proper ES6 iterables values), for convenience. - -# Installation - -``` -npm install --save obliterator -``` - -Note that `obliterator` comes along with its TypeScript declarations. - -# Usage - -## Summary - -_Classes_ - -- [Iterator](#iterator) - -_Functions_ - -- [chain](#chain) -- [combinations](#combinations) -- [consume](#consume) -- [every](#every) -- [filter](#filter) -- [find](#find) -- [forEach](#foreach) -- [forEachWithNullKeys](#foreachwithnullkeys) -- [includes](#includes) -- [iter](#iter) -- [map](#map) -- [match](#match) -- [permutations](#permutations) -- [powerSet](#powerSet) -- [some](#some) -- [split](#split) -- [take](#take) - -## Iterator - -A handy Iterator class easily usable with ES2015's `for ... of` loop constructs & spread operator. - -```js -import Iterator from 'obliterator/iterator'; -// Or -import {Iterator} from 'obliterator'; - -const iterator = new Iterator(function () { - // Define what the `next` function does - return {done: false, value: 34}; -}); - -// Checking that the given value is an iterator (native or else) -Iterator.is(value); - -// Creating an empty iterator -const emptyIterator = Iterator.empty(); - -// Creating a simple iterator from a single value -const simpleIterator = Iterator.of(34); - -// Creating a simple iterator from multiple values -const multipleIterator = Iterator.of(1, 2, 3); -``` - -## chain - -Variadic function chaining all the given iterable-like values. - -```js -import chain from 'obliterator/chain'; -// Or -import {chain} from 'obliterator'; - -const set1 = new Set('a'); -const set2 = new Set('bc'); - -const chained = chain(set1.values(), set2); - -chained.next(); ->>> {done: false, value: 'a'} -chained.next(); ->>> {done: false, value: 'b'} -``` - -## combinations - -Returns an iterator of combinations of the given array and of the given size. - -Note that for performance reasons, the yielded combination is always the same object. - -```js -import combinations from 'obliterator/combinations'; -// Or -import {combinations} from 'obliterator'; - -const iterator = combinations(['A', 'B', 'C', 'D'], 2); - -iterator.next().value; ->>> ['A', 'B'] -iterator.next().value; ->>> ['A', 'C'] -``` - -## consume - -Function consuming the given iterator fully or for n steps. - -```js -import consume from 'obliterator/consume'; -// Or -import {consume} from 'obliterator'; - -const set = new Set([1, 2, 3]); - -// Consuming the whole iterator -let iterator = set.values(); -consume(iterator); -iterator.next().done >>> true; - -// Consuming n steps -let iterator = set.values(); -consume(iterator, 2); -iterator.next().value >>> 3; -``` - -## every - -Function returning whether all items of an iterable-like match the given predicate function. - -```js -import every from 'obliterator/every'; -// Or -import {every} from 'obliterator'; - -every([2, 4, 6], n => n % 2 === 0); ->>> true - -every([1, 2, 3], n => n % 2 === 0); ->>> false -``` - -## filter - -Function returning an iterator filtering another one's values using the given predicate function. - -```js -import filter from 'obliterator/filter'; -// Or -import {filter} from 'obliterator'; - -const set = new Set([1, 2, 3, 4, 5]); - -const even = x => x % 2 === 0; - -const iterator = filter(set.values(), even); - -iterator.next().value >>> 2; -iterator.next().value >>> 4; -``` - -## find - -Function returning the next item matching given predicate function in an iterable-like. - -```js -import find from 'obliterator/find'; -// Or -import {find} from 'obliterator'; - -const set = new Set([1, 2, 3, 4, 5]); - -const even = x => x % 2 === 0; - -const values = set.values(); - -find(values, even); ->>> 2 - -find(values, even); ->>> 4 - -find(values, even); ->>> undefined -``` - -## forEach - -Function able to iterate over almost any JavaScript iterable value using a callback. - -Supported values range from arrays, typed arrays, sets, maps, objects, strings, arguments, iterators, arbitrary iterables etc. - -```js -import forEach from 'obliterator/foreach'; -// Or -import {forEach} from 'obliterator'; - -const set = new Set(['apple', 'banana']); - -forEach(set.values(), (value, i) => { - console.log(i, value); -}); - -// Iterating over a string -forEach('abc', (char, i) => ...); - -// Iterating over a map -forEach(map, (value, key) => ...); -``` - -## forEachWithNullKeys - -Variant of [forEach](#foreach) one can use to iterate over mixed values but with the twist that iterables without proper keys (lists, sets etc.), will yield `null` instead of an index key. - -Supported values range from arrays, typed arrays, sets, maps, objects, strings, arguments, iterators, arbitrary iterables etc. - -```js -import {forEachWithNullKeys} from 'obliterator/foreach'; - -const set = new Set(['apple', 'banana']); - -forEach(set, (value, key) => { - console.log(key, value); -}); ->>> null, 'apple' ->>> null, 'banana' -``` - -## includes - -Function returning whether the given value can be found in given iterable-like. - -```js -import {includes} from 'obliterator'; -// Or -import includes from 'obliterator/includes'; - -includes([1, 2, 3], 3); ->>> true; - -includes('test', 'a'); ->>> false; -``` - -## iter - -Function casting any iterable-like value to a proper iterator. Will throw an error if the given value cannot be cast as an iterator. - -```js -import {iter} from 'obliterator'; -// Or -import iter from 'obliterator/iter'; - -iter('test'); -iter(new Set([1, 2, 3])); - -// This will throw: -iter(null); -``` - -## map - -Function returning an iterator mapping another one's values using the given function. - -```js -import map from 'obliterator/map'; -// Or -import {map} from 'obliterator'; - -const set = new Set([1, 2, 3, 4, 5]); - -const triple = x => x * 3; - -const iterator = map(set.values(), triple); - -iterator.next().value >>> 3; -iterator.next().value >>> 6; -``` - -## match - -Function returning an iterator over the matches of a given regex applied to the target string. - -```js -import match from 'obliterator/match'; -// Or -import {match} from 'obliterator'; - -const iterator = match(/t/, 'test'); - -iterator.next().value.index >>> 0; -iterator.next().value.index >>> 3; -``` - -## permutations - -Returns an iterator of permutations of the given array and of the given size. - -Note that for performance reasons, the yielded permutation is always the same object. - -```js -import permutations from 'obliterator/permutations'; -// Or -import {permutations} from 'obliterator'; - -let iterator = permutations([1, 2, 3]); - -iterator.next().value ->>> [1, 2, 3] -iterator.next().value ->>> [1, 3, 2] - -iterator = permutations(['A', 'B', 'C', 'D'], 2); - -iterator.next().value; ->>> ['A', 'B'] -iterator.next().value; ->>> ['A', 'C'] -``` - -## powerSet - -Returns an iterator of sets composing the power set of the given array. - -```js -import powerSet from 'obliterator/power-set'; -// Or -import {powerSet} from 'obliterator'; - -const iterator = powerSet(['A', 'B', 'C']); - -iterator.next().value; ->>> [] -iterator.next().value; ->>> ['A'] -``` - -## some - -Returns whether the given iterable-like has some item matching the given predicate function. - -```js -import some from 'obliterator/some'; -// Or -import {some} from 'obliterator'; - -some(new Set([1, 2, 3]), n => n % 2 === 0); ->>> true - -some('test', c => c === 'a'); ->>> false -``` - -## split - -Returns an iterator over the splits of the target string, according to the given RegExp pattern. - -```js -import split from 'obliterator/split'; -// Or -import {split} from 'obliterator'; - -const iterator = split(/;/g, 'hello;world;super'); - -iterator.next().value; ->>> 'hello' -iterator.next().value; ->>> 'world' -``` - -## take - -Function taking values from given iterator and returning them in an array. - -```js -import take from 'obliterator/take'; -// Or -import {take} from 'obliterator'; - -const set = new Set([1, 2, 3]); - -// To take n values from the iterator -take(set.values(), 2); ->>> [1, 2] - -// To convert the full iterator into an array -take(set.values()); ->>> [1, 2, 3] -``` - -# Contribution - -Contributions are obviously welcome. Please be sure to lint the code & add the relevant unit tests before submitting any PR. - -``` -git clone git@github.com:Yomguithereal/obliterator.git -cd obliterator -npm install - -# To lint the code -npm run lint - -# To run the unit tests -npm test -``` - -# License - -[MIT](LICENSE.txt) diff --git a/libs/shared/graph-layouts/node_modules/obliterator/chain.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/chain.d.ts deleted file mode 100644 index 7cc4c78db..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/chain.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -import type {IntoInterator} from './types'; - -export default function chain<T>( - ...iterables: IntoInterator<T>[] -): IterableIterator<T>; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/chain.js b/libs/shared/graph-layouts/node_modules/obliterator/chain.js deleted file mode 100644 index 00eb68dce..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/chain.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Obliterator Chain Function - * =========================== - * - * Variadic function combining the given iterables. - */ -var Iterator = require('./iterator.js'); -var iter = require('./iter.js'); - -/** - * Chain. - * - * @param {...Iterator} iterables - Target iterables. - * @return {Iterator} - */ -module.exports = function chain() { - var iterables = arguments; - var current = null; - var i = -1; - - /* eslint-disable no-constant-condition */ - return new Iterator(function next() { - var step = null; - - do { - if (current === null) { - i++; - - if (i >= iterables.length) return {done: true}; - - current = iter(iterables[i]); - } - - step = current.next(); - - if (step.done === true) { - current = null; - continue; - } - - break; - } while (true); - - return step; - }); -}; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/combinations.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/combinations.d.ts deleted file mode 100644 index 901a0eaa9..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/combinations.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -export default function combinations<T>( - array: Array<T>, - r: number -): IterableIterator<Array<T>>; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/combinations.js b/libs/shared/graph-layouts/node_modules/obliterator/combinations.js deleted file mode 100644 index c60099d32..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/combinations.js +++ /dev/null @@ -1,76 +0,0 @@ -/** - * Obliterator Combinations Function - * ================================== - * - * Iterator returning combinations of the given array. - */ -var Iterator = require('./iterator.js'); - -/** - * Helper mapping indices to items. - */ -function indicesToItems(target, items, indices, r) { - for (var i = 0; i < r; i++) target[i] = items[indices[i]]; -} - -/** - * Combinations. - * - * @param {array} array - Target array. - * @param {number} r - Size of the subsequences. - * @return {Iterator} - */ -module.exports = function combinations(array, r) { - if (!Array.isArray(array)) - throw new Error( - 'obliterator/combinations: first argument should be an array.' - ); - - var n = array.length; - - if (typeof r !== 'number') - throw new Error( - 'obliterator/combinations: second argument should be omitted or a number.' - ); - - if (r > n) - throw new Error( - 'obliterator/combinations: the size of the subsequences should not exceed the length of the array.' - ); - - if (r === n) return Iterator.of(array.slice()); - - var indices = new Array(r), - subsequence = new Array(r), - first = true, - i; - - for (i = 0; i < r; i++) indices[i] = i; - - return new Iterator(function next() { - if (first) { - first = false; - - indicesToItems(subsequence, array, indices, r); - return {value: subsequence, done: false}; - } - - if (indices[r - 1]++ < n - 1) { - indicesToItems(subsequence, array, indices, r); - return {value: subsequence, done: false}; - } - - i = r - 2; - - while (i >= 0 && indices[i] >= n - (r - i)) --i; - - if (i < 0) return {done: true}; - - indices[i]++; - - while (++i < r) indices[i] = indices[i - 1] + 1; - - indicesToItems(subsequence, array, indices, r); - return {value: subsequence, done: false}; - }); -}; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/consume.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/consume.d.ts deleted file mode 100644 index 16812ee0e..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/consume.d.ts +++ /dev/null @@ -1 +0,0 @@ -export default function consume<T>(iterator: Iterator<T>, steps?: number): void; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/consume.js b/libs/shared/graph-layouts/node_modules/obliterator/consume.js deleted file mode 100644 index 1fa700749..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/consume.js +++ /dev/null @@ -1,29 +0,0 @@ -/* eslint no-constant-condition: 0 */ -/** - * Obliterator Consume Function - * ============================= - * - * Function consuming the given iterator for n or every steps. - */ - -/** - * Consume. - * - * @param {Iterator} iterator - Target iterator. - * @param {number} [steps] - Optional steps. - */ -module.exports = function consume(iterator, steps) { - var step, - l = arguments.length > 1 ? steps : Infinity, - i = 0; - - while (true) { - if (i === l) return; - - step = iterator.next(); - - if (step.done) return; - - i++; - } -}; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/every.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/every.d.ts deleted file mode 100644 index 361fd48e2..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/every.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type {IntoInterator} from './types'; - -type PredicateFunction<T> = (item: T) => boolean; - -export default function every<T>( - target: IntoInterator<T>, - predicate: PredicateFunction<T> -): boolean; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/every.js b/libs/shared/graph-layouts/node_modules/obliterator/every.js deleted file mode 100644 index f2d296c94..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/every.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Obliterator Every Function - * ========================== - * - * Function taking an iterable and a predicate and returning whether all - * its items match the given predicate. - */ -var iter = require('./iter.js'); - -/** - * Every. - * - * @param {Iterable} iterable - Target iterable. - * @param {function} predicate - Predicate function. - * @return {boolean} - */ -module.exports = function every(iterable, predicate) { - var iterator = iter(iterable); - - var step; - - while (((step = iterator.next()), !step.done)) { - if (!predicate(step.value)) return false; - } - - return true; -}; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/filter.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/filter.d.ts deleted file mode 100644 index 91982950c..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/filter.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type {IntoInterator} from './types'; - -type PredicateFunction<T> = (item: T) => boolean; - -export default function filter<T>( - target: IntoInterator<T>, - predicate: PredicateFunction<T> -): IterableIterator<T>; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/filter.js b/libs/shared/graph-layouts/node_modules/obliterator/filter.js deleted file mode 100644 index b17945e0e..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/filter.js +++ /dev/null @@ -1,28 +0,0 @@ -/** - * Obliterator Filter Function - * =========================== - * - * Function returning a iterator filtering the given iterator. - */ -var Iterator = require('./iterator.js'); -var iter = require('./iter.js'); - -/** - * Filter. - * - * @param {Iterable} target - Target iterable. - * @param {function} predicate - Predicate function. - * @return {Iterator} - */ -module.exports = function filter(target, predicate) { - var iterator = iter(target); - var step; - - return new Iterator(function () { - do { - step = iterator.next(); - } while (!step.done && !predicate(step.value)); - - return step; - }); -}; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/find.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/find.d.ts deleted file mode 100644 index e3dea30c8..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/find.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type {IntoInterator} from './types'; - -type PredicateFunction<T> = (item: T) => boolean; - -export default function find<T>( - target: IntoInterator<T>, - predicate: PredicateFunction<T> -): T | undefined; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/find.js b/libs/shared/graph-layouts/node_modules/obliterator/find.js deleted file mode 100644 index d7641cebf..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/find.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Obliterator Find Function - * ========================== - * - * Function taking an iterable and a predicate and returning the first item - * matching the given predicate. - */ -var iter = require('./iter.js'); - -/** - * Find. - * - * @param {Iterable} iterable - Target iterable. - * @param {function} predicate - Predicate function. - * @return {boolean} - */ -module.exports = function find(iterable, predicate) { - var iterator = iter(iterable); - - var step; - - while (((step = iterator.next()), !step.done)) { - if (predicate(step.value)) return step.value; - } - - return; -}; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/foreach-with-null-keys.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/foreach-with-null-keys.d.ts deleted file mode 100644 index 0b3073826..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/foreach-with-null-keys.d.ts +++ /dev/null @@ -1,29 +0,0 @@ -import type {Sequence} from './types'; - -interface ForEachTrait<K, V> { - forEach(callback: (value: V, key: K, self: this) => void): void; -} - -interface PlainObject<T> { - [key: string]: T; -} - -export default function forEachWithNullKeys<V>( - iterable: Set<V>, - callback: (value: V, key: null) => void -): void; - -export default function forEachWithNullKeys<K, V>( - iterable: ForEachTrait<K, V>, - callback: (value: V, key: K) => void -): void; - -export default function forEachWithNullKeys<T>( - iterable: Iterator<T> | Iterable<T> | Sequence<T>, - callback: (item: T, key: null) => void -): void; - -export default function forEachWithNullKeys<T>( - object: PlainObject<T>, - callback: (value: T, key: string) => void -): void; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/foreach-with-null-keys.js b/libs/shared/graph-layouts/node_modules/obliterator/foreach-with-null-keys.js deleted file mode 100644 index 97135add1..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/foreach-with-null-keys.js +++ /dev/null @@ -1,83 +0,0 @@ -/** - * Obliterator ForEachWithNullKeys Function - * ========================================= - * - * Helper function used to easily iterate over mixed values. - */ -var support = require('./support.js'); - -var ARRAY_BUFFER_SUPPORT = support.ARRAY_BUFFER_SUPPORT; -var SYMBOL_SUPPORT = support.SYMBOL_SUPPORT; - -/** - * Same function as the `forEach` but will yield `null` when the target - * does not have keys. - * - * @param {any} iterable - Iterable value. - * @param {function} callback - Callback function. - */ -module.exports = function forEachWithNullKeys(iterable, callback) { - var iterator, k, i, l, s; - - if (!iterable) - throw new Error('obliterator/forEachWithNullKeys: invalid iterable.'); - - if (typeof callback !== 'function') - throw new Error('obliterator/forEachWithNullKeys: expecting a callback.'); - - // The target is an array or a string or function arguments - if ( - Array.isArray(iterable) || - (ARRAY_BUFFER_SUPPORT && ArrayBuffer.isView(iterable)) || - typeof iterable === 'string' || - iterable.toString() === '[object Arguments]' - ) { - for (i = 0, l = iterable.length; i < l; i++) callback(iterable[i], null); - return; - } - - // The target is a Set - if (iterable instanceof Set) { - iterable.forEach(function (value) { - callback(value, null); - }); - return; - } - - // The target has a #.forEach method - if (typeof iterable.forEach === 'function') { - iterable.forEach(callback); - return; - } - - // The target is iterable - if ( - SYMBOL_SUPPORT && - Symbol.iterator in iterable && - typeof iterable.next !== 'function' - ) { - iterable = iterable[Symbol.iterator](); - } - - // The target is an iterator - if (typeof iterable.next === 'function') { - iterator = iterable; - i = 0; - - while (((s = iterator.next()), s.done !== true)) { - callback(s.value, null); - i++; - } - - return; - } - - // The target is a plain object - for (k in iterable) { - if (iterable.hasOwnProperty(k)) { - callback(iterable[k], k); - } - } - - return; -}; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/foreach.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/foreach.d.ts deleted file mode 100644 index db0bac77e..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/foreach.d.ts +++ /dev/null @@ -1,24 +0,0 @@ -import type {Sequence} from './types'; - -interface ForEachTrait<K, V> { - forEach(callback: (value: V, key: K, self: this) => void): void; -} - -interface PlainObject<T> { - [key: string]: T; -} - -export default function forEach<K, V>( - iterable: ForEachTrait<K, V>, - callback: (value: V, key: K) => void -): void; - -export default function forEach<T>( - iterable: Iterator<T> | Iterable<T> | Sequence<T>, - callback: (item: T, index: number) => void -): void; - -export default function forEach<T>( - object: PlainObject<T>, - callback: (value: T, key: string) => void -): void; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/foreach.js b/libs/shared/graph-layouts/node_modules/obliterator/foreach.js deleted file mode 100644 index 84af94fe9..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/foreach.js +++ /dev/null @@ -1,73 +0,0 @@ -/** - * Obliterator ForEach Function - * ============================= - * - * Helper function used to easily iterate over mixed values. - */ -var support = require('./support.js'); - -var ARRAY_BUFFER_SUPPORT = support.ARRAY_BUFFER_SUPPORT; -var SYMBOL_SUPPORT = support.SYMBOL_SUPPORT; - -/** - * Function able to iterate over almost any iterable JS value. - * - * @param {any} iterable - Iterable value. - * @param {function} callback - Callback function. - */ -module.exports = function forEach(iterable, callback) { - var iterator, k, i, l, s; - - if (!iterable) throw new Error('obliterator/forEach: invalid iterable.'); - - if (typeof callback !== 'function') - throw new Error('obliterator/forEach: expecting a callback.'); - - // The target is an array or a string or function arguments - if ( - Array.isArray(iterable) || - (ARRAY_BUFFER_SUPPORT && ArrayBuffer.isView(iterable)) || - typeof iterable === 'string' || - iterable.toString() === '[object Arguments]' - ) { - for (i = 0, l = iterable.length; i < l; i++) callback(iterable[i], i); - return; - } - - // The target has a #.forEach method - if (typeof iterable.forEach === 'function') { - iterable.forEach(callback); - return; - } - - // The target is iterable - if ( - SYMBOL_SUPPORT && - Symbol.iterator in iterable && - typeof iterable.next !== 'function' - ) { - iterable = iterable[Symbol.iterator](); - } - - // The target is an iterator - if (typeof iterable.next === 'function') { - iterator = iterable; - i = 0; - - while (((s = iterator.next()), s.done !== true)) { - callback(s.value, i); - i++; - } - - return; - } - - // The target is a plain object - for (k in iterable) { - if (iterable.hasOwnProperty(k)) { - callback(iterable[k], k); - } - } - - return; -}; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/includes.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/includes.d.ts deleted file mode 100644 index 1a8f9de2b..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/includes.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type {IntoInterator} from './types'; - -export default function includes<T>( - target: IntoInterator<T>, - value: T -): boolean; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/includes.js b/libs/shared/graph-layouts/node_modules/obliterator/includes.js deleted file mode 100644 index 01c788b57..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/includes.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Obliterator Includes Function - * ============================== - * - * Function taking an iterable and returning whether the given item can be - * found in it. - */ -var iter = require('./iter.js'); - -/** - * Includes. - * - * @param {Iterable} iterable - Target iterable. - * @param {function} value - Searched value. - * @return {boolean} - */ -module.exports = function includes(iterable, value) { - var iterator = iter(iterable); - - var step; - - while (((step = iterator.next()), !step.done)) { - if (step.value === value) return true; - } - - return false; -}; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/index.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/index.d.ts deleted file mode 100644 index 4a0371419..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/index.d.ts +++ /dev/null @@ -1,20 +0,0 @@ -export {default as Iterator} from './iterator'; -export {default as iter} from './iter'; -export {default as chain} from './chain'; -export {default as combinations} from './combinations'; -export {default as consume} from './consume'; -export {default as every} from './every'; -export {default as filter} from './filter'; -export {default as find} from './find'; -export {default as forEach} from './foreach'; -export {default as forEachWithNullKeys} from './foreach-with-null-keys'; -export {default as includes} from './includes'; -export {default as map} from './map'; -export {default as match} from './match'; -export {default as permutations} from './permutations'; -export {default as powerSet} from './power-set'; -export {default as range} from './range'; -export {default as some} from './some'; -export {default as split} from './split'; -export {default as take} from './take'; -export {default as takeInto} from './take-into'; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/index.js b/libs/shared/graph-layouts/node_modules/obliterator/index.js deleted file mode 100644 index a55393a5d..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/index.js +++ /dev/null @@ -1,26 +0,0 @@ -/** - * Obliterator Library Endpoint - * ============================= - * - * Exporting the library's functions. - */ -exports.Iterator = require('./iterator.js'); -exports.iter = require('./iter.js'); -exports.chain = require('./chain.js'); -exports.combinations = require('./combinations.js'); -exports.consume = require('./consume.js'); -exports.every = require('./every.js'); -exports.filter = require('./filter.js'); -exports.find = require('./find.js'); -exports.forEach = require('./foreach.js'); -exports.forEachWithNullKeys = require('./foreach-with-null-keys.js'); -exports.includes = require('./includes.js'); -exports.map = require('./map.js'); -exports.match = require('./match.js'); -exports.permutations = require('./permutations.js'); -exports.powerSet = require('./power-set.js'); -exports.range = require('./range.js'); -exports.some = require('./some.js'); -exports.split = require('./split.js'); -exports.take = require('./take.js'); -exports.takeInto = require('./take-into.js'); diff --git a/libs/shared/graph-layouts/node_modules/obliterator/iter.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/iter.d.ts deleted file mode 100644 index 55377454d..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/iter.d.ts +++ /dev/null @@ -1 +0,0 @@ -export default function iter<T>(target: unknown): Iterator<T>; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/iter.js b/libs/shared/graph-layouts/node_modules/obliterator/iter.js deleted file mode 100644 index 12ab82f30..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/iter.js +++ /dev/null @@ -1,46 +0,0 @@ -/** - * Obliterator Iter Function - * ========================== - * - * Function coercing values to an iterator. It can be quite useful when needing - * to handle iterables and iterators the same way. - */ -var Iterator = require('./iterator.js'); -var support = require('./support.js'); - -var ARRAY_BUFFER_SUPPORT = support.ARRAY_BUFFER_SUPPORT; -var SYMBOL_SUPPORT = support.SYMBOL_SUPPORT; - -function iterOrNull(target) { - // Indexed sequence - if ( - typeof target === 'string' || - Array.isArray(target) || - (ARRAY_BUFFER_SUPPORT && ArrayBuffer.isView(target)) - ) - return Iterator.fromSequence(target); - - // Invalid value - if (typeof target !== 'object' || target === null) return null; - - // Iterable - if (SYMBOL_SUPPORT && typeof target[Symbol.iterator] === 'function') - return target[Symbol.iterator](); - - // Iterator duck-typing - if (typeof target.next === 'function') return target; - - // Invalid object - return null; -} - -module.exports = function iter(target) { - var iterator = iterOrNull(target); - - if (!iterator) - throw new Error( - 'obliterator: target is not iterable nor a valid iterator.' - ); - - return iterator; -}; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/iterator.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/iterator.d.ts deleted file mode 100644 index 8b10451a6..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/iterator.d.ts +++ /dev/null @@ -1,18 +0,0 @@ -import type {Sequence} from './types'; - -type NextFunction<V> = () => IteratorResult<V>; - -export default class ObliteratorIterator<V> implements IterableIterator<V> { - // Constructor - constructor(next: NextFunction<V>); - - // Well-known methods - next(): IteratorResult<V>; - [Symbol.iterator](): IterableIterator<V>; - - // Static methods - static of<T>(...args: T[]): ObliteratorIterator<T>; - static empty<T>(): ObliteratorIterator<T>; - static is(value: any): boolean; - static fromSequence<T>(sequence: Sequence<T>): ObliteratorIterator<T>; -} diff --git a/libs/shared/graph-layouts/node_modules/obliterator/iterator.js b/libs/shared/graph-layouts/node_modules/obliterator/iterator.js deleted file mode 100644 index aa2418924..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/iterator.js +++ /dev/null @@ -1,96 +0,0 @@ -/** - * Obliterator Iterator Class - * =========================== - * - * Simple class representing the library's iterators. - */ - -/** - * Iterator class. - * - * @constructor - * @param {function} next - Next function. - */ -function Iterator(next) { - if (typeof next !== 'function') - throw new Error('obliterator/iterator: expecting a function!'); - - this.next = next; -} - -/** - * If symbols are supported, we add `next` to `Symbol.iterator`. - */ -if (typeof Symbol !== 'undefined') - Iterator.prototype[Symbol.iterator] = function () { - return this; - }; - -/** - * Returning an iterator of the given values. - * - * @param {any...} values - Values. - * @return {Iterator} - */ -Iterator.of = function () { - var args = arguments, - l = args.length, - i = 0; - - return new Iterator(function () { - if (i >= l) return {done: true}; - - return {done: false, value: args[i++]}; - }); -}; - -/** - * Returning an empty iterator. - * - * @return {Iterator} - */ -Iterator.empty = function () { - var iterator = new Iterator(function () { - return {done: true}; - }); - - return iterator; -}; - -/** - * Returning an iterator over the given indexed sequence. - * - * @param {string|Array} sequence - Target sequence. - * @return {Iterator} - */ -Iterator.fromSequence = function (sequence) { - var i = 0, - l = sequence.length; - - return new Iterator(function () { - if (i >= l) return {done: true}; - - return {done: false, value: sequence[i++]}; - }); -}; - -/** - * Returning whether the given value is an iterator. - * - * @param {any} value - Value. - * @return {boolean} - */ -Iterator.is = function (value) { - if (value instanceof Iterator) return true; - - return ( - typeof value === 'object' && - value !== null && - typeof value.next === 'function' - ); -}; - -/** - * Exporting. - */ -module.exports = Iterator; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/map.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/map.d.ts deleted file mode 100644 index bf087aae5..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/map.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type {IntoInterator} from './types'; - -type MapFunction<S, T> = (item: S) => T; - -export default function map<S, T>( - target: IntoInterator<S>, - predicate: MapFunction<S, T> -): IterableIterator<T>; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/map.js b/libs/shared/graph-layouts/node_modules/obliterator/map.js deleted file mode 100644 index 9efb94100..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/map.js +++ /dev/null @@ -1,29 +0,0 @@ -/** - * Obliterator Map Function - * =========================== - * - * Function returning a iterator mapping the given iterator's values. - */ -var Iterator = require('./iterator.js'); -var iter = require('./iter.js'); - -/** - * Map. - * - * @param {Iterator} target - Target iterable. - * @param {function} mapper - Map function. - * @return {Iterator} - */ -module.exports = function map(target, mapper) { - var iterator = iter(target); - - return new Iterator(function next() { - var step = iterator.next(); - - if (step.done) return step; - - return { - value: mapper(step.value) - }; - }); -}; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/match.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/match.d.ts deleted file mode 100644 index 3ff382efd..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/match.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -export default function match( - pattern: RegExp, - string: string -): IterableIterator<string>; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/match.js b/libs/shared/graph-layouts/node_modules/obliterator/match.js deleted file mode 100644 index 86c17fce5..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/match.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Obliterator Match Function - * =========================== - * - * Function returning an iterator over the matches of the given regex on the - * target string. - */ -var Iterator = require('./iterator.js'); - -/** - * Match. - * - * @param {RegExp} pattern - Regular expression to use. - * @param {string} string - Target string. - * @return {Iterator} - */ -module.exports = function match(pattern, string) { - var executed = false; - - if (!(pattern instanceof RegExp)) - throw new Error( - 'obliterator/match: invalid pattern. Expecting a regular expression.' - ); - - if (typeof string !== 'string') - throw new Error('obliterator/match: invalid target. Expecting a string.'); - - return new Iterator(function () { - if (executed && !pattern.global) { - pattern.lastIndex = 0; - return {done: true}; - } - - executed = true; - - var m = pattern.exec(string); - - if (m) return {value: m}; - - pattern.lastIndex = 0; - return {done: true}; - }); -}; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/package.json b/libs/shared/graph-layouts/node_modules/obliterator/package.json deleted file mode 100644 index c36cb964f..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/package.json +++ /dev/null @@ -1,46 +0,0 @@ -{ - "name": "obliterator", - "version": "2.0.2", - "description": "Higher order iterator library for JavaScript/TypeScript.", - "main": "index.js", - "types": "index.d.ts", - "scripts": { - "lint": "eslint *.js", - "prepublishOnly": "npm run lint && npm test", - "prettier": "prettier --write '*.js' '*.ts'", - "test": "mocha test.js && npm run test:types", - "test:types": "tsc --lib es2015,dom --noEmit --noImplicitAny --noImplicitReturns ./test-types.ts" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/yomguithereal/obliterator.git" - }, - "keywords": [ - "iterator" - ], - "author": { - "name": "Guillaume Plique", - "url": "http://github.com/Yomguithereal" - }, - "license": "MIT", - "bugs": { - "url": "https://github.com/yomguithereal/obliterator/issues" - }, - "homepage": "https://github.com/yomguithereal/obliterator#readme", - "devDependencies": { - "@yomguithereal/eslint-config": "^4.4.0", - "@yomguithereal/prettier-config": "^1.2.0", - "eslint": "^8.2.0", - "eslint-config-prettier": "^8.3.0", - "mocha": "^9.1.3", - "prettier": "^2.4.1", - "typescript": "^4.4.4" - }, - "eslintConfig": { - "extends": [ - "@yomguithereal/eslint-config", - "eslint-config-prettier" - ] - }, - "prettier": "@yomguithereal/prettier-config" -} diff --git a/libs/shared/graph-layouts/node_modules/obliterator/permutations.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/permutations.d.ts deleted file mode 100644 index 2e8ef37b6..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/permutations.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -export default function permutations<T>( - array: Array<T>, - r: number -): IterableIterator<Array<T>>; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/permutations.js b/libs/shared/graph-layouts/node_modules/obliterator/permutations.js deleted file mode 100644 index 3410ca42c..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/permutations.js +++ /dev/null @@ -1,94 +0,0 @@ -/** - * Obliterator Permutations Function - * ================================== - * - * Iterator returning permutations of the given array. - */ -var Iterator = require('./iterator.js'); - -/** - * Helper mapping indices to items. - */ -function indicesToItems(target, items, indices, r) { - for (var i = 0; i < r; i++) target[i] = items[indices[i]]; -} - -/** - * Permutations. - * - * @param {array} array - Target array. - * @param {number} r - Size of the subsequences. - * @return {Iterator} - */ -module.exports = function permutations(array, r) { - if (!Array.isArray(array)) - throw new Error( - 'obliterator/permutations: first argument should be an array.' - ); - - var n = array.length; - - if (arguments.length < 2) r = n; - - if (typeof r !== 'number') - throw new Error( - 'obliterator/permutations: second argument should be omitted or a number.' - ); - - if (r > n) - throw new Error( - 'obliterator/permutations: the size of the subsequences should not exceed the length of the array.' - ); - - var indices = new Uint32Array(n), - subsequence = new Array(r), - cycles = new Uint32Array(r), - first = true, - i; - - for (i = 0; i < n; i++) { - indices[i] = i; - - if (i < r) cycles[i] = n - i; - } - - i = r; - - return new Iterator(function next() { - if (first) { - first = false; - indicesToItems(subsequence, array, indices, r); - return {value: subsequence, done: false}; - } - - var tmp, j; - - i--; - - if (i < 0) return {done: true}; - - cycles[i]--; - - if (cycles[i] === 0) { - tmp = indices[i]; - - for (j = i; j < n - 1; j++) indices[j] = indices[j + 1]; - - indices[n - 1] = tmp; - - cycles[i] = n - i; - return next(); - } else { - j = cycles[i]; - tmp = indices[i]; - - indices[i] = indices[n - j]; - indices[n - j] = tmp; - - i = r; - - indicesToItems(subsequence, array, indices, r); - return {value: subsequence, done: false}; - } - }); -}; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/power-set.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/power-set.d.ts deleted file mode 100644 index 254094ad7..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/power-set.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -export default function powerSet<T>( - array: Array<T> -): IterableIterator<Array<T>>; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/power-set.js b/libs/shared/graph-layouts/node_modules/obliterator/power-set.js deleted file mode 100644 index cd63f9574..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/power-set.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Obliterator Power Set Function - * =============================== - * - * Iterator returning the power set of the given array. - */ -var Iterator = require('./iterator.js'), - combinations = require('./combinations.js'), - chain = require('./chain.js'); - -/** - * Power set. - * - * @param {array} array - Target array. - * @return {Iterator} - */ -module.exports = function powerSet(array) { - var n = array.length; - - var iterators = new Array(n + 1); - - iterators[0] = Iterator.of([]); - - for (var i = 1; i < n + 1; i++) iterators[i] = combinations(array, i); - - return chain.apply(null, iterators); -}; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/range.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/range.d.ts deleted file mode 100644 index bff37072d..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/range.d.ts +++ /dev/null @@ -1,10 +0,0 @@ -export default function range(end: number): IterableIterator<number>; -export default function range( - start: number, - end: number -): IterableIterator<number>; -export default function range( - start: number, - end: number, - step: number -): IterableIterator<number>; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/range.js b/libs/shared/graph-layouts/node_modules/obliterator/range.js deleted file mode 100644 index b00f9f02b..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/range.js +++ /dev/null @@ -1,44 +0,0 @@ -/** - * Obliterator Range Function - * =========================== - * - * Function returning a range iterator. - */ -var Iterator = require('./iterator.js'); - -/** - * Range. - * - * @param {number} start - Start. - * @param {number} end - End. - * @param {number} step - Step. - * @return {Iterator} - */ -module.exports = function range(start, end, step) { - if (arguments.length === 1) { - end = start; - start = 0; - } - - if (arguments.length < 3) step = 1; - - var i = start; - - var iterator = new Iterator(function () { - if (i < end) { - var value = i; - - i += step; - - return {value: value, done: false}; - } - - return {done: true}; - }); - - iterator.start = start; - iterator.end = end; - iterator.step = step; - - return iterator; -}; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/some.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/some.d.ts deleted file mode 100644 index cccd35f13..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/some.d.ts +++ /dev/null @@ -1,8 +0,0 @@ -import type {IntoInterator} from './types'; - -type PredicateFunction<T> = (item: T) => boolean; - -export default function some<T>( - target: IntoInterator<T>, - predicate: PredicateFunction<T> -): boolean; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/some.js b/libs/shared/graph-layouts/node_modules/obliterator/some.js deleted file mode 100644 index b7923ee45..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/some.js +++ /dev/null @@ -1,27 +0,0 @@ -/** - * Obliterator Some Function - * ========================== - * - * Function taking an iterable and a predicate and returning whether a - * matching item can be found. - */ -var iter = require('./iter.js'); - -/** - * Some. - * - * @param {Iterable} iterable - Target iterable. - * @param {function} predicate - Predicate function. - * @return {boolean} - */ -module.exports = function some(iterable, predicate) { - var iterator = iter(iterable); - - var step; - - while (((step = iterator.next()), !step.done)) { - if (predicate(step.value)) return true; - } - - return false; -}; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/split.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/split.d.ts deleted file mode 100644 index 5f54145b4..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/split.d.ts +++ /dev/null @@ -1,4 +0,0 @@ -export default function split( - pattern: RegExp, - string: string -): IterableIterator<string>; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/split.js b/libs/shared/graph-layouts/node_modules/obliterator/split.js deleted file mode 100644 index 9a765c0e9..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/split.js +++ /dev/null @@ -1,68 +0,0 @@ -/** - * Obliterator Split Function - * =========================== - * - * Function returning an iterator over the pieces of a regex split. - */ -var Iterator = require('./iterator.js'); - -/** - * Function used to make the given pattern global. - * - * @param {RegExp} pattern - Regular expression to make global. - * @return {RegExp} - */ -function makeGlobal(pattern) { - var flags = 'g'; - - if (pattern.multiline) flags += 'm'; - if (pattern.ignoreCase) flags += 'i'; - if (pattern.sticky) flags += 'y'; - if (pattern.unicode) flags += 'u'; - - return new RegExp(pattern.source, flags); -} - -/** - * Split. - * - * @param {RegExp} pattern - Regular expression to use. - * @param {string} string - Target string. - * @return {Iterator} - */ -module.exports = function split(pattern, string) { - if (!(pattern instanceof RegExp)) - throw new Error( - 'obliterator/split: invalid pattern. Expecting a regular expression.' - ); - - if (typeof string !== 'string') - throw new Error('obliterator/split: invalid target. Expecting a string.'); - - // NOTE: cloning the pattern has a performance cost but side effects for not - // doing so might be worse. - pattern = makeGlobal(pattern); - - var consumed = false, - current = 0; - - return new Iterator(function () { - if (consumed) return {done: true}; - - var match = pattern.exec(string), - value, - length; - - if (match) { - length = match.index + match[0].length; - - value = string.slice(current, match.index); - current = length; - } else { - consumed = true; - value = string.slice(current); - } - - return {value: value, done: false}; - }); -}; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/support.js b/libs/shared/graph-layouts/node_modules/obliterator/support.js deleted file mode 100644 index 0c00649ae..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/support.js +++ /dev/null @@ -1,2 +0,0 @@ -exports.ARRAY_BUFFER_SUPPORT = typeof ArrayBuffer !== 'undefined'; -exports.SYMBOL_SUPPORT = typeof Symbol !== 'undefined'; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/take-into.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/take-into.d.ts deleted file mode 100644 index cb1d4dbe1..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/take-into.d.ts +++ /dev/null @@ -1,9 +0,0 @@ -import type {IntoInterator} from './types'; - -// Requires a resolution of https://github.com/microsoft/TypeScript/issues/1213 -// export default function takeInto<C<~>, T>(ArrayClass: new <T>(n: number) => C<T>, iterator: Iterator<T>, n: number): C<T>; -export default function takeInto<T>( - ArrayClass: new <T>(arrayLength: number) => T[], - iterator: IntoInterator<T>, - n: number -): T[]; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/take-into.js b/libs/shared/graph-layouts/node_modules/obliterator/take-into.js deleted file mode 100644 index cc2db1875..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/take-into.js +++ /dev/null @@ -1,39 +0,0 @@ -/* eslint no-constant-condition: 0 */ -/** - * Obliterator Take Into Function - * =============================== - * - * Same as the take function but enables the user to select an array class - * in which to insert the retrieved values. - */ -var iter = require('./iter.js'); - -/** - * Take Into. - * - * @param {function} ArrayClass - Array class to use. - * @param {Iterable} iterable - Target iterable. - * @param {number} n - Number of items to take. - * @return {array} - */ -module.exports = function takeInto(ArrayClass, iterable, n) { - var array = new ArrayClass(n), - step, - i = 0; - - var iterator = iter(iterable); - - while (true) { - if (i === n) return array; - - step = iterator.next(); - - if (step.done) { - if (i !== n) return array.slice(0, i); - - return array; - } - - array[i++] = step.value; - } -}; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/take.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/take.d.ts deleted file mode 100644 index 346084841..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/take.d.ts +++ /dev/null @@ -1,6 +0,0 @@ -import type {IntoInterator} from './types'; - -export default function take<T>( - iterator: IntoInterator<T>, - n: number -): Array<T>; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/take.js b/libs/shared/graph-layouts/node_modules/obliterator/take.js deleted file mode 100644 index defe775aa..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/take.js +++ /dev/null @@ -1,39 +0,0 @@ -/* eslint no-constant-condition: 0 */ -/** - * Obliterator Take Function - * ========================== - * - * Function taking n or every value of the given iterator and returns them - * into an array. - */ -var iter = require('./iter.js'); - -/** - * Take. - * - * @param {Iterable} iterable - Target iterable. - * @param {number} [n] - Optional number of items to take. - * @return {array} - */ -module.exports = function take(iterable, n) { - var l = arguments.length > 1 ? n : Infinity, - array = l !== Infinity ? new Array(l) : [], - step, - i = 0; - - var iterator = iter(iterable); - - while (true) { - if (i === l) return array; - - step = iterator.next(); - - if (step.done) { - if (i !== n) array.length = i; - - return array; - } - - array[i++] = step.value; - } -}; diff --git a/libs/shared/graph-layouts/node_modules/obliterator/types.d.ts b/libs/shared/graph-layouts/node_modules/obliterator/types.d.ts deleted file mode 100644 index be9cca50e..000000000 --- a/libs/shared/graph-layouts/node_modules/obliterator/types.d.ts +++ /dev/null @@ -1,7 +0,0 @@ -export interface Sequence<T> { - length: number; - slice(from: number, to?: number): Sequence<T>; - [index: number]: T; -} - -export type IntoInterator<T> = Iterable<T> | Iterator<T> | Sequence<T>; diff --git a/libs/shared/graph-layouts/package.json b/libs/shared/graph-layouts/package.json deleted file mode 100644 index 0833b5d4c..000000000 --- a/libs/shared/graph-layouts/package.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "name": "@graphpolaris/graph-layouts", - "version": "0.0.1", - "type": "commonjs", - "dependencies": { - "graphology": "^0.24.1" - } -} diff --git a/libs/shared/graph-layouts/project.json b/libs/shared/graph-layouts/project.json deleted file mode 100644 index 3f2eab403..000000000 --- a/libs/shared/graph-layouts/project.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "root": "libs/shared/graph-layouts", - "sourceRoot": "libs/shared/graph-layouts/src", - "projectType": "library", - "targets": { - "build": { - "executor": "@nrwl/js:tsc", - "outputs": ["{options.outputPath}"], - "options": { - "outputPath": "dist/libs/shared/graph-layouts", - "main": "libs/shared/graph-layouts/src/index.ts", - "tsConfig": "libs/shared/graph-layouts/tsconfig.lib.json", - "assets": ["libs/shared/graph-layouts/*.md"] - } - }, - "lint": { - "executor": "@nrwl/linter:eslint", - "outputs": ["{options.outputFile}"], - "options": { - "lintFilePatterns": ["libs/shared/graph-layouts/**/*.ts"] - } - }, - "test": { - "executor": "@nrwl/jest:jest", - "outputs": ["coverage/libs/shared/graph-layouts"], - "options": { - "jestConfig": "libs/shared/graph-layouts/jest.config.js", - "passWithNoTests": true - } - } - }, - "tags": [] -} diff --git a/libs/shared/graph-layouts/src/index.ts b/libs/shared/graph-layouts/src/index.ts deleted file mode 100644 index 61989a30a..000000000 --- a/libs/shared/graph-layouts/src/index.ts +++ /dev/null @@ -1 +0,0 @@ -export * from './lib/shared-graph-layouts'; diff --git a/libs/shared/graph-layouts/src/lib/cytoscape-layouts.ts b/libs/shared/graph-layouts/src/lib/cytoscape-layouts.ts deleted file mode 100644 index 325377b8f..000000000 --- a/libs/shared/graph-layouts/src/lib/cytoscape-layouts.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Layout } from './layout'; -import { ILayoutFactory, LayoutAlgorithm } from './layout-creator-usecase'; - -export type CytoscapeProvider = 'Cytoscape'; - -export type CytoscapeLayoutAlgorithms = - | `${CytoscapeProvider}_coupe` - | `${CytoscapeProvider}_i4`; - -/** - * This is a ConcreteCreator - */ -export class CytoscapeFactory - implements ILayoutFactory<CytoscapeLayoutAlgorithms> -{ - createLayout(LayoutAlgorithm: CytoscapeLayoutAlgorithms): Cytoscape | null { - switch (LayoutAlgorithm) { - case 'Cytoscape_coupe': - return new CytoscapeCoupe(); - case 'Cytoscape_i4': - return new CytoscapeI4(); - default: - return null; - } - } -} - -export abstract class Cytoscape extends Layout<CytoscapeProvider> { - constructor(public override algorithm: LayoutAlgorithm<CytoscapeProvider>) { - super('Cytoscape', algorithm); - } - - public specialCytoscapeFunction() { - console.log('Only Cytoscape Layouts can do this.'); - } -} - -/** - * This is a ConcreteProduct - */ -class CytoscapeI4 extends Cytoscape { - constructor() { - super('Cytoscape_i4'); - } -} - -/** - * This is a ConcreteProduct - */ -class CytoscapeCoupe extends Cytoscape { - constructor() { - super('Cytoscape_coupe'); - } -} diff --git a/libs/shared/graph-layouts/src/lib/graphology-layouts.ts b/libs/shared/graph-layouts/src/lib/graphology-layouts.ts deleted file mode 100644 index 1e609bbe5..000000000 --- a/libs/shared/graph-layouts/src/lib/graphology-layouts.ts +++ /dev/null @@ -1,170 +0,0 @@ -import Graph from 'graphology'; -import { circular, random } from 'graphology-layout'; -import forceAtlas2, { - ForceAtlas2Settings, -} from 'graphology-layout-forceatlas2'; -import noverlap from 'graphology-layout-noverlap'; -import { RandomLayoutOptions } from 'graphology-layout/random'; -import { NoverlapSettings } from 'graphology-library/layout-noverlap'; -import { Attributes } from 'graphology-types'; -import { Layout } from './layout'; -import { ILayoutFactory, LayoutAlgorithm } from './layout-creator-usecase'; - -export type GraphologyProvider = 'Graphology'; - -export type GraphologyLayoutAlgorithms = - | `${GraphologyProvider}_circular` - | `${GraphologyProvider}_random` - | `${GraphologyProvider}_noverlap` - | `${GraphologyProvider}_forceAtlas2`; - -/** - * This is the Graphology Constructor for the main layouts available at - * https://graphology.github.io/ - */ -export class GraphologyFactory - implements ILayoutFactory<GraphologyLayoutAlgorithms> -{ - createLayout(layoutAlgorithm: GraphologyLayoutAlgorithms): Graphology | null { - switch (layoutAlgorithm) { - case 'Graphology_random': - return new GraphologyRandom(); - case 'Graphology_circular': - return new GraphologyCircular(); - case 'Graphology_noverlap': - return new GraphologyNoverlap(); - case 'Graphology_forceAtlas2': - return new GraphologyForceAtlas2(); - default: - return null; - } - } -} - -export abstract class Graphology extends Layout<GraphologyProvider> { - height: number = 100; - width: number = 100; - constructor(public override algorithm: LayoutAlgorithm<GraphologyProvider>) { - super('Graphology', algorithm); - this.setDimensions(100, 200); - } - - public specialGraphologyFunction() { - // graph.forEachNode((node, attr) => { - // graph.setNodeAttribute(node, 'x', 0); - // graph.setNodeAttribute(node, 'y', 0); - // }); - } - - public setDimensions(width = 100, height = 100) { - this.width = width; - this.height = height; - } -} - -/** - * This is a ConcreteProduct - */ -export class GraphologyCircular extends Graphology { - constructor() { - super('Graphology_circular'); - } - - public override layout( - graph: Graph<Attributes, Attributes, Attributes> - ): void { - // To directly assign the positions to the nodes: - circular.assign(graph, { - scale: 100, - }); - } -} - -const DEFAULT_RANDOM_SETTINGS: RandomLayoutOptions = { - scale: 250, -}; -/** - * This is a ConcreteProduct - */ -export class GraphologyRandom extends Graphology { - constructor() { - super('Graphology_random'); - } - - public override layout( - graph: Graph<Attributes, Attributes, Attributes> - ): void { - // const positions = random(graph); - - // To directly assign the positions to the nodes: - random.assign(graph, DEFAULT_RANDOM_SETTINGS); - } -} - -const DEFAULT_NOVERLAP_SETTINGS: NoverlapSettings = { - margin: 40, - ratio: 40, - // gridSize: 50, - - // gridSize ?number 20: number of grid cells horizontally and vertically subdivising the graph’s space. This is used as an optimization scheme. Set it to 1 and you will have O(n²) time complexity, which can sometimes perform better with very few nodes. - // margin ?number 5: margin to keep between nodes. - // expansion ?number 1.1: percentage of current space that nodes could attempt to move outside of. - // ratio ?number 1.0: ratio scaling node sizes. - // speed ?number 3: dampening factor that will slow down node movements to ease the overall process. -}; - -/** - * This is a ConcreteProduct - */ -export class GraphologyNoverlap extends Graphology { - constructor() { - super('Graphology_noverlap'); - } - - public override layout( - graph: Graph<Attributes, Attributes, Attributes> - ): void { - // // // To directly assign the positions to the nodes: - noverlap.assign(graph, { - maxIterations: 5000, - settings: DEFAULT_NOVERLAP_SETTINGS, - }); - } -} - -const DEFAULT_FORCEATLAS2_SETTINGS: ForceAtlas2Settings = { - gravity: 10, - adjustSizes: true, - linLogMode: true, - - // adjustSizes ?boolean false: should the node’s sizes be taken into account? - // barnesHutOptimize ?boolean false: whether to use the Barnes-Hut approximation to compute repulsion in O(n*log(n)) rather than default O(n^2), n being the number of nodes. - // barnesHutTheta ?number 0.5: Barnes-Hut approximation theta parameter. - // edgeWeightInfluence ?number 1: influence of the edge’s weights on the layout. To consider edge weight, don’t forget to pass weighted as true when applying the synchronous layout or when instantiating the worker. - // gravity ?number 1: strength of the layout’s gravity. - // linLogMode ?boolean false: whether to use Noack’s LinLog model. - // outboundAttractionDistribution ?boolean false - // scalingRatio ?number 1 - // slowDown ?number 1 - // strongGravityMode ?boolean false -}; - -/** - * This is a ConcreteProduct - */ -export class GraphologyForceAtlas2 extends Graphology { - constructor() { - super('Graphology_forceAtlas2'); - } - - public override layout( - graph: Graph<Attributes, Attributes, Attributes> - ): void { - // To directly assign the positions to the nodes: - - forceAtlas2.assign(graph, { - iterations: 500000, - settings: DEFAULT_FORCEATLAS2_SETTINGS, - }); - } -} diff --git a/libs/shared/graph-layouts/src/lib/layout-creator-usecase.spec.ts b/libs/shared/graph-layouts/src/lib/layout-creator-usecase.spec.ts deleted file mode 100644 index 95e16ec4d..000000000 --- a/libs/shared/graph-layouts/src/lib/layout-creator-usecase.spec.ts +++ /dev/null @@ -1,140 +0,0 @@ -import { - movieSchemaRaw, - northWindSchemaRaw, - simpleSchemaRaw, - twitterSchemaRaw, -} from '@graphpolaris/shared/mock-data'; -// import Graph, { MultiGraph } from 'graphology'; - -// import ladder from 'graphology-generators/classic/ladder'; -// import { LayoutFactory } from './layout-creator-usecase'; - -// /** -// * @jest-environment jsdom -// */ -// describe('LayoutFactory', () => { -// /** -// * @jest-environment jsdom -// */ -// it('should work with noverlap from graphology ', () => { -// const graph = new MultiGraph(); - -// // Adding some nodes -// // graph.addNode('John', { x: 0, y: 0, width: 200, height: 200 }); -// // graph.addNode('Martha', { x: 0, y: 0 }); -// graph.addNode('John'); -// graph.addNode('Martha'); - -// // Adding an edge -// graph.addEdge('John', 'Martha'); - -// const layoutFactory = new LayoutFactory(); -// const layoutAlgorithm = layoutFactory.createLayout( -// 'Graphology_forceAtlas2' -// ); -// layoutAlgorithm?.layout(graph); - -// graph.forEachNode((node, attr) => { -// console.log(node, attr); -// }); -// }); - -// test('should work with noverlap from graphology on generated graph', () => { -// // Creating a ladder graph -// const graph = ladder(Graph, 10); - -// graph.forEachNode((node, attr) => { -// graph.setNodeAttribute(node, 'x', 0); -// graph.setNodeAttribute(node, 'y', 0); -// }); - -// const layoutFactory = new LayoutFactory(); - -// const layout = layoutFactory.createLayout('Graphology_noverlap'); -// layout?.layout(graph); - -// graph.forEachNode((node, attr) => { -// console.log(node, attr); -// }); -// }); - -// test('should work with random from graphology on generated graph', () => { -// // Creating a ladder graph -// const graph = ladder(Graph, 10); - -// graph.forEachNode((node, attr) => { -// graph.setNodeAttribute(node, 'x', 0); -// graph.setNodeAttribute(node, 'y', 0); -// }); - -// const layoutFactory = new LayoutFactory(); - -// const layout = layoutFactory.createLayout('Graphology_random'); -// layout?.setDimensions(100, 100); -// layout?.layout(graph); - -// graph.forEachNode((node, attr) => { -// console.log(node, attr); -// }); -// }); - -// test('should work with circular from graphology on generated graph', () => { -// // Creating a ladder graph -// const graph = ladder(Graph, 100); - -// graph.forEachNode((node, attr) => { -// graph.setNodeAttribute(node, 'x', 0); -// graph.setNodeAttribute(node, 'y', 0); -// }); - -// const layoutFactory = new LayoutFactory(); - -// const layout = layoutFactory.createLayout('Graphology_circular'); -// layout?.setDimensions(100, 100); -// layout?.layout(graph); - -// graph.forEachNode((node, attr) => { -// console.log(node, attr); -// }); -// }); - -// test('should work with circular from graphology on generated graph', () => { -// // Creating a ladder graph -// const graph = ladder(Graph, 100); - -// graph.forEachNode((node, attr) => { -// graph.setNodeAttribute(node, 'x', 0); -// graph.setNodeAttribute(node, 'y', 0); -// }); - -// const layoutFactory = new LayoutFactory(); -// const layout = layoutFactory.createLayout('Graphology_forceAtlas2'); -// layout?.setDimensions(100, 100); -// layout?.layout(graph); - -// graph.forEachNode((node, attr) => { -// console.log(node, attr); -// }); -// }); - -// test('should add x,y for graphology layouts if not existing', () => { -// // console.log(Object.keys(AllLayoutAlgorithms)) - -// const graph = ladder(Graph, 100); - -// graph.forEachNode((node, attr) => { -// expect(graph.getNodeAttribute(node, 'x')).toBeUndefined(); -// expect(graph.getNodeAttribute(node, 'y')).toBeUndefined(); -// }); - -// const layoutFactory = new LayoutFactory(); -// const layout = layoutFactory.createLayout('Graphology_forceAtlas2'); -// layout?.setDimensions(100, 100); -// layout?.layout(graph); - -// graph.forEachNode((node, attr) => { -// expect(graph.getNodeAttribute(node, 'x')).toBeDefined(); -// expect(graph.getNodeAttribute(node, 'y')).toBeDefined(); -// }); -// }); -// }); diff --git a/libs/shared/graph-layouts/src/lib/layout-creator-usecase.ts b/libs/shared/graph-layouts/src/lib/layout-creator-usecase.ts deleted file mode 100644 index 930200eea..000000000 --- a/libs/shared/graph-layouts/src/lib/layout-creator-usecase.ts +++ /dev/null @@ -1,77 +0,0 @@ -import { - Cytoscape, - CytoscapeFactory, - CytoscapeLayoutAlgorithms, - CytoscapeProvider, -} from './cytoscape-layouts'; -import { - Graphology, - GraphologyFactory, - GraphologyLayoutAlgorithms, - GraphologyProvider, -} from './graphology-layouts'; -import { Layout } from './layout'; - -export type Providers = GraphologyProvider | CytoscapeProvider; -export type LayoutAlgorithm<Provider extends Providers> = - `${Provider}_${string}`; - -export type AllLayoutAlgorithms = - | GraphologyLayoutAlgorithms - | CytoscapeLayoutAlgorithms; - -export type AlgorithmToLayoutProvider<Algorithm extends AllLayoutAlgorithms> = - Algorithm extends GraphologyLayoutAlgorithms - ? Graphology - : Algorithm extends CytoscapeLayoutAlgorithms - ? Cytoscape - : Cytoscape | Graphology; - -export interface ILayoutFactory<Algorithm extends AllLayoutAlgorithms> { - createLayout: ( - Algorithm: Algorithm - ) => AlgorithmToLayoutProvider<Algorithm> | null; -} - -/** - * This is our Creator - */ -export class LayoutFactory implements ILayoutFactory<AllLayoutAlgorithms> { - private graphologyFactory = new GraphologyFactory(); - private cytoscapeFactory = new CytoscapeFactory(); - - private isSpecificAlgorithm<Algorithm extends AllLayoutAlgorithms>( - LayoutAlgorithm: AllLayoutAlgorithms, - startsWith: string - ): LayoutAlgorithm is Algorithm { - return LayoutAlgorithm.startsWith(startsWith); - } - - createLayout<Algorithm extends AllLayoutAlgorithms>( - layoutAlgorithm: Algorithm - ): AlgorithmToLayoutProvider<Algorithm> | null { - if ( - this.isSpecificAlgorithm<GraphologyLayoutAlgorithms>( - layoutAlgorithm, - 'Graphology' - ) - ) { - return this.graphologyFactory.createLayout( - layoutAlgorithm - ) as AlgorithmToLayoutProvider<Algorithm>; - } - - if ( - this.isSpecificAlgorithm<CytoscapeLayoutAlgorithms>( - layoutAlgorithm, - 'Cytoscape' - ) - ) { - return this.cytoscapeFactory.createLayout( - layoutAlgorithm - ) as AlgorithmToLayoutProvider<Algorithm>; - } - - return null; - } -} diff --git a/libs/shared/graph-layouts/src/lib/layout.ts b/libs/shared/graph-layouts/src/lib/layout.ts deleted file mode 100644 index 06f4da35e..000000000 --- a/libs/shared/graph-layouts/src/lib/layout.ts +++ /dev/null @@ -1,21 +0,0 @@ -import Graph from 'graphology'; -import { Providers, LayoutAlgorithm } from './layout-creator-usecase'; - -/** - * This is our Product - */ - -export abstract class Layout<provider extends Providers> { - constructor( - public provider: provider, - public algorithm: LayoutAlgorithm<provider> - ) { - console.log( - `Created the following Layout: ${provider} - ${this.algorithm}` - ); - } - - public layout(graph: Graph) { - console.log(`${this.provider} [${this.algorithm}] layouting now`); - } -} diff --git a/libs/shared/graph-layouts/tsconfig.json b/libs/shared/graph-layouts/tsconfig.json deleted file mode 100644 index 47e7fa539..000000000 --- a/libs/shared/graph-layouts/tsconfig.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "extends": "../../../tsconfig.base.json", - "compilerOptions": { - "module": "CommonJS", - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitOverride": true, - "noPropertyAccessFromIndexSignature": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - "composite": true - }, - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.lib.json" - }, - { - "path": "./tsconfig.spec.json" - } - ] -} diff --git a/libs/shared/graph-layouts/tsconfig.lib.json b/libs/shared/graph-layouts/tsconfig.lib.json deleted file mode 100644 index efdd77fbf..000000000 --- a/libs/shared/graph-layouts/tsconfig.lib.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "declaration": true, - "types": [] - }, - "include": ["**/*.ts"], - "exclude": ["**/*.spec.ts"] -} diff --git a/libs/shared/graph-layouts/tsconfig.spec.json b/libs/shared/graph-layouts/tsconfig.spec.json deleted file mode 100644 index cdccf0f19..000000000 --- a/libs/shared/graph-layouts/tsconfig.spec.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "extends": "./tsconfig.json", - "compilerOptions": { - "outDir": "../../../dist/out-tsc", - "module": "commonjs", - "types": ["jest", "node"], - "composite": true - }, - "include": ["**/*.test.ts", "**/*.spec.ts", "**/*.d.ts"] -} diff --git a/libs/shared/graph-layouts/yarn.lock b/libs/shared/graph-layouts/yarn.lock deleted file mode 100644 index 8992e29d7..000000000 --- a/libs/shared/graph-layouts/yarn.lock +++ /dev/null @@ -1,21 +0,0 @@ -# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. -# yarn lockfile v1 - - -events@^3.3.0: - version "3.3.0" - resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" - integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== - -graphology@^0.24.1: - version "0.24.1" - resolved "https://registry.yarnpkg.com/graphology/-/graphology-0.24.1.tgz#035e452e294b01168cf5c85d5dd0a4b7e4837d87" - integrity sha512-6lNz1PNTAe9Q6ioHKrXu0Lp047sgvOoHa4qmP/8mnJWCGv2iIZPQkuHPUb2/OWDWCqHpw2hKgJLJ55X/66xmHg== - dependencies: - events "^3.3.0" - obliterator "^2.0.2" - -obliterator@^2.0.2: - version "2.0.2" - resolved "https://registry.yarnpkg.com/obliterator/-/obliterator-2.0.2.tgz#25f50dc92e1181371b9d8209d11890f1a3c2fc21" - integrity sha512-g0TrA7SbUggROhDPK8cEu/qpItwH2LSKcNl4tlfBNT54XY+nOsqrs0Q68h1V9b3HOSpIWv15jb1lax2hAggdIg== -- GitLab