├── app
├── .electron
│ ├── Cookies-journal
│ ├── Cookies
│ ├── Cache
│ │ ├── data_0
│ │ ├── data_1
│ │ ├── data_2
│ │ ├── data_3
│ │ ├── index
│ │ └── f_00000c
│ └── GPUCache
│ │ ├── data_0
│ │ ├── data_1
│ │ ├── data_2
│ │ ├── data_3
│ │ └── index
├── assets
│ ├── images
│ │ └── pedal.png
│ ├── fonts
│ │ ├── Hasklig-Light.otf
│ │ ├── roboto
│ │ │ ├── Roboto-Bold.eot
│ │ │ ├── Roboto-Bold.ttf
│ │ │ ├── Roboto-Thin.eot
│ │ │ ├── Roboto-Thin.ttf
│ │ │ ├── Roboto-Bold.woff
│ │ │ ├── Roboto-Bold.woff2
│ │ │ ├── Roboto-Light.eot
│ │ │ ├── Roboto-Light.ttf
│ │ │ ├── Roboto-Light.woff
│ │ │ ├── Roboto-Light.woff2
│ │ │ ├── Roboto-Medium.eot
│ │ │ ├── Roboto-Medium.ttf
│ │ │ ├── Roboto-Medium.woff
│ │ │ ├── Roboto-Regular.eot
│ │ │ ├── Roboto-Regular.ttf
│ │ │ ├── Roboto-Thin.woff
│ │ │ ├── Roboto-Thin.woff2
│ │ │ ├── Roboto-Medium.woff2
│ │ │ ├── Roboto-Regular.woff
│ │ │ └── Roboto-Regular.woff2
│ │ ├── Raleway
│ │ │ ├── Raleway-Black.ttf
│ │ │ ├── Raleway-Bold.ttf
│ │ │ ├── Raleway-Light.ttf
│ │ │ ├── Raleway-Thin.ttf
│ │ │ ├── Raleway-Italic.ttf
│ │ │ ├── Raleway-Medium.ttf
│ │ │ ├── Raleway-Regular.ttf
│ │ │ ├── Raleway-BoldItalic.ttf
│ │ │ ├── Raleway-ExtraBold.ttf
│ │ │ ├── Raleway-ExtraLight.ttf
│ │ │ ├── Raleway-SemiBold.ttf
│ │ │ ├── Raleway-ThinItalic.ttf
│ │ │ ├── Raleway-BlackItalic.ttf
│ │ │ ├── Raleway-LightItalic.ttf
│ │ │ ├── Raleway-MediumItalic.ttf
│ │ │ ├── Raleway-ExtraBoldItalic.ttf
│ │ │ ├── Raleway-SemiBoldItalic.ttf
│ │ │ ├── Raleway-ExtraLightItalic.ttf
│ │ │ └── OFL.txt
│ │ └── Julius_Sans_One
│ │ │ ├── JuliusSansOne-Regular.ttf
│ │ │ └── OFL.txt
│ ├── js
│ │ ├── LICENSE
│ │ └── dispersion.js
│ └── css
│ │ └── style.css
├── components
│ ├── partials
│ │ ├── topbar.html
│ │ ├── project-add-bar.html
│ │ ├── publishCard.html
│ │ ├── daemon-load.html
│ │ ├── settings.html
│ │ └── FileHistoryPartial.html
│ ├── directives
│ │ ├── daemon-load-directive.js
│ │ ├── FadeInDirective.js
│ │ ├── topbarDirective.js
│ │ ├── project-directive.js
│ │ ├── publishDirective.js
│ │ ├── settings-directive.js
│ │ └── FileHistoryDirective.js
│ ├── controllers
│ │ ├── settingsController.js
│ │ ├── mainController.js
│ │ ├── filesController.js
│ │ ├── publishController.js
│ │ ├── ProjectController.js
│ │ ├── mockdata.js
│ │ └── FileHistoryController.js
│ └── factories
│ │ ├── FileHistoryFactory.js
│ │ ├── ProjectService.js
│ │ ├── fileFactory.js
│ │ ├── diskFactory.js
│ │ ├── publishService.js
│ │ └── ipfsService.js
├── test
│ ├── ipfsService.spec.js
│ ├── ipfsservicetest.js
│ ├── spectrontest.js
│ └── errorlog.txt
├── bower.json
├── app.js
├── main.js
├── package.json
├── karma.conf.js
└── index.html
├── todolist
├── .vscode
└── settings.json
├── test.html
├── .gitignore
├── LICENSE
├── README.md
└── test.css
/app/.electron/Cookies-journal:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/todolist:
--------------------------------------------------------------------------------
1 | persisitpublished state on project
2 | mark on files page published with icon
3 |
--------------------------------------------------------------------------------
/app/.electron/Cookies:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/.electron/Cookies
--------------------------------------------------------------------------------
/app/.electron/Cache/data_0:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/.electron/Cache/data_0
--------------------------------------------------------------------------------
/app/.electron/Cache/data_1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/.electron/Cache/data_1
--------------------------------------------------------------------------------
/app/.electron/Cache/data_2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/.electron/Cache/data_2
--------------------------------------------------------------------------------
/app/.electron/Cache/data_3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/.electron/Cache/data_3
--------------------------------------------------------------------------------
/app/.electron/Cache/index:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/.electron/Cache/index
--------------------------------------------------------------------------------
/app/assets/images/pedal.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/images/pedal.png
--------------------------------------------------------------------------------
/app/.electron/GPUCache/data_0:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/.electron/GPUCache/data_0
--------------------------------------------------------------------------------
/app/.electron/GPUCache/data_1:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/.electron/GPUCache/data_1
--------------------------------------------------------------------------------
/app/.electron/GPUCache/data_2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/.electron/GPUCache/data_2
--------------------------------------------------------------------------------
/app/.electron/GPUCache/data_3:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/.electron/GPUCache/data_3
--------------------------------------------------------------------------------
/app/.electron/GPUCache/index:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/.electron/GPUCache/index
--------------------------------------------------------------------------------
/app/assets/fonts/Hasklig-Light.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/Hasklig-Light.otf
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | // Place your settings in this file to overwrite default and user settings.
2 | {
3 | "editor.fontSize": 15,
4 | }
--------------------------------------------------------------------------------
/app/assets/fonts/roboto/Roboto-Bold.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/roboto/Roboto-Bold.eot
--------------------------------------------------------------------------------
/app/assets/fonts/roboto/Roboto-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/roboto/Roboto-Bold.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/roboto/Roboto-Thin.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/roboto/Roboto-Thin.eot
--------------------------------------------------------------------------------
/app/assets/fonts/roboto/Roboto-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/roboto/Roboto-Thin.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/Raleway/Raleway-Black.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/Raleway/Raleway-Black.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/Raleway/Raleway-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/Raleway/Raleway-Bold.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/Raleway/Raleway-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/Raleway/Raleway-Light.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/Raleway/Raleway-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/Raleway/Raleway-Thin.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/roboto/Roboto-Bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/roboto/Roboto-Bold.woff
--------------------------------------------------------------------------------
/app/assets/fonts/roboto/Roboto-Bold.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/roboto/Roboto-Bold.woff2
--------------------------------------------------------------------------------
/app/assets/fonts/roboto/Roboto-Light.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/roboto/Roboto-Light.eot
--------------------------------------------------------------------------------
/app/assets/fonts/roboto/Roboto-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/roboto/Roboto-Light.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/roboto/Roboto-Light.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/roboto/Roboto-Light.woff
--------------------------------------------------------------------------------
/app/assets/fonts/roboto/Roboto-Light.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/roboto/Roboto-Light.woff2
--------------------------------------------------------------------------------
/app/assets/fonts/roboto/Roboto-Medium.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/roboto/Roboto-Medium.eot
--------------------------------------------------------------------------------
/app/assets/fonts/roboto/Roboto-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/roboto/Roboto-Medium.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/roboto/Roboto-Medium.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/roboto/Roboto-Medium.woff
--------------------------------------------------------------------------------
/app/assets/fonts/roboto/Roboto-Regular.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/roboto/Roboto-Regular.eot
--------------------------------------------------------------------------------
/app/assets/fonts/roboto/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/roboto/Roboto-Regular.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/roboto/Roboto-Thin.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/roboto/Roboto-Thin.woff
--------------------------------------------------------------------------------
/app/assets/fonts/roboto/Roboto-Thin.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/roboto/Roboto-Thin.woff2
--------------------------------------------------------------------------------
/app/assets/fonts/Raleway/Raleway-Italic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/Raleway/Raleway-Italic.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/Raleway/Raleway-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/Raleway/Raleway-Medium.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/Raleway/Raleway-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/Raleway/Raleway-Regular.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/roboto/Roboto-Medium.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/roboto/Roboto-Medium.woff2
--------------------------------------------------------------------------------
/app/assets/fonts/roboto/Roboto-Regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/roboto/Roboto-Regular.woff
--------------------------------------------------------------------------------
/app/assets/fonts/roboto/Roboto-Regular.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/roboto/Roboto-Regular.woff2
--------------------------------------------------------------------------------
/app/assets/fonts/Raleway/Raleway-BoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/Raleway/Raleway-BoldItalic.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/Raleway/Raleway-ExtraBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/Raleway/Raleway-ExtraBold.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/Raleway/Raleway-ExtraLight.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/Raleway/Raleway-ExtraLight.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/Raleway/Raleway-SemiBold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/Raleway/Raleway-SemiBold.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/Raleway/Raleway-ThinItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/Raleway/Raleway-ThinItalic.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/Raleway/Raleway-BlackItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/Raleway/Raleway-BlackItalic.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/Raleway/Raleway-LightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/Raleway/Raleway-LightItalic.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/Raleway/Raleway-MediumItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/Raleway/Raleway-MediumItalic.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/Raleway/Raleway-ExtraBoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/Raleway/Raleway-ExtraBoldItalic.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/Raleway/Raleway-SemiBoldItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/Raleway/Raleway-SemiBoldItalic.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/Raleway/Raleway-ExtraLightItalic.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/Raleway/Raleway-ExtraLightItalic.ttf
--------------------------------------------------------------------------------
/app/assets/fonts/Julius_Sans_One/JuliusSansOne-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Dispersionjs/Dispersion/HEAD/app/assets/fonts/Julius_Sans_One/JuliusSansOne-Regular.ttf
--------------------------------------------------------------------------------
/app/components/partials/topbar.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/components/directives/daemon-load-directive.js:
--------------------------------------------------------------------------------
1 | angular.module('daemonDirective', [])
2 |
3 | .directive('daemonLoad', function() {
4 | return {
5 | restrict: 'E',
6 | transclude: true,
7 | scope: false,
8 | templateUrl: 'components/partials/daemon-load.html',
9 | replace: true
10 | };
11 | })
--------------------------------------------------------------------------------
/app/components/directives/FadeInDirective.js:
--------------------------------------------------------------------------------
1 |
2 | angular.module('FadeInEffect', [])
3 | .directive('fadeInEffect', function () {
4 | return {
5 | restrict: 'A',
6 | link: function ($scope, element) {
7 | var duration = 800;
8 | $(element).fadeIn(duration);
9 | }
10 | };
11 | })
12 |
13 |
--------------------------------------------------------------------------------
/app/components/directives/topbarDirective.js:
--------------------------------------------------------------------------------
1 | angular.module('topbarDirective', [])
2 |
3 | .directive('topBar', function() {
4 | return {
5 | restrict: 'E',
6 | transclude: true,
7 | controller: 'FilesController',
8 | scope: false,
9 | templateUrl: 'components/partials/topbar.html',
10 | replace: true
11 | };
12 | })
13 |
--------------------------------------------------------------------------------
/app/test/ipfsService.spec.js:
--------------------------------------------------------------------------------
1 |
2 | describe('IpfsService', function () {
3 | var ipfsService;
4 | beforeEach(angular.mock.module('ipfsService'));
5 |
6 | beforeEach(inject(function (_ipfsService_) {
7 | ipfsService = _ipfsService_;
8 | }));
9 |
10 | it('should be', function () {
11 | expect(ipfsService).to.be.a('Object');
12 | });
13 |
14 | })
--------------------------------------------------------------------------------
/app/components/directives/project-directive.js:
--------------------------------------------------------------------------------
1 | angular.module('projectDirective', [])
2 |
3 | .directive('projectAddBar', function () {
4 | return {
5 | restrict: 'E',
6 | transclude: true,
7 | controller: 'PublishController',
8 | controllerAs: 'pubCtrl',
9 |
10 | templateUrl: 'components/partials/project-add-bar.html',
11 | replace: true
12 | }
13 | })
--------------------------------------------------------------------------------
/app/components/directives/publishDirective.js:
--------------------------------------------------------------------------------
1 | angular.module('publishDirective', ['PublishController'])
2 |
3 |
4 | .directive('publishCard', function () {
5 | return {
6 | restrict: 'E',
7 | transclude: true,
8 | controller: 'PublishController',
9 | controllerAs: 'pubCtrl',
10 | scope: false,
11 | templateUrl: 'components/partials/publishCard.html',
12 | replace: true
13 | };
14 | })
--------------------------------------------------------------------------------
/app/test/ipfsservicetest.js:
--------------------------------------------------------------------------------
1 | var benv = require('benv');
2 |
3 |
4 |
5 | describe('calc module', function () {
6 | beforeEach(function setupEnvironment(done) {
7 | benv.setup(function () {
8 | benv.expose({
9 | angular: benv.require('../node_modules/angular/angular.js', 'angular')
10 | });
11 | done();
12 | });
13 | });
14 | // more stuff will go here
15 | afterEach(function destroySyntheticBrowser() {
16 | console.log("distroy")
17 | benv.teardown(true);
18 | });
19 | });
20 |
21 | console.log("In IPFS test!")
--------------------------------------------------------------------------------
/app/components/directives/settings-directive.js:
--------------------------------------------------------------------------------
1 | angular.module('settingsDirective', [])
2 |
3 | .directive('settings', function () {
4 | return {
5 | restrict: 'E',
6 | transclude: true,
7 | controller: 'SettingsController',
8 | controllerAs: 'settingsCtrl',
9 | link: function (scope, element, attribute) {
10 | $('.collapsible').collapsible({ accordion: false });
11 | // A setting that changes the collapsible behavior to expandable instead of the default accordion style
12 | },
13 | scope: false,
14 | templateUrl: 'components/partials/settings.html',
15 | replace: true
16 | };
17 | })
--------------------------------------------------------------------------------
/app/components/partials/project-add-bar.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/components/directives/FileHistoryDirective.js:
--------------------------------------------------------------------------------
1 |
2 | angular.module('FileHistoryDirective', ['FileHistoryController'])
3 |
4 | .directive('fileHistory', function () {
5 | return {
6 | restrict: 'E',
7 | transclude: true,
8 | scope: {
9 | index: '@',
10 | filename: '@',
11 | projectname: '@',
12 | projectobject: '@',
13 | mode: '@'
14 | },
15 | // link: function (scope) {
16 | // scope.updateEditorContent();
17 | // scope.recordIndex();
18 | // scope.toggleShowInfo();
19 | // },
20 | controller: 'FileHistoryController',
21 | templateUrl: 'components/partials/FileHistoryPartial.html',
22 | replace: true
23 | };
24 | })
--------------------------------------------------------------------------------
/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | -
14 | info_outline
15 |
16 |
17 |
18 |
19 | - time
20 | - hash
21 | - url
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/app/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dispersion",
3 | "description": "Electron based interface for ipfs",
4 | "main": "main.js",
5 | "authors": [
6 | "Dispersion"
7 | ],
8 | "license": "MIT",
9 | "keywords": [
10 | "electron",
11 | "ipfs"
12 | ],
13 | "homepage": "https://github.com/waggertron/Dispersion",
14 | "ignore": [
15 | "**/.*",
16 | "node_modules",
17 | "bower_components",
18 | "test",
19 | "tests"
20 | ],
21 | "dependencies": {
22 | "angular": "^1.5.8",
23 | "jquery": "^3.1.1",
24 | "angular-ui-ace": "^0.2.3",
25 | "materialize": "^0.97.7",
26 | "hammerjs": "^2.0.8",
27 | "angular-materialize": "^0.2.1",
28 | "angular-animate": "^1.5.8",
29 | "angular-aria": "^1.5.8",
30 | "angular-messages": "^1.5.8",
31 | "material-design-icons": "^3.0.1"
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/components/controllers/settingsController.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('SettingsController', [])
3 | //passing $scope and UserFactory as dependencies to controller
4 |
5 | .controller('SettingsController', ['IpfsService', SettingsController]);
6 | function SettingsController(IpfsService) {
7 | const self = this;
8 | self.activated = true;
9 | self.loadConfig = function () {
10 | IpfsService.getSettingsInfo().then(function (data) {
11 | self.peerID = data[0]
12 | self.bootStrapList = data[1]
13 | self.multiAddr = data[2]
14 | self.ipfsVersion = data[3]
15 | })
16 |
17 | }
18 | self.hashPeers = false;
19 | self.checkHealth = function (hash) {
20 | IpfsService.findProviders(hash).then(function (data) {
21 | console.log('theData', data)
22 | self.health = data.length;
23 | self.hashPeers = true;
24 | })
25 | }
26 |
27 | self.addPeer = function (address) {
28 | IpfsService.addPeer(address).then(function (data) {
29 | });
30 | }
31 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # nyc test coverage
18 | .nyc_output
19 |
20 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
21 | .grunt
22 |
23 | # node-waf configuration
24 | .lock-wscript
25 |
26 | # Compiled binary addons (http://nodejs.org/api/addons.html)
27 | build/Release
28 |
29 | # Dependency directories
30 | node_modules
31 | jspm_packages
32 | bower_components
33 |
34 |
35 | # Optional npm cache directory
36 | .npm
37 |
38 | # Optional REPL history
39 | .node_repl_history
40 |
41 | #files saved locally from electron apllication by user.
42 | savedfiles
43 | projectFolder
44 |
45 | #Apple files
46 | .DS_Store
47 |
48 | #local hash storage
49 | *data.json
50 |
51 | #from build
52 | app/appe-darwin-x64/
53 |
54 |
55 |
--------------------------------------------------------------------------------
/app/test/spectrontest.js:
--------------------------------------------------------------------------------
1 | var Application = require('spectron').Application;
2 | var assert = require('assert');
3 | var path = require("path");
4 | var appPath = path.resolve(__dirname, '../'); //require the whole thing
5 | var electronPath = path.resolve(__dirname, '../node_modules/.bin/electron');
6 | var expect = require('chai').expect;
7 | var chai = require('chai');
8 | var chaiAsPromised = require('chai-as-promised');
9 | //require('fluentnode')
10 | //var helpers = require('./global-setup')
11 |
12 |
13 | describe('application launch', function () {
14 | this.timeout(10000)
15 |
16 | beforeEach(function () {
17 | this.app = new Application({
18 | path: electronPath,
19 | args: [appPath]
20 | })
21 | return this.app.start()
22 | })
23 |
24 | afterEach(function () {
25 | if (this.app && this.app.isRunning()) {
26 | return this.app.stop()
27 | }
28 | })
29 |
30 | it('shows an initial window', function () {
31 | return this.app.client.getWindowCount().then(function (count) {
32 | assert.equal(count, 1)
33 | })
34 | })
35 | })
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016 Dispersionjs
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/app/assets/js/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014-2016 Materialize
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/app/app.js:
--------------------------------------------------------------------------------
1 | const childProcess = require('child_process');
2 | const exec = childProcess.exec;
3 | const spawn = childProcess.spawn;
4 | const storage = require('electron-json-storage');
5 | const fs = require('fs');
6 | const readChunk = require('read-chunk'); // npm install read-chunk
7 | const fileType = require('file-type');
8 | const https = require('https');
9 | const request = require('request');
10 | const username = require('username');
11 | const fse = require('fs-extra');
12 | const path = require('path');
13 | const {dialog} = require('electron').remote;
14 |
15 | angular.module('myApp', [
16 | 'topbarDirective',
17 | 'publishDirective',
18 | 'daemonDirective',
19 | 'settingsDirective',
20 | 'FileFactory',
21 | 'PublishService',
22 | 'MainController',
23 | 'DiskFactory',
24 | 'IpfsService',
25 | 'FilesController',
26 | 'PublishController',
27 | 'SettingsController',
28 | 'ui.ace',
29 | 'ProjectService',
30 | 'ProjectController',
31 | 'FileHistoryDirective',
32 | 'FadeInEffect',
33 | 'FileHistoryController',
34 | 'FileHistoryFactory',
35 | 'ui.materialize'
36 | ])
37 | .config(['$sceProvider', function ($sceProvider) {
38 | $sceProvider.enabled(false);
39 | }])
40 | .controller('ViewController', [viewController])
41 | function viewController() {
42 | const self = this;
43 | self.view = 'loading';
44 | self.changeView = function (view) {
45 | self.view = view;
46 | }
47 | }
48 |
49 |
--------------------------------------------------------------------------------
/app/components/partials/publishCard.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
{{projectName}}
8 |
Date added: {{value[0].date}}
9 |
10 |
11 |
mode_edit
12 |
13 |
14 |
done_allcurrently published
15 |
add
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | ## Dispersion
5 |
6 | A desktop application that allows users to save files on their IPFS local node.
7 |
8 | ##Getting Started
9 |
10 | Please install IPFS before using Dispersion. You can download IPFS from the following link: https://ipfs.io/docs/install/
11 |
12 |
13 | Installation
14 | ------------
15 |
16 | ```
17 | git clone https://github.com/Dispersionjs/Dispersion.git
18 | cd Dispersion/app
19 | npm run install:dispersion
20 | npm start
21 | ```
22 |
23 |
24 | ## Dashboard Page
25 |
26 | This page is used to view and add files or entire applications to IPFS.
27 | These files can then be staged for publish, downloaded or deleted from Dispersion.
28 |
29 | ## Publish
30 |
31 | Once a file is staged it appears on the publish page, where it can then be publish to your ipfs node's fixed IPNS.
32 | Selecting the + icon will publish to your IPNS. This can be mapped to a specific domain name.
33 |
34 | When selecting the pencil icon, the user can edit and save individual project files as well as manage a complete version history.
35 |
36 |
37 | ## Settings
38 |
39 | The settings can be accessed by clicking the gear icon in the top right corner of the application.
40 |
41 | The settings displays the users peerID, and MultAddr address(used to allow peers to add you to their trusted bootstrap list). It also allows you to add peers to your list as well as check the health of any content on ipfs, by displaying the number of nodes that have pinned the content.
42 |
--------------------------------------------------------------------------------
/app/test/errorlog.txt:
--------------------------------------------------------------------------------
1 | lookup error: failed to bind to any unicat udp port
2 | on adding large folder (1 gb) worked on second retry, should attempt to readd after wait period, alert user
3 | ll data from LOCAL STORAGE [Object, Object]
4 | >>>>>>ipfsService.js:22 [0;37m12:12:31.116 [31mERROR [0;34mcommands/h: [0merr: multipart: unexpected line in Next(): "(\x82h\xa0Q\xefh,\xaev\x1c\xe6\x87Ē~n\u007f8=9\xc7\r\xc1\xbc\xf1k\xec\xfa?V,\x14\xacs\t\xe3.\x10*\xb9\x94\x02O?\x12w\x85\xdco\u05fb\xc9{J\xebʽg\xf5=5u\xe64>z/\xf9m\xc3A\x16\xaaٛ\xd9\xcbqQ76ɴ\x9a7\xad<\xdb\x16\xa0u\xc1N%Źw4@L\x9fu\xb1.z\x8e\xc0\xa9`\"\xd5%d\xb1*\xd2\xfec\xed\xe0W\xea,\xabQ\x98\x8c\x9f\x1fP\x0eΞս\xb5\x9c \xf7\xf1)ڗ\xf8\x81,Rro\xb1l\xc4L\x9cE\x06\f\xe3bմ\x85\x06̸u\xbf\x86\xa3'\xd4C\xe6\xf3?8\xee-\xa9\xcf#\x10\xe4\x10?Q\x90\xac\xec\xe0e\x155\xc0\xa8\xdc\xf4.Y1\x9d\xaf\xfd\xb0E\x96\xcb\xc9<\xac\b\x93\"\xe4\xdd\x1e\x17\x05=\x80\aH[\xe3\xcdb\x84Q\x8c\x9b\x8b\x1dzrOW\xc4\x00m|\x98\x80\xa0\x88\x8d-\xc63\xea\xe6\xe95\xb0\x18\x11\x99\xe9\x1eXr\xbc\xad\xe2\x84\xdbf\x99u\xb0\x90\xb2Aw\x89\xe1+Lv\x97`\xfe\xff\xadk\xb2\x1f\x87G\vg(\x11]8\xecp\xebn\x0f\xd8\u007f\x9c\xe3eCx\xbb\xf4]\x88\xf6)\xce;\xe1\u007f\xdc\xdcG\x97\x19\xb9Է\xad'\x9e\xc0V\xee~4\xbe=0GӒM\uf680\xe9\xb8\\\xab\xa9\xd9 b\x8f$\xa9\x14\xac[!\xc8\fX\xd5\xf7\f\x1a\x1f\x13\xf4\v=\xc5O\x89m\xf4ƌ\xd36\xe3h\x8f\x81\xec\x9cl\x90\xd4\x03 \"K\xa8-L\xbb\x89\xa7\x9f\xfb\x1b۹e\x16\x99\xf0\x19\xb3\xa8\x04\x11\xfa7Sa\x92\xa3u\xa2n\xe1\x0em\xbb\x8ck2\xb1\v\xf9\xdd\xd3\xe3\xc6x2\xbc\xf8I\x1d\xdc\b\x9b\x10\n" [0;37mhandler.go:288[0m
5 | ipfsService.js:22 [0;37m12:12:34.765 [31mERROR [0;34m mdns: [0mmdns lookup error: failed to bind to any unicast udp port [0;37mmdns.go:131[0m
--------------------------------------------------------------------------------
/app/components/controllers/mainController.js:
--------------------------------------------------------------------------------
1 |
2 | angular
3 | .module('MainController', [])
4 | //passing $scope and UserFactory as dependencies to controller
5 | .controller('MainController', ['$scope', 'PublishService', 'FileFactory', 'DiskFactory', 'IpfsService', '$timeout', 'FileHistoryFactory', mainController]);
6 |
7 | function mainController($scope, PublishService, FileFactory, DiskFactory, IpfsService, $timeout, FileHistoryFactory) {
8 | //load publish object when switching to publish page
9 | const self = this;
10 | let secondAttempt = false;
11 | self.startApp = () => {
12 | IpfsService.init()
13 | .then((daemonStatus) => {
14 | self.daemonStatus = daemonStatus;
15 | return FileFactory.init()
16 | })
17 | .then(DiskFactory.init)
18 | .then(PublishService.init)
19 | .then(FileHistoryFactory.init)
20 | .then(() => {
21 | $timeout(() => {
22 | self.view = 'files';
23 | }, 500);
24 | })
25 | .catch((error) => {
26 | // $timeout(() => {
27 | // if (error && self.view !== 'files' && !secondAttempt) {
28 | // secondAttempt = true;
29 | // console.log('error in mainController.startApp, will attempt retry');
30 | // } else {
31 | // console.log('unable to load')
32 | // //add error view
33 | // }
34 | // }, 5000);
35 | console.error(error);
36 |
37 | });
38 | }
39 | // PublishService.init().then(
40 |
41 | // )
42 | // IpfsService.init().then((data) => {
43 |
44 | // console.log('daemondata', data)
45 | // self.daemonStatus = data;
46 | // });
47 | // DiskFactory.init();
48 | // FileFactory.init();
49 | // self.view = 'files';
50 | self.startApp();
51 | }
52 |
53 |
--------------------------------------------------------------------------------
/test.css:
--------------------------------------------------------------------------------
1 |
2 |
3 | ul li {
4 | cursor: pointer;
5 | -webkit-transition: padding .05s linear;
6 | transition: padding .05s linear;
7 | }
8 | ul li.drop {
9 | position: relative;
10 | }
11 | ul > li {
12 | display: inline-block;
13 | }
14 | ul li a {
15 | line-height: 80px;
16 | padding: 0 20px;
17 | height: 80px;
18 | color: #777;
19 | -webkit-transition: all .3s ease-out;
20 | transition: all .3s ease-out;
21 | }
22 | ul li a:hover {
23 | color: #eee;
24 | }
25 |
26 | .dropOut .triangle {
27 | width: 0;
28 | height: 0;
29 | position: absolute;
30 | border-left: 8px solid transparent;
31 | border-right: 8px solid transparent;
32 | border-bottom: 8px solid #000;
33 | top: -8px;
34 | left: 50%;
35 | margin-left: -8px;
36 | }
37 | .dropdownContain {
38 | width: 160px;
39 | position: absolute;
40 | z-index: 2;
41 | left: 50%;
42 | margin-left: -80px; /* half of width */
43 | top: -400px;
44 | }
45 | .dropOut {
46 | width: 160px;
47 | background: white;
48 | float: left;
49 | position: relative;
50 | margin-top: 0px;
51 | opacity: 0;
52 | border-radius: 4px;
53 | box-shadow: 0 1px 6px rgba(37, 126, 176, 0.15);
54 | -webkit-transition: all .3s ease-out;
55 | transition: all .3s ease-out;
56 | }
57 |
58 | .dropOut ul {
59 | float: left;
60 | padding: 10px 0;
61 | }
62 | .dropOut ul li {
63 | text-align: left;
64 | float: left;
65 | width: 125px;
66 | padding: 12px 0 10px 15px;
67 | margin: 0px 10px;
68 | color: #777;
69 | -webkit-border-radius: 4px;
70 | border-radius: 4px;
71 | -webkit-transition: background .3s ease-out;
72 | transition: background .3s ease-out;
73 | }
74 |
75 | .dropOut ul .mat:hover {
76 | background: #f6f6f6;
77 | }
78 |
79 | /*ul li:hover a { color: rgb(74, 122, 194); }
80 | ul li:hover .dropdownContain { top: 65px; }
81 | ul li:hover .underline { border-bottom-color: #777; }*/
82 | ul li:hover .dropOut { opacity: 1; margin-top: 8px; }
83 |
--------------------------------------------------------------------------------
/app/components/controllers/filesController.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('FilesController', [])
3 | //passing $scope and UserFactory as dependencies to controller
4 | .controller('FilesController', ['FileFactory', 'PublishService', 'DiskFactory', 'IpfsService', 'FileHistoryFactory', FilesController]);
5 |
6 | function FilesController(FileFactory, PublishService, DiskFactory, IpfsService, FileHistoryFactory) {
7 |
8 | const self = this;
9 | self.sortBy = 'time';
10 | //get Username of local user. Used for file saving
11 | username().then(username => {
12 | self.username = username;
13 | });
14 | self.files = FileFactory.data;
15 | self.getFileData = FileFactory.getFileData
16 | //shows additional info about pinned file
17 | self.showInfo = function (index) {
18 | $(`#sel-option${index}`).show();
19 | }
20 |
21 | self.addHash = FileFactory.addHash;
22 | self.formatDate = function (date) {
23 | let dateOut = new Date(date);
24 | return dateOut;
25 | };
26 |
27 | self.deleteHash = function (hash, index) {
28 | Materialize.toast("File Deleted!", 2000);
29 | IpfsService.unPin(hash);
30 | FileFactory.removeFile(index);
31 | }
32 |
33 | self.addToPublish = function (value) {
34 | Materialize.toast("Staged for Publish!", 2000);
35 | console.log('in add to publish, value: ', value);
36 | DiskFactory.addProject(value.pathToFile);
37 | PublishService.add({
38 | [value.file]: [{
39 | 'date': value.date,
40 | 'hash': value.hash,
41 | 'publish': true,
42 | 'changed': null,
43 | 'url': value.url,
44 | 'files': value.files
45 | }]
46 | });
47 | //initial add of all files to FileVersionHistory
48 | FileHistoryFactory.initialAdd(value.date, value.url, value.hash, value.files, value.file);
49 |
50 | // date, url, hash, filesArray, projectName
51 |
52 | }
53 |
54 | self.getIframeUrl = function (fileObj, fileName) {
55 | return fileObj + fileName;
56 | }
57 |
58 | }
--------------------------------------------------------------------------------
/app/main.js:
--------------------------------------------------------------------------------
1 | const electron = require('electron')
2 |
3 | // Module to control application life.
4 | const app = electron.app
5 | // Module to create native browser window.
6 | const BrowserWindow = electron.BrowserWindow
7 |
8 |
9 |
10 | // Keep a global reference of the window object, if you don't, the window will
11 | // be closed automatically when the JavaScript object is garbage collected.
12 | let mainWindow
13 |
14 | function createWindow() {
15 | // Create the browser window.
16 | mainWindow = new BrowserWindow({
17 | width: 1200,
18 | height: 800
19 | })
20 |
21 | // and load the index.html of the app.
22 | mainWindow.loadURL(`file://${__dirname}/index.html`)
23 |
24 | // Open the DevTools.
25 | // mainWindow.webContents.openDevTools()
26 | // Emitted when the window is closed.
27 | mainWindow.on('closed', function () {
28 | // Dereference the window object, usually you would store windows
29 | // in an array if your app supports multi windows, this is the time
30 | // when you should delete the corresponding element.
31 | mainWindow = null
32 | })
33 | }
34 | // app.clearCache(callback)
35 |
36 |
37 | // This method will be called when Electron has finished
38 | // initialization and is ready to create browser windows.
39 | // Some APIs can only be used after this event occurs.
40 | app.on('ready', createWindow)
41 | console.log(app.getPath('userData'))
42 | // app.getPath(('userData') + '/Cache')
43 | // Quit when all windows are closed.
44 | app.on('window-all-closed', function () {
45 | // On OS X it is common for applications and their menu bar
46 | // to stay active until the user quits explicitly with Cmd + Q
47 | if (process.platform !== 'darwin') {
48 | app.quit()
49 | }
50 | })
51 |
52 | app.on('activate', function () {
53 | // On OS X it's common to re-create a window in the app when the
54 | // dock icon is clicked and there are no other windows open.
55 | if (mainWindow === null) {
56 | createWindow()
57 | }
58 | })
59 |
--------------------------------------------------------------------------------
/app/components/controllers/publishController.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('PublishController', [])
3 | //passing $scope and UserFactory as dependencies to controller
4 |
5 | .controller('PublishController', ['PublishService', 'IpfsService', 'DiskFactory', 'ProjectService', PublishController]);
6 |
7 | function PublishController(PublishService, IpfsService, DiskFactory, ProjectService) {
8 | // PublishService.init().then(console.log('init called in publish controller'))
9 | const self = this;
10 | self.data = PublishService.data;
11 | self.currentlyPublished = PublishService.currentlyPublished;
12 | self.setAsPublished = PublishService.setPublished;
13 | self.isPublished = function (projectName) {
14 | return self.currentlyPublished() === projectName;
15 | }
16 | self.setProjectView = function (projectName) {
17 | console.log('setting project view for: ', projectName)
18 | ProjectService.changeSelectedProject(projectName)
19 | }
20 |
21 | // self.addPubDataOnEdit = function (pubObj, projectName) {
22 | // console.log('when clicked edit, adding this to published:', pubObj)
23 | // pubObj[0].publish = true;
24 | // PublishService.unshiftForEditFix(pubObj[0], projectName)
25 | // ProjectService.changeSelectedProject(projectName)
26 | // }
27 |
28 |
29 |
30 | self.publishToIpfs = function (value, name) {
31 | console.log('value, name in publish to ipfs called from publish controller', value, name)
32 | // self.publishedProjectCard = name;
33 | self.setAsPublished(name);
34 | ProjectService.changeSelectedProject(name);
35 | IpfsService.publish(value, name)
36 | // PublishService.add(value, true, name);
37 | }
38 |
39 | // self.activeButton = function (value) {
40 | // console.log('value passed to active button', value);
41 | // console.log('self.data: ', self.data);
42 | // self.currentlyPublished = value;
43 | // for (let key in self.data) {
44 | // if (self.data[key].toggled && self.data[key] !== value) {
45 | // self.data[key].toggled = false
46 | // }
47 | // }
48 | // value.toggled = !value.toggled;
49 | // }
50 | // self.addProject = DiskFactory.addProject;
51 | // self.overwrite = DiskFactory.overwrite;
52 | // self.delete = DiskFactory.delete;
53 |
54 | }
55 |
56 |
--------------------------------------------------------------------------------
/app/components/factories/FileHistoryFactory.js:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | angular.module('FileHistoryFactory', [])
8 | .factory('FileHistoryFactory', ['ProjectService', '$q', 'IpfsService', '$timeout', fileHistoryFactory])
9 |
10 | function fileHistoryFactory(ProjectService, $q, IpfsService, $timeout) {
11 | var historyData = {}
12 | function init() {
13 | return $q((resolve, reject) => {
14 | storage.get('fileVersions', (error, data) => {
15 | if (error) reject(error)
16 | console.log('file version data from local storage in init', data);
17 | for (let key in data) {
18 | historyData[key] = data[key]
19 | }
20 | resolve(data)
21 | // if (error) reject(error)
22 | //update history array
23 |
24 | })
25 |
26 | });
27 | }
28 | function getFileHistory() {
29 | return historyData
30 | }
31 |
32 | function updateLocalStorage() {
33 | storage.set('fileVersions', historyData)
34 | }
35 |
36 |
37 | function addFileVersion(fileVersionObj, projectName) {
38 | console.log('addFileVersion called in fileHistoryFactory, fileVersionObj, projectname: \n', fileVersionObj, projectName);
39 | historyData[projectName].push(fileVersionObj);
40 | $timeout((updateLocalStorage), 5000);
41 | }
42 | function addInitialFileVersionOnPublish(date, url, hash, filesArray, projectName) {
43 | console.log('addintila file version on publish, passed in args: ', ...arguments)
44 | if (!historyData[projectName]) {
45 | historyData[projectName] = [];
46 | filesArray.forEach((filename, index) => {
47 | historyData[projectName].push({
48 | date: date,
49 | url: url + filename,
50 | hash: hash,
51 | file: filename
52 | })
53 | console.log(`item #${index} added: `, {
54 | date: date,
55 | url: url + filename,
56 | hash: hash,
57 | file: filename
58 | });
59 | })
60 | updateLocalStorage()
61 | }
62 | // historyData[projectName].push(fileVersionObj);
63 | // $timeout((updateLocalStorage), 2000);
64 | }
65 |
66 | return {
67 | fileHistory: historyData,
68 | getFileHistory: getFileHistory,
69 | add: addFileVersion,
70 | init: init,
71 | initialAdd: addInitialFileVersionOnPublish
72 | };
73 | }
74 |
--------------------------------------------------------------------------------
/app/components/factories/ProjectService.js:
--------------------------------------------------------------------------------
1 |
2 | angular.module('ProjectService', [])
3 | .service('ProjectService', ['$http', '$q', 'PublishService', projectService]);
4 |
5 |
6 | function projectService($http, $q, PublishService) {
7 | /**returns length -1 of currently selected project data array */
8 | const self = this;
9 | self.init = () => {
10 | $q((resolve, reject) => {
11 | storage.get('currentlyPublished', (error, data) => {
12 | if (error) reject(error);
13 | resolve(data);
14 | })
15 | })
16 | }
17 | // self.publishedArrayLength = () => self.publishedProjectVersions().length - 1;
18 | /** returns all published event objects from the projectArray history */
19 | self.publishedProjectVersions = () => {
20 | if (!PublishService.data || !PublishService.data[self.selected]) return [];
21 | return PublishService.data[self.selected].filter((pubObj) => {
22 | return pubObj.publish === true;
23 | })
24 | }
25 |
26 | /** returns the url of the currently selected project version */
27 | self.currentUrl = (file) => {
28 | if (!file) {
29 | return self.selectedVersion().url;
30 | } else {
31 | return self.selectedVersion().url
32 | }
33 | }
34 |
35 |
36 | //should refactor self one \/
37 | /** returns a string that was the last changed file of the publish event */
38 | // self.currentFile = () => self.selectedVersion.changed;
39 | // self.currentFileType = () => self.currentFile();
40 |
41 | self.changeSelectedVersion = (index) => {
42 | //will need to change to account for unpublished projects
43 | //
44 | self.currentIndex = index;
45 | // self.selectedVersion = self.publishedProjectVersions.length === 1 ? self.publishedProjectVersions()[self.publishedArrayLength() - index] : null;
46 |
47 | }
48 |
49 | self.getContentUrl = () => {
50 | return self.currentUrl() + self.currentFile();
51 | }
52 | self.changeSelectedProject = (projectName) => { self.selected = projectName }
53 | self.currentIndex = 0;
54 | self.selectedVersionFilesList = () => self.selectedVersion().files;
55 | self.selected = '';
56 | self.currentProject = () => self.selected;
57 | self.selectedVersion = () => {
58 | if (!self.publishedProjectVersions()) return [];
59 | return self.publishedProjectVersions()[self.currentIndex];
60 | }
61 | }
--------------------------------------------------------------------------------
/app/components/partials/daemon-load.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
24 |
25 |
Spinning Up Local Daemon
26 |
27 |
--------------------------------------------------------------------------------
/app/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "dispersion",
3 | "version": "1.0.0",
4 | "description": "Electron based interface for ipfs",
5 | "main": "main.js",
6 | "scripts": {
7 | "test": "mocha test",
8 | "start": "electron .",
9 | "clean": "rm -rf ./dist",
10 | "install:dispersion": "npm install && ./node_modules/bower/bin/bower install",
11 | "clean:osx": "rm -rf ./dist/osx",
12 | "pack": "npm run clean:osx && electron-packager . \"EA Todo\" --out=dist/osx --platform=darwin --arch=x64 --version=0.36.2 --icon=assets/osx/logo.icns --ignore=dist --ignore=assets --ignore=builder.json --ignore=bower.json --ignore=README.md --ignore=.gitignore --ignore=preview.png",
13 | "build": "npm run pack:osx && electron-builder \"dist/osx/EA Todo-darwin-x64/EA Todo.app\" --platform=osx --out=\"dist/osx\" --config=builder.json"
14 | },
15 | "repository": {
16 | "type": "git",
17 | "url": "git+https://github.com/dispersionjs/Dispersion.git"
18 | },
19 | "keywords": [
20 | "electron",
21 | "ipfs",
22 | "ipns",
23 | "dispersion",
24 | "webhosting",
25 | "p2p",
26 | "peer-to-peer",
27 | "distributed-web",
28 | "dag",
29 | "dht"
30 | ],
31 | "author": "Dispersion",
32 | "license": "MIT",
33 | "bugs": {
34 | "url": "https://github.com/dispersionjs/Dispersion/issues"
35 | },
36 | "homepage": "http://dispersion.io",
37 | "dependencies": {
38 | "angular": "^1.5.8",
39 | "dialog": "^0.2.0",
40 | "electron": "^1.4.2",
41 | "electron-builder": "^7.11.4",
42 | "electron-json-storage": "^2.0.0",
43 | "electron-packager": "^8.1.0",
44 | "file-type": "^3.8.0",
45 | "fs": "0.0.1-security",
46 | "fs-extra": "^0.30.0",
47 | "hammerjs": "^2.0.8",
48 | "https": "^1.0.0",
49 | "jquery": "^3.1.1",
50 | "mime": "^1.3.4",
51 | "read-chunk": "^2.0.0",
52 | "remote": "^0.2.6",
53 | "request": "^2.75.0",
54 | "username": "^2.2.2"
55 | },
56 | "devDependencies": {
57 | "angular-mocks": "^1.5.8",
58 | "benv": "^3.1.0",
59 | "chai": "^3.5.0",
60 | "chai-as-promised": "^6.0.0",
61 | "describe-it": "^1.7.0",
62 | "electron-mocha": "^3.1.1",
63 | "eslint": "^3.9.0",
64 | "eslint-config-airbnb": "^12.0.0",
65 | "eslint-plugin-react": "^6.4.1",
66 | "expect.js": "^0.3.1",
67 | "jasmine-core": "^2.5.2",
68 | "karma": "^1.3.0",
69 | "karma-chrome-launcher": "^2.0.0",
70 | "karma-electron": "^5.1.1",
71 | "karma-jasmine": "^1.0.2",
72 | "karma-mocha": "^1.2.0",
73 | "karma-phantomjs-launcher": "^1.0.2",
74 | "spectron": "^3.4.0"
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/app/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration
2 | // Generated on Fri Oct 21 2016 11:40:19 GMT-0700 (PDT)
3 |
4 | module.exports = function (config) {
5 | config.set({
6 |
7 | // base path that will be used to resolve all patterns (eg. files, exclude)
8 | basePath: '',
9 |
10 |
11 | // frameworks to use
12 | // available frameworks: https://npmjs.org/browse/keyword/karma-adapter
13 | frameworks: ['jasmine'],
14 |
15 |
16 | // list of files / patterns to load in the browser
17 | files: [
18 | './node_modules/angular/angular.js',
19 | './node_modules/angular-mocks/angular-mocks.js',
20 | './components/factories/ipfsService.js',
21 | './app.js',
22 | 'test/ipfsService.spec.js'
23 | ],
24 |
25 |
26 | // list of files to exclude
27 | exclude: [
28 | ],
29 |
30 |
31 | // preprocess matching files before serving them to the browser
32 | // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor
33 | preprocessors: {
34 | },
35 |
36 |
37 | // test results reporter to use
38 | // possible values: 'dots', 'progress'
39 | // available reporters: https://npmjs.org/browse/keyword/karma-reporter
40 | reporters: ['progress'],
41 |
42 |
43 | // web server port
44 | port: 9876,
45 |
46 |
47 | // enable / disable colors in the output (reporters and logs)
48 | colors: true,
49 |
50 |
51 | // level of logging
52 | // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG
53 | logLevel: config.LOG_INFO,
54 |
55 |
56 | // enable / disable watching file and executing tests whenever any file changes
57 | autoWatch: true,
58 |
59 | // start these browsers
60 | // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher
61 | // Inside `karma.conf.js`
62 | browsers: ['Electron'],
63 |
64 | // If you would like Node.js integration support (e.g. `require`)
65 | // then, you must include this in `preprocessors` and `client`
66 | // DEV: preprocessors is for backfilling `__filename` and local `require` paths
67 | preprocessors: {
68 | '**/*.js': ['electron']
69 | },
70 | // DEV: `useIframe: false` is for launching a new window instead of using an iframe
71 | // In Electron, iframes don't get `nodeIntegration` priveleges yet windows do
72 | client: {
73 | useIframe: false
74 | },
75 |
76 | // Continuous Integration mode
77 | // if true, Karma captures browsers, runs the tests and exits
78 | singleRun: false,
79 |
80 | // Concurrency level
81 | // how many browser should be started simultaneous
82 | concurrency: Infinity
83 | })
84 | }
85 |
--------------------------------------------------------------------------------
/app/components/factories/fileFactory.js:
--------------------------------------------------------------------------------
1 | var module = angular
2 | .module('FileFactory', [])
3 |
4 | module.service('FileFactory', ['$q', 'IpfsService', fileFactory]);
5 |
6 | function fileFactory($q, IpfsService) {
7 | let fileData = [];
8 |
9 | function addToFileData(hashObj) {
10 | hashObj.fileType = testFileType(hashObj);
11 | fileData.push(hashObj);
12 | storage.set('files', fileData, (error) => {
13 | if (error) {
14 | console.log('error in addFile to data in file Factory, the error is: \n');
15 | console.error(error);
16 | }
17 | })
18 | }
19 |
20 | function removeFile(index) {
21 | fileData.splice(index,1);
22 | storage.set('files', fileData, (error) => {
23 | if (error) {
24 | console.log('error in addFile to data in file Factory, the error is: \n');
25 | console.error(error);
26 | }
27 | })
28 | }
29 |
30 |
31 | function addHash() {
32 | dialog.showOpenDialog({ properties: ['openFile', 'openDirectory', 'multiSelections'] }, function (selected) {
33 | if (selected) {
34 | IpfsService.addFile(selected[0]).then((addedHashObject) => {
35 | addedHashObject.pathToFile = selected[0];
36 | console.log('path on obj', addedHashObject.pathToFile);
37 | addToFileData(addedHashObject);
38 | });
39 | }
40 | });
41 | }
42 |
43 | function init() {
44 | return $q((resolve, reject) => {
45 | storage.get('files', (error, data) => {
46 | console.log('files key in local storage', data)
47 | if (error) {
48 | console.error(error)
49 | reject()
50 | } else {
51 | Object.assign(fileData, data);
52 | console.log('files loaded from storage: \n', data)
53 | resolve(fileData);
54 | }
55 | })
56 | })
57 | }
58 | function testFileType(item) {
59 | let fileName = item.file
60 | if (fileName.includes('.jpg') || fileName.includes('.png') || fileName.includes('.JPG') || fileName.includes('.PNG') || fileName.includes('.jpeg')) {
61 | return 'image';
62 | } else if (!fileName.includes('.')) {
63 | return 'folder';
64 | } else if (fileName.includes('.xl')) {
65 | return 'excel';
66 | } else if (fileName.includes('.pdf') || fileName.includes('.txt') || fileName.includes('.doc')) {
67 | return 'doc';
68 | } else {
69 | return 'other';
70 | }
71 | }
72 |
73 | function getFileData() {
74 | return fileData;
75 | }
76 | return {
77 | removeFile: removeFile,
78 | addHash: addHash,
79 | data: fileData,
80 | add: addToFileData,
81 | getFileData: getFileData,
82 | init: init
83 | }
84 | }
--------------------------------------------------------------------------------
/app/components/partials/settings.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/app/components/factories/diskFactory.js:
--------------------------------------------------------------------------------
1 | var module = angular
2 | .module('DiskFactory', [])
3 |
4 | module.factory('DiskFactory', ['$q', 'PublishService', 'IpfsService', diskFactory]);
5 |
6 | function diskFactory($q, PublishServic, IpfsService) {
7 | //Add "projectFolder" to local app folder
8 | //Return promise
9 | function initProjectFolder() {
10 | $q((resolve, reject) => {
11 | fse.ensureDir(path.resolve(__dirname + `/../projectFolder`), (err) => {
12 | if (err) {
13 | reject(err);
14 | } else {
15 | console.log('projectFolder made in Dispersion directory: ', path.resolve(__dirname + `/../projectFolder`));
16 | resolve()
17 | }
18 | });
19 | })
20 | }
21 |
22 | function copyProjectToAppStorage(copyFromPath) {
23 |
24 | let copyFrom = '/' + copyFromPath;
25 | let pathBrokenIntoArray = copyFrom.split('/');
26 | let project = '/' + pathBrokenIntoArray[pathBrokenIntoArray.length - 1]
27 | let copyTo = path.resolve(__dirname + `/../projectFolder` + project)
28 |
29 | console.log('copy from ', copyFrom)
30 | console.log('copyTo ', copyTo)
31 |
32 | fse.copy(copyFrom, copyTo, (err) => {
33 | if (err) return console.error(err);
34 | console.log('copied folder to local directory')
35 | })
36 | }
37 | ///Users/ygoldobin/Desktop/test
38 | ///Users/ygoldobin/Desktop/codesmithHackathon1
39 | // (//index.html, dispersion, data)
40 | function overwriteFileInProject(fileName, projectName, data, fileVersionObj) {
41 | if (fileName[0] !== '/') fileName = '/' + fileName;
42 | let pathToProjectFolder = path.resolve(__dirname + `/../projectFolder/` + projectName);
43 | fs.writeFile(pathToProjectFolder + fileName, data, (err) => {
44 | if (err) return console.error(err);
45 | IpfsService.rehashProject(pathToProjectFolder, fileVersionObj, fileName, projectName, true)
46 | // console.log('overwrote file at this path: \n', path.resolve(__dirname + `/../projectFolder` + projectFolderName + fileName))
47 | })
48 |
49 | }
50 |
51 | function deleteAProjectFolder(deletePath) {
52 |
53 | let pathBrokenIntoArray = deletePath.split('/');
54 | let deleteProject = '/' + pathBrokenIntoArray[pathBrokenIntoArray.length - 1]
55 | let deleteIt = path.resolve(__dirname + `/../projectFolder` + deleteProject)
56 |
57 | fse.emptyDir(deleteIt, (err) => {
58 | if (err) throw err;
59 | console.log('deleted directory contents')
60 | })
61 | }
62 |
63 | //function to clear specific project file given the string;
64 | //function returns a promise that resolves when a folder is cleared
65 | //function that requests a hash and resolves a promise with the hash data
66 |
67 | return {
68 | init: initProjectFolder,
69 | addProject: copyProjectToAppStorage,
70 | overwrite: overwriteFileInProject,
71 | delete: deleteAProjectFolder
72 | }
73 | }
--------------------------------------------------------------------------------
/app/components/factories/publishService.js:
--------------------------------------------------------------------------------
1 | var module = angular
2 | .module('PublishService', [])
3 |
4 |
5 | module.factory('PublishService', ['$q', pubService]);
6 |
7 | function pubService($q) {
8 | let publishData = {};
9 | // function init() {
10 | // return loadPublished()
11 | // }
12 | function init() {
13 | return $q((resolve, reject) => {
14 | storage.get('publish', (error, data) => {
15 | if (error) reject(error);
16 | publishData = Object.assign(publishData, data);
17 | // console.log('publishData in publish service:', publishData)
18 | storage.get('currentlyPublished', (err, name) => {
19 | currentlyPublished = name;
20 | console.log(currentlyPublished);
21 | resolve(data)
22 | })
23 | });
24 | })
25 | }
26 | let currentlyPublished;
27 | function getCurrentlyPublished() {
28 | return currentlyPublished;
29 | }
30 | function setCurrentlyPublished(name) {
31 | currentlyPublished = name;
32 | storage.set('currentlyPublished', name);
33 | }
34 | function updateStore() {
35 | // uncomment later, just for a check
36 | storage.set('publish', publishData)
37 | storage.get('currentlyPublished', (error, data) => {
38 | currentlyPublished = data;
39 | })
40 | }
41 | // //unshift for edit fix is here, add an unhashed object for edit purposes//
42 | // function unshiftForEditFix(pubObj, name) {
43 | // console.log('unshifting pubObj ', pubObj, "onto ",name )
44 | // publishData[name].unshift(pubObj)
45 | // updateStore()
46 | // }
47 |
48 | function addToPublish(pubObj, snapshot = false, name = '') {
49 | console.log('publishData ', publishData)
50 | console.log('pubObj ', pubObj)
51 | if (snapshot) {
52 | // for (let key in pubObj) {
53 | // console.log('key in publishData', publishData[key])
54 | console.log('unshifting after rehash of project', pubObj)
55 | console.log(publishData)
56 | //THIS LINE RIGHT HERE
57 | publishData[name].unshift(pubObj)
58 | // }
59 | } else {
60 | console.log('add to publish called in publish service');
61 | console.log('pubObj in add to publish: \n', pubObj);
62 | for (let key in pubObj) {
63 | if (!publishData[key]) {
64 | console.log('key, publishData');
65 | console.log(key, publishData)
66 | publishData[key] = pubObj[key];
67 | } else {
68 | console.log('this project has already been published')
69 | //add more logic to maybe just append to array
70 | }
71 | }
72 | }
73 | updateStore()
74 | }
75 |
76 | return {
77 | data: publishData,
78 | add: addToPublish,
79 | init: init,
80 | currentlyPublished: getCurrentlyPublished,
81 | setPublished: setCurrentlyPublished,
82 | // unshiftForEditFix: unshiftForEditFix,
83 | updatePublishData: updateStore
84 | }
85 | }
86 |
87 |
88 |
--------------------------------------------------------------------------------
/app/components/partials/FileHistoryPartial.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
25 |
26 |
27 |
28 |
38 |
39 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
![]()
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
--------------------------------------------------------------------------------
/app/components/controllers/ProjectController.js:
--------------------------------------------------------------------------------
1 | angular.module('ProjectController', [])
2 | .controller('ProjectController', ['$http', 'ProjectService', '$scope', '$timeout', projectController]);
3 |
4 | function projectController($http, ProjectService, $scope, $timeout) {
5 | const self = this;
6 | self.projectArray = ProjectService.projectArray;
7 | self.publishedVersions = ProjectService.publishedProjectVersions;
8 | self.selectedVersion = ProjectService.selectedVersion;
9 | self.currentFile = ProjectService.currentFile;//function
10 | self.currentUrl = ProjectService.currentUrl; //function
11 |
12 | self.filesList = ProjectService.selectedVersionFilesList;//function
13 | self.fileVersions = ProjectService.fileChangedVersions; //function
14 | self.mediaContentUrl = '';
15 | self.showEditor = false;
16 | self.showMedia = false;
17 | self.showFiles = false;
18 | self.lastProjectIndex = null;
19 | self.fileContentViewIndex = null;
20 | self.currentlySelectedFile = null;
21 |
22 | self.setFileContentViewIndex = (index) => {
23 | self.fileContentViewIndex = index;
24 | }
25 | self.changeCurrentlySelectedFile = (fileName, index = 0) => {
26 | self.showEditor = false;
27 | $timeout(() => {
28 | if (!self.isImage(fileName) && (self.fileContentViewIndex === null || self.currentlySelectedFile !== fileName)) {
29 | self.showEditor = true;
30 | self.setFileContentViewIndex(index);
31 | self.currentlySelectedFile = fileName;
32 |
33 | } else {
34 | self.showEditor = false;
35 | self.fileContentViewIndex = null;
36 | self.currentlySelectedFile = null;
37 | }
38 | }, 0);
39 | }
40 |
41 | self.toggleShowFiles = (index) => {
42 | self.showFiles = self.lastVersionIndex === undefined || index !== self.lastVersionIndex ? true : !self.showFiles;
43 | self.lastVersionIndex = index;
44 | }
45 | self.getMediaContentUrl = () => self.mediaContentUrl;
46 | self.currentProject = ProjectService.currentProject;//function
47 | //clean this function up
48 | self.selectVersion = function (index) {
49 | ProjectService.changeSelectedVersion(index);
50 | // if (self.showIframe && self.lastProjectIndex !== null && index === self.lastProjectIndex) {
51 | // // if (self.showIframe && self.lastProjectIndex !== null && index === self.lastProjectIndex) {
52 | // self.showIframe = false;
53 | // } else {
54 | // self.showIframe = true;
55 | // }
56 | if (self.lastProjectIndex === index) {
57 | self.lastProjectIndex = index;
58 |
59 | } else {
60 | self.lastProjectIndex = index;
61 | }
62 |
63 | }
64 | self.getMode = function (filename) {
65 | let textTester = /(\.html$)|(\.js$)|(\.css$)|(\.txt$)|(\.json$)|(\.md$)|(\.log$)/gmi;
66 | let text = textTester.test(filename);
67 | return text ? self.getAceMode(filename.split('.').pop()) : false;
68 | }
69 | self.getAceMode = function (ext) {
70 | switch (ext) {
71 | case 'js':
72 | return 'javascript';
73 | case 'html':
74 | return 'html';
75 | case 'css':
76 | return 'css';
77 | case 'json':
78 | return 'json';
79 | default:
80 | return '';
81 | }
82 | }
83 | self.isImage = (file) => {
84 | let imageTester = /(\.jpeg$)|(\.jpg$)|(\.png$)|(\.gif$)|(\.json$)|(\.md$)|(\.log$)/i;
85 | return imageTester.test(file);
86 | }
87 | self.modalTrigger = function () {
88 | console.log('in modalTrigger')
89 | $('#projectModal').openModal()
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/app/assets/fonts/Julius_Sans_One/OFL.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012, LatinoType (luciano@latinotype.com), with Reserved Font Names 'Julius'
2 | This Font Software is licensed under the SIL Open Font License, Version 1.1.
3 | This license is copied below, and is also available with a FAQ at:
4 | http://scripts.sil.org/OFL
5 |
6 |
7 | -----------------------------------------------------------
8 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
9 | -----------------------------------------------------------
10 |
11 | PREAMBLE
12 | The goals of the Open Font License (OFL) are to stimulate worldwide
13 | development of collaborative font projects, to support the font creation
14 | efforts of academic and linguistic communities, and to provide a free and
15 | open framework in which fonts may be shared and improved in partnership
16 | with others.
17 |
18 | The OFL allows the licensed fonts to be used, studied, modified and
19 | redistributed freely as long as they are not sold by themselves. The
20 | fonts, including any derivative works, can be bundled, embedded,
21 | redistributed and/or sold with any software provided that any reserved
22 | names are not used by derivative works. The fonts and derivatives,
23 | however, cannot be released under any other type of license. The
24 | requirement for fonts to remain under this license does not apply
25 | to any document created using the fonts or their derivatives.
26 |
27 | DEFINITIONS
28 | "Font Software" refers to the set of files released by the Copyright
29 | Holder(s) under this license and clearly marked as such. This may
30 | include source files, build scripts and documentation.
31 |
32 | "Reserved Font Name" refers to any names specified as such after the
33 | copyright statement(s).
34 |
35 | "Original Version" refers to the collection of Font Software components as
36 | distributed by the Copyright Holder(s).
37 |
38 | "Modified Version" refers to any derivative made by adding to, deleting,
39 | or substituting -- in part or in whole -- any of the components of the
40 | Original Version, by changing formats or by porting the Font Software to a
41 | new environment.
42 |
43 | "Author" refers to any designer, engineer, programmer, technical
44 | writer or other person who contributed to the Font Software.
45 |
46 | PERMISSION & CONDITIONS
47 | Permission is hereby granted, free of charge, to any person obtaining
48 | a copy of the Font Software, to use, study, copy, merge, embed, modify,
49 | redistribute, and sell modified and unmodified copies of the Font
50 | Software, subject to the following conditions:
51 |
52 | 1) Neither the Font Software nor any of its individual components,
53 | in Original or Modified Versions, may be sold by itself.
54 |
55 | 2) Original or Modified Versions of the Font Software may be bundled,
56 | redistributed and/or sold with any software, provided that each copy
57 | contains the above copyright notice and this license. These can be
58 | included either as stand-alone text files, human-readable headers or
59 | in the appropriate machine-readable metadata fields within text or
60 | binary files as long as those fields can be easily viewed by the user.
61 |
62 | 3) No Modified Version of the Font Software may use the Reserved Font
63 | Name(s) unless explicit written permission is granted by the corresponding
64 | Copyright Holder. This restriction only applies to the primary font name as
65 | presented to the users.
66 |
67 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
68 | Software shall not be used to promote, endorse or advertise any
69 | Modified Version, except to acknowledge the contribution(s) of the
70 | Copyright Holder(s) and the Author(s) or with their explicit written
71 | permission.
72 |
73 | 5) The Font Software, modified or unmodified, in part or in whole,
74 | must be distributed entirely under this license, and must not be
75 | distributed under any other license. The requirement for fonts to
76 | remain under this license does not apply to any document created
77 | using the Font Software.
78 |
79 | TERMINATION
80 | This license becomes null and void if any of the above conditions are
81 | not met.
82 |
83 | DISCLAIMER
84 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
85 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
86 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
87 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
88 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
89 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
90 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
91 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
92 | OTHER DEALINGS IN THE FONT SOFTWARE.
93 |
--------------------------------------------------------------------------------
/app/components/controllers/mockdata.js:
--------------------------------------------------------------------------------
1 | const testProjectData = {
2 | "Dispersion": [
3 | {
4 | "date": "2016-10-14T18:22:23.133Z",
5 | "hash": "QmehudYxpxDW3egZraNvq7MKEXzky8GLRcxJ6VbmpUcbxV",
6 | "publish": true,
7 | "changed": "/smoke_trail.jpeg",
8 | "url": "https://ipfs.io/ipfs/QmehudYxpxDW3egZraNvq7MKEXzky8GLRcxJ6VbmpUcbxV",
9 | "files": [
10 | "/index.html",
11 | "/main.js",
12 | "/styles.css"
13 | ]
14 | },
15 | {
16 | "date": "2016-10-15T18:22:23.133Z",
17 | "hash": "QmPdqizZHVSKbCGkv6rXaotXwdwRC5jHQLUNy2niEfNg1o",
18 | "publish": true,
19 | "changed": "/styles.css",
20 | "url": "https://ipfs.io/ipfs/QmPdqizZHVSKbCGkv6rXaotXwdwRC5jHQLUNy2niEfNg1o",
21 | "files": [
22 | "/index.html",
23 | "/main.js",
24 | "/styles.css",
25 | "/smoke_trail.jpeg"
26 | ]
27 | },
28 | {
29 | "date": "2016-10-16T18:22:23.133Z",
30 | "hash": "QmXEib3wKC3ZnNQGyLJdZJ5iPpmgoqoJyqPfLNdTRbwtUg",
31 | "publish": true,
32 | "changed": "/main.js",
33 | "url": "https://ipfs.io/ipfs/QmXEib3wKC3ZnNQGyLJdZJ5iPpmgoqoJyqPfLNdTRbwtUg",
34 | "files": [
35 | "/index.html",
36 | "/main.js",
37 | "/styles.css",
38 | "/smoke_trail.jpeg"
39 | ]
40 | },
41 | {
42 | "date": "2016-10-17T18:22:23.133Z",
43 | "hash": "QmTG9nQUhYJdH5uraNyVdDftoTWDhBgPtTbdCp9x7Xawrx",
44 | "publish": true,
45 | "changed": "/index.html",
46 | "url": "https://ipfs.io/ipfs/QmTG9nQUhYJdH5uraNyVdDftoTWDhBgPtTbdCp9x7Xawrx",
47 | "files": [
48 | "/index.html",
49 | "/main.js",
50 | "/styles.css",
51 | "/smoke_trail.jpeg"
52 | ]
53 | },
54 | {
55 | "date": "2016-10-18T18:22:23.133Z",
56 | "hash": "QmT45exg6ZEiCBxC4LfoVZPvPkzdtQvNqWxbF9CJN3Xnec",
57 | "publish": false,
58 | "changed": "/index.html",
59 | "url": "https://ipfs.io/ipfs/QmT45exg6ZEiCBxC4LfoVZPvPkzdtQvNqWxbF9CJN3Xnec",
60 | "files": [
61 | "/index.html",
62 | "/main.js",
63 | "/styles.css",
64 | "/smoke_trail.jpeg"
65 | ]
66 | },
67 | {
68 | "date": "2016-10-19T18:22:23.133Z",
69 | "hash": "QmXtuj4RRhSNDxNpa2MKaea4sZ5GRprjvtrdaTH84pY9NC",
70 | "publish": false,
71 | "changed": "/index.html",
72 | "url": "https://ipfs.io/ipfs/QmXtuj4RRhSNDxNpa2MKaea4sZ5GRprjvtrdaTH84pY9NC",
73 | "files": [
74 | "/index.html",
75 | "/main.js",
76 | "/styles.css",
77 | "/smoke_trail.jpeg"
78 | ]
79 | },
80 | {
81 | "date": "2016-10-20T18:22:23.133Z",
82 | "hash": "QmWxnq9onYoNcsYjTpk1mcHTCU6bgmXBCALwkP7roP68HY",
83 | "publish": false,
84 | "changed": "/index.html",
85 | "url": "https://ipfs.io/ipfs/QmWxnq9onYoNcsYjTpk1mcHTCU6bgmXBCALwkP7roP68HY",
86 | "files": [
87 | "/index.html",
88 | "/main.js",
89 | "/styles.css",
90 | "/smoke_trail.jpeg"
91 | ]
92 | }
93 | ]
94 | }
95 | const testFileData = {
96 | "Dispersion": [
97 | {
98 | "date": "2016-10-18T18:22:23.133Z",
99 | "hash": "QmT45exg6ZEiCBxC4LfoVZPvPkzdtQvNqWxbF9CJN3Xnec",
100 | "file": "/index.html",
101 | "hash":
102 | "url": "https://ipfs.io/ipfs/QmT45exg6ZEiCBxC4LfoVZPvPkzdtQvNqWxbF9CJN3Xnec",
103 | },
104 | {
105 | "date": "2016-10-19T18:22:23.133Z",
106 | "hash": "QmXtuj4RRhSNDxNpa2MKaea4sZ5GRprjvtrdaTH84pY9NC",
107 | "file": "/index.html",
108 | "url": "https://ipfs.io/ipfs/QmXtuj4RRhSNDxNpa2MKaea4sZ5GRprjvtrdaTH84pY9NC/index.html",
109 | },
110 | {
111 | "date": "2016-10-20T18:22:23.133Z",
112 | "hash": "QmWxnq9onYoNcsYjTpk1mcHTCU6bgmXBCALwkP7roP68HY",
113 | "file": "/index.html",
114 | "url": "https://ipfs.io/ipfs/QmWxnq9onYoNcsYjTpk1mcHTCU6bgmXBCALwkP7roP68HY/index.html",
115 | }
116 | ],
117 | "yang": [
118 | {
119 | "date": "2016-10-18T18:22:23.133Z",
120 | "hash": "QmT45exg6ZEiCBxC4LfoVZPvPkzdtQvNqWxbF9CJN3Xnec",
121 | "file": "/index.html",
122 | "url": "https://ipfs.io/ipfs/QmT45exg6ZEiCBxC4LfoVZPvPkzdtQvNqWxbF9CJN3Xnec/index.html",
123 | },
124 | {
125 | "date": "2016-10-19T18:22:23.133Z",
126 | "hash": "QmXtuj4RRhSNDxNpa2MKaea4sZ5GRprjvtrdaTH84pY9NC",
127 | "file": "/index.html",
128 | "url": "https://ipfs.io/ipfs/QmXtuj4RRhSNDxNpa2MKaea4sZ5GRprjvtrdaTH84pY9NC/index.html",
129 | },
130 | {
131 | "date": "2016-10-20T18:22:23.133Z",
132 | "hash": "QmWxnq9onYoNcsYjTpk1mcHTCU6bgmXBCALwkP7roP68HY",
133 | "file": "/index.html",
134 | "url": "https://ipfs.io/ipfs/QmWxnq9onYoNcsYjTpk1mcHTCU6bgmXBCALwkP7roP68HY/index.html",
135 | }
136 | ]
137 | }
138 |
--------------------------------------------------------------------------------
/app/assets/fonts/Raleway/OFL.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2010, Matt McInerney (matt@pixelspread.com),
2 | Copyright (c) 2011, Pablo Impallari (www.impallari.com|impallari@gmail.com),
3 | Copyright (c) 2011, Rodrigo Fuenzalida (www.rfuenzalida.com|hello@rfuenzalida.com), with Reserved Font Name Raleway
4 | This Font Software is licensed under the SIL Open Font License, Version 1.1.
5 | This license is copied below, and is also available with a FAQ at:
6 | http://scripts.sil.org/OFL
7 |
8 |
9 | -----------------------------------------------------------
10 | SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
11 | -----------------------------------------------------------
12 |
13 | PREAMBLE
14 | The goals of the Open Font License (OFL) are to stimulate worldwide
15 | development of collaborative font projects, to support the font creation
16 | efforts of academic and linguistic communities, and to provide a free and
17 | open framework in which fonts may be shared and improved in partnership
18 | with others.
19 |
20 | The OFL allows the licensed fonts to be used, studied, modified and
21 | redistributed freely as long as they are not sold by themselves. The
22 | fonts, including any derivative works, can be bundled, embedded,
23 | redistributed and/or sold with any software provided that any reserved
24 | names are not used by derivative works. The fonts and derivatives,
25 | however, cannot be released under any other type of license. The
26 | requirement for fonts to remain under this license does not apply
27 | to any document created using the fonts or their derivatives.
28 |
29 | DEFINITIONS
30 | "Font Software" refers to the set of files released by the Copyright
31 | Holder(s) under this license and clearly marked as such. This may
32 | include source files, build scripts and documentation.
33 |
34 | "Reserved Font Name" refers to any names specified as such after the
35 | copyright statement(s).
36 |
37 | "Original Version" refers to the collection of Font Software components as
38 | distributed by the Copyright Holder(s).
39 |
40 | "Modified Version" refers to any derivative made by adding to, deleting,
41 | or substituting -- in part or in whole -- any of the components of the
42 | Original Version, by changing formats or by porting the Font Software to a
43 | new environment.
44 |
45 | "Author" refers to any designer, engineer, programmer, technical
46 | writer or other person who contributed to the Font Software.
47 |
48 | PERMISSION & CONDITIONS
49 | Permission is hereby granted, free of charge, to any person obtaining
50 | a copy of the Font Software, to use, study, copy, merge, embed, modify,
51 | redistribute, and sell modified and unmodified copies of the Font
52 | Software, subject to the following conditions:
53 |
54 | 1) Neither the Font Software nor any of its individual components,
55 | in Original or Modified Versions, may be sold by itself.
56 |
57 | 2) Original or Modified Versions of the Font Software may be bundled,
58 | redistributed and/or sold with any software, provided that each copy
59 | contains the above copyright notice and this license. These can be
60 | included either as stand-alone text files, human-readable headers or
61 | in the appropriate machine-readable metadata fields within text or
62 | binary files as long as those fields can be easily viewed by the user.
63 |
64 | 3) No Modified Version of the Font Software may use the Reserved Font
65 | Name(s) unless explicit written permission is granted by the corresponding
66 | Copyright Holder. This restriction only applies to the primary font name as
67 | presented to the users.
68 |
69 | 4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
70 | Software shall not be used to promote, endorse or advertise any
71 | Modified Version, except to acknowledge the contribution(s) of the
72 | Copyright Holder(s) and the Author(s) or with their explicit written
73 | permission.
74 |
75 | 5) The Font Software, modified or unmodified, in part or in whole,
76 | must be distributed entirely under this license, and must not be
77 | distributed under any other license. The requirement for fonts to
78 | remain under this license does not apply to any document created
79 | using the Font Software.
80 |
81 | TERMINATION
82 | This license becomes null and void if any of the above conditions are
83 | not met.
84 |
85 | DISCLAIMER
86 | THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
87 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
88 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
89 | OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
90 | COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
91 | INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
92 | DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
93 | FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
94 | OTHER DEALINGS IN THE FONT SOFTWARE.
95 |
--------------------------------------------------------------------------------
/app/assets/css/style.css:
--------------------------------------------------------------------------------
1 | @font-face {
2 | font-family: "Julius Sans One";
3 | src: url("./../fonts/Julius_Sans_One/JuliusSansOne-Regular.ttf");
4 | }
5 |
6 | html {
7 | font-weight: 300;
8 | }
9 |
10 | body {
11 | background: #eeeeee;
12 | }
13 |
14 | a {
15 | text-decoration:none;
16 | }
17 |
18 | h1 {
19 | font-size: 32px;
20 | text-align: center;
21 | color: #eeeeee;
22 | margin:0;
23 | padding-top: 8px;
24 | padding-bottom: 8px
25 | }
26 |
27 | .brand-logo {
28 | font-family: "Julius Sans One";
29 | font-weight: 200;
30 | letter-spacing: .15em;
31 | }
32 |
33 | .tabs .indicator {
34 | /*color: #4db6ac;*/
35 | background-color: #607d8b ;
36 | }
37 |
38 | i {
39 | color: white;
40 | }
41 |
42 | .file-icon-images i {
43 | color: #ffc107;
44 | }
45 |
46 | .sel-box{
47 | position:relative;
48 | }
49 |
50 | .add-icon {
51 | font-size: 55px;
52 | cursor: pointer;
53 | }
54 |
55 | [ng\:cloak], [ng-cloak], [data-ng-cloak], [x-ng-cloak], .ng-cloak, .x-ng-cloak {
56 | display: none !important;
57 | }
58 |
59 | .title {
60 | font-weight: bold;
61 | color:#4db6ac;
62 | }
63 |
64 | blockquote {
65 | margin: 20px 0;
66 | padding-left: 1.5rem;
67 | border-left: 5px solid #ffb300; /* Just change the color value and that's it*/
68 | }
69 |
70 | .btn-ad {
71 | margin-left: 10px;
72 | }
73 |
74 | #hash-input, #project-input {
75 | font-size: 32px;
76 | padding-left: 65px;
77 | }
78 |
79 | #hash-input:hover {
80 | cursor: pointer;
81 | font-size: 32px;
82 | padding-left: 65px;
83 | }
84 |
85 | .card .card-action {
86 | position: relative;
87 | display: flex;
88 | align-items: center;
89 | justify-content: space-between;
90 | }
91 |
92 | .project-nav-bar{
93 | font-size: 2.1rem;
94 | margin-left: 30px;
95 | font-family: "Julius Sans One";
96 | font-weight: 200;
97 | letter-spacing: .15em;
98 | }
99 |
100 | /*CSS for Daemon Load*/
101 | .preload {
102 | margin: 0;
103 | position: absolute;
104 | overflow: hidden;
105 | z-index: 999;
106 | width: 100%;
107 | height: 100vh;
108 | top: 0;
109 | background: #ff8300;
110 | background: linear-gradient(to top left, #ffff66 -40%, #ff8300);
111 | }
112 |
113 | .container {
114 | position: absolute;
115 | top:0;
116 | bottom: 0;
117 | left: 0;
118 | right: 0;
119 | width: 350px;
120 | height: 350px;
121 | margin: auto;
122 | }
123 |
124 | .part {
125 | width: 350px;
126 | position: absolute;
127 | }
128 |
129 | .svgpath {
130 | fill: rgba(145,220,90,0);
131 | stroke: #ff8300;
132 | stroke-width: 1.8px;
133 | stroke-dasharray: 1000;
134 | stroke-linecap: round;
135 | z-index: 2;
136 | }
137 |
138 | .svgbg {
139 | fill: rgba(255,255,255,0.2);
140 | z-index: 1;
141 | }
142 |
143 | #playload {
144 | animation: dash 2.5s reverse ease-in-out infinite;
145 | }
146 |
147 | @keyframes dash {
148 | to {
149 | stroke-dashoffset: 2000;
150 | }
151 | }
152 |
153 | .settings-item span {
154 | font-size: 21px;
155 | font-weight: thin;
156 | }
157 |
158 | .projectView .ace_editor {
159 | min-height: 200px;
160 | }
161 |
162 | .projectView ul li {
163 | display: inline;
164 | }
165 |
166 | .projectView #outer{
167 | width: 320px;
168 | height: 180px;
169 |
170 | }
171 |
172 | .projectView img{
173 | max-width:100%;
174 | max-height:100%;
175 | }
176 |
177 | .projectView button.selected {
178 | background-color: lightblue;
179 | }
180 |
181 | .projectView .changedFile::after {
182 | content: '*changed';
183 | }
184 |
185 | .projectView .mediaContentWrapper {
186 | max-height: 900px;
187 | max-width: 600px;
188 | }
189 | .projectView .fileVersion {
190 | margin: 0;
191 | font-size: 15px;
192 | text-decoration: none;
193 | }
194 |
195 | .save-delete {
196 | padding-top: 8px;
197 | }
198 |
199 | .fileVersionListItem {
200 | margin: 0;
201 | padding-top: 10px;
202 | padding: 0;
203 | height: 20px;
204 | }
205 | .fileVersionList {
206 | padding: 0;
207 | padding-top: 8px;
208 | padding-bottom: 8px;
209 | display: flex;
210 | }
211 |
212 | .transparent {
213 | background-color: transparent;
214 | background-repeat:no-repeat;
215 | border: none;
216 | cursor:pointer;
217 | overflow: hidden;
218 | outline:none;
219 | }
220 |
221 | .projectView .editor {
222 | width: 100%;
223 | min-height: 400px;
224 | max-height: 800px;
225 | }
226 |
227 | .content-link {
228 | cursor: pointer;
229 | }
230 |
231 | .close-modal {
232 | position: absolute;
233 | right: 5px;
234 | top: 5px;
235 | cursor:pointer;
236 | color: #fff;
237 | border: 1px solid #AEAEAE;
238 | border-radius: 30px;
239 | background: #605F61;
240 | font-size: 31px;
241 | font-weight: bold;
242 | display: inline-block;
243 | line-height: 0px;
244 | padding: 11px 3px;
245 | }
246 |
247 | .close-modal:before {
248 | content: "×";
249 | }
250 |
251 | .iframe-wrap {
252 | z-index: 9999;
253 | position: absolute;
254 | top:22px;
255 | left:50%;
256 | transform: translate(-50%, 0);
257 | width: 95vw;
258 | height: 100vw;
259 | background-color: #fafafa;
260 | border-radius: 2px;
261 | }
262 |
263 | .file-iframe {
264 | width: 100%;
265 | height: 100%;
266 | }
267 |
268 | .modal {
269 | width: 90%;
270 | max-height: 85%;
271 | }
272 |
273 | .modal.modal-fixed-footer {
274 | height: 85%;
275 | }
276 |
277 | @media only screen and (max-width: 992px) {
278 | .modal {
279 | width: 90%;
280 | }
281 | }
282 |
283 | .modal h4 {
284 | text-align: center;
285 | padding-top: 15px;
286 | }
287 |
288 | .project {
289 | margin-left: 25px;
290 | }
291 |
292 | .individual-file-partial{
293 | padding: 5px;
294 | }
295 |
296 | .save-delete-buttons{
297 | width: 157px;
298 | }
299 |
300 | .proj-modal-button {
301 | margin-left:5px;
302 | }
303 |
304 | .pub-version-list {
305 | padding-right: 5px;
306 | }
307 |
308 | .ace-chaos .ace_print-margin {
309 | border-left: none;
310 | background: none;
311 | }
312 |
313 | div.ace_print-margin {
314 | width: 0 !important;
315 | }
316 |
317 | .backdrop {
318 | background-color: #455a64;
319 | }
320 |
321 | .collection-item > .collapsible-header {
322 | transition: 400ms ease;
323 | }
324 | .collection-item > .collapsible-header:hover {
325 | background-color: rgba(255,255,255,0.7) !important;
326 | }
327 |
328 | .body-wrapper {
329 | padding: 5px;
330 | }
331 |
332 | .ipfs-version {
333 | position: absolute;
334 | right: 20px;
335 | top: 10px;
336 | }
337 |
338 | .side-nav a, .material-icons {
339 | cursor: pointer;
340 | }
341 |
342 | .file-headers {
343 | border-top: none;
344 | border-right: none;
345 | border-left: none;
346 | margin: none;
347 | box-shadow: none;
348 | }
--------------------------------------------------------------------------------
/app/assets/js/dispersion.js:
--------------------------------------------------------------------------------
1 | // required by the index.html file
2 | // executed in the renderer process for that window.
3 |
4 |
5 | (function (window) {
6 | //Dispersion Library Definition
7 | function define_Dispersion_Library() {
8 | var Dispersion = {};
9 |
10 |
11 | // On click submits inputed file to be hashed.
12 | Dispersion.submitFile = function (filepath) {
13 |
14 | //file or directory to be hashed.
15 | let hashFile = filepath
16 | if (hashFile.includes('/')) hashFile = `"${hashFile}"`;
17 | // recursively hashes directory or file and adds to ipfs
18 | let command = `ipfs add -r ${hashFile}`;
19 |
20 | exec(command, function (error, stdout, stderr) {
21 | //grabs just the filename from the absolute path of the added file
22 | let fileLocationArray = hashFile.split('/');
23 | let name = fileLocationArray[fileLocationArray.length - 1];
24 | //separate hashes from folder into an array
25 | let hashArray = stdout.trim().split('\n');
26 | let topHash = hashArray[hashArray.length - 1].split(' ');
27 | let file = topHash.slice(2).join(' ');
28 | let hashObj = {
29 | "file": file,
30 | "time": new Date().toUTCString(),
31 | "url": "https://ipfs.io/ipfs/" + topHash[1],
32 | 'files': []
33 | }
34 | //iterates over the individual hashes, makes requests to them, and stores top level hash in local storage
35 | hashArray.forEach(function (hString, index) {
36 | let tempArray = hString.split(' ');
37 | var requestObj = {
38 | [tempArray[1]]: {
39 | "url": "https://ipfs.io/ipfs/" + tempArray[1]
40 | }
41 | }
42 | //grabs the inner file paths and pushes into file array
43 | if (index < hashArray.length - 1) {
44 | hashObj.files.push(`/${tempArray[2].split('/').slice(1).join('/')}`)
45 | }
46 | //store top hash in local storage
47 | storage.set(topHash[1], hashObj, function (error) {
48 | if (error) throw error;
49 | });
50 | //requests each hash url 5 times
51 |
52 | //good functionality to abstract into its own function
53 | for (let key in requestObj) {
54 | let url = requestObj[key]["url"]
55 | for (let i = 0; i < 5; i++) {
56 | request(url, (err, response, body) => {
57 | if (err) {
58 | console.log('error making distribute request to IPFS');
59 | console.error(err);
60 | } else {
61 | console.log(url)
62 | console.log(response.statusCode)
63 | }
64 | })
65 | }
66 | }
67 | })
68 | })
69 | }
70 |
71 | //Removes the pinned object from local storage.
72 | Dispersion.unPin = function (pinHash) {
73 | let pinRmCommand = 'ipfs pin rm ' + pinHash;
74 | exec(pinRmCommand, function (error, stdout, stderr) {
75 | storage.remove(pinHash, function (error) {
76 | if (error) throw error;
77 | });
78 | if (error !== null) {
79 | console.log('exec error: ' + error);
80 | }
81 | })
82 | }
83 |
84 | //publishes the hash to the Peer ID ipns
85 | Dispersion.publishHash = function (hash) {
86 | let publishIt = 'ipfs name publish ' + hash;
87 | console.log(publishIt);
88 | exec(publishIt, function (error, stdout, stderr) {
89 | console.log(stdout, hash);
90 | let hashed = `http://gateway.ipfs.io/ipns/${stdout.split(' ')[2].slice(0, -1)}`
91 | //$('#hashlink').text(hashed);
92 | if (error !== null) {
93 | console.log('exec error: ' + error);
94 | }
95 | })
96 | }
97 |
98 | //function to add pin to local storage
99 | Dispersion.addPin = function (pinHash, pinDescription) {
100 | let pinCommand = 'ipfs pin add ' + pinHash;
101 | let hashObject = {
102 | "file": pinDescription,
103 | "pinnedBy": 'someone else',
104 | "pinDate": new Date(),
105 | "url": "https://ipfs.io/ipfs/" + pinHash
106 | };
107 | exec(pinCommand, function (error, stdout, stderr) {
108 | //saves pinned hash to Electron App storage
109 | storage.set(pinHash, hashObject, function (error) {
110 | if (error) throw error;
111 | });
112 | if (error !== null) {
113 | console.log('exec error: ' + error);
114 | }
115 | })
116 | }
117 |
118 | //save selected hash to local computer's desktop
119 | Dispersion.saveToDisk = function (pinHash, username) {
120 | //set save-to directory to a file on user's desktop
121 | let directory = `/Users/${username}/Desktop/ipfs`
122 | let pinSaveCommand = `ipfs get --output="${directory}" ${pinHash}`;
123 | exec(pinSaveCommand, function (error, stdout, stderr) {
124 | if (error !== null) console.log('exec error: ' + error);
125 | //get data from hash for file save
126 | storage.get(pinHash, function (error, data) {
127 | if (error) throw error;
128 | //check if the hash has already been pinned.
129 | if (Object.keys(data).length === 0) {
130 | alert("Please pin before download!");
131 | return;
132 | }
133 | //initial location and name of saved hash. Default to Desktop
134 | let fileLocation = `${directory}/${pinHash}`
135 | //filename of hash
136 | let filename = data.file
137 | let fileExtension;
138 | //determine and set file extension for saving
139 | if (!filename.includes('.')) {
140 | let buffer = readChunk.sync(fileLocation, 0, 262);
141 | fileExtension = `.${fileType(buffer).ext}`;
142 | } else {
143 | fileExtension = ''
144 | }
145 | //rename file based on filename and extension
146 | fs.rename(fileLocation, `"${directory}/${filename}${fileExtension}"`, function (err) {
147 | if (err) console.log('ERROR: ' + err);
148 | });
149 | });
150 | })
151 | }
152 |
153 | //function to start daemon
154 | Dispersion.startDaemon = function () {
155 | let daemonCommand = spawn('ipfs', ['daemon']);
156 | daemonCommand.stdout.on('data', function (data) {
157 | let dataString = data.toString();
158 | let result = /Daemon is ready/.test(dataString);
159 | if (result) {
160 | console.log('the daemon is running')
161 | }
162 | });
163 | daemonCommand.stderr.on('data', function (data) {
164 | let dataString = data.toString();
165 | let result = /daemon is running/.test(dataString);
166 | if (result) {
167 | console.log('Warning: Daemon already is running in a seperate process! Closing this application will not kill your IPFS Daemon.')
168 | }
169 | })
170 | }
171 | return Dispersion;
172 | }
173 |
174 | document.ondragover = document.ondrop = (ev) => {
175 | ev.preventDefault()
176 | }
177 |
178 | document.body.ondrop = (ev) => {
179 | console.log('hi ', ev.dataTransfer.files[0].path)
180 | $('#hash-input').val(ev.dataTransfer.files[0].path);
181 | ev.preventDefault()
182 | $('#hash-input').trigger('input');
183 | // $('#project-input').trigger('input');
184 | }
185 |
186 |
187 |
188 |
189 |
190 |
191 | //define globally if it doesn't already exist
192 | if (typeof (Dispersion) === 'undefined') {
193 | window.Dispersion = define_Dispersion_Library();
194 | } else {
195 | console.log("Dispersion already defined.");
196 | }
197 |
198 | })(window);
199 |
--------------------------------------------------------------------------------
/app/components/controllers/FileHistoryController.js:
--------------------------------------------------------------------------------
1 | angular.module('FileHistoryController', [])
2 | .controller('FileHistoryController', ['ProjectService', '$scope', '$http', 'DiskFactory', 'FileHistoryFactory', fileHistoryController]);
3 | function fileHistoryController(ProjectService, $scope, $http, DiskFactory, FileHistoryFactory) {
4 | //TODO:
5 |
6 | FileHistoryFactory.init()
7 |
8 | $scope.showInfo = false;
9 | $scope.showEditor = false;
10 | $scope.showMedia = false;
11 | $scope.ext = $scope.filename.split('.').pop();
12 | $scope.previousEditorContent = '';
13 | $scope.theme = 'monokai';
14 | $scope.modes = [
15 | 'abap',
16 | 'actionscript',
17 | 'ada',
18 | 'apache_conf',
19 | 'asciidoc',
20 | 'assembly_x86',
21 | 'autohotkey',
22 | 'batchfile',
23 | 'c9search',
24 | 'c_cpp',
25 | 'cirru',
26 | 'clojure',
27 | 'cobol',
28 | 'coffee',
29 | 'coldfusion',
30 | 'csharp',
31 | 'css',
32 | 'curly',
33 | 'd',
34 | 'dart',
35 | 'diff',
36 | 'dockerfile',
37 | 'dot',
38 | 'dummy',
39 | 'dummysyntax',
40 | 'eiffel',
41 | 'ejs',
42 | 'elixir',
43 | 'elm',
44 | 'erlang',
45 | 'forth',
46 | 'ftl',
47 | 'gcode',
48 | 'gherkin',
49 | 'gitignore',
50 | 'glsl',
51 | 'golang',
52 | 'groovy',
53 | 'haml',
54 | 'handlebars',
55 | 'haskell',
56 | 'haxe',
57 | 'html',
58 | 'html_ruby',
59 | 'ini',
60 | 'io',
61 | 'jack',
62 | 'jade',
63 | 'java',
64 | 'javascript',
65 | 'json',
66 | 'jsoniq',
67 | 'jsp',
68 | 'jsx',
69 | 'julia',
70 | 'latex',
71 | 'less',
72 | 'liquid',
73 | 'lisp',
74 | 'livescript',
75 | 'logiql',
76 | 'lsl',
77 | 'lua',
78 | 'luapage',
79 | 'lucene',
80 | 'makefile',
81 | 'markdown',
82 | 'matlab',
83 | 'mel',
84 | 'mushcode',
85 | 'mysql',
86 | 'nix',
87 | 'objectivec',
88 | 'ocaml',
89 | 'pascal',
90 | 'perl',
91 | 'pgsql',
92 | 'php',
93 | 'powershell',
94 | 'praat',
95 | 'prolog',
96 | 'properties',
97 | 'protobuf',
98 | 'python',
99 | 'r',
100 | 'rdoc',
101 | 'rhtml',
102 | 'ruby',
103 | 'rust',
104 | 'sass',
105 | 'scad',
106 | 'scala',
107 | 'scheme',
108 | 'scss',
109 | 'sh',
110 | 'sjs',
111 | 'smarty',
112 | 'snippets',
113 | 'soy_template',
114 | 'space',
115 | 'sql',
116 | 'stylus',
117 | 'svg',
118 | 'tcl',
119 | 'tex',
120 | 'text',
121 | 'textile',
122 | 'toml',
123 | 'twig',
124 | 'typescript',
125 | 'vala',
126 | 'vbscript',
127 | 'velocity',
128 | 'verilog',
129 | 'vhdl',
130 | 'xml',
131 | 'xquery',
132 | 'yaml',
133 | ];
134 | $scope.projectobj = JSON.parse($scope.projectobject);
135 |
136 | $scope.versions = function () {
137 | if (!FileHistoryFactory.getFileHistory()[$scope.projectname]) return []
138 | return FileHistoryFactory.getFileHistory()[$scope.projectname].filter((version) => {
139 | let file = $scope.filename
140 | if (file) {
141 | if (file[0] !== '/') file = '/' + file;
142 | return version.file === file;
143 | }
144 | });
145 | }
146 | $scope.toggleEditor = () => {
147 | $scope.showEditor = !$scope.showEditor;
148 | }
149 | $scope.toggleShowInfo = () => {
150 | console.log('clicked toggle show info')
151 | $scope.showInfo = !$scope.showInfo;
152 | }
153 |
154 | //instead now make new file history obj
155 | $scope.makeNewHistoryObj = () => {
156 | return [$scope.filename, $scope.projectname, $scope.editorContent, { date: new Date().toUTCString(), file: $scope.filename }]
157 | }
158 |
159 | //make new history, need to add to file history factroy data store
160 | $scope.saveFile = function () {
161 | Materialize.toast("New Version Saved", 2000);
162 | console.log('$scope.editorcontent in saveFile', $scope.editorContent);
163 | let fileDataSaveArray = $scope.makeNewHistoryObj();
164 | console.log('save clicked, historyoobj generated: \n', fileDataSaveArray);
165 | console.log('pushing to FilehHistoryfactory')
166 | FileHistoryFactory.add(fileDataSaveArray[3], fileDataSaveArray[1])
167 | DiskFactory.overwrite(...fileDataSaveArray);
168 | }
169 | $scope.recordIndex = function (index) {
170 | console.log(index)
171 | $scope.openVersionIndex = index;
172 | }
173 |
174 | // delete item from file factroy array
175 | $scope.delete = function () {
176 | //update to change in extended full app data store model
177 | Materialize.toast("Version deleted", 2000);
178 | console.log('filehistoryversions:', $scope.fileHistoryVersions)
179 | console.log($scope.openVersionIndex);
180 | console.log('deleteitem:', $scope.fileHistoryVersions[$scope.openVersionIndex])
181 | let deleteItem = $scope.fileHistoryVersions[$scope.openVersionIndex]
182 | if (confirm('Are you sure you wish to delete: ', $scope.filename.slice(1), deleteItem.date)) {
183 | $scope.fileHistoryVersions.splice($scope.openVersionIndex, 1);
184 | }
185 | $scope.aceEditor.setValue('');
186 | $scope.openVersionIndex = 0;
187 | $scope.updateEditorContent(0, $scope.fileHistoryVersions[0]);
188 | }
189 | $scope.aceEditor;
190 | $scope.aceLoaded = function (_editor) {
191 | _editor.$blockScrolling = Infinity;
192 | $scope.aceEditor = _editor;
193 |
194 |
195 | $scope.renderer = _editor.renderer;
196 | $scope.session = _editor.getSession();
197 | $scope.session.setUndoManager(new ace.UndoManager());
198 | _editor.on("changeSession", function (e) {
199 | })
200 | $scope.session.on("change", function (e) {
201 | $scope.editorContent = $scope.session.getValue()
202 | })
203 | }
204 | $scope.aceChanged = function (e) {
205 |
206 | };
207 |
208 | //change to use just url on file obj
209 | $scope.updateEditorContent = function (index = 0, file) {
210 | if (!$scope.image) {
211 | let version = file ? file : $scope.versions()[index];
212 | if (version && version.data) {
213 | $scope.aceEditor.setValue(version.data)
214 | $scope.showEditor = true;
215 | } else {
216 | if (version && version.url) {
217 | $http.get(version.url).then((res) => {
218 | $scope.versions()[index].data = res.data;
219 | $scope.previousEditorContent = $scope.editorContent;
220 | $scope.editorContent = res.data;
221 | $scope.showEditor = true;
222 | });
223 | }
224 | }
225 | }
226 | }
227 | // $scope.updateEditorContent = function (index = 0, file) {
228 | // // console.log($scope.aceEditor);
229 | // if (!$scope.image) {
230 | // let version = file ? file : $scope.fileHistoryVersions[index];
231 |
232 | // // console.log(version);
233 |
234 | // if (version && version.data) {
235 | // // $scope.editorContent = version.data;
236 | // $scope.aceEditor.setValue(version.data)
237 | // $scope.showEditor = true;
238 | // } else {
239 | // if (version && version.url) {
240 | // $http.get(version.url + $scope.filename).then((res) => {
241 | // // console.log('http called for ', version.url + $scope.filename)
242 | // $scope.fileHistoryVersions[index].data = res.data;
243 | // $scope.previousEditorContent = $scope.editorContent;
244 | // $scope.editorContent = res.data;
245 | // // $scope.aceEditor.setValue(res.data);
246 | // $scope.showEditor = true;
247 | // });
248 | // }
249 | // // $scope.showEditor = false;
250 | // }
251 | // }
252 | // }
253 | $scope.clearEditor = function () {
254 | console.log('clear clicked', $scope.editorContent)
255 | $scope.previousEditorContent = $scope.editorContent;
256 | $scope.aceEditor.setValue('');
257 | }
258 | $scope.undo = function () {
259 | console.log('undo clicked');
260 | console.log($scope.previousEditorContent);
261 | $scope.editorContent = $scope.previousEditorContent;
262 | }
263 |
264 | $scope.getMediaContent = (url) => {
265 |
266 | $scope.showEditor = false;
267 | $scope.mediaContentUrl = url;
268 | $scope.showMedia = true;
269 | }
270 |
271 | //
272 | $scope.getContentUrl = ProjectService.getContentUrl; //function
273 | // $http.get(self.getContentUrl(file)).then((res) => {
274 | // $scope.editorContent = res.data;
275 | // })
276 |
277 | $scope.themes = [
278 | "chrome",
279 | "clouds",
280 | "crimson_editor",
281 | "dawn",
282 | "dreamweaver",
283 | "eclipse",
284 | "github",
285 | "solarized_light",
286 | "textmate",
287 | "tomorrow",
288 | "xcode",
289 | "kuroir",
290 | "katzenmilch",
291 | "ambiance",
292 | "chaos",
293 | "clouds_midnight",
294 | "cobalt",
295 | "idle_fingers",
296 | "kr_theme",
297 | "merbivore",
298 | "merbivore_soft",
299 | "mono_industrial",
300 | "monokai",
301 | "pastel_on_dark",
302 | "solarized_dark",
303 | "terminal",
304 | "tomorrow_night",
305 | "tomorrow_night_blue",
306 | "tomorrow_night_bright",
307 | "tomorrow_night_eighties",
308 | "twilight",
309 | "vibrant_ink"
310 | ];
311 | $scope.updateEditorContent();
312 | $scope.recordIndex();
313 | $scope.toggleShowInfo();
314 | }
315 |
316 |
317 |
318 |
319 |
320 | //taken from project ctrl
321 | // needs lots of refactoring
322 | // self.aceOptions = {
323 | // useWrapMode: true,
324 | // showGutter: true,
325 | // onLoad: self.aceLoaded,
326 | // onChange: self.aceChanged,
327 | // enableBasicAutocompletion: true,
328 | // // enableLiveAutocompletion: true
329 | // enableSnippets: true
330 | // // advanced: {
331 | // // enableSnippets: true,
332 | // // enableBasicAutocompletion: true,
333 | // // enableLiveAutocompletion: true
334 | // // }
335 | // };
336 | // self.aceLoaded = function (_editor) {
337 | // // Options
338 | // _editor.setReadOnly(true);
339 | // };
340 |
341 | // self.aceChanged = function (e) {
342 | // //
343 | // };
344 | // self.isImage = (file) => {
345 | // let imageTester = /(\.jpeg$)|(\.jpg$)|(\.png$)|(\.gif$)|(\.json$)|(\.md$)|(\.log$)/i;
346 | // return imageTester.test(file);
347 | // }
348 | // self.isText = (file) => {
349 | // let textTester = /(\.html$)|(\.js$)|(\.css$)|(\.txt$)|(\.json$)|(\.md$)|(\.log$)/i;
350 | // return textTester.test(file);
351 | // }
352 | // self.updateEditorContent = (index, url) => {
353 | // console.log(self.fileVersions(self.filesList()[index]))
354 | // if (!url) {
355 | // url = self.currentUrl() + self.filesList()[index];
356 | // }
357 | // let splitArr = url.split('/')
358 | // let file = splitArr[splitArr.length - 1];
359 | // let textTester = /(\.html$)|(\.js$)|(\.css$)|(\.txt$)|(\.json$)|(\.md$)|(\.log$)/;
360 | // let text = textTester.test(file);
361 | // let type;
362 | // if (text) {
363 | // type = textTester.exec(file)[0].slice(1);
364 | // }
365 | // if (!text) {
366 | // self.getMediaContent(url);
367 | // } else {
368 |
369 | // console.log(type);
370 | // self.getContent(url);
371 | // }
372 | // }
373 | // self.getMediaContent = (url) => {
374 |
375 | // self.showEditor = false;
376 | // self.mediaContentUrl = url;
377 | // self.showMedia = true;
378 | // }
--------------------------------------------------------------------------------
/app/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | Dispersion
7 |
8 |
9 |
10 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
38 |
39 |
40 |
41 |
42 |
46 |
47 |
53 |
54 |
55 |
56 |
99 |
100 |
101 |
102 |
103 |
110 |
111 |
112 |
125 |
126 |
127 |
128 |
138 |
139 |
140 |
141 |
151 |
152 |
153 |
154 |
155 |
158 |
159 |
160 |
161 |
162 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
233 |
234 |
--------------------------------------------------------------------------------
/app/components/factories/ipfsService.js:
--------------------------------------------------------------------------------
1 | angular
2 | .module('IpfsService', [])
3 | .factory('IpfsService', ['$q', '$interval', 'PublishService', ipfsService]);
4 |
5 | function ipfsService($q, $interval, PublishService) {
6 |
7 | ///may have made some breaking changes, please try and clean up and test thoroughly
8 | let daemonLoadedStatus = () => daemonLoaded;
9 | let daemonLoaded = false;
10 |
11 | function startDaemon() {
12 | return $q(function (resolve, reject) {
13 | let daemonCommand = spawn('ipfs', ['daemon']);
14 | daemonCommand.stdout.on('data', function (data) {
15 | let dataString = data.toString();
16 | let result = /Daemon is ready/.test(dataString);
17 | if (result) {
18 | console.log('the daemon is running')
19 | resolve(result);
20 | }
21 | });
22 | daemonCommand.stderr.on('data', function (data) {
23 | let dataString = data.toString();
24 | let result = /daemon is running/.test(dataString);
25 | if (result) {
26 | console.log('Warning: Daemon already is running in a seperate process! Closing this application will not kill your IPFS Daemon.')
27 | resolve(result);
28 | } else {
29 | reject(dataString);
30 | }
31 | })
32 | })
33 | }
34 |
35 | //Hashes file, puts it in storage, and requests it to distribute
36 | function submitFile(filepath) {
37 | return $q((resolve, reject) => {
38 | //file or directory to be hashed.
39 | let hashFile = filepath
40 | if (hashFile.includes('/')) hashFile = `"${hashFile}"`;
41 | // recursively hashes directory or file and adds to ipfs
42 | let command = `ipfs add -r ${hashFile}`;
43 |
44 | exec(command, function (error, stdout, stderr) {
45 | //grabs just the filename from the absolute path of the added file
46 | let fileLocationArray = hashFile.split('/');
47 | let name = fileLocationArray[fileLocationArray.length - 1];
48 | //separate hashes from folder into an array
49 | let hashArray = stdout.trim().split('\n');
50 | console.log('hash array, tophash');
51 | console.log(hashArray)
52 | let topHash = hashArray[hashArray.length - 1].split(' ');
53 | console.log(topHash)
54 | let file = topHash.slice(2).join(' ');
55 | let hashObj = {
56 | "file": file,
57 | "hash": topHash[1],
58 | "date": new Date().toUTCString(),
59 | "url": "https://ipfs.io/ipfs/" + topHash[1],
60 | // "url": "http://ipfs.io/ipfs/" + topHash[1],
61 | 'files': []
62 | }
63 | hashArray.forEach(function (hString, index) {
64 | let tempArray = hString.split(' ');
65 | var requestObj = {
66 | [tempArray[1]]: {
67 | "url": "https://ipfs.io/ipfs/" + tempArray[1]
68 | // "url": "http://ipfs.io/ipfs/" + tempArray[1]
69 | }
70 | }
71 | if ((/\./.test(tempArray[tempArray.length - 1])) && index < hashArray.length - 1) {
72 | console.log('tempArray', tempArray)
73 | // hashObj.files.push(`/${tempArray[2].split('/').slice(1).join('/')}`)
74 | hashObj.files.push(`/${tempArray.slice(2).join('\ ').split('/').slice(1).join('/')}`)
75 | }
76 |
77 | requestHashes(requestObj)
78 | resolve(hashObj)
79 | })
80 | })
81 | })
82 | }
83 | function rehashProject(filepath, fileVersionObject, fileName, projectName, addToPublishHistory = false) {
84 | //file or directory to be hashed.
85 | // recursively hashes directory or file and adds to ipfs
86 | // let command = `ipfs add -r "${filepath}"`;
87 |
88 | // exec(command, function (error, stdout, stderr) {
89 | // //grabs just the filename from the absolute path of the added file
90 |
91 | // let hashArray = stdout.trim().split('\n');
92 |
93 | // let topHash = hashArray[hashArray.length - 1].split(' ')[1];
94 | // console.log(topHash)
95 | // fileVersionObject.hash = topHash;
96 | // fileVersionObject.url = `https://ipfs.io/ipfs/${topHash}${fileName}`;
97 |
98 | // let hashObj = {
99 | // "file": fileName,
100 | // "hash": topHash[1],
101 | // "url": "https://ipfs.io/ipfs/" + topHash[1] + fileName,
102 | // }
103 | // hashArray.forEach(function (hString, index) {
104 | // let tempArray = hString.split(' ');
105 | // var requestObj = {
106 | // [tempArray[1]]: {
107 | // "url": "https://ipfs.io/ipfs/" + tempArray[1]
108 | // }
109 | // }
110 | // requestHashes(requestObj)
111 | // })
112 | // })
113 | let command = `ipfs add -r "${filepath}"`;
114 |
115 | exec(command, function (error, stdout, stderr) {
116 | //grabs just the filename from the absolute path of the added file
117 |
118 | let hashArray = stdout.trim().split('\n');
119 |
120 | let topHash = hashArray[hashArray.length - 1].split(' ')[1];
121 | console.log(topHash)
122 | fileVersionObject.hash = topHash;
123 | fileVersionObject.url = `https://ipfs.io/ipfs/${topHash}${fileName}`;
124 | // fileVersionObject.url = `http://ipfs.io/ipfs/${topHash}${fileName}`;
125 |
126 | let hashObj = {
127 | "hash": topHash,
128 | "date": new Date().toUTCString(),
129 | "url": "https://ipfs.io/ipfs/" + topHash,
130 | // "url": "http://ipfs.io/ipfs/" + topHash,
131 | 'files': [],
132 | 'publish': false
133 | }
134 |
135 |
136 | hashArray.forEach(function (hString, index) {
137 | let tempArray = hString.split(' ');
138 | var requestObj = {
139 | [tempArray[1]]: {
140 | "url": "https://ipfs.io/ipfs/" + tempArray[1]
141 | // "url": "http://ipfs.io/ipfs/" + tempArray[1]
142 | }
143 | }
144 | if ((/\./.test(tempArray[tempArray.length - 1])) && index < hashArray.length - 1) {
145 | console.log('tempArray', tempArray)
146 | // hashObj.files.push(`/${tempArray[2].split('/').slice(1).join('/')}`)
147 | hashObj.files.push(`/${tempArray.slice(2).join('\ ').split('/').slice(1).join('/')}`)
148 | }
149 | requestHashes(requestObj)
150 | })
151 | PublishService.add(hashObj, true, projectName)
152 | })
153 | }
154 |
155 | function requestHashes(requestObj) {
156 | for (let key in requestObj) {
157 | let url = requestObj[key]["url"];
158 | for (let i = 0; i < 5; i++) {
159 | request(url, (err, response, body) => {
160 | if (err) {
161 | console.log('error making distribute request to IPFS');
162 | console.error(err);
163 | } else {
164 | console.log(response.statusCode)
165 | }
166 | })
167 | }
168 | }
169 | }
170 |
171 |
172 | function unPin(pinHash) {
173 | return $q(function (resolve, reject) {
174 | let pinRmCommand = 'ipfs pin rm ' + pinHash;
175 | exec(pinRmCommand, function (error, stdout, stderr) {
176 | console.log(stdout)
177 | resolve()
178 | if (error !== null) {
179 | reject(error);
180 | }
181 | })
182 | })
183 | }
184 |
185 | function publishHash(publishObj, projectName) {
186 | // console.log(projectName)
187 | // console.log(publishObj)
188 | if (PublishService && PublishService.data && PublishService.data[projectName] && PublishService.data[projectName][0]) {
189 | PublishService.data[projectName][0]['publish'] = true;
190 | console.log("reach into publish service data", PublishService.data[projectName][0]);
191 | }
192 | console.log('publish obj 0', publishObj[0])
193 | hash = publishObj[0]['hash']
194 | console.log('hash in publishHash hash');
195 | let publishIt = 'ipfs name publish ' + hash;
196 | exec(publishIt, function (error, stdout, stderr) {
197 | console.log(stdout, hash);
198 | let hashed = `http://gateway.ipfs.io/ipns/${stdout.split(' ')[2].slice(0, -1)}`
199 | //$('#hashlink').text(hashed);
200 | if (error !== null) {
201 | console.log('exec error: ' + error);
202 | } else {
203 | PublishService.updatePublishData()
204 | }
205 | })
206 | }
207 |
208 | function addPin(pinHash, pinDescription) {
209 | let pinCommand = 'ipfs pin add ' + pinHash;
210 | let hashObject = {
211 | "file": pinDescription,
212 | "pinnedBy": 'someone else',
213 | "pinDate": new Date(),
214 | "url": "https://ipfs.io/ipfs/" + pinHash
215 | // "url": "http://ipfs.io/ipfs/" + pinHash
216 | };
217 | exec(pinCommand, function (error, stdout, stderr) {
218 | //saves pinned hash to Electron App storage
219 | storage.set(pinHash, hashObject, function (error) {
220 | if (error) throw error;
221 | });
222 | if (error !== null) {
223 | console.log('exec error: ' + error);
224 | }
225 | })
226 | }
227 |
228 | function getFileData(hash, file) {
229 | return $q(function (resolve, reject) {
230 | let fileCommand = `ipfs cat ${hash}/${file}`;
231 | exec(fileCommand, function (error, stdout, stderr) {
232 | resolve(stdout)
233 | if (error !== null) {
234 | console.log('exec error: ' + error);
235 | }
236 | })
237 | })
238 | }
239 |
240 | function saveToDisk(pinHash, username) {
241 | //set save-to directory to a file on user's desktop
242 | let directory = `/Users/${username}/Desktop/ipfs`
243 | let pinSaveCommand = `ipfs get --output="${directory}" ${pinHash}`;
244 | exec(pinSaveCommand, function (error, stdout, stderr) {
245 | if (error !== null) console.log('exec error: ' + error);
246 | //get data from hash for file save
247 | storage.get(pinHash, function (error, data) {
248 | if (error) throw error;
249 | //check if the hash has already been pinned.
250 | if (Object.keys(data).length === 0) {
251 | alert("Please pin before download!");
252 | return;
253 | }
254 | //initial location and name of saved hash. Default to Desktop
255 | let fileLocation = `${directory}/${pinHash}`
256 | //filename of hash
257 | let filename = data.file
258 | let fileExtension;
259 | //determine and set file extension for saving
260 | if (!filename.includes('.')) {
261 | let buffer = readChunk.sync(fileLocation, 0, 262);
262 | fileExtension = `.${fileType(buffer).ext}`;
263 | } else {
264 | fileExtension = ''
265 | }
266 | //rename file based on filename and extension
267 | fs.rename(fileLocation, `"${directory}/${filename}${fileExtension}"`, function (err) {
268 | if (err) console.log('ERROR: ' + err);
269 | });
270 | });
271 | })
272 | }
273 |
274 | function getPeerID() {
275 | return $q(function (resolve, reject) {
276 | let idCommand = 'ipfs config show';
277 | exec(idCommand, function (error, stdout, stderr) {
278 | if (error !== null) console.log('exec error: ' + error);
279 | let peerID = JSON.parse(stdout)['Identity']['PeerID'];
280 | let bootstrap = JSON.parse(stdout)['Bootstrap'];
281 | let ipnsLink = `https://gateway.ipfs.io/ipns/${peerID}`;
282 | let peerArray = [ipnsLink, bootstrap]
283 | resolve(peerArray)
284 | })
285 | })
286 | }
287 |
288 | function findProviders(hash) {
289 | return $q(function (resolve, reject) {
290 | let provs = `ipfs dht findprovs ${hash}`;
291 | exec(provs, function (error, stdout, stderr) {
292 | if (error !== null) console.log('exec error: ' + error);
293 | resolve(stdout.split('\n'))
294 | })
295 | })
296 | }
297 |
298 | function getSettingsInfo() {
299 | return $q(function (resolve, reject) {
300 | getPeerID().then(function (data) {
301 | let idCommand = 'ipfs id';
302 | exec(idCommand, function (error, stdout, stderr) {
303 | if (error !== null) console.log('exec error: ' + error);
304 | let multiAddr = JSON.parse(stdout)['Addresses'][3];
305 | let version = JSON.parse(stdout)["ProtocolVersion"].split('/')[1]
306 | data.push(multiAddr, version)
307 | resolve(data)
308 | })
309 | })
310 | })
311 | }
312 |
313 | function addBootstrapPeer(peerAddress) {
314 | return $q(function (resolve, reject) {
315 | let idCommand = `ipfs bootstrap add ${peerAddress}`;
316 | exec(idCommand, function (error, stdout, stderr) {
317 | if (error !== null) console.log('exec error: ' + error);
318 | let success = `peer added`
319 | resolve(success)
320 | })
321 | })
322 | }
323 |
324 | return {
325 | findProviders: findProviders,
326 | addPeer: addBootstrapPeer,
327 | getSettingsInfo: getSettingsInfo,
328 | getFileData: getFileData,
329 | rehashProject: rehashProject,
330 | init: startDaemon,
331 | addFile: submitFile,
332 | saveToDisk: saveToDisk,
333 | pin: addPin,
334 | unPin: unPin,
335 | publish: publishHash
336 | }
337 | }
--------------------------------------------------------------------------------
/app/.electron/Cache/f_00000c:
--------------------------------------------------------------------------------
1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o'
43 | } else if (obj.outerHTML) {
44 | return obj.outerHTML
45 | } else if (isNode(obj)) {
46 | return serialize(obj)
47 | } else {
48 | var constructor = 'Object'
49 | if (obj.constructor && typeof obj.constructor === 'function') {
50 | constructor = obj.constructor.name
51 | }
52 |
53 | strs.push(constructor)
54 | strs.push('{')
55 | var first = true
56 | for (var key in obj) {
57 | if (Object.prototype.hasOwnProperty.call(obj, key)) {
58 | if (first) {
59 | first = false
60 | } else {
61 | strs.push(', ')
62 | }
63 |
64 | strs.push(key + ': ' + stringify(obj[key], depth - 1))
65 | }
66 | }
67 | strs.push('}')
68 | }
69 | return strs.join('')
70 | default:
71 | return obj
72 | }
73 | }
74 |
75 | module.exports = stringify
76 |
77 | },{"./util":2,"dom-serialize":6}],2:[function(require,module,exports){
78 | exports.instanceOf = function (value, constructorName) {
79 | return Object.prototype.toString.apply(value) === '[object ' + constructorName + ']'
80 | }
81 |
82 | exports.elm = function (id) {
83 | return document.getElementById(id)
84 | }
85 |
86 | exports.generateId = function (prefix) {
87 | return prefix + Math.floor(Math.random() * 10000)
88 | }
89 |
90 | exports.isUndefined = function (value) {
91 | return typeof value === 'undefined'
92 | }
93 |
94 | exports.isDefined = function (value) {
95 | return !exports.isUndefined(value)
96 | }
97 |
98 | exports.parseQueryParams = function (locationSearch) {
99 | var params = {}
100 | var pairs = locationSearch.substr(1).split('&')
101 | var keyValue
102 |
103 | for (var i = 0; i < pairs.length; i++) {
104 | keyValue = pairs[i].split('=')
105 | params[decodeURIComponent(keyValue[0])] = decodeURIComponent(keyValue[1])
106 | }
107 |
108 | return params
109 | }
110 |
111 | },{}],3:[function(require,module,exports){
112 | // Load our dependencies
113 | var stringify = require('../common/stringify')
114 |
115 | // Define our context Karma constructor
116 | var ContextKarma = function (callParentKarmaMethod) {
117 | // Define local variables
118 | var hasError = false
119 | var self = this
120 |
121 | // Define our loggers
122 | // DEV: These are intentionally repeated in client and context
123 | this.log = function (type, args) {
124 | var values = []
125 |
126 | for (var i = 0; i < args.length; i++) {
127 | values.push(this.stringify(args[i], 3))
128 | }
129 |
130 | this.info({log: values.join(', '), type: type})
131 | }
132 |
133 | this.stringify = stringify
134 |
135 | // Define our proxy error handler
136 | // DEV: We require one in our context to track `hasError`
137 | this.error = function () {
138 | hasError = true
139 | callParentKarmaMethod('error', [].slice.call(arguments))
140 | return false
141 | }
142 |
143 | // Define our start handler
144 | var UNIMPLEMENTED_START = function () {
145 | this.error('You need to include some adapter that implements __karma__.start method!')
146 | }
147 | // all files loaded, let's start the execution
148 | this.loaded = function () {
149 | // has error -> cancel
150 | if (!hasError) {
151 | this.start(this.config)
152 | }
153 |
154 | // remove reference to child iframe
155 | this.start = UNIMPLEMENTED_START
156 | }
157 | // supposed to be overriden by the context
158 | // TODO(vojta): support multiple callbacks (queue)
159 | this.start = UNIMPLEMENTED_START
160 |
161 | // Define proxy methods
162 | // DEV: This is a closured `for` loop (same as a `forEach`) for IE support
163 | var proxyMethods = ['complete', 'info', 'result']
164 | for (var i = 0; i < proxyMethods.length; i++) {
165 | (function bindProxyMethod (methodName) {
166 | self[methodName] = function boundProxyMethod () {
167 | callParentKarmaMethod(methodName, [].slice.call(arguments))
168 | }
169 | }(proxyMethods[i]))
170 | }
171 |
172 | // Define bindings for context window
173 | this.setupContext = function (contextWindow) {
174 | // If we clear the context after every run and we already had an error
175 | // then stop now. Otherwise, carry on.
176 | if (self.config.clearContext && hasError) {
177 | return
178 | }
179 |
180 | // Perform window level bindings
181 | // DEV: We return `self.error` since we want to `return false` to ignore errors
182 | contextWindow.onerror = function () {
183 | return self.error.apply(self, arguments)
184 | }
185 | // DEV: We must defined a function since we don't want to pass the event object
186 | contextWindow.onbeforeunload = function (e, b) {
187 | callParentKarmaMethod('onbeforeunload', [])
188 | }
189 |
190 | contextWindow.dump = function () {
191 | self.log('dump', arguments)
192 | }
193 |
194 | contextWindow.alert = function (msg) {
195 | self.log('alert', [msg])
196 | }
197 |
198 | // If we want to overload our console, then do it
199 | var getConsole = function (currentWindow) {
200 | return currentWindow.console || {
201 | log: function () {},
202 | info: function () {},
203 | warn: function () {},
204 | error: function () {},
205 | debug: function () {}
206 | }
207 | }
208 | if (self.config.captureConsole) {
209 | // patch the console
210 | var localConsole = contextWindow.console = getConsole(contextWindow)
211 | var logMethods = ['log', 'info', 'warn', 'error', 'debug']
212 | var patchConsoleMethod = function (method) {
213 | var orig = localConsole[method]
214 | if (!orig) {
215 | return
216 | }
217 | localConsole[method] = function () {
218 | self.log(method, arguments)
219 | return Function.prototype.apply.call(orig, localConsole, arguments)
220 | }
221 | }
222 | for (var i = 0; i < logMethods.length; i++) {
223 | patchConsoleMethod(logMethods[i])
224 | }
225 | }
226 | }
227 | }
228 |
229 | // Define call/proxy methods
230 | ContextKarma.getDirectCallParentKarmaMethod = function (parentWindow) {
231 | return function directCallParentKarmaMethod (method, args) {
232 | // If the method doesn't exist, then error out
233 | if (!parentWindow.karma[method]) {
234 | parentWindow.karma.error('Expected Karma method "' + method + '" to exist but it doesn\'t')
235 | return
236 | }
237 |
238 | // Otherwise, run our method
239 | parentWindow.karma[method].apply(parentWindow.karma, args)
240 | }
241 | }
242 | ContextKarma.getPostMessageCallParentKarmaMethod = function (parentWindow) {
243 | return function postMessageCallParentKarmaMethod (method, args) {
244 | parentWindow.postMessage({__karmaMethod: method, __karmaArguments: args}, window.location.origin)
245 | }
246 | }
247 |
248 | // Export our module
249 | module.exports = ContextKarma
250 |
251 | },{"../common/stringify":1}],4:[function(require,module,exports){
252 | // Load in our dependencies
253 | var ContextKarma = require('./karma')
254 |
255 | // Resolve our parent window
256 | var parentWindow = window.opener || window.parent
257 |
258 | // Define a remote call method for Karma
259 | var callParentKarmaMethod = ContextKarma.getDirectCallParentKarmaMethod(parentWindow)
260 |
261 | // If we don't have access to the window, then use `postMessage`
262 | // DEV: In Electron, we don't have access to the parent window due to it being in a separate process
263 | // DEV: We avoid using this in Internet Explorer as they only support strings
264 | // http://caniuse.com/#search=postmessage
265 | var haveParentAccess = false
266 | try { haveParentAccess = !!parentWindow.window } catch (err) { /* Ignore errors (likely permisison errors) */ }
267 | if (!haveParentAccess) {
268 | callParentKarmaMethod = ContextKarma.getPostMessageCallParentKarmaMethod(parentWindow)
269 | }
270 |
271 | // Define a window-scoped Karma
272 | window.__karma__ = new ContextKarma(callParentKarmaMethod)
273 |
274 | },{"./karma":3}],5:[function(require,module,exports){
275 | (function (global){
276 |
277 | var NativeCustomEvent = global.CustomEvent;
278 |
279 | function useNative () {
280 | try {
281 | var p = new NativeCustomEvent('cat', { detail: { foo: 'bar' } });
282 | return 'cat' === p.type && 'bar' === p.detail.foo;
283 | } catch (e) {
284 | }
285 | return false;
286 | }
287 |
288 | /**
289 | * Cross-browser `CustomEvent` constructor.
290 | *
291 | * https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent.CustomEvent
292 | *
293 | * @public
294 | */
295 |
296 | module.exports = useNative() ? NativeCustomEvent :
297 |
298 | // IE >= 9
299 | 'function' === typeof document.createEvent ? function CustomEvent (type, params) {
300 | var e = document.createEvent('CustomEvent');
301 | if (params) {
302 | e.initCustomEvent(type, params.bubbles, params.cancelable, params.detail);
303 | } else {
304 | e.initCustomEvent(type, false, false, void 0);
305 | }
306 | return e;
307 | } :
308 |
309 | // IE <= 8
310 | function CustomEvent (type, params) {
311 | var e = document.createEventObject();
312 | e.type = type;
313 | if (params) {
314 | e.bubbles = Boolean(params.bubbles);
315 | e.cancelable = Boolean(params.cancelable);
316 | e.detail = params.detail;
317 | } else {
318 | e.bubbles = false;
319 | e.cancelable = false;
320 | e.detail = void 0;
321 | }
322 | return e;
323 | }
324 |
325 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
326 | },{}],6:[function(require,module,exports){
327 |
328 | /**
329 | * Module dependencies.
330 | */
331 |
332 | var extend = require('extend');
333 | var encode = require('ent/encode');
334 | var CustomEvent = require('custom-event');
335 | var voidElements = require('void-elements');
336 |
337 | /**
338 | * Module exports.
339 | */
340 |
341 | exports = module.exports = serialize;
342 | exports.serializeElement = serializeElement;
343 | exports.serializeAttribute = serializeAttribute;
344 | exports.serializeText = serializeText;
345 | exports.serializeComment = serializeComment;
346 | exports.serializeDocument = serializeDocument;
347 | exports.serializeDoctype = serializeDoctype;
348 | exports.serializeDocumentFragment = serializeDocumentFragment;
349 | exports.serializeNodeList = serializeNodeList;
350 |
351 | /**
352 | * Serializes any DOM node. Returns a string.
353 | *
354 | * @param {Node} node - DOM Node to serialize
355 | * @param {String} [context] - optional arbitrary "context" string to use (useful for event listeners)
356 | * @param {Function} [fn] - optional callback function to use in the "serialize" event for this call
357 | * @param {EventTarget} [eventTarget] - optional EventTarget instance to emit the "serialize" event on (defaults to `node`)
358 | * return {String}
359 | * @public
360 | */
361 |
362 | function serialize (node, context, fn, eventTarget) {
363 | if (!node) return '';
364 | if ('function' === typeof context) {
365 | fn = context;
366 | context = null;
367 | }
368 | if (!context) context = null;
369 |
370 | var rtn;
371 | var nodeType = node.nodeType;
372 |
373 | if (!nodeType && 'number' === typeof node.length) {
374 | // assume it's a NodeList or Array of Nodes
375 | rtn = exports.serializeNodeList(node, context, fn);
376 | } else {
377 |
378 | if ('function' === typeof fn) {
379 | // one-time "serialize" event listener
380 | node.addEventListener('serialize', fn, false);
381 | }
382 |
383 | // emit a custom "serialize" event on `node`, in case there
384 | // are event listeners for custom serialization of this node
385 | var e = new CustomEvent('serialize', {
386 | bubbles: true,
387 | cancelable: true,
388 | detail: {
389 | serialize: null,
390 | context: context
391 | }
392 | });
393 |
394 | e.serializeTarget = node;
395 |
396 | var target = eventTarget || node;
397 | var cancelled = !target.dispatchEvent(e);
398 |
399 | // `e.detail.serialize` can be set to a:
400 | // String - returned directly
401 | // Node - goes through serializer logic instead of `node`
402 | // Anything else - get Stringified first, and then returned directly
403 | var s = e.detail.serialize;
404 | if (s != null) {
405 | if ('string' === typeof s) {
406 | rtn = s;
407 | } else if ('number' === typeof s.nodeType) {
408 | // make it go through the serialization logic
409 | rtn = serialize(s, context, null, target);
410 | } else {
411 | rtn = String(s);
412 | }
413 | } else if (!cancelled) {
414 | // default serialization logic
415 | switch (nodeType) {
416 | case 1 /* element */:
417 | rtn = exports.serializeElement(node, context, eventTarget);
418 | break;
419 | case 2 /* attribute */:
420 | rtn = exports.serializeAttribute(node);
421 | break;
422 | case 3 /* text */:
423 | rtn = exports.serializeText(node);
424 | break;
425 | case 8 /* comment */:
426 | rtn = exports.serializeComment(node);
427 | break;
428 | case 9 /* document */:
429 | rtn = exports.serializeDocument(node, context, eventTarget);
430 | break;
431 | case 10 /* doctype */:
432 | rtn = exports.serializeDoctype(node);
433 | break;
434 | case 11 /* document fragment */:
435 | rtn = exports.serializeDocumentFragment(node, context, eventTarget);
436 | break;
437 | }
438 | }
439 |
440 | if ('function' === typeof fn) {
441 | node.removeEventListener('serialize', fn, false);
442 | }
443 | }
444 |
445 | return rtn || '';
446 | }
447 |
448 | /**
449 | * Serialize an Attribute node.
450 | */
451 |
452 | function serializeAttribute (node, opts) {
453 | return node.name + '="' + encode(node.value, extend({
454 | named: true
455 | }, opts)) + '"';
456 | }
457 |
458 | /**
459 | * Serialize a DOM element.
460 | */
461 |
462 | function serializeElement (node, context, eventTarget) {
463 | var c, i, l;
464 | var name = node.nodeName.toLowerCase();
465 |
466 | // opening tag
467 | var r = '<' + name;
468 |
469 | // attributes
470 | for (i = 0, c = node.attributes, l = c.length; i < l; i++) {
471 | r += ' ' + exports.serializeAttribute(c[i]);
472 | }
473 |
474 | r += '>';
475 |
476 | // child nodes
477 | r += exports.serializeNodeList(node.childNodes, context, null, eventTarget);
478 |
479 | // closing tag, only for non-void elements
480 | if (!voidElements[name]) {
481 | r += '' + name + '>';
482 | }
483 |
484 | return r;
485 | }
486 |
487 | /**
488 | * Serialize a text node.
489 | */
490 |
491 | function serializeText (node, opts) {
492 | return encode(node.nodeValue, extend({
493 | named: true,
494 | special: { '<': true, '>': true, '&': true }
495 | }, opts));
496 | }
497 |
498 | /**
499 | * Serialize a comment node.
500 | */
501 |
502 | function serializeComment (node) {
503 | return '';
504 | }
505 |
506 | /**
507 | * Serialize a Document node.
508 | */
509 |
510 | function serializeDocument (node, context, eventTarget) {
511 | return exports.serializeNodeList(node.childNodes, context, null, eventTarget);
512 | }
513 |
514 | /**
515 | * Serialize a DOCTYPE node.
516 | * See: http://stackoverflow.com/a/10162353
517 | */
518 |
519 | function serializeDoctype (node) {
520 | var r = '';
535 | return r;
536 | }
537 |
538 | /**
539 | * Serialize a DocumentFragment instance.
540 | */
541 |
542 | function serializeDocumentFragment (node, context, eventTarget) {
543 | return exports.serializeNodeList(node.childNodes, context, null, eventTarget);
544 | }
545 |
546 | /**
547 | * Serialize a NodeList/Array of nodes.
548 | */
549 |
550 | function serializeNodeList (list, context, fn, eventTarget) {
551 | var r = '';
552 | for (var i = 0, l = list.length; i < l; i++) {
553 | r += serialize(list[i], context, fn, eventTarget);
554 | }
555 | return r;
556 | }
557 |
558 | },{"custom-event":5,"ent/encode":7,"extend":9,"void-elements":11}],7:[function(require,module,exports){
559 | var punycode = require('punycode');
560 | var revEntities = require('./reversed.json');
561 |
562 | module.exports = encode;
563 |
564 | function encode (str, opts) {
565 | if (typeof str !== 'string') {
566 | throw new TypeError('Expected a String');
567 | }
568 | if (!opts) opts = {};
569 |
570 | var numeric = true;
571 | if (opts.named) numeric = false;
572 | if (opts.numeric !== undefined) numeric = opts.numeric;
573 |
574 | var special = opts.special || {
575 | '"': true, "'": true,
576 | '<': true, '>': true,
577 | '&': true
578 | };
579 |
580 | var codePoints = punycode.ucs2.decode(str);
581 | var chars = [];
582 | for (var i = 0; i < codePoints.length; i++) {
583 | var cc = codePoints[i];
584 | var c = punycode.ucs2.encode([ cc ]);
585 | var e = revEntities[cc];
586 | if (e && (cc >= 127 || special[c]) && !numeric) {
587 | chars.push('&' + (/;$/.test(e) ? e : e + ';'));
588 | }
589 | else if (cc < 32 || cc >= 127 || special[c]) {
590 | chars.push('' + cc + ';');
591 | }
592 | else {
593 | chars.push(c);
594 | }
595 | }
596 | return chars.join('');
597 | }
598 |
599 | },{"./reversed.json":8,"punycode":10}],8:[function(require,module,exports){
600 | module.exports={
601 | "9": "Tab;",
602 | "10": "NewLine;",
603 | "33": "excl;",
604 | "34": "quot;",
605 | "35": "num;",
606 | "36": "dollar;",
607 | "37": "percnt;",
608 | "38": "amp;",
609 | "39": "apos;",
610 | "40": "lpar;",
611 | "41": "rpar;",
612 | "42": "midast;",
613 | "43": "plus;",
614 | "44": "comma;",
615 | "46": "period;",
616 | "47": "sol;",
617 | "58": "colon;",
618 | "59": "semi;",
619 | "60": "lt;",
620 | "61": "equals;",
621 | "62": "gt;",
622 | "63": "quest;",
623 | "64": "commat;",
624 | "91": "lsqb;",
625 | "92": "bsol;",
626 | "93": "rsqb;",
627 | "94": "Hat;",
628 | "95": "UnderBar;",
629 | "96": "grave;",
630 | "123": "lcub;",
631 | "124": "VerticalLine;",
632 | "125": "rcub;",
633 | "160": "NonBreakingSpace;",
634 | "161": "iexcl;",
635 | "162": "cent;",
636 | "163": "pound;",
637 | "164": "curren;",
638 | "165": "yen;",
639 | "166": "brvbar;",
640 | "167": "sect;",
641 | "168": "uml;",
642 | "169": "copy;",
643 | "170": "ordf;",
644 | "171": "laquo;",
645 | "172": "not;",
646 | "173": "shy;",
647 | "174": "reg;",
648 | "175": "strns;",
649 | "176": "deg;",
650 | "177": "pm;",
651 | "178": "sup2;",
652 | "179": "sup3;",
653 | "180": "DiacriticalAcute;",
654 | "181": "micro;",
655 | "182": "para;",
656 | "183": "middot;",
657 | "184": "Cedilla;",
658 | "185": "sup1;",
659 | "186": "ordm;",
660 | "187": "raquo;",
661 | "188": "frac14;",
662 | "189": "half;",
663 | "190": "frac34;",
664 | "191": "iquest;",
665 | "192": "Agrave;",
666 | "193": "Aacute;",
667 | "194": "Acirc;",
668 | "195": "Atilde;",
669 | "196": "Auml;",
670 | "197": "Aring;",
671 | "198": "AElig;",
672 | "199": "Ccedil;",
673 | "200": "Egrave;",
674 | "201": "Eacute;",
675 | "202": "Ecirc;",
676 | "203": "Euml;",
677 | "204": "Igrave;",
678 | "205": "Iacute;",
679 | "206": "Icirc;",
680 | "207": "Iuml;",
681 | "208": "ETH;",
682 | "209": "Ntilde;",
683 | "210": "Ograve;",
684 | "211": "Oacute;",
685 | "212": "Ocirc;",
686 | "213": "Otilde;",
687 | "214": "Ouml;",
688 | "215": "times;",
689 | "216": "Oslash;",
690 | "217": "Ugrave;",
691 | "218": "Uacute;",
692 | "219": "Ucirc;",
693 | "220": "Uuml;",
694 | "221": "Yacute;",
695 | "222": "THORN;",
696 | "223": "szlig;",
697 | "224": "agrave;",
698 | "225": "aacute;",
699 | "226": "acirc;",
700 | "227": "atilde;",
701 | "228": "auml;",
702 | "229": "aring;",
703 | "230": "aelig;",
704 | "231": "ccedil;",
705 | "232": "egrave;",
706 | "233": "eacute;",
707 | "234": "ecirc;",
708 | "235": "euml;",
709 | "236": "igrave;",
710 | "237": "iacute;",
711 | "238": "icirc;",
712 | "239": "iuml;",
713 | "240": "eth;",
714 | "241": "ntilde;",
715 | "242": "ograve;",
716 | "243": "oacute;",
717 | "244": "ocirc;",
718 | "245": "otilde;",
719 | "246": "ouml;",
720 | "247": "divide;",
721 | "248": "oslash;",
722 | "249": "ugrave;",
723 | "250": "uacute;",
724 | "251": "ucirc;",
725 | "252": "uuml;",
726 | "253": "yacute;",
727 | "254": "thorn;",
728 | "255": "yuml;",
729 | "256": "Amacr;",
730 | "257": "amacr;",
731 | "258": "Abreve;",
732 | "259": "abreve;",
733 | "260": "Aogon;",
734 | "261": "aogon;",
735 | "262": "Cacute;",
736 | "263": "cacute;",
737 | "264": "Ccirc;",
738 | "265": "ccirc;",
739 | "266": "Cdot;",
740 | "267": "cdot;",
741 | "268": "Ccaron;",
742 | "269": "ccaron;",
743 | "270": "Dcaron;",
744 | "271": "dcaron;",
745 | "272": "Dstrok;",
746 | "273": "dstrok;",
747 | "274": "Emacr;",
748 | "275": "emacr;",
749 | "278": "Edot;",
750 | "279": "edot;",
751 | "280": "Eogon;",
752 | "281": "eogon;",
753 | "282": "Ecaron;",
754 | "283": "ecaron;",
755 | "284": "Gcirc;",
756 | "285": "gcirc;",
757 | "286": "Gbreve;",
758 | "287": "gbreve;",
759 | "288": "Gdot;",
760 | "289": "gdot;",
761 | "290": "Gcedil;",
762 | "292": "Hcirc;",
763 | "293": "hcirc;",
764 | "294": "Hstrok;",
765 | "295": "hstrok;",
766 | "296": "Itilde;",
767 | "297": "itilde;",
768 | "298": "Imacr;",
769 | "299": "imacr;",
770 | "302": "Iogon;",
771 | "303": "iogon;",
772 | "304": "Idot;",
773 | "305": "inodot;",
774 | "306": "IJlig;",
775 | "307": "ijlig;",
776 | "308": "Jcirc;",
777 | "309": "jcirc;",
778 | "310": "Kcedil;",
779 | "311": "kcedil;",
780 | "312": "kgreen;",
781 | "313": "Lacute;",
782 | "314": "lacute;",
783 | "315": "Lcedil;",
784 | "316": "lcedil;",
785 | "317": "Lcaron;",
786 | "318": "lcaron;",
787 | "319": "Lmidot;",
788 | "320": "lmidot;",
789 | "321": "Lstrok;",
790 | "322": "lstrok;",
791 | "323": "Nacute;",
792 | "324": "nacute;",
793 | "325": "Ncedil;",
794 | "326": "ncedil;",
795 | "327": "Ncaron;",
796 | "328": "ncaron;",
797 | "329": "napos;",
798 | "330": "ENG;",
799 | "331": "eng;",
800 | "332": "Omacr;",
801 | "333": "omacr;",
802 | "336": "Odblac;",
803 | "337": "odblac;",
804 | "338": "OElig;",
805 | "339": "oelig;",
806 | "340": "Racute;",
807 | "341": "racute;",
808 | "342": "Rcedil;",
809 | "343": "rcedil;",
810 | "344": "Rcaron;",
811 | "345": "rcaron;",
812 | "346": "Sacute;",
813 | "347": "sacute;",
814 | "348": "Scirc;",
815 | "349": "scirc;",
816 | "350": "Scedil;",
817 | "351": "scedil;",
818 | "352": "Scaron;",
819 | "353": "scaron;",
820 | "354": "Tcedil;",
821 | "355": "tcedil;",
822 | "356": "Tcaron;",
823 | "357": "tcaron;",
824 | "358": "Tstrok;",
825 | "359": "tstrok;",
826 | "360": "Utilde;",
827 | "361": "utilde;",
828 | "362": "Umacr;",
829 | "363": "umacr;",
830 | "364": "Ubreve;",
831 | "365": "ubreve;",
832 | "366": "Uring;",
833 | "367": "uring;",
834 | "368": "Udblac;",
835 | "369": "udblac;",
836 | "370": "Uogon;",
837 | "371": "uogon;",
838 | "372": "Wcirc;",
839 | "373": "wcirc;",
840 | "374": "Ycirc;",
841 | "375": "ycirc;",
842 | "376": "Yuml;",
843 | "377": "Zacute;",
844 | "378": "zacute;",
845 | "379": "Zdot;",
846 | "380": "zdot;",
847 | "381": "Zcaron;",
848 | "382": "zcaron;",
849 | "402": "fnof;",
850 | "437": "imped;",
851 | "501": "gacute;",
852 | "567": "jmath;",
853 | "710": "circ;",
854 | "711": "Hacek;",
855 | "728": "breve;",
856 | "729": "dot;",
857 | "730": "ring;",
858 | "731": "ogon;",
859 | "732": "tilde;",
860 | "733": "DiacriticalDoubleAcute;",
861 | "785": "DownBreve;",
862 | "913": "Alpha;",
863 | "914": "Beta;",
864 | "915": "Gamma;",
865 | "916": "Delta;",
866 | "917": "Epsilon;",
867 | "918": "Zeta;",
868 | "919": "Eta;",
869 | "920": "Theta;",
870 | "921": "Iota;",
871 | "922": "Kappa;",
872 | "923": "Lambda;",
873 | "924": "Mu;",
874 | "925": "Nu;",
875 | "926": "Xi;",
876 | "927": "Omicron;",
877 | "928": "Pi;",
878 | "929": "Rho;",
879 | "931": "Sigma;",
880 | "932": "Tau;",
881 | "933": "Upsilon;",
882 | "934": "Phi;",
883 | "935": "Chi;",
884 | "936": "Psi;",
885 | "937": "Omega;",
886 | "945": "alpha;",
887 | "946": "beta;",
888 | "947": "gamma;",
889 | "948": "delta;",
890 | "949": "epsilon;",
891 | "950": "zeta;",
892 | "951": "eta;",
893 | "952": "theta;",
894 | "953": "iota;",
895 | "954": "kappa;",
896 | "955": "lambda;",
897 | "956": "mu;",
898 | "957": "nu;",
899 | "958": "xi;",
900 | "959": "omicron;",
901 | "960": "pi;",
902 | "961": "rho;",
903 | "962": "varsigma;",
904 | "963": "sigma;",
905 | "964": "tau;",
906 | "965": "upsilon;",
907 | "966": "phi;",
908 | "967": "chi;",
909 | "968": "psi;",
910 | "969": "omega;",
911 | "977": "vartheta;",
912 | "978": "upsih;",
913 | "981": "varphi;",
914 | "982": "varpi;",
915 | "988": "Gammad;",
916 | "989": "gammad;",
917 | "1008": "varkappa;",
918 | "1009": "varrho;",
919 | "1013": "varepsilon;",
920 | "1014": "bepsi;",
921 | "1025": "IOcy;",
922 | "1026": "DJcy;",
923 | "1027": "GJcy;",
924 | "1028": "Jukcy;",
925 | "1029": "DScy;",
926 | "1030": "Iukcy;",
927 | "1031": "YIcy;",
928 | "1032": "Jsercy;",
929 | "1033": "LJcy;",
930 | "1034": "NJcy;",
931 | "1035": "TSHcy;",
932 | "1036": "KJcy;",
933 | "1038": "Ubrcy;",
934 | "1039": "DZcy;",
935 | "1040": "Acy;",
936 | "1041": "Bcy;",
937 | "1042": "Vcy;",
938 | "1043": "Gcy;",
939 | "1044": "Dcy;",
940 | "1045": "IEcy;",
941 | "1046": "ZHcy;",
942 | "1047": "Zcy;",
943 | "1048": "Icy;",
944 | "1049": "Jcy;",
945 | "1050": "Kcy;",
946 | "1051": "Lcy;",
947 | "1052": "Mcy;",
948 | "1053": "Ncy;",
949 | "1054": "Ocy;",
950 | "1055": "Pcy;",
951 | "1056": "Rcy;",
952 | "1057": "Scy;",
953 | "1058": "Tcy;",
954 | "1059": "Ucy;",
955 | "1060": "Fcy;",
956 | "1061": "KHcy;",
957 | "1062": "TScy;",
958 | "1063": "CHcy;",
959 | "1064": "SHcy;",
960 | "1065": "SHCHcy;",
961 | "1066": "HARDcy;",
962 | "1067": "Ycy;",
963 | "1068": "SOFTcy;",
964 | "1069": "Ecy;",
965 | "1070": "YUcy;",
966 | "1071": "YAcy;",
967 | "1072": "acy;",
968 | "1073": "bcy;",
969 | "1074": "vcy;",
970 | "1075": "gcy;",
971 | "1076": "dcy;",
972 | "1077": "iecy;",
973 | "1078": "zhcy;",
974 | "1079": "zcy;",
975 | "1080": "icy;",
976 | "1081": "jcy;",
977 | "1082": "kcy;",
978 | "1083": "lcy;",
979 | "1084": "mcy;",
980 | "1085": "ncy;",
981 | "1086": "ocy;",
982 | "1087": "pcy;",
983 | "1088": "rcy;",
984 | "1089": "scy;",
985 | "1090": "tcy;",
986 | "1091": "ucy;",
987 | "1092": "fcy;",
988 | "1093": "khcy;",
989 | "1094": "tscy;",
990 | "1095": "chcy;",
991 | "1096": "shcy;",
992 | "1097": "shchcy;",
993 | "1098": "hardcy;",
994 | "1099": "ycy;",
995 | "1100": "softcy;",
996 | "1101": "ecy;",
997 | "1102": "yucy;",
998 | "1103": "yacy;",
999 | "1105": "iocy;",
1000 | "1106": "djcy;",
1001 | "1107": "gjcy;",
1002 | "1108": "jukcy;",
1003 | "1109": "dscy;",
1004 | "1110": "iukcy;",
1005 | "1111": "yicy;",
1006 | "1112": "jsercy;",
1007 | "1113": "ljcy;",
1008 | "1114": "njcy;",
1009 | "1115": "tshcy;",
1010 | "1116": "kjcy;",
1011 | "1118": "ubrcy;",
1012 | "1119": "dzcy;",
1013 | "8194": "ensp;",
1014 | "8195": "emsp;",
1015 | "8196": "emsp13;",
1016 | "8197": "emsp14;",
1017 | "8199": "numsp;",
1018 | "8200": "puncsp;",
1019 | "8201": "ThinSpace;",
1020 | "8202": "VeryThinSpace;",
1021 | "8203": "ZeroWidthSpace;",
1022 | "8204": "zwnj;",
1023 | "8205": "zwj;",
1024 | "8206": "lrm;",
1025 | "8207": "rlm;",
1026 | "8208": "hyphen;",
1027 | "8211": "ndash;",
1028 | "8212": "mdash;",
1029 | "8213": "horbar;",
1030 | "8214": "Vert;",
1031 | "8216": "OpenCurlyQuote;",
1032 | "8217": "rsquor;",
1033 | "8218": "sbquo;",
1034 | "8220": "OpenCurlyDoubleQuote;",
1035 | "8221": "rdquor;",
1036 | "8222": "ldquor;",
1037 | "8224": "dagger;",
1038 | "8225": "ddagger;",
1039 | "8226": "bullet;",
1040 | "8229": "nldr;",
1041 | "8230": "mldr;",
1042 | "8240": "permil;",
1043 | "8241": "pertenk;",
1044 | "8242": "prime;",
1045 | "8243": "Prime;",
1046 | "8244": "tprime;",
1047 | "8245": "bprime;",
1048 | "8249": "lsaquo;",
1049 | "8250": "rsaquo;",
1050 | "8254": "OverBar;",
1051 | "8257": "caret;",
1052 | "8259": "hybull;",
1053 | "8260": "frasl;",
1054 | "8271": "bsemi;",
1055 | "8279": "qprime;",
1056 | "8287": "MediumSpace;",
1057 | "8288": "NoBreak;",
1058 | "8289": "ApplyFunction;",
1059 | "8290": "it;",
1060 | "8291": "InvisibleComma;",
1061 | "8364": "euro;",
1062 | "8411": "TripleDot;",
1063 | "8412": "DotDot;",
1064 | "8450": "Copf;",
1065 | "8453": "incare;",
1066 | "8458": "gscr;",
1067 | "8459": "Hscr;",
1068 | "8460": "Poincareplane;",
1069 | "8461": "quaternions;",
1070 | "8462": "planckh;",
1071 | "8463": "plankv;",
1072 | "8464": "Iscr;",
1073 | "8465": "imagpart;",
1074 | "8466": "Lscr;",
1075 | "8467": "ell;",
1076 | "8469": "Nopf;",
1077 | "8470": "numero;",
1078 | "8471": "copysr;",
1079 | "8472": "wp;",
1080 | "8473": "primes;",
1081 | "8474": "rationals;",
1082 | "8475": "Rscr;",
1083 | "8476": "Rfr;",
1084 | "8477": "Ropf;",
1085 | "8478": "rx;",
1086 | "8482": "trade;",
1087 | "8484": "Zopf;",
1088 | "8487": "mho;",
1089 | "8488": "Zfr;",
1090 | "8489": "iiota;",
1091 | "8492": "Bscr;",
1092 | "8493": "Cfr;",
1093 | "8495": "escr;",
1094 | "8496": "expectation;",
1095 | "8497": "Fscr;",
1096 | "8499": "phmmat;",
1097 | "8500": "oscr;",
1098 | "8501": "aleph;",
1099 | "8502": "beth;",
1100 | "8503": "gimel;",
1101 | "8504": "daleth;",
1102 | "8517": "DD;",
1103 | "8518": "DifferentialD;",
1104 | "8519": "exponentiale;",
1105 | "8520": "ImaginaryI;",
1106 | "8531": "frac13;",
1107 | "8532": "frac23;",
1108 | "8533": "frac15;",
1109 | "8534": "frac25;",
1110 | "8535": "frac35;",
1111 | "8536": "frac45;",
1112 | "8537": "frac16;",
1113 | "8538": "frac56;",
1114 | "8539": "frac18;",
1115 | "8540": "frac38;",
1116 | "8541": "frac58;",
1117 | "8542": "frac78;",
1118 | "8592": "slarr;",
1119 | "8593": "uparrow;",
1120 | "8594": "srarr;",
1121 | "8595": "ShortDownArrow;",
1122 | "8596": "leftrightarrow;",
1123 | "8597": "varr;",
1124 | "8598": "UpperLeftArrow;",
1125 | "8599": "UpperRightArrow;",
1126 | "8600": "searrow;",
1127 | "8601": "swarrow;",
1128 | "8602": "nleftarrow;",
1129 | "8603": "nrightarrow;",
1130 | "8605": "rightsquigarrow;",
1131 | "8606": "twoheadleftarrow;",
1132 | "8607": "Uarr;",
1133 | "8608": "twoheadrightarrow;",
1134 | "8609": "Darr;",
1135 | "8610": "leftarrowtail;",
1136 | "8611": "rightarrowtail;",
1137 | "8612": "mapstoleft;",
1138 | "8613": "UpTeeArrow;",
1139 | "8614": "RightTeeArrow;",
1140 | "8615": "mapstodown;",
1141 | "8617": "larrhk;",
1142 | "8618": "rarrhk;",
1143 | "8619": "looparrowleft;",
1144 | "8620": "rarrlp;",
1145 | "8621": "leftrightsquigarrow;",
1146 | "8622": "nleftrightarrow;",
1147 | "8624": "lsh;",
1148 | "8625": "rsh;",
1149 | "8626": "ldsh;",
1150 | "8627": "rdsh;",
1151 | "8629": "crarr;",
1152 | "8630": "curvearrowleft;",
1153 | "8631": "curvearrowright;",
1154 | "8634": "olarr;",
1155 | "8635": "orarr;",
1156 | "8636": "lharu;",
1157 | "8637": "lhard;",
1158 | "8638": "upharpoonright;",
1159 | "8639": "upharpoonleft;",
1160 | "8640": "RightVector;",
1161 | "8641": "rightharpoondown;",
1162 | "8642": "RightDownVector;",
1163 | "8643": "LeftDownVector;",
1164 | "8644": "rlarr;",
1165 | "8645": "UpArrowDownArrow;",
1166 | "8646": "lrarr;",
1167 | "8647": "llarr;",
1168 | "8648": "uuarr;",
1169 | "8649": "rrarr;",
1170 | "8650": "downdownarrows;",
1171 | "8651": "ReverseEquilibrium;",
1172 | "8652": "rlhar;",
1173 | "8653": "nLeftarrow;",
1174 | "8654": "nLeftrightarrow;",
1175 | "8655": "nRightarrow;",
1176 | "8656": "Leftarrow;",
1177 | "8657": "Uparrow;",
1178 | "8658": "Rightarrow;",
1179 | "8659": "Downarrow;",
1180 | "8660": "Leftrightarrow;",
1181 | "8661": "vArr;",
1182 | "8662": "nwArr;",
1183 | "8663": "neArr;",
1184 | "8664": "seArr;",
1185 | "8665": "swArr;",
1186 | "8666": "Lleftarrow;",
1187 | "8667": "Rrightarrow;",
1188 | "8669": "zigrarr;",
1189 | "8676": "LeftArrowBar;",
1190 | "8677": "RightArrowBar;",
1191 | "8693": "duarr;",
1192 | "8701": "loarr;",
1193 | "8702": "roarr;",
1194 | "8703": "hoarr;",
1195 | "8704": "forall;",
1196 | "8705": "complement;",
1197 | "8706": "PartialD;",
1198 | "8707": "Exists;",
1199 | "8708": "NotExists;",
1200 | "8709": "varnothing;",
1201 | "8711": "nabla;",
1202 | "8712": "isinv;",
1203 | "8713": "notinva;",
1204 | "8715": "SuchThat;",
1205 | "8716": "NotReverseElement;",
1206 | "8719": "Product;",
1207 | "8720": "Coproduct;",
1208 | "8721": "sum;",
1209 | "8722": "minus;",
1210 | "8723": "mp;",
1211 | "8724": "plusdo;",
1212 | "8726": "ssetmn;",
1213 | "8727": "lowast;",
1214 | "8728": "SmallCircle;",
1215 | "8730": "Sqrt;",
1216 | "8733": "vprop;",
1217 | "8734": "infin;",
1218 | "8735": "angrt;",
1219 | "8736": "angle;",
1220 | "8737": "measuredangle;",
1221 | "8738": "angsph;",
1222 | "8739": "VerticalBar;",
1223 | "8740": "nsmid;",
1224 | "8741": "spar;",
1225 | "8742": "nspar;",
1226 | "8743": "wedge;",
1227 | "8744": "vee;",
1228 | "8745": "cap;",
1229 | "8746": "cup;",
1230 | "8747": "Integral;",
1231 | "8748": "Int;",
1232 | "8749": "tint;",
1233 | "8750": "oint;",
1234 | "8751": "DoubleContourIntegral;",
1235 | "8752": "Cconint;",
1236 | "8753": "cwint;",
1237 | "8754": "cwconint;",
1238 | "8755": "CounterClockwiseContourIntegral;",
1239 | "8756": "therefore;",
1240 | "8757": "because;",
1241 | "8758": "ratio;",
1242 | "8759": "Proportion;",
1243 | "8760": "minusd;",
1244 | "8762": "mDDot;",
1245 | "8763": "homtht;",
1246 | "8764": "Tilde;",
1247 | "8765": "bsim;",
1248 | "8766": "mstpos;",
1249 | "8767": "acd;",
1250 | "8768": "wreath;",
1251 | "8769": "nsim;",
1252 | "8770": "esim;",
1253 | "8771": "TildeEqual;",
1254 | "8772": "nsimeq;",
1255 | "8773": "TildeFullEqual;",
1256 | "8774": "simne;",
1257 | "8775": "NotTildeFullEqual;",
1258 | "8776": "TildeTilde;",
1259 | "8777": "NotTildeTilde;",
1260 | "8778": "approxeq;",
1261 | "8779": "apid;",
1262 | "8780": "bcong;",
1263 | "8781": "CupCap;",
1264 | "8782": "HumpDownHump;",
1265 | "8783": "HumpEqual;",
1266 | "8784": "esdot;",
1267 | "8785": "eDot;",
1268 | "8786": "fallingdotseq;",
1269 | "8787": "risingdotseq;",
1270 | "8788": "coloneq;",
1271 | "8789": "eqcolon;",
1272 | "8790": "eqcirc;",
1273 | "8791": "cire;",
1274 | "8793": "wedgeq;",
1275 | "8794": "veeeq;",
1276 | "8796": "trie;",
1277 | "8799": "questeq;",
1278 | "8800": "NotEqual;",
1279 | "8801": "equiv;",
1280 | "8802": "NotCongruent;",
1281 | "8804": "leq;",
1282 | "8805": "GreaterEqual;",
1283 | "8806": "LessFullEqual;",
1284 | "8807": "GreaterFullEqual;",
1285 | "8808": "lneqq;",
1286 | "8809": "gneqq;",
1287 | "8810": "NestedLessLess;",
1288 | "8811": "NestedGreaterGreater;",
1289 | "8812": "twixt;",
1290 | "8813": "NotCupCap;",
1291 | "8814": "NotLess;",
1292 | "8815": "NotGreater;",
1293 | "8816": "NotLessEqual;",
1294 | "8817": "NotGreaterEqual;",
1295 | "8818": "lsim;",
1296 | "8819": "gtrsim;",
1297 | "8820": "NotLessTilde;",
1298 | "8821": "NotGreaterTilde;",
1299 | "8822": "lg;",
1300 | "8823": "gtrless;",
1301 | "8824": "ntlg;",
1302 | "8825": "ntgl;",
1303 | "8826": "Precedes;",
1304 | "8827": "Succeeds;",
1305 | "8828": "PrecedesSlantEqual;",
1306 | "8829": "SucceedsSlantEqual;",
1307 | "8830": "prsim;",
1308 | "8831": "succsim;",
1309 | "8832": "nprec;",
1310 | "8833": "nsucc;",
1311 | "8834": "subset;",
1312 | "8835": "supset;",
1313 | "8836": "nsub;",
1314 | "8837": "nsup;",
1315 | "8838": "SubsetEqual;",
1316 | "8839": "supseteq;",
1317 | "8840": "nsubseteq;",
1318 | "8841": "nsupseteq;",
1319 | "8842": "subsetneq;",
1320 | "8843": "supsetneq;",
1321 | "8845": "cupdot;",
1322 | "8846": "uplus;",
1323 | "8847": "SquareSubset;",
1324 | "8848": "SquareSuperset;",
1325 | "8849": "SquareSubsetEqual;",
1326 | "8850": "SquareSupersetEqual;",
1327 | "8851": "SquareIntersection;",
1328 | "8852": "SquareUnion;",
1329 | "8853": "oplus;",
1330 | "8854": "ominus;",
1331 | "8855": "otimes;",
1332 | "8856": "osol;",
1333 | "8857": "odot;",
1334 | "8858": "ocir;",
1335 | "8859": "oast;",
1336 | "8861": "odash;",
1337 | "8862": "plusb;",
1338 | "8863": "minusb;",
1339 | "8864": "timesb;",
1340 | "8865": "sdotb;",
1341 | "8866": "vdash;",
1342 | "8867": "LeftTee;",
1343 | "8868": "top;",
1344 | "8869": "UpTee;",
1345 | "8871": "models;",
1346 | "8872": "vDash;",
1347 | "8873": "Vdash;",
1348 | "8874": "Vvdash;",
1349 | "8875": "VDash;",
1350 | "8876": "nvdash;",
1351 | "8877": "nvDash;",
1352 | "8878": "nVdash;",
1353 | "8879": "nVDash;",
1354 | "8880": "prurel;",
1355 | "8882": "vltri;",
1356 | "8883": "vrtri;",
1357 | "8884": "trianglelefteq;",
1358 | "8885": "trianglerighteq;",
1359 | "8886": "origof;",
1360 | "8887": "imof;",
1361 | "8888": "mumap;",
1362 | "8889": "hercon;",
1363 | "8890": "intercal;",
1364 | "8891": "veebar;",
1365 | "8893": "barvee;",
1366 | "8894": "angrtvb;",
1367 | "8895": "lrtri;",
1368 | "8896": "xwedge;",
1369 | "8897": "xvee;",
1370 | "8898": "xcap;",
1371 | "8899": "xcup;",
1372 | "8900": "diamond;",
1373 | "8901": "sdot;",
1374 | "8902": "Star;",
1375 | "8903": "divonx;",
1376 | "8904": "bowtie;",
1377 | "8905": "ltimes;",
1378 | "8906": "rtimes;",
1379 | "8907": "lthree;",
1380 | "8908": "rthree;",
1381 | "8909": "bsime;",
1382 | "8910": "cuvee;",
1383 | "8911": "cuwed;",
1384 | "8912": "Subset;",
1385 | "8913": "Supset;",
1386 | "8914": "Cap;",
1387 | "8915": "Cup;",
1388 | "8916": "pitchfork;",
1389 | "8917": "epar;",
1390 | "8918": "ltdot;",
1391 | "8919": "gtrdot;",
1392 | "8920": "Ll;",
1393 | "8921": "ggg;",
1394 | "8922": "LessEqualGreater;",
1395 | "8923": "gtreqless;",
1396 | "8926": "curlyeqprec;",
1397 | "8927": "curlyeqsucc;",
1398 | "8928": "nprcue;",
1399 | "8929": "nsccue;",
1400 | "8930": "nsqsube;",
1401 | "8931": "nsqsupe;",
1402 | "8934": "lnsim;",
1403 | "8935": "gnsim;",
1404 | "8936": "prnsim;",
1405 | "8937": "succnsim;",
1406 | "8938": "ntriangleleft;",
1407 | "8939": "ntriangleright;",
1408 | "8940": "ntrianglelefteq;",
1409 | "8941": "ntrianglerighteq;",
1410 | "8942": "vellip;",
1411 | "8943": "ctdot;",
1412 | "8944": "utdot;",
1413 | "8945": "dtdot;",
1414 | "8946": "disin;",
1415 | "8947": "isinsv;",
1416 | "8948": "isins;",
1417 | "8949": "isindot;",
1418 | "8950": "notinvc;",
1419 | "8951": "notinvb;",
1420 | "8953": "isinE;",
1421 | "8954": "nisd;",
1422 | "8955": "xnis;",
1423 | "8956": "nis;",
1424 | "8957": "notnivc;",
1425 | "8958": "notnivb;",
1426 | "8965": "barwedge;",
1427 | "8966": "doublebarwedge;",
1428 | "8968": "LeftCeiling;",
1429 | "8969": "RightCeiling;",
1430 | "8970": "lfloor;",
1431 | "8971": "RightFloor;",
1432 | "8972": "drcrop;",
1433 | "8973": "dlcrop;",
1434 | "8974": "urcrop;",
1435 | "8975": "ulcrop;",
1436 | "8976": "bnot;",
1437 | "8978": "profline;",
1438 | "8979": "profsurf;",
1439 | "8981": "telrec;",
1440 | "8982": "target;",
1441 | "8988": "ulcorner;",
1442 | "8989": "urcorner;",
1443 | "8990": "llcorner;",
1444 | "8991": "lrcorner;",
1445 | "8994": "sfrown;",
1446 | "8995": "ssmile;",
1447 | "9005": "cylcty;",
1448 | "9006": "profalar;",
1449 | "9014": "topbot;",
1450 | "9021": "ovbar;",
1451 | "9023": "solbar;",
1452 | "9084": "angzarr;",
1453 | "9136": "lmoustache;",
1454 | "9137": "rmoustache;",
1455 | "9140": "tbrk;",
1456 | "9141": "UnderBracket;",
1457 | "9142": "bbrktbrk;",
1458 | "9180": "OverParenthesis;",
1459 | "9181": "UnderParenthesis;",
1460 | "9182": "OverBrace;",
1461 | "9183": "UnderBrace;",
1462 | "9186": "trpezium;",
1463 | "9191": "elinters;",
1464 | "9251": "blank;",
1465 | "9416": "oS;",
1466 | "9472": "HorizontalLine;",
1467 | "9474": "boxv;",
1468 | "9484": "boxdr;",
1469 | "9488": "boxdl;",
1470 | "9492": "boxur;",
1471 | "9496": "boxul;",
1472 | "9500": "boxvr;",
1473 | "9508": "boxvl;",
1474 | "9516": "boxhd;",
1475 | "9524": "boxhu;",
1476 | "9532": "boxvh;",
1477 | "9552": "boxH;",
1478 | "9553": "boxV;",
1479 | "9554": "boxdR;",
1480 | "9555": "boxDr;",
1481 | "9556": "boxDR;",
1482 | "9557": "boxdL;",
1483 | "9558": "boxDl;",
1484 | "9559": "boxDL;",
1485 | "9560": "boxuR;",
1486 | "9561": "boxUr;",
1487 | "9562": "boxUR;",
1488 | "9563": "boxuL;",
1489 | "9564": "boxUl;",
1490 | "9565": "boxUL;",
1491 | "9566": "boxvR;",
1492 | "9567": "boxVr;",
1493 | "9568": "boxVR;",
1494 | "9569": "boxvL;",
1495 | "9570": "boxVl;",
1496 | "9571": "boxVL;",
1497 | "9572": "boxHd;",
1498 | "9573": "boxhD;",
1499 | "9574": "boxHD;",
1500 | "9575": "boxHu;",
1501 | "9576": "boxhU;",
1502 | "9577": "boxHU;",
1503 | "9578": "boxvH;",
1504 | "9579": "boxVh;",
1505 | "9580": "boxVH;",
1506 | "9600": "uhblk;",
1507 | "9604": "lhblk;",
1508 | "9608": "block;",
1509 | "9617": "blk14;",
1510 | "9618": "blk12;",
1511 | "9619": "blk34;",
1512 | "9633": "square;",
1513 | "9642": "squf;",
1514 | "9643": "EmptyVerySmallSquare;",
1515 | "9645": "rect;",
1516 | "9646": "marker;",
1517 | "9649": "fltns;",
1518 | "9651": "xutri;",
1519 | "9652": "utrif;",
1520 | "9653": "utri;",
1521 | "9656": "rtrif;",
1522 | "9657": "triangleright;",
1523 | "9661": "xdtri;",
1524 | "9662": "dtrif;",
1525 | "9663": "triangledown;",
1526 | "9666": "ltrif;",
1527 | "9667": "triangleleft;",
1528 | "9674": "lozenge;",
1529 | "9675": "cir;",
1530 | "9708": "tridot;",
1531 | "9711": "xcirc;",
1532 | "9720": "ultri;",
1533 | "9721": "urtri;",
1534 | "9722": "lltri;",
1535 | "9723": "EmptySmallSquare;",
1536 | "9724": "FilledSmallSquare;",
1537 | "9733": "starf;",
1538 | "9734": "star;",
1539 | "9742": "phone;",
1540 | "9792": "female;",
1541 | "9794": "male;",
1542 | "9824": "spadesuit;",
1543 | "9827": "clubsuit;",
1544 | "9829": "heartsuit;",
1545 | "9830": "diams;",
1546 | "9834": "sung;",
1547 | "9837": "flat;",
1548 | "9838": "natural;",
1549 | "9839": "sharp;",
1550 | "10003": "checkmark;",
1551 | "10007": "cross;",
1552 | "10016": "maltese;",
1553 | "10038": "sext;",
1554 | "10072": "VerticalSeparator;",
1555 | "10098": "lbbrk;",
1556 | "10099": "rbbrk;",
1557 | "10184": "bsolhsub;",
1558 | "10185": "suphsol;",
1559 | "10214": "lobrk;",
1560 | "10215": "robrk;",
1561 | "10216": "LeftAngleBracket;",
1562 | "10217": "RightAngleBracket;",
1563 | "10218": "Lang;",
1564 | "10219": "Rang;",
1565 | "10220": "loang;",
1566 | "10221": "roang;",
1567 | "10229": "xlarr;",
1568 | "10230": "xrarr;",
1569 | "10231": "xharr;",
1570 | "10232": "xlArr;",
1571 | "10233": "xrArr;",
1572 | "10234": "xhArr;",
1573 | "10236": "xmap;",
1574 | "10239": "dzigrarr;",
1575 | "10498": "nvlArr;",
1576 | "10499": "nvrArr;",
1577 | "10500": "nvHarr;",
1578 | "10501": "Map;",
1579 | "10508": "lbarr;",
1580 | "10509": "rbarr;",
1581 | "10510": "lBarr;",
1582 | "10511": "rBarr;",
1583 | "10512": "RBarr;",
1584 | "10513": "DDotrahd;",
1585 | "10514": "UpArrowBar;",
1586 | "10515": "DownArrowBar;",
1587 | "10518": "Rarrtl;",
1588 | "10521": "latail;",
1589 | "10522": "ratail;",
1590 | "10523": "lAtail;",
1591 | "10524": "rAtail;",
1592 | "10525": "larrfs;",
1593 | "10526": "rarrfs;",
1594 | "10527": "larrbfs;",
1595 | "10528": "rarrbfs;",
1596 | "10531": "nwarhk;",
1597 | "10532": "nearhk;",
1598 | "10533": "searhk;",
1599 | "10534": "swarhk;",
1600 | "10535": "nwnear;",
1601 | "10536": "toea;",
1602 | "10537": "tosa;",
1603 | "10538": "swnwar;",
1604 | "10547": "rarrc;",
1605 | "10549": "cudarrr;",
1606 | "10550": "ldca;",
1607 | "10551": "rdca;",
1608 | "10552": "cudarrl;",
1609 | "10553": "larrpl;",
1610 | "10556": "curarrm;",
1611 | "10557": "cularrp;",
1612 | "10565": "rarrpl;",
1613 | "10568": "harrcir;",
1614 | "10569": "Uarrocir;",
1615 | "10570": "lurdshar;",
1616 | "10571": "ldrushar;",
1617 | "10574": "LeftRightVector;",
1618 | "10575": "RightUpDownVector;",
1619 | "10576": "DownLeftRightVector;",
1620 | "10577": "LeftUpDownVector;",
1621 | "10578": "LeftVectorBar;",
1622 | "10579": "RightVectorBar;",
1623 | "10580": "RightUpVectorBar;",
1624 | "10581": "RightDownVectorBar;",
1625 | "10582": "DownLeftVectorBar;",
1626 | "10583": "DownRightVectorBar;",
1627 | "10584": "LeftUpVectorBar;",
1628 | "10585": "LeftDownVectorBar;",
1629 | "10586": "LeftTeeVector;",
1630 | "10587": "RightTeeVector;",
1631 | "10588": "RightUpTeeVector;",
1632 | "10589": "RightDownTeeVector;",
1633 | "10590": "DownLeftTeeVector;",
1634 | "10591": "DownRightTeeVector;",
1635 | "10592": "LeftUpTeeVector;",
1636 | "10593": "LeftDownTeeVector;",
1637 | "10594": "lHar;",
1638 | "10595": "uHar;",
1639 | "10596": "rHar;",
1640 | "10597": "dHar;",
1641 | "10598": "luruhar;",
1642 | "10599": "ldrdhar;",
1643 | "10600": "ruluhar;",
1644 | "10601": "rdldhar;",
1645 | "10602": "lharul;",
1646 | "10603": "llhard;",
1647 | "10604": "rharul;",
1648 | "10605": "lrhard;",
1649 | "10606": "UpEquilibrium;",
1650 | "10607": "ReverseUpEquilibrium;",
1651 | "10608": "RoundImplies;",
1652 | "10609": "erarr;",
1653 | "10610": "simrarr;",
1654 | "10611": "larrsim;",
1655 | "10612": "rarrsim;",
1656 | "10613": "rarrap;",
1657 | "10614": "ltlarr;",
1658 | "10616": "gtrarr;",
1659 | "10617": "subrarr;",
1660 | "10619": "suplarr;",
1661 | "10620": "lfisht;",
1662 | "10621": "rfisht;",
1663 | "10622": "ufisht;",
1664 | "10623": "dfisht;",
1665 | "10629": "lopar;",
1666 | "10630": "ropar;",
1667 | "10635": "lbrke;",
1668 | "10636": "rbrke;",
1669 | "10637": "lbrkslu;",
1670 | "10638": "rbrksld;",
1671 | "10639": "lbrksld;",
1672 | "10640": "rbrkslu;",
1673 | "10641": "langd;",
1674 | "10642": "rangd;",
1675 | "10643": "lparlt;",
1676 | "10644": "rpargt;",
1677 | "10645": "gtlPar;",
1678 | "10646": "ltrPar;",
1679 | "10650": "vzigzag;",
1680 | "10652": "vangrt;",
1681 | "10653": "angrtvbd;",
1682 | "10660": "ange;",
1683 | "10661": "range;",
1684 | "10662": "dwangle;",
1685 | "10663": "uwangle;",
1686 | "10664": "angmsdaa;",
1687 | "10665": "angmsdab;",
1688 | "10666": "angmsdac;",
1689 | "10667": "angmsdad;",
1690 | "10668": "angmsdae;",
1691 | "10669": "angmsdaf;",
1692 | "10670": "angmsdag;",
1693 | "10671": "angmsdah;",
1694 | "10672": "bemptyv;",
1695 | "10673": "demptyv;",
1696 | "10674": "cemptyv;",
1697 | "10675": "raemptyv;",
1698 | "10676": "laemptyv;",
1699 | "10677": "ohbar;",
1700 | "10678": "omid;",
1701 | "10679": "opar;",
1702 | "10681": "operp;",
1703 | "10683": "olcross;",
1704 | "10684": "odsold;",
1705 | "10686": "olcir;",
1706 | "10687": "ofcir;",
1707 | "10688": "olt;",
1708 | "10689": "ogt;",
1709 | "10690": "cirscir;",
1710 | "10691": "cirE;",
1711 | "10692": "solb;",
1712 | "10693": "bsolb;",
1713 | "10697": "boxbox;",
1714 | "10701": "trisb;",
1715 | "10702": "rtriltri;",
1716 | "10703": "LeftTriangleBar;",
1717 | "10704": "RightTriangleBar;",
1718 | "10716": "iinfin;",
1719 | "10717": "infintie;",
1720 | "10718": "nvinfin;",
1721 | "10723": "eparsl;",
1722 | "10724": "smeparsl;",
1723 | "10725": "eqvparsl;",
1724 | "10731": "lozf;",
1725 | "10740": "RuleDelayed;",
1726 | "10742": "dsol;",
1727 | "10752": "xodot;",
1728 | "10753": "xoplus;",
1729 | "10754": "xotime;",
1730 | "10756": "xuplus;",
1731 | "10758": "xsqcup;",
1732 | "10764": "qint;",
1733 | "10765": "fpartint;",
1734 | "10768": "cirfnint;",
1735 | "10769": "awint;",
1736 | "10770": "rppolint;",
1737 | "10771": "scpolint;",
1738 | "10772": "npolint;",
1739 | "10773": "pointint;",
1740 | "10774": "quatint;",
1741 | "10775": "intlarhk;",
1742 | "10786": "pluscir;",
1743 | "10787": "plusacir;",
1744 | "10788": "simplus;",
1745 | "10789": "plusdu;",
1746 | "10790": "plussim;",
1747 | "10791": "plustwo;",
1748 | "10793": "mcomma;",
1749 | "10794": "minusdu;",
1750 | "10797": "loplus;",
1751 | "10798": "roplus;",
1752 | "10799": "Cross;",
1753 | "10800": "timesd;",
1754 | "10801": "timesbar;",
1755 | "10803": "smashp;",
1756 | "10804": "lotimes;",
1757 | "10805": "rotimes;",
1758 | "10806": "otimesas;",
1759 | "10807": "Otimes;",
1760 | "10808": "odiv;",
1761 | "10809": "triplus;",
1762 | "10810": "triminus;",
1763 | "10811": "tritime;",
1764 | "10812": "iprod;",
1765 | "10815": "amalg;",
1766 | "10816": "capdot;",
1767 | "10818": "ncup;",
1768 | "10819": "ncap;",
1769 | "10820": "capand;",
1770 | "10821": "cupor;",
1771 | "10822": "cupcap;",
1772 | "10823": "capcup;",
1773 | "10824": "cupbrcap;",
1774 | "10825": "capbrcup;",
1775 | "10826": "cupcup;",
1776 | "10827": "capcap;",
1777 | "10828": "ccups;",
1778 | "10829": "ccaps;",
1779 | "10832": "ccupssm;",
1780 | "10835": "And;",
1781 | "10836": "Or;",
1782 | "10837": "andand;",
1783 | "10838": "oror;",
1784 | "10839": "orslope;",
1785 | "10840": "andslope;",
1786 | "10842": "andv;",
1787 | "10843": "orv;",
1788 | "10844": "andd;",
1789 | "10845": "ord;",
1790 | "10847": "wedbar;",
1791 | "10854": "sdote;",
1792 | "10858": "simdot;",
1793 | "10861": "congdot;",
1794 | "10862": "easter;",
1795 | "10863": "apacir;",
1796 | "10864": "apE;",
1797 | "10865": "eplus;",
1798 | "10866": "pluse;",
1799 | "10867": "Esim;",
1800 | "10868": "Colone;",
1801 | "10869": "Equal;",
1802 | "10871": "eDDot;",
1803 | "10872": "equivDD;",
1804 | "10873": "ltcir;",
1805 | "10874": "gtcir;",
1806 | "10875": "ltquest;",
1807 | "10876": "gtquest;",
1808 | "10877": "LessSlantEqual;",
1809 | "10878": "GreaterSlantEqual;",
1810 | "10879": "lesdot;",
1811 | "10880": "gesdot;",
1812 | "10881": "lesdoto;",
1813 | "10882": "gesdoto;",
1814 | "10883": "lesdotor;",
1815 | "10884": "gesdotol;",
1816 | "10885": "lessapprox;",
1817 | "10886": "gtrapprox;",
1818 | "10887": "lneq;",
1819 | "10888": "gneq;",
1820 | "10889": "lnapprox;",
1821 | "10890": "gnapprox;",
1822 | "10891": "lesseqqgtr;",
1823 | "10892": "gtreqqless;",
1824 | "10893": "lsime;",
1825 | "10894": "gsime;",
1826 | "10895": "lsimg;",
1827 | "10896": "gsiml;",
1828 | "10897": "lgE;",
1829 | "10898": "glE;",
1830 | "10899": "lesges;",
1831 | "10900": "gesles;",
1832 | "10901": "eqslantless;",
1833 | "10902": "eqslantgtr;",
1834 | "10903": "elsdot;",
1835 | "10904": "egsdot;",
1836 | "10905": "el;",
1837 | "10906": "eg;",
1838 | "10909": "siml;",
1839 | "10910": "simg;",
1840 | "10911": "simlE;",
1841 | "10912": "simgE;",
1842 | "10913": "LessLess;",
1843 | "10914": "GreaterGreater;",
1844 | "10916": "glj;",
1845 | "10917": "gla;",
1846 | "10918": "ltcc;",
1847 | "10919": "gtcc;",
1848 | "10920": "lescc;",
1849 | "10921": "gescc;",
1850 | "10922": "smt;",
1851 | "10923": "lat;",
1852 | "10924": "smte;",
1853 | "10925": "late;",
1854 | "10926": "bumpE;",
1855 | "10927": "preceq;",
1856 | "10928": "succeq;",
1857 | "10931": "prE;",
1858 | "10932": "scE;",
1859 | "10933": "prnE;",
1860 | "10934": "succneqq;",
1861 | "10935": "precapprox;",
1862 | "10936": "succapprox;",
1863 | "10937": "prnap;",
1864 | "10938": "succnapprox;",
1865 | "10939": "Pr;",
1866 | "10940": "Sc;",
1867 | "10941": "subdot;",
1868 | "10942": "supdot;",
1869 | "10943": "subplus;",
1870 | "10944": "supplus;",
1871 | "10945": "submult;",
1872 | "10946": "supmult;",
1873 | "10947": "subedot;",
1874 | "10948": "supedot;",
1875 | "10949": "subseteqq;",
1876 | "10950": "supseteqq;",
1877 | "10951": "subsim;",
1878 | "10952": "supsim;",
1879 | "10955": "subsetneqq;",
1880 | "10956": "supsetneqq;",
1881 | "10959": "csub;",
1882 | "10960": "csup;",
1883 | "10961": "csube;",
1884 | "10962": "csupe;",
1885 | "10963": "subsup;",
1886 | "10964": "supsub;",
1887 | "10965": "subsub;",
1888 | "10966": "supsup;",
1889 | "10967": "suphsub;",
1890 | "10968": "supdsub;",
1891 | "10969": "forkv;",
1892 | "10970": "topfork;",
1893 | "10971": "mlcp;",
1894 | "10980": "DoubleLeftTee;",
1895 | "10982": "Vdashl;",
1896 | "10983": "Barv;",
1897 | "10984": "vBar;",
1898 | "10985": "vBarv;",
1899 | "10987": "Vbar;",
1900 | "10988": "Not;",
1901 | "10989": "bNot;",
1902 | "10990": "rnmid;",
1903 | "10991": "cirmid;",
1904 | "10992": "midcir;",
1905 | "10993": "topcir;",
1906 | "10994": "nhpar;",
1907 | "10995": "parsim;",
1908 | "11005": "parsl;",
1909 | "64256": "fflig;",
1910 | "64257": "filig;",
1911 | "64258": "fllig;",
1912 | "64259": "ffilig;",
1913 | "64260": "ffllig;"
1914 | }
1915 | },{}],9:[function(require,module,exports){
1916 | 'use strict';
1917 |
1918 | var hasOwn = Object.prototype.hasOwnProperty;
1919 | var toStr = Object.prototype.toString;
1920 |
1921 | var isArray = function isArray(arr) {
1922 | if (typeof Array.isArray === 'function') {
1923 | return Array.isArray(arr);
1924 | }
1925 |
1926 | return toStr.call(arr) === '[object Array]';
1927 | };
1928 |
1929 | var isPlainObject = function isPlainObject(obj) {
1930 | if (!obj || toStr.call(obj) !== '[object Object]') {
1931 | return false;
1932 | }
1933 |
1934 | var hasOwnConstructor = hasOwn.call(obj, 'constructor');
1935 | var hasIsPrototypeOf = obj.constructor && obj.constructor.prototype && hasOwn.call(obj.constructor.prototype, 'isPrototypeOf');
1936 | // Not own constructor property must be Object
1937 | if (obj.constructor && !hasOwnConstructor && !hasIsPrototypeOf) {
1938 | return false;
1939 | }
1940 |
1941 | // Own properties are enumerated firstly, so to speed up,
1942 | // if last one is own, then all properties are own.
1943 | var key;
1944 | for (key in obj) {/**/}
1945 |
1946 | return typeof key === 'undefined' || hasOwn.call(obj, key);
1947 | };
1948 |
1949 | module.exports = function extend() {
1950 | var options, name, src, copy, copyIsArray, clone,
1951 | target = arguments[0],
1952 | i = 1,
1953 | length = arguments.length,
1954 | deep = false;
1955 |
1956 | // Handle a deep copy situation
1957 | if (typeof target === 'boolean') {
1958 | deep = target;
1959 | target = arguments[1] || {};
1960 | // skip the boolean and the target
1961 | i = 2;
1962 | } else if ((typeof target !== 'object' && typeof target !== 'function') || target == null) {
1963 | target = {};
1964 | }
1965 |
1966 | for (; i < length; ++i) {
1967 | options = arguments[i];
1968 | // Only deal with non-null/undefined values
1969 | if (options != null) {
1970 | // Extend the base object
1971 | for (name in options) {
1972 | src = target[name];
1973 | copy = options[name];
1974 |
1975 | // Prevent never-ending loop
1976 | if (target !== copy) {
1977 | // Recurse if we're merging plain objects or arrays
1978 | if (deep && copy && (isPlainObject(copy) || (copyIsArray = isArray(copy)))) {
1979 | if (copyIsArray) {
1980 | copyIsArray = false;
1981 | clone = src && isArray(src) ? src : [];
1982 | } else {
1983 | clone = src && isPlainObject(src) ? src : {};
1984 | }
1985 |
1986 | // Never move original objects, clone them
1987 | target[name] = extend(deep, clone, copy);
1988 |
1989 | // Don't bring in undefined values
1990 | } else if (typeof copy !== 'undefined') {
1991 | target[name] = copy;
1992 | }
1993 | }
1994 | }
1995 | }
1996 | }
1997 |
1998 | // Return the modified object
1999 | return target;
2000 | };
2001 |
2002 |
2003 | },{}],10:[function(require,module,exports){
2004 | (function (global){
2005 | /*! https://mths.be/punycode v1.4.1 by @mathias */
2006 | ;(function(root) {
2007 |
2008 | /** Detect free variables */
2009 | var freeExports = typeof exports == 'object' && exports &&
2010 | !exports.nodeType && exports;
2011 | var freeModule = typeof module == 'object' && module &&
2012 | !module.nodeType && module;
2013 | var freeGlobal = typeof global == 'object' && global;
2014 | if (
2015 | freeGlobal.global === freeGlobal ||
2016 | freeGlobal.window === freeGlobal ||
2017 | freeGlobal.self === freeGlobal
2018 | ) {
2019 | root = freeGlobal;
2020 | }
2021 |
2022 | /**
2023 | * The `punycode` object.
2024 | * @name punycode
2025 | * @type Object
2026 | */
2027 | var punycode,
2028 |
2029 | /** Highest positive signed 32-bit float value */
2030 | maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1
2031 |
2032 | /** Bootstring parameters */
2033 | base = 36,
2034 | tMin = 1,
2035 | tMax = 26,
2036 | skew = 38,
2037 | damp = 700,
2038 | initialBias = 72,
2039 | initialN = 128, // 0x80
2040 | delimiter = '-', // '\x2D'
2041 |
2042 | /** Regular expressions */
2043 | regexPunycode = /^xn--/,
2044 | regexNonASCII = /[^\x20-\x7E]/, // unprintable ASCII chars + non-ASCII chars
2045 | regexSeparators = /[\x2E\u3002\uFF0E\uFF61]/g, // RFC 3490 separators
2046 |
2047 | /** Error messages */
2048 | errors = {
2049 | 'overflow': 'Overflow: input needs wider integers to process',
2050 | 'not-basic': 'Illegal input >= 0x80 (not a basic code point)',
2051 | 'invalid-input': 'Invalid input'
2052 | },
2053 |
2054 | /** Convenience shortcuts */
2055 | baseMinusTMin = base - tMin,
2056 | floor = Math.floor,
2057 | stringFromCharCode = String.fromCharCode,
2058 |
2059 | /** Temporary variable */
2060 | key;
2061 |
2062 | /*--------------------------------------------------------------------------*/
2063 |
2064 | /**
2065 | * A generic error utility function.
2066 | * @private
2067 | * @param {String} type The error type.
2068 | * @returns {Error} Throws a `RangeError` with the applicable error message.
2069 | */
2070 | function error(type) {
2071 | throw new RangeError(errors[type]);
2072 | }
2073 |
2074 | /**
2075 | * A generic `Array#map` utility function.
2076 | * @private
2077 | * @param {Array} array The array to iterate over.
2078 | * @param {Function} callback The function that gets called for every array
2079 | * item.
2080 | * @returns {Array} A new array of values returned by the callback function.
2081 | */
2082 | function map(array, fn) {
2083 | var length = array.length;
2084 | var result = [];
2085 | while (length--) {
2086 | result[length] = fn(array[length]);
2087 | }
2088 | return result;
2089 | }
2090 |
2091 | /**
2092 | * A simple `Array#map`-like wrapper to work with domain name strings or email
2093 | * addresses.
2094 | * @private
2095 | * @param {String} domain The domain name or email address.
2096 | * @param {Function} callback The function that gets called for every
2097 | * character.
2098 | * @returns {Array} A new string of characters returned by the callback
2099 | * function.
2100 | */
2101 | function mapDomain(string, fn) {
2102 | var parts = string.split('@');
2103 | var result = '';
2104 | if (parts.length > 1) {
2105 | // In email addresses, only the domain name should be punycoded. Leave
2106 | // the local part (i.e. everything up to `@`) intact.
2107 | result = parts[0] + '@';
2108 | string = parts[1];
2109 | }
2110 | // Avoid `split(regex)` for IE8 compatibility. See #17.
2111 | string = string.replace(regexSeparators, '\x2E');
2112 | var labels = string.split('.');
2113 | var encoded = map(labels, fn).join('.');
2114 | return result + encoded;
2115 | }
2116 |
2117 | /**
2118 | * Creates an array containing the numeric code points of each Unicode
2119 | * character in the string. While JavaScript uses UCS-2 internally,
2120 | * this function will convert a pair of surrogate halves (each of which
2121 | * UCS-2 exposes as separate characters) into a single code point,
2122 | * matching UTF-16.
2123 | * @see `punycode.ucs2.encode`
2124 | * @see
2125 | * @memberOf punycode.ucs2
2126 | * @name decode
2127 | * @param {String} string The Unicode input string (UCS-2).
2128 | * @returns {Array} The new array of code points.
2129 | */
2130 | function ucs2decode(string) {
2131 | var output = [],
2132 | counter = 0,
2133 | length = string.length,
2134 | value,
2135 | extra;
2136 | while (counter < length) {
2137 | value = string.charCodeAt(counter++);
2138 | if (value >= 0xD800 && value <= 0xDBFF && counter < length) {
2139 | // high surrogate, and there is a next character
2140 | extra = string.charCodeAt(counter++);
2141 | if ((extra & 0xFC00) == 0xDC00) { // low surrogate
2142 | output.push(((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000);
2143 | } else {
2144 | // unmatched surrogate; only append this code unit, in case the next
2145 | // code unit is the high surrogate of a surrogate pair
2146 | output.push(value);
2147 | counter--;
2148 | }
2149 | } else {
2150 | output.push(value);
2151 | }
2152 | }
2153 | return output;
2154 | }
2155 |
2156 | /**
2157 | * Creates a string based on an array of numeric code points.
2158 | * @see `punycode.ucs2.decode`
2159 | * @memberOf punycode.ucs2
2160 | * @name encode
2161 | * @param {Array} codePoints The array of numeric code points.
2162 | * @returns {String} The new Unicode string (UCS-2).
2163 | */
2164 | function ucs2encode(array) {
2165 | return map(array, function(value) {
2166 | var output = '';
2167 | if (value > 0xFFFF) {
2168 | value -= 0x10000;
2169 | output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800);
2170 | value = 0xDC00 | value & 0x3FF;
2171 | }
2172 | output += stringFromCharCode(value);
2173 | return output;
2174 | }).join('');
2175 | }
2176 |
2177 | /**
2178 | * Converts a basic code point into a digit/integer.
2179 | * @see `digitToBasic()`
2180 | * @private
2181 | * @param {Number} codePoint The basic numeric code point value.
2182 | * @returns {Number} The numeric value of a basic code point (for use in
2183 | * representing integers) in the range `0` to `base - 1`, or `base` if
2184 | * the code point does not represent a value.
2185 | */
2186 | function basicToDigit(codePoint) {
2187 | if (codePoint - 48 < 10) {
2188 | return codePoint - 22;
2189 | }
2190 | if (codePoint - 65 < 26) {
2191 | return codePoint - 65;
2192 | }
2193 | if (codePoint - 97 < 26) {
2194 | return codePoint - 97;
2195 | }
2196 | return base;
2197 | }
2198 |
2199 | /**
2200 | * Converts a digit/integer into a basic code point.
2201 | * @see `basicToDigit()`
2202 | * @private
2203 | * @param {Number} digit The numeric value of a basic code point.
2204 | * @returns {Number} The basic code point whose value (when used for
2205 | * representing integers) is `digit`, which needs to be in the range
2206 | * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is
2207 | * used; else, the lowercase form is used. The behavior is undefined
2208 | * if `flag` is non-zero and `digit` has no uppercase form.
2209 | */
2210 | function digitToBasic(digit, flag) {
2211 | // 0..25 map to ASCII a..z or A..Z
2212 | // 26..35 map to ASCII 0..9
2213 | return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5);
2214 | }
2215 |
2216 | /**
2217 | * Bias adaptation function as per section 3.4 of RFC 3492.
2218 | * https://tools.ietf.org/html/rfc3492#section-3.4
2219 | * @private
2220 | */
2221 | function adapt(delta, numPoints, firstTime) {
2222 | var k = 0;
2223 | delta = firstTime ? floor(delta / damp) : delta >> 1;
2224 | delta += floor(delta / numPoints);
2225 | for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) {
2226 | delta = floor(delta / baseMinusTMin);
2227 | }
2228 | return floor(k + (baseMinusTMin + 1) * delta / (delta + skew));
2229 | }
2230 |
2231 | /**
2232 | * Converts a Punycode string of ASCII-only symbols to a string of Unicode
2233 | * symbols.
2234 | * @memberOf punycode
2235 | * @param {String} input The Punycode string of ASCII-only symbols.
2236 | * @returns {String} The resulting string of Unicode symbols.
2237 | */
2238 | function decode(input) {
2239 | // Don't use UCS-2
2240 | var output = [],
2241 | inputLength = input.length,
2242 | out,
2243 | i = 0,
2244 | n = initialN,
2245 | bias = initialBias,
2246 | basic,
2247 | j,
2248 | index,
2249 | oldi,
2250 | w,
2251 | k,
2252 | digit,
2253 | t,
2254 | /** Cached calculation results */
2255 | baseMinusT;
2256 |
2257 | // Handle the basic code points: let `basic` be the number of input code
2258 | // points before the last delimiter, or `0` if there is none, then copy
2259 | // the first basic code points to the output.
2260 |
2261 | basic = input.lastIndexOf(delimiter);
2262 | if (basic < 0) {
2263 | basic = 0;
2264 | }
2265 |
2266 | for (j = 0; j < basic; ++j) {
2267 | // if it's not a basic code point
2268 | if (input.charCodeAt(j) >= 0x80) {
2269 | error('not-basic');
2270 | }
2271 | output.push(input.charCodeAt(j));
2272 | }
2273 |
2274 | // Main decoding loop: start just after the last delimiter if any basic code
2275 | // points were copied; start at the beginning otherwise.
2276 |
2277 | for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) {
2278 |
2279 | // `index` is the index of the next character to be consumed.
2280 | // Decode a generalized variable-length integer into `delta`,
2281 | // which gets added to `i`. The overflow checking is easier
2282 | // if we increase `i` as we go, then subtract off its starting
2283 | // value at the end to obtain `delta`.
2284 | for (oldi = i, w = 1, k = base; /* no condition */; k += base) {
2285 |
2286 | if (index >= inputLength) {
2287 | error('invalid-input');
2288 | }
2289 |
2290 | digit = basicToDigit(input.charCodeAt(index++));
2291 |
2292 | if (digit >= base || digit > floor((maxInt - i) / w)) {
2293 | error('overflow');
2294 | }
2295 |
2296 | i += digit * w;
2297 | t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
2298 |
2299 | if (digit < t) {
2300 | break;
2301 | }
2302 |
2303 | baseMinusT = base - t;
2304 | if (w > floor(maxInt / baseMinusT)) {
2305 | error('overflow');
2306 | }
2307 |
2308 | w *= baseMinusT;
2309 |
2310 | }
2311 |
2312 | out = output.length + 1;
2313 | bias = adapt(i - oldi, out, oldi == 0);
2314 |
2315 | // `i` was supposed to wrap around from `out` to `0`,
2316 | // incrementing `n` each time, so we'll fix that now:
2317 | if (floor(i / out) > maxInt - n) {
2318 | error('overflow');
2319 | }
2320 |
2321 | n += floor(i / out);
2322 | i %= out;
2323 |
2324 | // Insert `n` at position `i` of the output
2325 | output.splice(i++, 0, n);
2326 |
2327 | }
2328 |
2329 | return ucs2encode(output);
2330 | }
2331 |
2332 | /**
2333 | * Converts a string of Unicode symbols (e.g. a domain name label) to a
2334 | * Punycode string of ASCII-only symbols.
2335 | * @memberOf punycode
2336 | * @param {String} input The string of Unicode symbols.
2337 | * @returns {String} The resulting Punycode string of ASCII-only symbols.
2338 | */
2339 | function encode(input) {
2340 | var n,
2341 | delta,
2342 | handledCPCount,
2343 | basicLength,
2344 | bias,
2345 | j,
2346 | m,
2347 | q,
2348 | k,
2349 | t,
2350 | currentValue,
2351 | output = [],
2352 | /** `inputLength` will hold the number of code points in `input`. */
2353 | inputLength,
2354 | /** Cached calculation results */
2355 | handledCPCountPlusOne,
2356 | baseMinusT,
2357 | qMinusT;
2358 |
2359 | // Convert the input in UCS-2 to Unicode
2360 | input = ucs2decode(input);
2361 |
2362 | // Cache the length
2363 | inputLength = input.length;
2364 |
2365 | // Initialize the state
2366 | n = initialN;
2367 | delta = 0;
2368 | bias = initialBias;
2369 |
2370 | // Handle the basic code points
2371 | for (j = 0; j < inputLength; ++j) {
2372 | currentValue = input[j];
2373 | if (currentValue < 0x80) {
2374 | output.push(stringFromCharCode(currentValue));
2375 | }
2376 | }
2377 |
2378 | handledCPCount = basicLength = output.length;
2379 |
2380 | // `handledCPCount` is the number of code points that have been handled;
2381 | // `basicLength` is the number of basic code points.
2382 |
2383 | // Finish the basic string - if it is not empty - with a delimiter
2384 | if (basicLength) {
2385 | output.push(delimiter);
2386 | }
2387 |
2388 | // Main encoding loop:
2389 | while (handledCPCount < inputLength) {
2390 |
2391 | // All non-basic code points < n have been handled already. Find the next
2392 | // larger one:
2393 | for (m = maxInt, j = 0; j < inputLength; ++j) {
2394 | currentValue = input[j];
2395 | if (currentValue >= n && currentValue < m) {
2396 | m = currentValue;
2397 | }
2398 | }
2399 |
2400 | // Increase `delta` enough to advance the decoder's state to ,
2401 | // but guard against overflow
2402 | handledCPCountPlusOne = handledCPCount + 1;
2403 | if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) {
2404 | error('overflow');
2405 | }
2406 |
2407 | delta += (m - n) * handledCPCountPlusOne;
2408 | n = m;
2409 |
2410 | for (j = 0; j < inputLength; ++j) {
2411 | currentValue = input[j];
2412 |
2413 | if (currentValue < n && ++delta > maxInt) {
2414 | error('overflow');
2415 | }
2416 |
2417 | if (currentValue == n) {
2418 | // Represent delta as a generalized variable-length integer
2419 | for (q = delta, k = base; /* no condition */; k += base) {
2420 | t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias);
2421 | if (q < t) {
2422 | break;
2423 | }
2424 | qMinusT = q - t;
2425 | baseMinusT = base - t;
2426 | output.push(
2427 | stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0))
2428 | );
2429 | q = floor(qMinusT / baseMinusT);
2430 | }
2431 |
2432 | output.push(stringFromCharCode(digitToBasic(q, 0)));
2433 | bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength);
2434 | delta = 0;
2435 | ++handledCPCount;
2436 | }
2437 | }
2438 |
2439 | ++delta;
2440 | ++n;
2441 |
2442 | }
2443 | return output.join('');
2444 | }
2445 |
2446 | /**
2447 | * Converts a Punycode string representing a domain name or an email address
2448 | * to Unicode. Only the Punycoded parts of the input will be converted, i.e.
2449 | * it doesn't matter if you call it on a string that has already been
2450 | * converted to Unicode.
2451 | * @memberOf punycode
2452 | * @param {String} input The Punycoded domain name or email address to
2453 | * convert to Unicode.
2454 | * @returns {String} The Unicode representation of the given Punycode
2455 | * string.
2456 | */
2457 | function toUnicode(input) {
2458 | return mapDomain(input, function(string) {
2459 | return regexPunycode.test(string)
2460 | ? decode(string.slice(4).toLowerCase())
2461 | : string;
2462 | });
2463 | }
2464 |
2465 | /**
2466 | * Converts a Unicode string representing a domain name or an email address to
2467 | * Punycode. Only the non-ASCII parts of the domain name will be converted,
2468 | * i.e. it doesn't matter if you call it with a domain that's already in
2469 | * ASCII.
2470 | * @memberOf punycode
2471 | * @param {String} input The domain name or email address to convert, as a
2472 | * Unicode string.
2473 | * @returns {String} The Punycode representation of the given domain name or
2474 | * email address.
2475 | */
2476 | function toASCII(input) {
2477 | return mapDomain(input, function(string) {
2478 | return regexNonASCII.test(string)
2479 | ? 'xn--' + encode(string)
2480 | : string;
2481 | });
2482 | }
2483 |
2484 | /*--------------------------------------------------------------------------*/
2485 |
2486 | /** Define the public API */
2487 | punycode = {
2488 | /**
2489 | * A string representing the current Punycode.js version number.
2490 | * @memberOf punycode
2491 | * @type String
2492 | */
2493 | 'version': '1.4.1',
2494 | /**
2495 | * An object of methods to convert from JavaScript's internal character
2496 | * representation (UCS-2) to Unicode code points, and back.
2497 | * @see
2498 | * @memberOf punycode
2499 | * @type Object
2500 | */
2501 | 'ucs2': {
2502 | 'decode': ucs2decode,
2503 | 'encode': ucs2encode
2504 | },
2505 | 'decode': decode,
2506 | 'encode': encode,
2507 | 'toASCII': toASCII,
2508 | 'toUnicode': toUnicode
2509 | };
2510 |
2511 | /** Expose `punycode` */
2512 | // Some AMD build optimizers, like r.js, check for specific condition patterns
2513 | // like the following:
2514 | if (
2515 | typeof define == 'function' &&
2516 | typeof define.amd == 'object' &&
2517 | define.amd
2518 | ) {
2519 | define('punycode', function() {
2520 | return punycode;
2521 | });
2522 | } else if (freeExports && freeModule) {
2523 | if (module.exports == freeExports) {
2524 | // in Node.js, io.js, or RingoJS v0.8.0+
2525 | freeModule.exports = punycode;
2526 | } else {
2527 | // in Narwhal or RingoJS v0.7.0-
2528 | for (key in punycode) {
2529 | punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]);
2530 | }
2531 | }
2532 | } else {
2533 | // in Rhino or a web browser
2534 | root.punycode = punycode;
2535 | }
2536 |
2537 | }(this));
2538 |
2539 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
2540 | },{}],11:[function(require,module,exports){
2541 | /**
2542 | * This file automatically generated from `pre-publish.js`.
2543 | * Do not manually edit.
2544 | */
2545 |
2546 | module.exports = {
2547 | "area": true,
2548 | "base": true,
2549 | "br": true,
2550 | "col": true,
2551 | "embed": true,
2552 | "hr": true,
2553 | "img": true,
2554 | "input": true,
2555 | "keygen": true,
2556 | "link": true,
2557 | "menuitem": true,
2558 | "meta": true,
2559 | "param": true,
2560 | "source": true,
2561 | "track": true,
2562 | "wbr": true
2563 | };
2564 |
2565 | },{}]},{},[4]);
2566 |
--------------------------------------------------------------------------------