├── src ├── assets │ ├── .gitkeep │ └── favicons │ │ ├── favicon.ico │ │ ├── favicon-16x16.png │ │ ├── favicon-32x32.png │ │ ├── mstile-150x150.png │ │ ├── apple-touch-icon.png │ │ ├── android-chrome-192x192.png │ │ ├── android-chrome-384x384.png │ │ ├── browserconfig.xml │ │ ├── manifest.json │ │ └── safari-pinned-tab.svg ├── app │ ├── app.component.css │ ├── home │ │ ├── home.component.css │ │ ├── home.component.ts │ │ ├── home.component.spec.ts │ │ └── home.component.html │ ├── ode │ │ ├── ode.component.css │ │ ├── ode.component.spec.ts │ │ ├── ode.component.html │ │ └── ode.component.ts │ ├── sde │ │ ├── sde.component.css │ │ ├── sde.component.spec.ts │ │ ├── sde.component.html │ │ └── sde.component.ts │ ├── index.ts │ ├── app.component.ts │ ├── api.service.spec.ts │ ├── app.component.html │ ├── app.component.spec.ts │ ├── app.module.ts │ └── api.service.ts ├── favicon.ico ├── styles.css ├── environments │ ├── environment.prod.ts │ └── environment.ts ├── typings.d.ts ├── .htaccess ├── main.ts ├── tsconfig.json ├── polyfills.ts ├── test.ts └── index.html ├── e2e ├── app.po.ts ├── app.e2e-spec.ts └── tsconfig.json ├── .editorconfig ├── .gitignore ├── CITATION.bib ├── protractor.conf.js ├── karma.conf.js ├── LICENSE.md ├── angular-cli.json ├── package.json ├── README.md └── tslint.json /src/assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/app.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/home/home.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/ode/ode.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/sde/sde.component.css: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /src/app/index.ts: -------------------------------------------------------------------------------- 1 | export * from './app.component'; 2 | export * from './app.module'; 3 | -------------------------------------------------------------------------------- /src/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SciML/DiffEqOnline/HEAD/src/favicon.ico -------------------------------------------------------------------------------- /src/styles.css: -------------------------------------------------------------------------------- 1 | /* You can add global styles to this file, and also import other style files */ 2 | -------------------------------------------------------------------------------- /src/assets/favicons/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SciML/DiffEqOnline/HEAD/src/assets/favicons/favicon.ico -------------------------------------------------------------------------------- /src/assets/favicons/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SciML/DiffEqOnline/HEAD/src/assets/favicons/favicon-16x16.png -------------------------------------------------------------------------------- /src/assets/favicons/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SciML/DiffEqOnline/HEAD/src/assets/favicons/favicon-32x32.png -------------------------------------------------------------------------------- /src/assets/favicons/mstile-150x150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SciML/DiffEqOnline/HEAD/src/assets/favicons/mstile-150x150.png -------------------------------------------------------------------------------- /src/assets/favicons/apple-touch-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SciML/DiffEqOnline/HEAD/src/assets/favicons/apple-touch-icon.png -------------------------------------------------------------------------------- /src/assets/favicons/android-chrome-192x192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SciML/DiffEqOnline/HEAD/src/assets/favicons/android-chrome-192x192.png -------------------------------------------------------------------------------- /src/assets/favicons/android-chrome-384x384.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SciML/DiffEqOnline/HEAD/src/assets/favicons/android-chrome-384x384.png -------------------------------------------------------------------------------- /src/environments/environment.prod.ts: -------------------------------------------------------------------------------- 1 | export const environment = { 2 | production: true, 3 | apiBaseURL: "http://diffeqonline.herokuapp.com" 4 | }; 5 | -------------------------------------------------------------------------------- /src/typings.d.ts: -------------------------------------------------------------------------------- 1 | // Typings reference file, you can add your own global typings here 2 | // https://www.typescriptlang.org/docs/handbook/writing-declaration-files.html 3 | 4 | declare var System: any; 5 | 6 | declare module 'file-saver'; 7 | -------------------------------------------------------------------------------- /e2e/app.po.ts: -------------------------------------------------------------------------------- 1 | import { browser, element, by } from 'protractor'; 2 | 3 | export class JuliaApiDemoPage { 4 | navigateTo() { 5 | return browser.get('/'); 6 | } 7 | 8 | getParagraphText() { 9 | return element(by.css('app-root h1')).getText(); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/app/app.component.ts: -------------------------------------------------------------------------------- 1 | import { Component } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-root', 5 | templateUrl: './app.component.html', 6 | styleUrls: ['./app.component.css'] 7 | }) 8 | export class AppComponent { 9 | title = 'app works!'; 10 | } 11 | -------------------------------------------------------------------------------- /src/assets/favicons/browserconfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | #ffc40d 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Editor configuration, see http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | 11 | [*.md] 12 | max_line_length = 0 13 | trim_trailing_whitespace = false 14 | -------------------------------------------------------------------------------- /src/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | Options Indexes FollowSymLinks 3 | RewriteEngine On 4 | RewriteBase /crisis-center/ 5 | RewriteRule ^index\.html$ - [L] 6 | RewriteCond %{REQUEST_FILENAME} !-f 7 | RewriteCond %{REQUEST_FILENAME} !-d 8 | RewriteRule . /index.html [L] 9 | 10 | -------------------------------------------------------------------------------- /src/app/home/home.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | 3 | @Component({ 4 | selector: 'app-home', 5 | templateUrl: './home.component.html', 6 | styleUrls: ['./home.component.css'] 7 | }) 8 | export class HomeComponent implements OnInit { 9 | 10 | constructor() { } 11 | 12 | ngOnInit() { 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/assets/favicons/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "", 3 | "icons": [ 4 | { 5 | "src": "\/android-chrome-192x192.png", 6 | "sizes": "192x192", 7 | "type": "image\/png" 8 | }, 9 | { 10 | "src": "\/android-chrome-384x384.png", 11 | "sizes": "384x384", 12 | "type": "image\/png" 13 | } 14 | ], 15 | "theme_color": "#ffffff", 16 | "display": "standalone" 17 | } 18 | -------------------------------------------------------------------------------- /e2e/app.e2e-spec.ts: -------------------------------------------------------------------------------- 1 | import { JuliaApiDemoPage } from './app.po'; 2 | 3 | describe('julia-api-demo App', function() { 4 | let page: JuliaApiDemoPage; 5 | 6 | beforeEach(() => { 7 | page = new JuliaApiDemoPage(); 8 | }); 9 | 10 | it('should display message saying app works', () => { 11 | page.navigateTo(); 12 | expect(page.getParagraphText()).toEqual('app works!'); 13 | }); 14 | }); 15 | -------------------------------------------------------------------------------- /src/main.ts: -------------------------------------------------------------------------------- 1 | import './polyfills.ts'; 2 | 3 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic'; 4 | import { enableProdMode } from '@angular/core'; 5 | import { environment } from './environments/environment'; 6 | import { AppModule } from './app/'; 7 | 8 | if (environment.production) { 9 | enableProdMode(); 10 | } 11 | 12 | platformBrowserDynamic().bootstrapModule(AppModule); 13 | -------------------------------------------------------------------------------- /e2e/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compileOnSave": false, 3 | "compilerOptions": { 4 | "declaration": false, 5 | "emitDecoratorMetadata": true, 6 | "experimentalDecorators": true, 7 | "module": "commonjs", 8 | "moduleResolution": "node", 9 | "outDir": "../dist/out-tsc-e2e", 10 | "sourceMap": true, 11 | "target": "es5", 12 | "typeRoots": [ 13 | "../node_modules/@types" 14 | ] 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "declaration": false, 4 | "emitDecoratorMetadata": true, 5 | "experimentalDecorators": true, 6 | "lib": ["es6", "dom"], 7 | "mapRoot": "./", 8 | "module": "es6", 9 | "moduleResolution": "node", 10 | "outDir": "../dist/out-tsc", 11 | "sourceMap": true, 12 | "target": "es5", 13 | "typeRoots": [ 14 | "../node_modules/@types" 15 | ] 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/environments/environment.ts: -------------------------------------------------------------------------------- 1 | // The file contents for the current environment will overwrite these during build. 2 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do 3 | // `ng build --env=prod` then `environment.prod.ts` will be used instead. 4 | // The list of which env maps to which file can be found in `angular-cli.json`. 5 | 6 | export const environment = { 7 | production: false, 8 | apiBaseURL: "http://localhost:7777" 9 | }; 10 | -------------------------------------------------------------------------------- /src/app/api.service.spec.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-unused-variable */ 2 | 3 | import { TestBed, async, inject } from '@angular/core/testing'; 4 | import { ApiService } from './api.service'; 5 | 6 | describe('Service: ApiService', () => { 7 | beforeEach(() => { 8 | TestBed.configureTestingModule({ 9 | providers: [ApiService] 10 | }); 11 | }); 12 | 13 | it('should ...', inject([ApiService], (service: ApiService) => { 14 | expect(service).toBeTruthy(); 15 | })); 16 | }); 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See http://help.github.com/ignore-files/ for more about ignoring files. 2 | 3 | *.log 4 | /.ipynb_checkpoints 5 | /docs/.ipynb_checkpoints 6 | /api/.ipynb_checkpoints 7 | 8 | # compiled output 9 | /dist 10 | /tmp 11 | 12 | # dependencies 13 | /node_modules 14 | /bower_components 15 | 16 | # IDEs and editors 17 | /.idea 18 | /.vscode 19 | .project 20 | .classpath 21 | *.launch 22 | .settings/ 23 | 24 | # misc 25 | /.sass-cache 26 | /connect.lock 27 | /coverage/* 28 | /libpeerconnection.log 29 | npm-debug.log 30 | testem.log 31 | /typings 32 | 33 | # e2e 34 | /e2e/*.js 35 | /e2e/*.map 36 | 37 | #System Files 38 | .DS_Store 39 | Thumbs.db 40 | -------------------------------------------------------------------------------- /CITATION.bib: -------------------------------------------------------------------------------- 1 | @article{DifferentialEquations.jl-2017, 2 | author = {Rackauckas, Christopher and Nie, Qing}, 3 | doi = {10.5334/jors.151}, 4 | journal = {The Journal of Open Research Software}, 5 | keywords = {Applied Mathematics}, 6 | note = {Exported from https://app.dimensions.ai on 2019/05/05}, 7 | number = {1}, 8 | pages = {}, 9 | title = {DifferentialEquations.jl – A Performant and Feature-Rich Ecosystem for Solving Differential Equations in Julia}, 10 | url = {https://app.dimensions.ai/details/publication/pub.1085583166 and http://openresearchsoftware.metajnl.com/articles/10.5334/jors.151/galley/245/download/}, 11 | volume = {5}, 12 | year = {2017} 13 | } 14 | -------------------------------------------------------------------------------- /src/polyfills.ts: -------------------------------------------------------------------------------- 1 | // This file includes polyfills needed by Angular 2 and is loaded before 2 | // the app. You can add your own extra polyfills to this file. 3 | import 'core-js/es6/symbol'; 4 | import 'core-js/es6/object'; 5 | import 'core-js/es6/function'; 6 | import 'core-js/es6/parse-int'; 7 | import 'core-js/es6/parse-float'; 8 | import 'core-js/es6/number'; 9 | import 'core-js/es6/math'; 10 | import 'core-js/es6/string'; 11 | import 'core-js/es6/date'; 12 | import 'core-js/es6/array'; 13 | import 'core-js/es6/regexp'; 14 | import 'core-js/es6/map'; 15 | import 'core-js/es6/set'; 16 | import 'core-js/es6/reflect'; 17 | 18 | import 'core-js/es7/reflect'; 19 | import 'zone.js/dist/zone'; 20 | -------------------------------------------------------------------------------- /src/app/ode/ode.component.spec.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-unused-variable */ 2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 3 | import { By } from '@angular/platform-browser'; 4 | import { DebugElement } from '@angular/core'; 5 | 6 | import { OdeComponent } from './ode.component'; 7 | 8 | describe('OdeComponent', () => { 9 | let component: OdeComponent; 10 | let fixture: ComponentFixture; 11 | 12 | beforeEach(async(() => { 13 | TestBed.configureTestingModule({ 14 | declarations: [ OdeComponent ] 15 | }) 16 | .compileComponents(); 17 | })); 18 | 19 | beforeEach(() => { 20 | fixture = TestBed.createComponent(OdeComponent); 21 | component = fixture.componentInstance; 22 | fixture.detectChanges(); 23 | }); 24 | 25 | it('should create', () => { 26 | expect(component).toBeTruthy(); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /src/app/sde/sde.component.spec.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-unused-variable */ 2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 3 | import { By } from '@angular/platform-browser'; 4 | import { DebugElement } from '@angular/core'; 5 | 6 | import { SdeComponent } from './sde.component'; 7 | 8 | describe('SdeComponent', () => { 9 | let component: SdeComponent; 10 | let fixture: ComponentFixture; 11 | 12 | beforeEach(async(() => { 13 | TestBed.configureTestingModule({ 14 | declarations: [ SdeComponent ] 15 | }) 16 | .compileComponents(); 17 | })); 18 | 19 | beforeEach(() => { 20 | fixture = TestBed.createComponent(SdeComponent); 21 | component = fixture.componentInstance; 22 | fixture.detectChanges(); 23 | }); 24 | 25 | it('should create', () => { 26 | expect(component).toBeTruthy(); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /src/app/home/home.component.spec.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-unused-variable */ 2 | import { async, ComponentFixture, TestBed } from '@angular/core/testing'; 3 | import { By } from '@angular/platform-browser'; 4 | import { DebugElement } from '@angular/core'; 5 | 6 | import { HomeComponent } from './home.component'; 7 | 8 | describe('HomeComponent', () => { 9 | let component: HomeComponent; 10 | let fixture: ComponentFixture; 11 | 12 | beforeEach(async(() => { 13 | TestBed.configureTestingModule({ 14 | declarations: [ HomeComponent ] 15 | }) 16 | .compileComponents(); 17 | })); 18 | 19 | beforeEach(() => { 20 | fixture = TestBed.createComponent(HomeComponent); 21 | component = fixture.componentInstance; 22 | fixture.detectChanges(); 23 | }); 24 | 25 | it('should create', () => { 26 | expect(component).toBeTruthy(); 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /protractor.conf.js: -------------------------------------------------------------------------------- 1 | // Protractor configuration file, see link for more information 2 | // https://github.com/angular/protractor/blob/master/docs/referenceConf.js 3 | 4 | /*global jasmine */ 5 | var SpecReporter = require('jasmine-spec-reporter'); 6 | 7 | exports.config = { 8 | allScriptsTimeout: 11000, 9 | specs: [ 10 | './e2e/**/*.e2e-spec.ts' 11 | ], 12 | capabilities: { 13 | 'browserName': 'chrome' 14 | }, 15 | directConnect: true, 16 | baseUrl: 'http://localhost:4200/', 17 | framework: 'jasmine', 18 | jasmineNodeOpts: { 19 | showColors: true, 20 | defaultTimeoutInterval: 30000, 21 | print: function() {} 22 | }, 23 | useAllAngular2AppRoots: true, 24 | beforeLaunch: function() { 25 | require('ts-node').register({ 26 | project: 'e2e' 27 | }); 28 | }, 29 | onPrepare: function() { 30 | jasmine.getEnv().addReporter(new SpecReporter()); 31 | } 32 | }; 33 | -------------------------------------------------------------------------------- /src/app/app.component.html: -------------------------------------------------------------------------------- 1 |
2 | 7 |
8 | 11 |
12 | ODEs 13 |
14 |
15 | SDEs 16 |
17 |
18 | 23 |
24 |
25 | 26 |
27 | 32 |
33 |
34 | -------------------------------------------------------------------------------- /src/app/app.component.spec.ts: -------------------------------------------------------------------------------- 1 | /* tslint:disable:no-unused-variable */ 2 | 3 | import { TestBed, async } from '@angular/core/testing'; 4 | import { AppComponent } from './app.component'; 5 | 6 | describe('App: JuliaApiDemo', () => { 7 | beforeEach(() => { 8 | TestBed.configureTestingModule({ 9 | declarations: [ 10 | AppComponent 11 | ], 12 | }); 13 | }); 14 | 15 | it('should create the app', async(() => { 16 | let fixture = TestBed.createComponent(AppComponent); 17 | let app = fixture.debugElement.componentInstance; 18 | expect(app).toBeTruthy(); 19 | })); 20 | 21 | it(`should have as title 'app works!'`, async(() => { 22 | let fixture = TestBed.createComponent(AppComponent); 23 | let app = fixture.debugElement.componentInstance; 24 | expect(app.title).toEqual('app works!'); 25 | })); 26 | 27 | it('should render title in a h1 tag', async(() => { 28 | let fixture = TestBed.createComponent(AppComponent); 29 | fixture.detectChanges(); 30 | let compiled = fixture.debugElement.nativeElement; 31 | expect(compiled.querySelector('h1').textContent).toContain('app works!'); 32 | })); 33 | }); 34 | -------------------------------------------------------------------------------- /src/app/app.module.ts: -------------------------------------------------------------------------------- 1 | import { BrowserModule } from '@angular/platform-browser'; 2 | import { NgModule } from '@angular/core'; 3 | import { FormsModule } from '@angular/forms'; 4 | import { HttpModule } from '@angular/http'; 5 | import { RouterModule } from '@angular/router'; 6 | import { ClarityModule } from 'clarity-angular'; 7 | import { AppComponent } from './app.component'; 8 | import { OdeComponent } from './ode/ode.component'; 9 | import { SdeComponent } from './sde/sde.component'; 10 | import { HomeComponent } from './home/home.component'; 11 | 12 | const routing = RouterModule.forRoot([ 13 | { path: '', component: HomeComponent }, 14 | { path: 'ode', component: OdeComponent }, 15 | { path: 'sde', component: SdeComponent } 16 | 17 | // { path: 'radios', component: RadiosComponent } 18 | ]); 19 | 20 | @NgModule({ 21 | declarations: [ 22 | AppComponent, 23 | OdeComponent, 24 | SdeComponent, 25 | HomeComponent 26 | ], 27 | imports: [ 28 | BrowserModule, 29 | FormsModule, 30 | HttpModule, 31 | routing, 32 | ClarityModule 33 | ], 34 | providers: [], 35 | bootstrap: [AppComponent] 36 | }) 37 | export class AppModule { } 38 | -------------------------------------------------------------------------------- /karma.conf.js: -------------------------------------------------------------------------------- 1 | // Karma configuration file, see link for more information 2 | // https://karma-runner.github.io/0.13/config/configuration-file.html 3 | 4 | module.exports = function (config) { 5 | config.set({ 6 | basePath: '', 7 | frameworks: ['jasmine', 'angular-cli'], 8 | plugins: [ 9 | require('karma-jasmine'), 10 | require('karma-chrome-launcher'), 11 | require('karma-remap-istanbul'), 12 | require('angular-cli/plugins/karma') 13 | ], 14 | files: [ 15 | { pattern: './src/test.ts', watched: false } 16 | ], 17 | preprocessors: { 18 | './src/test.ts': ['angular-cli'] 19 | }, 20 | remapIstanbulReporter: { 21 | reports: { 22 | html: 'coverage', 23 | lcovonly: './coverage/coverage.lcov' 24 | } 25 | }, 26 | angularCli: { 27 | config: './angular-cli.json', 28 | environment: 'dev' 29 | }, 30 | reporters: config.angularCli && config.angularCli.codeCoverage 31 | ? ['progress', 'karma-remap-istanbul'] 32 | : ['progress'], 33 | port: 9876, 34 | colors: true, 35 | logLevel: config.LOG_INFO, 36 | autoWatch: true, 37 | browsers: ['Chrome'], 38 | singleRun: false 39 | }); 40 | }; 41 | -------------------------------------------------------------------------------- /src/test.ts: -------------------------------------------------------------------------------- 1 | import './polyfills.ts'; 2 | 3 | import 'zone.js/dist/long-stack-trace-zone'; 4 | import 'zone.js/dist/proxy.js'; 5 | import 'zone.js/dist/sync-test'; 6 | import 'zone.js/dist/jasmine-patch'; 7 | import 'zone.js/dist/async-test'; 8 | import 'zone.js/dist/fake-async-test'; 9 | 10 | // Unfortunately there's no typing for the `__karma__` variable. Just declare it as any. 11 | declare var __karma__: any; 12 | declare var require: any; 13 | 14 | // Prevent Karma from running prematurely. 15 | __karma__.loaded = function () {}; 16 | 17 | 18 | Promise.all([ 19 | System.import('@angular/core/testing'), 20 | System.import('@angular/platform-browser-dynamic/testing') 21 | ]) 22 | // First, initialize the Angular testing environment. 23 | .then(([testing, testingBrowser]) => { 24 | testing.getTestBed().initTestEnvironment( 25 | testingBrowser.BrowserDynamicTestingModule, 26 | testingBrowser.platformBrowserDynamicTesting() 27 | ); 28 | }) 29 | // Then we find all the tests. 30 | .then(() => require.context('./', true, /\.spec\.ts/)) 31 | // And load the modules. 32 | .then(context => context.keys().map(context)) 33 | // Finally, start Karma to run the tests. 34 | .then(__karma__.start, __karma__.error); 35 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The DiffEqOnline package is licensed under the MIT "Expat" License: 2 | 3 | > Copyright (c) 2016: ChrisRackauckas and Alex Mellnik 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 | > 23 | -------------------------------------------------------------------------------- /src/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | DifferentialEquations.jl on the web, powered by Mux.jl and Plots.jl 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 27 | 28 | 29 |
30 | Loading... 31 |
32 |
33 |

If this message doesn't go away, it may be because you are using an older browser. Try it with a newer version of Chrome, Firefox, Opera or Edge.

34 |
35 |
36 | 37 | 38 | -------------------------------------------------------------------------------- /angular-cli.json: -------------------------------------------------------------------------------- 1 | { 2 | "project": { 3 | "version": "1.0.0-beta.19-3", 4 | "name": "julia-api-demo" 5 | }, 6 | "apps": [ 7 | { 8 | "root": "src", 9 | "outDir": "dist", 10 | "assets": [ 11 | "assets", 12 | "favicon.ico" 13 | ], 14 | "index": "index.html", 15 | "main": "main.ts", 16 | "test": "test.ts", 17 | "tsconfig": "tsconfig.json", 18 | "prefix": "app", 19 | "mobile": false, 20 | "styles": [ 21 | "../node_modules/clarity-icons/clarity-icons.min.css", 22 | "../node_modules/clarity-ui/clarity-ui.min.css", 23 | "styles.css" 24 | ], 25 | "scripts": [ 26 | "../node_modules/mutationobserver-shim/dist/mutationobserver.min.js", 27 | "../node_modules/@webcomponents/custom-elements/custom-elements.min.js", 28 | "../node_modules/clarity-icons/clarity-icons.min.js" 29 | ], 30 | "environments": { 31 | "source": "environments/environment.ts", 32 | "dev": "environments/environment.ts", 33 | "prod": "environments/environment.prod.ts" 34 | } 35 | } 36 | ], 37 | "addons": [], 38 | "packages": [], 39 | "e2e": { 40 | "protractor": { 41 | "config": "./protractor.conf.js" 42 | } 43 | }, 44 | "test": { 45 | "karma": { 46 | "config": "./karma.conf.js" 47 | } 48 | }, 49 | "defaults": { 50 | "styleExt": "css", 51 | "prefixInterfaces": false, 52 | "inline": { 53 | "style": false, 54 | "template": false 55 | }, 56 | "spec": { 57 | "class": false, 58 | "component": true, 59 | "directive": true, 60 | "module": false, 61 | "pipe": true, 62 | "service": true 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "julia-api-demo", 3 | "version": "0.0.0", 4 | "license": "MIT", 5 | "angular-cli": {}, 6 | "scripts": { 7 | "start": "ng serve", 8 | "lint": "tslint \"src/**/*.ts\"", 9 | "test": "ng test", 10 | "pree2e": "webdriver-manager update", 11 | "e2e": "protractor", 12 | "prodbuild": "ng build --prod --base-href=http://app.juliadiffeq.org/" 13 | }, 14 | "private": true, 15 | "dependencies": { 16 | "@angular/common": "~2.1.0", 17 | "@angular/compiler": "~2.1.0", 18 | "@angular/core": "~2.1.0", 19 | "@angular/forms": "~2.1.0", 20 | "@angular/http": "~2.1.0", 21 | "@angular/platform-browser": "~2.1.0", 22 | "@angular/platform-browser-dynamic": "~2.1.0", 23 | "@angular/router": "~3.1.0", 24 | "@webcomponents/custom-elements": "^1.0.0-alpha.3", 25 | "clarity-angular": "^0.7.5-dev", 26 | "clarity-icons": "^0.7.5-dev", 27 | "clarity-ui": "^0.7.5-dev", 28 | "core-js": "^2.4.1", 29 | "file-saver": "^1.3.3", 30 | "mutationobserver-shim": "^0.3.2", 31 | "plotly": "^1.0.6", 32 | "rxjs": "5.0.0-beta.12", 33 | "ts-helpers": "^1.1.1", 34 | "zone.js": "^0.6.23" 35 | }, 36 | "devDependencies": { 37 | "@types/jasmine": "^2.2.30", 38 | "@types/node": "^6.0.42", 39 | "angular-cli": "1.0.0-beta.19-3", 40 | "codelyzer": "1.0.0-beta.1", 41 | "jasmine-core": "2.4.1", 42 | "jasmine-spec-reporter": "2.5.0", 43 | "karma": "1.2.0", 44 | "karma-chrome-launcher": "^2.0.0", 45 | "karma-cli": "^1.0.1", 46 | "karma-jasmine": "^1.0.2", 47 | "karma-remap-istanbul": "^0.2.1", 48 | "protractor": "4.0.9", 49 | "ts-node": "1.2.1", 50 | "tslint": "3.13.0", 51 | "typescript": "~2.0.3", 52 | "webdriver-manager": "10.2.5" 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/app/api.service.ts: -------------------------------------------------------------------------------- 1 | import { Injectable } from '@angular/core'; 2 | import { Http, Headers, RequestOptions, Response } from '@angular/http'; 3 | import { Observable } from 'rxjs/Observable'; 4 | 5 | import 'rxjs/add/operator/map'; 6 | import 'rxjs/add/operator/catch'; 7 | 8 | @Injectable() 9 | export class ApiService { 10 | 11 | private headers = new Headers({ 'Content-Type': 'application/json', 'charset': 'UTF-8' }); 12 | private options = new RequestOptions({ headers: this.headers }); 13 | 14 | constructor(private http: Http) { } 15 | 16 | passDiffEq(apiUrl:string, model:any) { 17 | // Encode the array string as a base64 string to make sure we don't have any crazy characters 18 | return this.http.get(apiUrl + '/solveit/' + btoa(JSON.stringify(model))) 19 | .map(res => res.json().data) 20 | .catch(this.handleError); 21 | } 22 | 23 | wakeUp(apiUrl:string) { 24 | return this.http.get(apiUrl + '/wakeup') 25 | .map(res => res.json().data) 26 | .catch(this.handleError); 27 | } 28 | 29 | private handleError (error: Response | any) { 30 | // In a real world app, we might use a remote logging infrastructure 31 | let errMsg: string; 32 | var err = ''; 33 | if (error instanceof Response) { 34 | // Normally errors come in as response objects 35 | const body = error.json() || ''; 36 | err = body.message || JSON.stringify(body); 37 | errMsg = `${error.status} - ${error.statusText || ''}: ${err}`; 38 | console.error(errMsg); 39 | // Check for timeout errors. The 0 status is what appears since the Access-Control-Allow-Origin headers are not set by Heroku when it times out. 40 | if ((error.status==503)||(error.status==0)) { 41 | err = 'The server timed out trying to calculate your response. Try reloading, and if that doesn\'t work try DifferentialEquations.jl!'; 42 | } 43 | return Observable.throw(err); 44 | } else { 45 | // A generic error fallback 46 | errMsg = error.message ? error.message : error.toString(); 47 | console.error(errMsg); 48 | return Observable.throw(errMsg); 49 | } 50 | } 51 | 52 | 53 | } 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DifferentialEquations.jl Online 2 | 3 | This is the front-end of [http://app.juliadiffeq.org/](http://app.juliadiffeq.org/), a website that solves differential equations in your browser using the power of [DifferentialEquations.jl](https://github.com/JuliaDiffEq/DifferentialEquations.jl). 4 | 5 | ## Installation 6 | 7 | First, make sure you have node installed. You can download it [here](https://nodejs.org) or with something like 8 | 9 | ``` 10 | sudo yum install nodejs 11 | ``` 12 | 13 | and install angular-cli using the instructions [here](https://github.com/angular/angular-cli). 14 | 15 | Clone the repo and navigate to it. Then run 16 | 17 | ``` 18 | sudo npm install 19 | ``` 20 | 21 | to install all the dependencies. 22 | 23 | ## Local development 24 | 25 | Run `ng serve` for a dev server. 26 | Navigate a browser to `http://localhost:4200/`. 27 | The app will automatically reload if you change any of the source files. 28 | 29 | The development build of the website allows you to select the url of the API, so you can test it with a local instance of the API. To setup the backend API and run it locally, see [the repository for the backend](https://github.com/JuliaDiffEq/DiffEqOnlineServer). 30 | 31 | # Development notes for the angular-cli front end 32 | 33 | Everything that follows was automatically generated by angular-cli. 34 | 35 | This project was generated with [angular-cli](https://github.com/angular/angular-cli) version 1.0.0-beta.19-3. 36 | 37 | ## Development server 38 | Run `ng serve` for a dev server. Navigate to `http://localhost:4200/`. The app will automatically reload if you change any of the source files. 39 | 40 | ## Code scaffolding 41 | 42 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive/pipe/service/class`. 43 | 44 | ## Build 45 | 46 | Run `ng build` to build the project. The build artifacts will be stored in the `dist/` directory. Use the `-prod` flag for a production build. 47 | 48 | ## Running unit tests 49 | 50 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io). 51 | 52 | ## Running end-to-end tests 53 | 54 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/). 55 | Before running the tests make sure you are serving the app via `ng serve`. 56 | 57 | ## Deploying to Github Pages 58 | 59 | Run `ng github-pages:deploy` to deploy to Github Pages. 60 | 61 | ## Further help 62 | 63 | To get more help on the `angular-cli` use `ng --help` or go check out the [Angular-CLI README](https://github.com/angular/angular-cli/blob/master/README.md). 64 | -------------------------------------------------------------------------------- /src/app/home/home.component.html: -------------------------------------------------------------------------------- 1 |

DifferentialEquations.jl Online

2 |

This page allows you to use some of the functionality of 3 | DifferentialEquations.jl in 4 | your browser. To get started, click on one of the tools above.

5 | 6 |

Authors

7 |

This tool was built by Alex Mellnik 8 | and Chris Rackauckas.

9 | 10 |

How it works

11 |

DifferentialEquations.jl 12 | is a package written in Julia, a high-performance 13 | language for technical computing. A web interface frontend was built using Angular 14 | and was linked to Julia via Mux.jl. The 15 | results are parsed via ParameterizedFunctions.jl, 16 | a component of the DifferentialEquations.jl ecosystem which performs conversions 17 | between natrual syntax to Julia code for parameterized differential equations. 18 | The end result is a clean interface for users to explore some of the functionality 19 | of a performant Julia library directly from their browser.

20 | 21 |

Supporting and Citing

22 |

The software in this ecosystem was developed as part of academic research. If 23 | you would like to help support it, 24 | please star the repository 25 | as such metrics may help us secure funding in the future. If you use JuliaDiffEq 26 | software as part of your research, teaching, or other activities, we would be grateful 27 | if you could cite our (and others!) work. Please see our 28 | citation page for guidelines.

29 | 30 |

More Information

31 |

For more information on about DifferentialEquations.jl, please 32 | see the documentation. For more 33 | information on JuliaDiffEq, please visit our website.

34 | 35 |

Contributing

36 |

If you would like to help contribute to DifferentialEquations.jl Online, please 37 | let us know at the DiffEqOnline Github repository. 38 | If you are interested in participating in the Google Summer of Code, please let 39 | us know and we can help you find an interesting and impactful project in the 40 | JuliaDiffEq ecosystem.

41 | -------------------------------------------------------------------------------- /tslint.json: -------------------------------------------------------------------------------- 1 | { 2 | "rulesDirectory": [ 3 | "node_modules/codelyzer" 4 | ], 5 | "rules": { 6 | "class-name": true, 7 | "comment-format": [ 8 | true, 9 | "check-space" 10 | ], 11 | "curly": true, 12 | "eofline": true, 13 | "forin": true, 14 | "indent": [ 15 | true, 16 | "spaces" 17 | ], 18 | "label-position": true, 19 | "label-undefined": true, 20 | "max-line-length": [ 21 | true, 22 | 140 23 | ], 24 | "member-access": false, 25 | "member-ordering": [ 26 | true, 27 | "static-before-instance", 28 | "variables-before-functions" 29 | ], 30 | "no-arg": true, 31 | "no-bitwise": true, 32 | "no-console": [ 33 | true, 34 | "debug", 35 | "info", 36 | "time", 37 | "timeEnd", 38 | "trace" 39 | ], 40 | "no-construct": true, 41 | "no-debugger": true, 42 | "no-duplicate-key": true, 43 | "no-duplicate-variable": true, 44 | "no-empty": false, 45 | "no-eval": true, 46 | "no-inferrable-types": true, 47 | "no-shadowed-variable": true, 48 | "no-string-literal": false, 49 | "no-switch-case-fall-through": true, 50 | "no-trailing-whitespace": true, 51 | "no-unused-expression": true, 52 | "no-unused-variable": true, 53 | "no-unreachable": true, 54 | "no-use-before-declare": true, 55 | "no-var-keyword": true, 56 | "object-literal-sort-keys": false, 57 | "one-line": [ 58 | true, 59 | "check-open-brace", 60 | "check-catch", 61 | "check-else", 62 | "check-whitespace" 63 | ], 64 | "quotemark": [ 65 | true, 66 | "single" 67 | ], 68 | "radix": true, 69 | "semicolon": [ 70 | "always" 71 | ], 72 | "triple-equals": [ 73 | true, 74 | "allow-null-check" 75 | ], 76 | "typedef-whitespace": [ 77 | true, 78 | { 79 | "call-signature": "nospace", 80 | "index-signature": "nospace", 81 | "parameter": "nospace", 82 | "property-declaration": "nospace", 83 | "variable-declaration": "nospace" 84 | } 85 | ], 86 | "variable-name": false, 87 | "whitespace": [ 88 | true, 89 | "check-branch", 90 | "check-decl", 91 | "check-operator", 92 | "check-separator", 93 | "check-type" 94 | ], 95 | 96 | "directive-selector-prefix": [true, "app"], 97 | "component-selector-prefix": [true, "app"], 98 | "directive-selector-name": [true, "camelCase"], 99 | "component-selector-name": [true, "kebab-case"], 100 | "directive-selector-type": [true, "attribute"], 101 | "component-selector-type": [true, "element"], 102 | "use-input-property-decorator": true, 103 | "use-output-property-decorator": true, 104 | "use-host-property-decorator": true, 105 | "no-input-rename": true, 106 | "no-output-rename": true, 107 | "use-life-cycle-interface": true, 108 | "use-pipe-transform-interface": true, 109 | "component-class-suffix": true, 110 | "directive-class-suffix": true, 111 | "templates-use-public": true, 112 | "invoke-injectable": true 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/app/ode/ode.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 | 6 | 7 |
8 |
9 | 10 | 11 |
12 |
13 | 14 | 15 |
16 |
17 | 18 | ( 19 | 20 | , 21 | 22 | ) 23 |
24 |
25 | 26 | 27 |
28 |
29 | 30 | 31 |
32 |
33 | 34 |
35 | 40 |
41 |
42 |
43 | 44 | 45 |
46 |
47 | 48 |
49 | 50 | 51 | 52 | 53 |
54 | 55 | Waking up the back-end solver... 56 | 57 |
58 |
59 | 60 | 61 | 62 | 63 |
64 | 65 | {{serverError}} 66 | 67 |
68 |
69 | 70 |
71 | 72 |
75 |
76 | 77 |
78 |

To access the data in a spreadsheet format or further modify the plot, hover over the plot and click "save and edit plot in cloud".

79 |
80 | -------------------------------------------------------------------------------- /src/app/sde/sde.component.html: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 |
5 | 6 | 7 |
8 |
9 | 10 | 11 |
12 |
13 | 14 | 15 |
16 |
17 | 18 | 19 |
20 |
21 | 22 | 23 |
24 |
25 | 26 | ( 27 | 28 | , 29 | 30 | ) 31 |
32 |
33 | 34 | 35 |
36 |
37 | 38 | 39 |
40 |
41 | 42 |
43 | 48 |
49 |
50 |
51 | 52 | 53 |
54 |
55 | 56 |
57 | 58 | 59 | 60 | 61 |
62 | 63 | Waking up the back-end solver... 64 | 65 |
66 |
67 | 68 | 69 | 70 | 71 |
72 | 73 | {{serverError}} 74 | 75 |
76 |
77 | 78 |
79 | 80 |
83 |
84 | 85 |
86 |

To access the data in a spreadsheet format or further modify the plot, hover over the plot and click "save and edit plot in cloud".

87 |
88 | -------------------------------------------------------------------------------- /src/app/sde/sde.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { Http } from '@angular/http'; 3 | import { ApiService } from '../api.service'; 4 | import { environment } from '../../environments/environment'; 5 | import { Router, ActivatedRoute, Params } from '@angular/router'; 6 | 7 | declare var Plotly: any; 8 | 9 | @Component({ 10 | selector: 'app-sde', 11 | templateUrl: './sde.component.html', 12 | styleUrls: ['./sde.component.css'], 13 | providers: [ApiService] 14 | }) 15 | export class SdeComponent implements OnInit { 16 | 17 | constructor( 18 | private http: Http, 19 | private ApiService: ApiService, 20 | private route: ActivatedRoute, 21 | private router: Router 22 | ) { } 23 | 24 | private apiUrl = environment.apiBaseURL; 25 | private showAPIField = !environment.production; 26 | private serverAwake = false; 27 | private waitingOnServer = false; 28 | private serverError = ''; 29 | 30 | // Initial values 31 | private settings = { 32 | diffEqText: 'dx = a*x - b*x*y\ndy = -c*y + d*x*y', 33 | noiseText: 'dx = a*x\ndy = a*y', 34 | parameters: "a=1.5, b=1, c=3, d=1", 35 | noiseParameters: "a=0.25", 36 | timeSpan: [0.0, 10.0], 37 | initialConditions: "1.0, 1.0", 38 | solver: "SRIW1", 39 | vars: "[:x, :y]", 40 | title: 'Stochastic Lotka-Volterra Equation' 41 | }; 42 | 43 | private model: any; 44 | 45 | private SDEsolvers = [ 46 | {name: 'SRIW1' , desc: "Rossler's Strong Order 1.5 SRIW1 method"}, 47 | {name: 'SRA1' , desc: "Rossler's Strong Order 2.0 SRA1 method (for additive noise)"} 48 | ]; 49 | 50 | private resultsObj: any; 51 | 52 | ngOnInit() { 53 | this.wakeUp(); 54 | var payload = this.route.snapshot.params['settings']; 55 | if (payload) { 56 | console.log('Payload is: ' + payload); 57 | try { 58 | this.settings = JSON.parse(atob(payload)); 59 | this.solve(); 60 | } catch(e) { 61 | console.log('Invalid settings in url, using default ones. Error: ' + e); 62 | } 63 | } 64 | this.updateSettingsInURL(); 65 | } 66 | 67 | // Take the current settings and bake them into the URL 68 | updateSettingsInURL() { 69 | return this.router.navigate(['/sde/', { 70 | settings: btoa(JSON.stringify(this.settings)) 71 | }]); 72 | } 73 | 74 | solve() { 75 | // Build a model to pass to the back end -- this is mostly the same as the settings object but with some tweaks to make it better understandable to the api 76 | this.model = Object.assign({}, { 77 | diffEqText: this.settings.diffEqText, 78 | noiseText: this.settings.noiseText, 79 | timeSpan: this.settings.timeSpan, 80 | parameters: this.settings.parameters.replace(/\s/g, '').split(','), 81 | noiseParameters: this.settings.noiseParameters.replace(/\s/g, '').split(','), 82 | initialConditions: this.settings.initialConditions.replace(/\s/g, '').split(','), 83 | vars: this.settings.vars, 84 | solver: this.settings.solver, 85 | title: this.settings.title 86 | }); 87 | console.log(this.model); 88 | this.waitingOnServer = true; 89 | this.sendDiffEq(); 90 | } 91 | 92 | sendDiffEq() { 93 | return this.ApiService.passDiffEq(this.apiUrl, this.model).subscribe( 94 | data => this.resultsObj = data, 95 | error => this.handleServerError(error), 96 | () => this.plot() 97 | ); 98 | } 99 | 100 | wakeUp() { 101 | return this.ApiService.wakeUp(this.apiUrl).subscribe( 102 | data => this.serverAwake = data.awake, 103 | error => this.serverError = error 104 | ); 105 | } 106 | 107 | 108 | plot() { 109 | var self = this; 110 | self.waitingOnServer = false; 111 | console.log(self.resultsObj); 112 | var series = JSON.parse(this.resultsObj.series); 113 | var layout = JSON.parse(this.resultsObj.layout); 114 | layout.title = this.resultsObj.title; 115 | layout.margin.b = 20; 116 | layout.margin.l = 20; 117 | layout.margin.t = 50; 118 | console.log(layout); 119 | Plotly.newPlot('results-plot',series,layout); 120 | } 121 | 122 | serverErrorClose() { 123 | this.serverError=''; 124 | } 125 | 126 | handleServerError(error) { 127 | this.waitingOnServer = false; 128 | this.serverError = error; 129 | } 130 | 131 | } 132 | -------------------------------------------------------------------------------- /src/app/ode/ode.component.ts: -------------------------------------------------------------------------------- 1 | import { Component, OnInit } from '@angular/core'; 2 | import { Http } from '@angular/http'; 3 | import { ApiService } from '../api.service'; 4 | import { environment } from '../../environments/environment'; 5 | import { Router, ActivatedRoute, Params } from '@angular/router'; 6 | 7 | declare var Plotly: any; 8 | 9 | @Component({ 10 | selector: 'app-ode', 11 | templateUrl: './ode.component.html', 12 | styleUrls: ['./ode.component.css'], 13 | providers: [ApiService] 14 | }) 15 | export class OdeComponent implements OnInit { 16 | 17 | constructor( 18 | private http: Http, 19 | private ApiService: ApiService, 20 | private route: ActivatedRoute, 21 | private router: Router 22 | ) { } 23 | 24 | private apiUrl = environment.apiBaseURL; 25 | private showAPIField = !environment.production; 26 | private serverAwake = false; 27 | private waitingOnServer = false; 28 | private serverError = ''; 29 | 30 | // Initial values 31 | private settings = { 32 | diffEqText: 'dx = a*x - b*x*y\ndy = -c*y + d*x*y', 33 | parameters: "a=1.5, b=1, c=3, d=1", 34 | timeSpan: [0.0, 10.0], 35 | initialConditions: "1.0, 1.0", 36 | solver: 'Tsit5', 37 | vars: "[:x, :y]", 38 | title: 'The Lotka-Volterra Equations: Model of Rabbits and Wolves' 39 | }; 40 | 41 | private model: any; 42 | 43 | private ODEsolvers = [ 44 | {name: 'BS3' , desc: 'Bogacki-Shampine 3/2 method'}, 45 | {name: 'Tsit5', desc: 'Tsitouras 5/4 Runge-Kutta method'}, 46 | {name: 'Vern6' , desc: "Verner's \"Most Efficient\" 6/5 Runge-Kutta method"}, 47 | {name: 'Vern7' , desc: "Verner's \"Most Efficient\" 7/6 Runge-Kutta method"}, 48 | {name: 'Rosenbrock23' , desc: "Rosenbrock's method"} 49 | ]; 50 | 51 | private resultsObj: any; 52 | 53 | ngOnInit() { 54 | this.wakeUp(); 55 | var payload = this.route.snapshot.params['settings']; 56 | if (payload) { 57 | console.log('Payload is: ' + payload); 58 | try { 59 | this.settings = JSON.parse(atob(payload)); 60 | this.solve(); 61 | } catch(e) { 62 | console.log('Invalid settings in url, using default ones. Error: ' + e); 63 | } 64 | } 65 | this.updateSettingsInURL(); 66 | } 67 | 68 | // Take the current settings and bake them into the URL 69 | updateSettingsInURL() { 70 | return this.router.navigate(['/ode/', { 71 | settings: btoa(JSON.stringify(this.settings)) 72 | }]); 73 | } 74 | 75 | solve() { 76 | this.updateSettingsInURL(); 77 | // Build a model to pass to the back end -- this is mostly the same as the settings object but with some tweaks to make it better understandable to the api 78 | this.model = Object.assign({}, { 79 | diffEqText: this.settings.diffEqText, 80 | timeSpan: this.settings.timeSpan, 81 | parameters: this.settings.parameters.replace(/\s/g, '').split(','), 82 | initialConditions: this.settings.initialConditions.replace(/\s/g, '').split(','), 83 | vars: this.settings.vars, 84 | solver: this.settings.solver, 85 | title: this.settings.title 86 | }); 87 | console.log(this.model); 88 | this.waitingOnServer = true; 89 | this.sendDiffEq(); 90 | } 91 | 92 | sendDiffEq() { 93 | return this.ApiService.passDiffEq(this.apiUrl, this.model).subscribe( 94 | data => this.resultsObj = data, 95 | error => this.handleServerError(error), 96 | () => this.plot() 97 | ); 98 | } 99 | 100 | wakeUp() { 101 | return this.ApiService.wakeUp(this.apiUrl).subscribe( 102 | data => this.serverAwake = data.awake, 103 | error => this.serverError = error 104 | ); 105 | } 106 | 107 | 108 | plot() { 109 | var self = this; 110 | self.waitingOnServer = false; 111 | console.log(self.resultsObj); 112 | var series = JSON.parse(this.resultsObj.series); 113 | var layout = JSON.parse(this.resultsObj.layout); 114 | layout.title = this.resultsObj.title; 115 | layout.margin.b = 20; 116 | layout.margin.l = 20; 117 | layout.margin.t = 50; 118 | console.log(layout); 119 | Plotly.newPlot('results-plot',series,layout); 120 | } 121 | 122 | serverErrorClose() { 123 | this.serverError=''; 124 | } 125 | 126 | handleServerError(error) { 127 | this.waitingOnServer = false; 128 | this.serverError = error; 129 | } 130 | 131 | } 132 | -------------------------------------------------------------------------------- /src/assets/favicons/safari-pinned-tab.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 7 | 8 | Created by potrace 1.11, written by Peter Selinger 2001-2013 9 | 10 | 12 | 26 | 43 | 65 | 66 | 67 | --------------------------------------------------------------------------------