├── executor
├── .gitignore
├── requirements.txt
├── Dockerfile
├── executor_server.py
└── executor_utils.py
├── oj-client
├── src
│ ├── assets
│ │ └── .gitkeep
│ ├── app
│ │ ├── app.component.css
│ │ ├── components
│ │ │ ├── navbar
│ │ │ │ ├── navbar.component.css
│ │ │ │ ├── navbar.component.spec.ts
│ │ │ │ ├── navbar.component.ts
│ │ │ │ └── navbar.component.html
│ │ │ ├── new-problem
│ │ │ │ ├── new-problem.component.css
│ │ │ │ ├── new-problem.component.spec.ts
│ │ │ │ ├── new-problem.component.ts
│ │ │ │ └── new-problem.component.html
│ │ │ ├── problem-detail
│ │ │ │ ├── problem-detail.component.css
│ │ │ │ ├── problem-detail.component.html
│ │ │ │ ├── problem-detail.component.spec.ts
│ │ │ │ └── problem-detail.component.ts
│ │ │ ├── editor
│ │ │ │ ├── editor.component.css
│ │ │ │ ├── editor.component.spec.ts
│ │ │ │ ├── editor.component.html
│ │ │ │ └── editor.component.ts
│ │ │ └── problem-list
│ │ │ │ ├── problem-list.component.css
│ │ │ │ ├── problem-list.component.html
│ │ │ │ ├── problem-list.component.spec.ts
│ │ │ │ └── problem-list.component.ts
│ │ ├── app.component.html
│ │ ├── models
│ │ │ └── problem.model.ts
│ │ ├── pipes
│ │ │ ├── search.pipe.spec.ts
│ │ │ └── search.pipe.ts
│ │ ├── app.component.ts
│ │ ├── services
│ │ │ ├── data.service.spec.ts
│ │ │ ├── input.service.spec.ts
│ │ │ ├── input.service.ts
│ │ │ ├── collaboration.service.spec.ts
│ │ │ ├── collaboration.service.ts
│ │ │ └── data.service.ts
│ │ ├── app.routes.ts
│ │ ├── app.component.spec.ts
│ │ ├── app.module.ts
│ │ └── mock-problems.ts
│ ├── styles.css
│ ├── environments
│ │ ├── environment.prod.ts
│ │ └── environment.ts
│ ├── favicon.ico
│ ├── typings.d.ts
│ ├── tsconfig.app.json
│ ├── index.html
│ ├── tsconfig.spec.json
│ ├── main.ts
│ ├── test.ts
│ └── polyfills.ts
├── e2e
│ ├── app.po.ts
│ ├── tsconfig.e2e.json
│ └── app.e2e-spec.ts
├── .editorconfig
├── tsconfig.json
├── .gitignore
├── protractor.conf.js
├── karma.conf.js
├── README.md
├── package.json
├── .angular-cli.json
└── tslint.json
├── oj-server
├── .gitignore
├── models
│ └── problemModel.js
├── package.json
├── module
│ └── redisClient.js
├── server.js
├── services
│ ├── problemService.js
│ └── editorSocketService.js
├── routes
│ └── rest.js
└── package-lock.json
├── public
├── favicon.ico
├── glyphicons-halflings-regular.e18bbf611f2a2e43afc0.ttf
├── glyphicons-halflings-regular.f4769f9bdb7466be6508.eot
├── glyphicons-halflings-regular.448c34a56d699c29117a.woff2
├── glyphicons-halflings-regular.fa2772327f55d8198301.woff
├── index.html
├── inline.bundle.js.map
├── inline.bundle.js
├── main.bundle.js.map
└── main.bundle.js
├── README.md
└── launch.sh
/executor/.gitignore:
--------------------------------------------------------------------------------
1 | *.pyc
--------------------------------------------------------------------------------
/oj-client/src/assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/oj-server/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
--------------------------------------------------------------------------------
/oj-client/src/app/app.component.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/executor/requirements.txt:
--------------------------------------------------------------------------------
1 | flask
2 | docker
3 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/navbar/navbar.component.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/new-problem/new-problem.component.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/problem-detail/problem-detail.component.css:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/oj-client/src/app/app.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/oj-client/src/styles.css:
--------------------------------------------------------------------------------
1 | /* You can add global styles to this file, and also import other style files */
2 |
--------------------------------------------------------------------------------
/oj-client/src/environments/environment.prod.ts:
--------------------------------------------------------------------------------
1 | export const environment = {
2 | production: true
3 | };
4 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qichen90/Collaborative-Online-Judge-System/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/oj-client/src/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qichen90/Collaborative-Online-Judge-System/HEAD/oj-client/src/favicon.ico
--------------------------------------------------------------------------------
/oj-client/src/app/models/problem.model.ts:
--------------------------------------------------------------------------------
1 | export class Problem {
2 | id: number;
3 | name: string;
4 | desc: string;
5 | difficulty: string;
6 | }
--------------------------------------------------------------------------------
/oj-client/src/typings.d.ts:
--------------------------------------------------------------------------------
1 | /* SystemJS module definition */
2 | declare var module: NodeModule;
3 | interface NodeModule {
4 | id: string;
5 | }
6 |
--------------------------------------------------------------------------------
/public/glyphicons-halflings-regular.e18bbf611f2a2e43afc0.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qichen90/Collaborative-Online-Judge-System/HEAD/public/glyphicons-halflings-regular.e18bbf611f2a2e43afc0.ttf
--------------------------------------------------------------------------------
/public/glyphicons-halflings-regular.f4769f9bdb7466be6508.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qichen90/Collaborative-Online-Judge-System/HEAD/public/glyphicons-halflings-regular.f4769f9bdb7466be6508.eot
--------------------------------------------------------------------------------
/public/glyphicons-halflings-regular.448c34a56d699c29117a.woff2:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qichen90/Collaborative-Online-Judge-System/HEAD/public/glyphicons-halflings-regular.448c34a56d699c29117a.woff2
--------------------------------------------------------------------------------
/public/glyphicons-halflings-regular.fa2772327f55d8198301.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/qichen90/Collaborative-Online-Judge-System/HEAD/public/glyphicons-halflings-regular.fa2772327f55d8198301.woff
--------------------------------------------------------------------------------
/oj-client/src/app/pipes/search.pipe.spec.ts:
--------------------------------------------------------------------------------
1 | import { SearchPipe } from './search.pipe';
2 |
3 | describe('SearchPipe', () => {
4 | it('create an instance', () => {
5 | const pipe = new SearchPipe();
6 | expect(pipe).toBeTruthy();
7 | });
8 | });
9 |
--------------------------------------------------------------------------------
/oj-client/e2e/app.po.ts:
--------------------------------------------------------------------------------
1 | import { browser, by, element } from 'protractor';
2 |
3 | export class AppPage {
4 | navigateTo() {
5 | return browser.get('/');
6 | }
7 |
8 | getParagraphText() {
9 | return element(by.css('app-root h1')).getText();
10 | }
11 | }
12 |
--------------------------------------------------------------------------------
/oj-client/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';
10 | }
11 |
--------------------------------------------------------------------------------
/executor/Dockerfile:
--------------------------------------------------------------------------------
1 | FROM ubuntu:16.04
2 | LABEL maintainer="qichen90"
3 |
4 | RUN apt-get update
5 | RUN apt-get install -y openjdk-8-jdk
6 | RUN apt-get install -y python3
7 | # need to build image again
8 | # docker build -t $imagename -f Dockerfile
9 | RUN apt-get install -y g++
10 |
--------------------------------------------------------------------------------
/oj-client/src/tsconfig.app.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/app",
5 | "baseUrl": "./",
6 | "module": "es2015",
7 | "types": []
8 | },
9 | "exclude": [
10 | "test.ts",
11 | "**/*.spec.ts"
12 | ]
13 | }
14 |
--------------------------------------------------------------------------------
/oj-client/.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 = off
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/oj-client/e2e/tsconfig.e2e.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/e2e",
5 | "baseUrl": "./",
6 | "module": "commonjs",
7 | "target": "es5",
8 | "types": [
9 | "jasmine",
10 | "jasminewd2",
11 | "node"
12 | ]
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Collaborative-Online-Judge-System
2 |
3 | This online judge system is Google-Doc like collaborative code editor.
4 |
5 | Major parts:
6 | oj-client : Angular2-based front end with bootstrap
7 | oj-server : node.js backend platform with express.js middleware
8 | executor: Python Flask server with Docker Engine API
9 |
10 |
--------------------------------------------------------------------------------
/oj-server/models/problemModel.js:
--------------------------------------------------------------------------------
1 | const mongoose = require('mongoose');
2 | // Capitalize Number, String.
3 | const ProblemSchema = mongoose.Schema({
4 | id: Number,
5 | name: String,
6 | desc: String,
7 | difficulty: String
8 | });
9 |
10 | const ProblemModel = mongoose.model('ProblemModel', ProblemSchema);
11 |
12 | module.exports = ProblemModel;
--------------------------------------------------------------------------------
/oj-client/e2e/app.e2e-spec.ts:
--------------------------------------------------------------------------------
1 | import { AppPage } from './app.po';
2 |
3 | describe('oj-client App', () => {
4 | let page: AppPage;
5 |
6 | beforeEach(() => {
7 | page = new AppPage();
8 | });
9 |
10 | it('should display welcome message', () => {
11 | page.navigateTo();
12 | expect(page.getParagraphText()).toEqual('Welcome to app!');
13 | });
14 | });
15 |
--------------------------------------------------------------------------------
/oj-client/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | OjClient
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/oj-client/src/tsconfig.spec.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "../out-tsc/spec",
5 | "baseUrl": "./",
6 | "module": "commonjs",
7 | "types": [
8 | "jasmine",
9 | "node"
10 | ]
11 | },
12 | "files": [
13 | "test.ts"
14 | ],
15 | "include": [
16 | "**/*.spec.ts",
17 | "**/*.d.ts"
18 | ]
19 | }
20 |
--------------------------------------------------------------------------------
/oj-client/src/main.ts:
--------------------------------------------------------------------------------
1 | import { enableProdMode } from '@angular/core';
2 | import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
3 |
4 | import { AppModule } from './app/app.module';
5 | import { environment } from './environments/environment';
6 |
7 | if (environment.production) {
8 | enableProdMode();
9 | }
10 |
11 | platformBrowserDynamic().bootstrapModule(AppModule)
12 | .catch(err => console.log(err));
13 |
--------------------------------------------------------------------------------
/oj-client/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 | };
9 |
--------------------------------------------------------------------------------
/oj-client/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compileOnSave": false,
3 | "compilerOptions": {
4 | "outDir": "./dist/out-tsc",
5 | "sourceMap": true,
6 | "declaration": false,
7 | "moduleResolution": "node",
8 | "emitDecoratorMetadata": true,
9 | "experimentalDecorators": true,
10 | "target": "es5",
11 | "typeRoots": [
12 | "node_modules/@types"
13 | ],
14 | "lib": [
15 | "es2017",
16 | "dom"
17 | ]
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/problem-detail/problem-detail.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{problem.id}}. {{problem.name}}
7 |
8 |
9 | {{problem.desc}}
10 |
11 |
12 |
13 |
16 |
--------------------------------------------------------------------------------
/oj-client/src/app/services/data.service.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed, inject } from '@angular/core/testing';
2 |
3 | import { DataService } from './data.service';
4 |
5 | describe('DataService', () => {
6 | beforeEach(() => {
7 | TestBed.configureTestingModule({
8 | providers: [DataService]
9 | });
10 | });
11 |
12 | it('should be created', inject([DataService], (service: DataService) => {
13 | expect(service).toBeTruthy();
14 | }));
15 | });
16 |
--------------------------------------------------------------------------------
/oj-client/src/app/pipes/search.pipe.ts:
--------------------------------------------------------------------------------
1 | import { Pipe, PipeTransform } from '@angular/core';
2 | import { Problem } from '../models/problem.model';
3 |
4 | @Pipe({
5 | name: 'search'
6 | })
7 | export class SearchPipe implements PipeTransform {
8 |
9 | transform(problems: Problem[], term: string): Problem[] {
10 | // get filtered problem list
11 | return problems.filter(
12 | problem => problem.name.toLowerCase().includes(term));
13 | }
14 |
15 | }
16 |
--------------------------------------------------------------------------------
/oj-client/src/app/services/input.service.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed, inject } from '@angular/core/testing';
2 |
3 | import { InputService } from './input.service';
4 |
5 | describe('InputService', () => {
6 | beforeEach(() => {
7 | TestBed.configureTestingModule({
8 | providers: [InputService]
9 | });
10 | });
11 |
12 | it('should be created', inject([InputService], (service: InputService) => {
13 | expect(service).toBeTruthy();
14 | }));
15 | });
16 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/editor/editor.component.css:
--------------------------------------------------------------------------------
1 | @media screen {
2 | #editor {
3 | height: 600px;
4 | }
5 | .lang-select {
6 | width: 100px;
7 | margin-right: 10px;
8 | }
9 | header .btn {
10 | margin: 0 5px;
11 | }
12 | footer .btn {
13 | margin: 0 5px;
14 | }
15 | .editor-footer, .editor-header {
16 | margin: 10px 0;
17 | }
18 | .cursor {
19 | /*position:absolute;*/
20 | background: rgba(0, 250, 0, 0.5);
21 | z-index: 40;
22 | width: 2px !important;
23 | }
24 | }
--------------------------------------------------------------------------------
/oj-client/src/app/services/input.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { BehaviorSubject } from 'rxjs/BehaviorSubject';
3 | import { Observable } from 'rxjs/Rx';
4 |
5 | @Injectable()
6 | export class InputService {
7 | private inputSubject$ = new BehaviorSubject('');
8 | constructor() { }
9 |
10 | changeInput(term) {
11 | this.inputSubject$.next(term);
12 | }
13 |
14 | getInput(): Observable {
15 | return this.inputSubject$.asObservable();
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/oj-client/src/app/services/collaboration.service.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed, inject } from '@angular/core/testing';
2 |
3 | import { CollaborationService } from './collaboration.service';
4 |
5 | describe('CollaborationService', () => {
6 | beforeEach(() => {
7 | TestBed.configureTestingModule({
8 | providers: [CollaborationService]
9 | });
10 | });
11 |
12 | it('should be created', inject([CollaborationService], (service: CollaborationService) => {
13 | expect(service).toBeTruthy();
14 | }));
15 | });
16 |
--------------------------------------------------------------------------------
/oj-server/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "oj-server",
3 | "version": "1.0.0",
4 | "description": "",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1",
8 | "start": "nodemon server.js"
9 | },
10 | "author": "",
11 | "license": "ISC",
12 | "dependencies": {
13 | "body-parser": "^1.18.2",
14 | "express": "^4.16.2",
15 | "mongoose": "^5.0.3",
16 | "node-rest-client": "^3.1.0",
17 | "redis": "^2.8.0",
18 | "socket.io": "^2.0.4"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/problem-list/problem-list.component.css:
--------------------------------------------------------------------------------
1 | .difficulty {
2 | min-width: 65px;
3 | margin-right: 10px;
4 | }
5 |
6 | .label.difficulty {
7 | padding-top: 0.6em;
8 | color: #fbfdfa;
9 | font-size: 12px;
10 | }
11 |
12 | .title {
13 | font-size: 1.2em;
14 | }
15 |
16 | .diff-easy {
17 | background-color: #42ebf4;
18 | }
19 |
20 | .diff-medium {
21 | background-color: #92cf5c;
22 | }
23 |
24 | .diff-hard {
25 | background-color: #dd0d1e;
26 | }
27 |
28 | .diff-super {
29 | background-color: #8d16e2;
30 | }
--------------------------------------------------------------------------------
/launch.sh:
--------------------------------------------------------------------------------
1 | #! bin/bash
2 | # bash for launching the application in mac os
3 | # sh launch.sh
4 |
5 | # fuser -k 3000/tcp #not working on mac os
6 | # fuser -k 5000/tcp
7 |
8 | # brew services restart redis
9 |
10 | # cd ./oj-client
11 | # ng build --watch &
12 |
13 | cd ./oj-server
14 | npm start &
15 |
16 | cd ./executor
17 | # pip3 install requirements.txt
18 | python3 executor_server.py &
19 |
20 | echo "===app runing==="
21 | read -p "PRESS [enter] to terminate processes." PRESSKEY
22 |
23 | # fuser -k 3000/tcp
24 | # fuser -k 5000/tcp
25 | brew services stop redis
--------------------------------------------------------------------------------
/oj-client/src/app/components/problem-list/problem-list.component.html:
--------------------------------------------------------------------------------
1 |
13 |
--------------------------------------------------------------------------------
/executor/executor_server.py:
--------------------------------------------------------------------------------
1 | import json
2 | from flask import Flask
3 | app = Flask(__name__)
4 | from flask import jsonify
5 | from flask import request
6 |
7 | import executor_utils as eu
8 |
9 | @app.route('/build_and_run', methods=['POST'])
10 | def build_and_run():
11 | data = request.get_json()
12 | if 'code' not in data or 'lang' not in data:
13 | return 'No code or language found'
14 | code = data['code']
15 | lang = data['lang']
16 |
17 | print("API got called with code: %s in %s" % (code, lang))
18 |
19 | result = eu.build_and_run(code, lang)
20 |
21 | return jsonify(result)
22 |
23 | if __name__ == '__main__':
24 | eu.load_image() # load docker image
25 | app.run(debug=True)
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | OjClient
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/oj-client/.gitignore:
--------------------------------------------------------------------------------
1 | # See http://help.github.com/ignore-files/ for more about ignoring files.
2 |
3 | # compiled output
4 | /dist
5 | /dist-server
6 | /tmp
7 | /out-tsc
8 |
9 | # dependencies
10 | /node_modules
11 |
12 | # IDEs and editors
13 | /.idea
14 | .project
15 | .classpath
16 | .c9/
17 | *.launch
18 | .settings/
19 | *.sublime-workspace
20 |
21 | # IDE - VSCode
22 | .vscode/*
23 | !.vscode/settings.json
24 | !.vscode/tasks.json
25 | !.vscode/launch.json
26 | !.vscode/extensions.json
27 |
28 | # misc
29 | /.sass-cache
30 | /connect.lock
31 | /coverage
32 | /libpeerconnection.log
33 | npm-debug.log
34 | testem.log
35 | /typings
36 |
37 | # e2e
38 | /e2e/*.js
39 | /e2e/*.map
40 |
41 | # System Files
42 | .DS_Store
43 | Thumbs.db
44 |
--------------------------------------------------------------------------------
/oj-client/src/test.ts:
--------------------------------------------------------------------------------
1 | // This file is required by karma.conf.js and loads recursively all the .spec and framework files
2 |
3 | import 'zone.js/dist/zone-testing';
4 | import { getTestBed } from '@angular/core/testing';
5 | import {
6 | BrowserDynamicTestingModule,
7 | platformBrowserDynamicTesting
8 | } from '@angular/platform-browser-dynamic/testing';
9 |
10 | declare const require: any;
11 |
12 | // First, initialize the Angular testing environment.
13 | getTestBed().initTestEnvironment(
14 | BrowserDynamicTestingModule,
15 | platformBrowserDynamicTesting()
16 | );
17 | // Then we find all the tests.
18 | const context = require.context('./', true, /\.spec\.ts$/);
19 | // And load the modules.
20 | context.keys().map(context);
21 |
--------------------------------------------------------------------------------
/oj-client/src/app/app.routes.ts:
--------------------------------------------------------------------------------
1 | import { Routes, RouterModule} from '@angular/router';
2 | import { ProblemListComponent } from './components/problem-list/problem-list.component';
3 | import { ProblemDetailComponent } from './components/problem-detail/problem-detail.component';
4 |
5 | const routes: Routes = [
6 | {
7 | path: '',
8 | redirectTo: 'problems',
9 | pathMatch: 'full'//exactly match
10 | },
11 | {
12 | path: 'problems',
13 | component: ProblemListComponent
14 | },
15 | {
16 | path: 'problems/:id',
17 | component: ProblemDetailComponent
18 | },
19 | {
20 | path: '**',
21 | redirectTo: 'problems'
22 | }
23 | ]
24 |
25 | export const routing = RouterModule.forRoot(routes);
--------------------------------------------------------------------------------
/oj-client/src/app/components/editor/editor.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { EditorComponent } from './editor.component';
4 |
5 | describe('EditorComponent', () => {
6 | let component: EditorComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [ EditorComponent ]
12 | })
13 | .compileComponents();
14 | }));
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(EditorComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should create', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/navbar/navbar.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { NavbarComponent } from './navbar.component';
4 |
5 | describe('NavbarComponent', () => {
6 | let component: NavbarComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [ NavbarComponent ]
12 | })
13 | .compileComponents();
14 | }));
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(NavbarComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should create', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/new-problem/new-problem.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { NewProblemComponent } from './new-problem.component';
4 |
5 | describe('NewProblemComponent', () => {
6 | let component: NewProblemComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [ NewProblemComponent ]
12 | })
13 | .compileComponents();
14 | }));
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(NewProblemComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should create', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/problem-list/problem-list.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { ProblemListComponent } from './problem-list.component';
4 |
5 | describe('ProblemListComponent', () => {
6 | let component: ProblemListComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [ ProblemListComponent ]
12 | })
13 | .compileComponents();
14 | }));
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(ProblemListComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should create', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/problem-detail/problem-detail.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { async, ComponentFixture, TestBed } from '@angular/core/testing';
2 |
3 | import { ProblemDetailComponent } from './problem-detail.component';
4 |
5 | describe('ProblemDetailComponent', () => {
6 | let component: ProblemDetailComponent;
7 | let fixture: ComponentFixture;
8 |
9 | beforeEach(async(() => {
10 | TestBed.configureTestingModule({
11 | declarations: [ ProblemDetailComponent ]
12 | })
13 | .compileComponents();
14 | }));
15 |
16 | beforeEach(() => {
17 | fixture = TestBed.createComponent(ProblemDetailComponent);
18 | component = fixture.componentInstance;
19 | fixture.detectChanges();
20 | });
21 |
22 | it('should create', () => {
23 | expect(component).toBeTruthy();
24 | });
25 | });
26 |
--------------------------------------------------------------------------------
/oj-client/protractor.conf.js:
--------------------------------------------------------------------------------
1 | // Protractor configuration file, see link for more information
2 | // https://github.com/angular/protractor/blob/master/lib/config.ts
3 |
4 | const { SpecReporter } = require('jasmine-spec-reporter');
5 |
6 | exports.config = {
7 | allScriptsTimeout: 11000,
8 | specs: [
9 | './e2e/**/*.e2e-spec.ts'
10 | ],
11 | capabilities: {
12 | 'browserName': 'chrome'
13 | },
14 | directConnect: true,
15 | baseUrl: 'http://localhost:4200/',
16 | framework: 'jasmine',
17 | jasmineNodeOpts: {
18 | showColors: true,
19 | defaultTimeoutInterval: 30000,
20 | print: function() {}
21 | },
22 | onPrepare() {
23 | require('ts-node').register({
24 | project: 'e2e/tsconfig.e2e.json'
25 | });
26 | jasmine.getEnv().addReporter(new SpecReporter({ spec: { displayStacktrace: true } }));
27 | }
28 | };
29 |
--------------------------------------------------------------------------------
/oj-server/module/redisClient.js:
--------------------------------------------------------------------------------
1 | var redis = require('redis');
2 |
3 | // only one client created
4 | var client = redis.createClient();
5 |
6 | function set(key, value, callback) {
7 | client.set(key, value, function(err, res) {
8 | if(err) {
9 | console.log(err);
10 | return ;
11 | }
12 | callback(res);
13 | });
14 | }
15 |
16 | function get(key, callback) {
17 | client.get(key, function(err, res){
18 | if(err) {
19 | console.log(err);
20 | return ;
21 | }
22 | callback(res);
23 | });
24 | }
25 |
26 | // since redis is used as cache, data only valid for a period
27 | function expire(key, timeInSeconds){
28 | client.expire(key, timeInSeconds);
29 | }
30 |
31 | function quit() {
32 | client.quit();
33 | }
34 |
35 | module.exports = {
36 | get: get,
37 | set: set,
38 | expire: expire,
39 | quit: quit,
40 | redisPrint: redis.print
41 | };
--------------------------------------------------------------------------------
/oj-client/src/app/components/problem-detail/problem-detail.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { DataService } from '../../services/data.service';
3 | import { Problem } from '../../models/problem.model';
4 | import { ActivatedRoute, Params } from '@angular/router';
5 |
6 | @Component({
7 | selector: 'app-problem-detail',
8 | templateUrl: './problem-detail.component.html',
9 | styleUrls: ['./problem-detail.component.css']
10 | })
11 | export class ProblemDetailComponent implements OnInit {
12 | problem: Problem;
13 |
14 | constructor(private dataService: DataService,
15 | private route: ActivatedRoute) { }
16 |
17 | ngOnInit() {
18 | // subscribe: when params changes, this.problem will be updated
19 | // +: conver string to int
20 | this.route.params.subscribe(params => {
21 | this.dataService.getProblem(+params['id'])
22 | .then(problem => this.problem = problem);
23 | });
24 | }
25 |
26 | }
27 |
--------------------------------------------------------------------------------
/oj-client/karma.conf.js:
--------------------------------------------------------------------------------
1 | // Karma configuration file, see link for more information
2 | // https://karma-runner.github.io/1.0/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-jasmine-html-reporter'),
12 | require('karma-coverage-istanbul-reporter'),
13 | require('@angular/cli/plugins/karma')
14 | ],
15 | client:{
16 | clearContext: false // leave Jasmine Spec Runner output visible in browser
17 | },
18 | coverageIstanbulReporter: {
19 | reports: [ 'html', 'lcovonly' ],
20 | fixWebpackSourcePaths: true
21 | },
22 | angularCli: {
23 | environment: 'dev'
24 | },
25 | reporters: ['progress', 'kjhtml'],
26 | port: 9876,
27 | colors: true,
28 | logLevel: config.LOG_INFO,
29 | autoWatch: true,
30 | browsers: ['Chrome'],
31 | singleRun: false
32 | });
33 | };
34 |
--------------------------------------------------------------------------------
/oj-client/src/app/app.component.spec.ts:
--------------------------------------------------------------------------------
1 | import { TestBed, async } from '@angular/core/testing';
2 | import { AppComponent } from './app.component';
3 | describe('AppComponent', () => {
4 | beforeEach(async(() => {
5 | TestBed.configureTestingModule({
6 | declarations: [
7 | AppComponent
8 | ],
9 | }).compileComponents();
10 | }));
11 | it('should create the app', async(() => {
12 | const fixture = TestBed.createComponent(AppComponent);
13 | const app = fixture.debugElement.componentInstance;
14 | expect(app).toBeTruthy();
15 | }));
16 | it(`should have as title 'app'`, async(() => {
17 | const fixture = TestBed.createComponent(AppComponent);
18 | const app = fixture.debugElement.componentInstance;
19 | expect(app.title).toEqual('app');
20 | }));
21 | it('should render title in a h1 tag', async(() => {
22 | const fixture = TestBed.createComponent(AppComponent);
23 | fixture.detectChanges();
24 | const compiled = fixture.debugElement.nativeElement;
25 | expect(compiled.querySelector('h1').textContent).toContain('Welcome to app!');
26 | }));
27 | });
28 |
--------------------------------------------------------------------------------
/oj-server/server.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const app = express();
3 | const restRouter = require('./routes/rest');
4 | const mongoose = require('mongoose');
5 | const path = require('path');
6 | const http = require('http');
7 |
8 | // remeber to add database user
9 | mongoose.connect('mongodb://qichen90:cs5036@ds125068.mlab.com:25068/problems-db')
10 |
11 | app.use('/api/v1', restRouter);
12 |
13 | app.use(express.static(path.join(__dirname,'../public')));
14 | app.use((req, res) => {
15 | res.sendFile('index.html', {root: path.join(__dirname, '../public')});
16 | });
17 |
18 |
19 | var socketIO = require('socket.io');
20 | var io = socketIO();
21 | var editorSocketService = require('./services/editorSocketService')(io); // function call
22 | //connect io with server
23 | const server = http.createServer(app);
24 | io.attach(server);
25 | server.listen(3000);
26 | server.on('listening', onListening);
27 |
28 | // listening call back
29 | function onListening(){
30 | console.log('App listening on port 3000...');
31 | }
32 |
33 | // app.listen(3000, () => console.log('Example app listening on port 3000!'));
--------------------------------------------------------------------------------
/oj-client/README.md:
--------------------------------------------------------------------------------
1 | # OjClient
2 |
3 | This project was generated with [Angular CLI](https://github.com/angular/angular-cli) version 1.6.7.
4 |
5 | ## Development server
6 |
7 | 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.
8 |
9 | ## Code scaffolding
10 |
11 | Run `ng generate component component-name` to generate a new component. You can also use `ng generate directive|pipe|service|class|guard|interface|enum|module`.
12 |
13 | ## Build
14 |
15 | 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.
16 |
17 | ## Running unit tests
18 |
19 | Run `ng test` to execute the unit tests via [Karma](https://karma-runner.github.io).
20 |
21 | ## Running end-to-end tests
22 |
23 | Run `ng e2e` to execute the end-to-end tests via [Protractor](http://www.protractortest.org/).
24 |
25 | ## Further help
26 |
27 | 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).
28 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/navbar/navbar.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { FormControl } from '@angular/forms';
3 | import { Subscription } from 'rxjs/Subscription';
4 | import { Router } from '@angular/router';
5 | import { InputService } from '../../services/input.service';
6 | import 'rxjs/add/operator/debounceTime';
7 |
8 | @Component({
9 | selector: 'app-navbar',
10 | templateUrl: './navbar.component.html',
11 | styleUrls: ['./navbar.component.css']
12 | })
13 | export class NavbarComponent implements OnInit {
14 | title = 'LabCode';
15 | searchBox: FormControl = new FormControl();
16 | subscription: Subscription;
17 |
18 | constructor(private inputService: InputService,
19 | private router: Router) { }
20 |
21 | ngOnInit() {
22 | this.subscription = this.searchBox
23 | .valueChanges
24 | .debounceTime(200)
25 | .subscribe(term => {this.inputService.changeInput(term)});
26 | }
27 |
28 | ngOnDestroy() {
29 | this.subscription.unsubscribe();
30 | }
31 |
32 | searchProblem(): void {
33 | this.router.navigate(['/problems']);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/problem-list/problem-list.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { Problem } from '../../models/problem.model';
3 | import { DataService } from '../../services/data.service';
4 | import { Subscription } from 'rxjs/Subscription';
5 | import { InputService } from '../../services/input.service';
6 |
7 | @Component({
8 | selector: 'app-problem-list',
9 | templateUrl: './problem-list.component.html',
10 | styleUrls: ['./problem-list.component.css']
11 | })
12 | export class ProblemListComponent implements OnInit {
13 | problems: Problem[];
14 | subcriptionProblems: Subscription;
15 | // for navbar
16 | searchTerm: String = '';
17 | subscriptionInput: Subscription;
18 |
19 | constructor(private dataService: DataService,
20 | private inputService: InputService) { }
21 |
22 | ngOnInit() {
23 | this.getProblems();
24 | this.getSearchTerm();
25 | }
26 | ngOnDestroy() {
27 | this.subcriptionProblems.unsubscribe();
28 | }
29 |
30 | getProblems() {
31 | this.subcriptionProblems = this.dataService.getProblems()
32 | .subscribe(problems => {
33 | this.problems = problems;
34 | });
35 | }
36 |
37 | getSearchTerm(): void {
38 | this.subscriptionInput = this.inputService.getInput()
39 | .subscribe(term => this.searchTerm = term);
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/navbar/navbar.component.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
13 |
14 |
15 |
27 |
28 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/new-problem/new-problem.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { Problem } from '../../models/problem.model';
3 | import { DataService } from '../../services/data.service';
4 |
5 | const DEFAULT_PROBLEM: Problem = Object.freeze({
6 | id: 0,
7 | name: '',
8 | desc: '',
9 | difficulty: 'easy'
10 | })
11 |
12 | @Component({
13 | selector: 'app-new-problem',
14 | templateUrl: './new-problem.component.html',
15 | styleUrls: ['./new-problem.component.css']
16 | })
17 | export class NewProblemComponent implements OnInit {
18 | // create a shadow copy of problem and assign it to newProblem
19 | // Object.assign() copies property values. If the source value is a reference to an object, it only copies that reference value.
20 | newProblem: Problem = Object.assign({}, DEFAULT_PROBLEM);
21 | difficulties: string[] = ['easy', 'medium', 'hard', 'super'];
22 |
23 | constructor(private dataService: DataService) { }
24 |
25 | ngOnInit() {
26 | }
27 |
28 | addProblem(){
29 | this.dataService.addProblem(this.newProblem);
30 | // assign newProblem a new problem instance
31 | // Otherwise newProblem have same reference as the one we added to the list
32 | // then when next time add new problem, it will override the problem we have already add into the problem list.
33 | this.newProblem = Object.assign({}, DEFAULT_PROBLEM);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/new-problem/new-problem.component.html:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/oj-client/src/app/app.module.ts:
--------------------------------------------------------------------------------
1 | import { BrowserModule } from '@angular/platform-browser';
2 | import { NgModule } from '@angular/core';
3 | import { FormsModule, ReactiveFormsModule } from '@angular/forms';
4 | import { HttpClientModule } from '@angular/common/http';
5 | import { CollaborationService } from './services/collaboration.service';
6 |
7 |
8 | import { AppComponent } from './app.component';
9 | import { ProblemListComponent } from './components/problem-list/problem-list.component';
10 |
11 | import { DataService } from './services/data.service';
12 | import { ProblemDetailComponent } from './components/problem-detail/problem-detail.component';
13 | import { InputService } from './services/input.service';
14 |
15 | import { routing } from './app.routes';
16 | import { NewProblemComponent } from './components/new-problem/new-problem.component';
17 | import { NavbarComponent } from './components/navbar/navbar.component';
18 | import { EditorComponent } from './components/editor/editor.component';
19 | import { SearchPipe } from './pipes/search.pipe'
20 |
21 |
22 | @NgModule({
23 | declarations: [
24 | AppComponent,
25 | ProblemListComponent,
26 | ProblemDetailComponent,
27 | NewProblemComponent,
28 | NavbarComponent,
29 | EditorComponent,
30 | SearchPipe
31 | ],
32 | imports: [
33 | BrowserModule,
34 | routing,
35 | FormsModule,
36 | HttpClientModule,
37 | ReactiveFormsModule
38 | ],
39 | providers: [DataService,
40 | CollaborationService,
41 | InputService
42 | ],
43 | bootstrap: [AppComponent]
44 | })
45 | export class AppModule { }
46 |
--------------------------------------------------------------------------------
/oj-client/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "oj-client",
3 | "version": "0.0.0",
4 | "license": "MIT",
5 | "scripts": {
6 | "ng": "ng",
7 | "start": "ng serve",
8 | "build": "ng build --prod",
9 | "test": "ng test",
10 | "lint": "ng lint",
11 | "e2e": "ng e2e"
12 | },
13 | "private": true,
14 | "dependencies": {
15 | "@angular/animations": "^5.2.0",
16 | "@angular/common": "^5.2.0",
17 | "@angular/compiler": "^5.2.0",
18 | "@angular/core": "^5.2.0",
19 | "@angular/forms": "^5.2.0",
20 | "@angular/http": "^5.2.0",
21 | "@angular/platform-browser": "^5.2.0",
22 | "@angular/platform-browser-dynamic": "^5.2.0",
23 | "@angular/router": "^5.2.0",
24 | "ace-builds": "^1.3.0",
25 | "bootstrap": "^3.3.7",
26 | "core-js": "^2.4.1",
27 | "jquery": "^3.3.1",
28 | "rxjs": "^5.5.6",
29 | "socket.io": "^2.0.4",
30 | "zone.js": "^0.8.19"
31 | },
32 | "devDependencies": {
33 | "@angular/cli": "1.6.7",
34 | "@angular/compiler-cli": "^5.2.0",
35 | "@angular/language-service": "^5.2.0",
36 | "@types/jasmine": "~2.8.3",
37 | "@types/jasminewd2": "~2.0.2",
38 | "@types/node": "~6.0.60",
39 | "codelyzer": "^4.0.1",
40 | "jasmine-core": "~2.8.0",
41 | "jasmine-spec-reporter": "~4.2.1",
42 | "karma": "~2.0.0",
43 | "karma-chrome-launcher": "~2.2.0",
44 | "karma-coverage-istanbul-reporter": "^1.2.1",
45 | "karma-jasmine": "~1.1.0",
46 | "karma-jasmine-html-reporter": "^0.2.2",
47 | "protractor": "~5.1.2",
48 | "ts-node": "~4.1.0",
49 | "tslint": "~5.9.1",
50 | "typescript": "~2.5.3"
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/oj-client/src/app/mock-problems.ts:
--------------------------------------------------------------------------------
1 | import { Problem } from './models/problem.model';
2 |
3 | export const PROBLEMS: Problem[] = [
4 | {
5 | "id":1,
6 | "name":"Two Sum",
7 | "desc":"Given an array of integers, find two numbers such that they add up to a specific target number.\n\nThe function twoSum should return indices of the two numbers such that they add up to the target, where index1 must be less than index2. Please note that your returned answers (both index1 and index2) are NOT zero-based.",
8 | "difficulty":"easy"
9 | },
10 | {
11 | "id":2,
12 | "name":"3Sum",
13 | "desc":"Given an array S of n integers, are there elements a, b, c in S such that a + b + c = 0? Find all unique triplets in the array which gives the sum of zero.",
14 | "difficulty":"medium"
15 | },
16 | {
17 | "id":3,
18 | "name":"4Sum",
19 | "desc":"Given an array S of n integers, are there elements a, b, c, and d in S such that a + b + c + d = target?\n\nFind all unique quadruplets in the array which gives the sum of target.",
20 | "difficulty":"medium"
21 | },
22 | {
23 | "id":4,
24 | "name":"Triangle Count",
25 | "desc":"Given an array of integers, how many three numbers can be found in the array, so that we can build an triangle whose three edges length is the three numbers that we find?",
26 | "difficulty":"hard"},
27 | {
28 | "id":5,
29 | "name":"Sliding Window Maximum",
30 | "desc":"Given an array of n integer with duplicate number, and a moving window(size k), move the window at each iteration from the start of the array, find the maximum number inside the window at each moving.",
31 | "difficulty":"super"
32 | }
33 | ];
--------------------------------------------------------------------------------
/oj-client/src/app/services/collaboration.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Observable } from 'rxjs/Observable';
3 | import { Subject } from 'rxjs/Subject';
4 |
5 | declare var io: any; // io is already imported in angular.cli.json
6 |
7 | @Injectable()
8 | export class CollaborationService {
9 | collaborationSocket: any;
10 | private _userSource = new Subject();
11 | constructor() { }
12 |
13 | init(editor: any, sessionId: string): Observable {
14 | // send to server
15 | this.collaborationSocket = io(window.location.origin, {query: 'sessionId=' + sessionId});
16 | // //wait for 'message' event from server
17 | // this.collaborationSocket.on("message", (message) => {
18 | // console.log('message received from the server: ' + message);
19 | // })
20 |
21 | // handle the changes from server
22 | this.collaborationSocket.on('change', (delta: string) => {
23 | console.log('collaboration: editor changes by ' + delta);
24 | delta = JSON.parse(delta);
25 | editor.lastAppliedChange = delta;
26 | // apply the changes on editor
27 | editor.getSession().getDocument().applyDeltas([delta]);
28 | });
29 | // handle user changes
30 | this.collaborationSocket.on('userchange', (users: string[]) => {
31 | console.log('user changed: ' + users);
32 | this._userSource.next(users.toString());
33 | })
34 |
35 | return this._userSource.asObservable();
36 | }
37 |
38 | // emit event to make changes and inform server and other collaborators
39 | change(delta: string): void {
40 | // emit "change" event
41 | this.collaborationSocket.emit('change', delta);
42 | }
43 |
44 | restoreBuffer(): void {
45 | // let the server handle the event
46 | this.collaborationSocket.emit('restoreBuffer');
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/oj-server/services/problemService.js:
--------------------------------------------------------------------------------
1 | const ProblemModel = require('../models/problemModel');
2 |
3 | const getProblems = function(){
4 | // in the callback function, the first argument is error
5 | // do not forget to handle error
6 | return new Promise((resolve, reject) => {
7 | ProblemModel.find({}, (err, problems) => {
8 | if(err) {
9 | reject(err);
10 | }else {
11 | resolve(problems);
12 | }
13 | });
14 | });
15 | };
16 |
17 | const getProblem = function(id){
18 | return new Promise((resolve, reject) => {
19 | ProblemModel.findOne({id: id}, (err, problem) => {
20 | if(err) {
21 | reject(err);
22 | }else {
23 | resolve(problem);
24 | }
25 | });
26 | });
27 | };
28 |
29 | const addProblem = function(newProblem){
30 | return new Promise((resolve, reject) => {
31 | ProblemModel.findOne({name: newProblem.name}, (err, problem) => {
32 | //if problem already exists
33 | if(problem) {
34 | reject("Problem name already exists!");
35 | }else {
36 | ProblemModel.count({}, (err, num) => {
37 | if(err){
38 | reject(err);
39 | }
40 | newProblem.id = num + 1;
41 | // create mongodb object
42 | let mongoProblem = new ProblemModel(newProblem);
43 | mongoProblem.save();
44 | resolve(mongoProblem);
45 | });
46 | }
47 | });
48 | });
49 | };
50 |
51 | // modify problem
52 | const editProblem = function(editedProblem){
53 | return new Promise((resolve, reject) => {
54 | ProblemModel.update({name: editedProblem.name}, (err, problem) => {
55 | if(!problem){
56 | reject('No problem exists!');
57 | }else{
58 | resolve(problem);
59 | }
60 | });
61 | });
62 | };
63 |
64 | module.exports = {
65 | getProblems,
66 | getProblem,
67 | addProblem,
68 | editProblem
69 | };
--------------------------------------------------------------------------------
/oj-client/src/app/components/editor/editor.component.html:
--------------------------------------------------------------------------------
1 |
2 |
37 |
38 |
39 |
40 |
41 | Output: {{output}}
42 |
43 |
44 | Users: {{users}}
45 |
46 |
47 |
51 |
--------------------------------------------------------------------------------
/oj-server/routes/rest.js:
--------------------------------------------------------------------------------
1 | const express = require('express');
2 | const router = express.Router();
3 |
4 | // request body is json format, json parser is used to parse the body
5 | const bodyParser = require('body-parser');
6 | const jsonParser = bodyParser.json();
7 |
8 | const problemService = require('../services/problemService');
9 |
10 | const nodeRestClient = require('node-rest-client').Client;
11 | const restClient = new nodeRestClient();
12 | EXECUTOR_SERVER_URL = 'http://localhost:5000/build_and_run';
13 | restClient.registerMethod('build_and_run', EXECUTOR_SERVER_URL, 'POST');
14 |
15 | //GET all problems
16 | router.get('/problems', (req, res) => {
17 | problemService.getProblems()
18 | .then(problems => res.json(problems));
19 | });
20 |
21 | //GET problem by id
22 | router.get('/problems/:id', (req, res) => {
23 | const id = req.params.id;
24 | problemService.getProblem(+id)
25 | .then(problem => res.json(problem));
26 | });
27 |
28 | //POST new problem
29 | router.post('/problems', jsonParser, (req, res) => {
30 | problemService.addProblem(req.body)
31 | .then(problem => res.json(problem),
32 | error => res.status(400).send("Problem name already exists!")
33 | );
34 | });
35 |
36 | // build and run problem
37 | router.post('/build_and_run', jsonParser, (req, res) => {
38 | const userCode = req.body.code;
39 | const lang = req.body.lang;
40 | console.log('lang: ' + lang + ', code: ' + userCode);
41 | const args = {data: {code: userCode, lang: lang},
42 | headers: {'Content-Type': 'application/json'}};
43 |
44 | restClient.methods.build_and_run(
45 | args,
46 | (data, response) => {
47 | const text = `Build output: ${data['build']}, execute output: ${data['run']}`;
48 | console.log(text);
49 | res.json(text);
50 | }
51 | );
52 | });
53 |
54 | // edit problem
55 | router.put('/problems', jsonParser, (req, res) => {
56 | problemService.editProblem(req.body)
57 | .then(problem => res.json(problem),
58 | error => res.status(400).send("Failed to update problem"));
59 | });
60 |
61 | module.exports = router;
--------------------------------------------------------------------------------
/oj-client/.angular-cli.json:
--------------------------------------------------------------------------------
1 | {
2 | "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
3 | "project": {
4 | "name": "oj-client"
5 | },
6 | "apps": [
7 | {
8 | "root": "src",
9 | "outDir": "../public",
10 | "assets": [
11 | "assets",
12 | "favicon.ico"
13 | ],
14 | "index": "index.html",
15 | "main": "main.ts",
16 | "polyfills": "polyfills.ts",
17 | "test": "test.ts",
18 | "tsconfig": "tsconfig.app.json",
19 | "testTsconfig": "tsconfig.spec.json",
20 | "prefix": "app",
21 | "styles": [
22 | "styles.css",
23 | "../node_modules/bootstrap/dist/css/bootstrap.min.css"
24 | ],
25 | "scripts": [
26 | "../node_modules/jquery/dist/jquery.js",
27 | "../node_modules/bootstrap/dist/js/bootstrap.js",
28 | "../node_modules/ace-builds/src-min-noconflict/ace.js",
29 | "../node_modules/ace-builds/src-min-noconflict/theme-eclipse.js",
30 | "../node_modules/ace-builds/src-min-noconflict/mode-java.js",
31 | "../node_modules/ace-builds/src-min-noconflict/mode-python.js",
32 | "../node_modules/ace-builds/src-min-noconflict/mode-c_cpp.js",
33 | "../node_modules/socket.io-client/dist/socket.io.js"
34 | ],
35 | "environmentSource": "environments/environment.ts",
36 | "environments": {
37 | "dev": "environments/environment.ts",
38 | "prod": "environments/environment.prod.ts"
39 | }
40 | }
41 | ],
42 | "e2e": {
43 | "protractor": {
44 | "config": "./protractor.conf.js"
45 | }
46 | },
47 | "lint": [
48 | {
49 | "project": "src/tsconfig.app.json",
50 | "exclude": "**/node_modules/**"
51 | },
52 | {
53 | "project": "src/tsconfig.spec.json",
54 | "exclude": "**/node_modules/**"
55 | },
56 | {
57 | "project": "e2e/tsconfig.e2e.json",
58 | "exclude": "**/node_modules/**"
59 | }
60 | ],
61 | "test": {
62 | "karma": {
63 | "config": "./karma.conf.js"
64 | }
65 | },
66 | "defaults": {
67 | "styleExt": "css",
68 | "component": {}
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/oj-client/src/polyfills.ts:
--------------------------------------------------------------------------------
1 | /**
2 | * This file includes polyfills needed by Angular and is loaded before the app.
3 | * You can add your own extra polyfills to this file.
4 | *
5 | * This file is divided into 2 sections:
6 | * 1. Browser polyfills. These are applied before loading ZoneJS and are sorted by browsers.
7 | * 2. Application imports. Files imported after ZoneJS that should be loaded before your main
8 | * file.
9 | *
10 | * The current setup is for so-called "evergreen" browsers; the last versions of browsers that
11 | * automatically update themselves. This includes Safari >= 10, Chrome >= 55 (including Opera),
12 | * Edge >= 13 on the desktop, and iOS 10 and Chrome on mobile.
13 | *
14 | * Learn more in https://angular.io/docs/ts/latest/guide/browser-support.html
15 | */
16 |
17 | /***************************************************************************************************
18 | * BROWSER POLYFILLS
19 | */
20 |
21 | /** IE9, IE10 and IE11 requires all of the following polyfills. **/
22 | // import 'core-js/es6/symbol';
23 | // import 'core-js/es6/object';
24 | // import 'core-js/es6/function';
25 | // import 'core-js/es6/parse-int';
26 | // import 'core-js/es6/parse-float';
27 | // import 'core-js/es6/number';
28 | // import 'core-js/es6/math';
29 | // import 'core-js/es6/string';
30 | // import 'core-js/es6/date';
31 | // import 'core-js/es6/array';
32 | // import 'core-js/es6/regexp';
33 | // import 'core-js/es6/map';
34 | // import 'core-js/es6/weak-map';
35 | // import 'core-js/es6/set';
36 |
37 | /** IE10 and IE11 requires the following for NgClass support on SVG elements */
38 | // import 'classlist.js'; // Run `npm install --save classlist.js`.
39 |
40 | /** IE10 and IE11 requires the following for the Reflect API. */
41 | // import 'core-js/es6/reflect';
42 |
43 |
44 | /** Evergreen browsers require these. **/
45 | // Used for reflect-metadata in JIT. If you use AOT (and only Angular decorators), you can remove.
46 | import 'core-js/es7/reflect';
47 |
48 |
49 | /**
50 | * Required to support Web Animations `@angular/platform-browser/animations`.
51 | * Needed for: All but Chrome, Firefox and Opera. http://caniuse.com/#feat=web-animation
52 | **/
53 | // import 'web-animations-js'; // Run `npm install --save web-animations-js`.
54 |
55 |
56 |
57 | /***************************************************************************************************
58 | * Zone JS is required by default for Angular itself.
59 | */
60 | import 'zone.js/dist/zone'; // Included with Angular CLI.
61 |
62 |
63 |
64 | /***************************************************************************************************
65 | * APPLICATION IMPORTS
66 | */
67 |
--------------------------------------------------------------------------------
/oj-client/src/app/services/data.service.ts:
--------------------------------------------------------------------------------
1 | import { Injectable } from '@angular/core';
2 | import { Problem } from '../models/problem.model';
3 | import { HttpClient, HttpRequest, HttpResponse } from '@angular/common/http';
4 | import { Observable } from 'rxjs/Rx';
5 | import { BehaviorSubject } from 'rxjs/BehaviorSubject';
6 | import { HttpHeaders } from '@angular/common/http';
7 |
8 | @Injectable()
9 | export class DataService {
10 | private _problemSource = new BehaviorSubject([]);
11 |
12 | constructor(private httpClient: HttpClient) { }
13 |
14 | // return a list of problems
15 | getProblems(): Observable {
16 | this.httpClient.get('api/v1/problems')
17 | .toPromise()
18 | .then((res: any) => {
19 | this._problemSource.next(res);
20 | })
21 | .catch(this.handleError);
22 | return this._problemSource.asObservable();
23 |
24 | }
25 | //use subscribe
26 | // getProblems(): Observable {
27 | // this.httpClient.get('api/v1/problems')
28 | // .subscribe((res:any) => this._problemSource.next(res));
29 | // return this._problemSource.asObservable();
30 |
31 | // }
32 |
33 | // return a problem by id
34 | getProblem(id: number): Promise {
35 | return this.httpClient.get(`api/v1/problems/${id}`)
36 | .toPromise()
37 | .then((res: any) => res)
38 | .catch(this.handleError);
39 | }
40 |
41 | // add problem
42 | addProblem(problem: Problem){
43 | const options = {headers: new HttpHeaders({'Content-Type': 'application/json'})};
44 | return this.httpClient.post('api/v1/problems', problem, options)
45 | .toPromise()
46 | .then((res: any) => {
47 | this.getProblems();
48 | return res;
49 | })
50 | .catch(this.handleError);
51 | }
52 |
53 | // build and run: POST
54 | buildAndRun(data): Promise{
55 | const options = {headers: new HttpHeaders({'Content-Type': 'application/json'})};
56 | return this.httpClient.post('api/v1/build_and_run', data, options)
57 | .toPromise()
58 | .then(res => {
59 | console.log(res);
60 | return res;
61 | })
62 | .catch(this.handleError);
63 | }
64 |
65 | // // modify problem
66 | // editProblem(problem: Problem) {
67 | // const options = {headers: new HttpHeaders({'Content-Type': 'application/json'})};
68 | // return this.httpClient.post('api/v1/problems', problem, options)
69 | // .toPromise()
70 | // .
71 | // }
72 |
73 | // handle errors
74 | private handleError(error: any): Promise{
75 | console.error('Error reference', error);
76 | return Promise.reject(error.body || error);
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/oj-client/src/app/components/editor/editor.component.ts:
--------------------------------------------------------------------------------
1 | import { Component, OnInit } from '@angular/core';
2 | import { CollaborationService } from '../../services/collaboration.service';
3 | import { ActivatedRoute, Params } from '@angular/router';
4 | import { DataService } from '../../services/data.service';
5 | import { Subscription } from 'rxjs/Subscription';
6 |
7 | declare var ace: any;// must be declared
8 | @Component({
9 | selector: 'app-editor',
10 | templateUrl: './editor.component.html',
11 | styleUrls: ['./editor.component.css']
12 | })
13 | export class EditorComponent implements OnInit {
14 | editor: any;
15 |
16 | defaultContent = {
17 | 'Java': `public class Solution{
18 | public static void main(String[] args){
19 | // Please type your code here...
20 | }
21 | }`,
22 | 'Python': `class Solution:
23 | def example():
24 | # Please type your code here...
25 | `,
26 | 'C++':`int main(){
27 | /* Please type your code here... */
28 | }`
29 | }
30 |
31 | languages: string[] = ['Java', 'Python', 'C++'];
32 | language: string = 'Java';
33 | sessionId: string;
34 |
35 | output: string;
36 |
37 | users: string;
38 | subscriptionUsers: Subscription;
39 |
40 | // inject route service and collaborationService
41 | constructor(private collaboration: CollaborationService,
42 | private route: ActivatedRoute,
43 | private dataService: DataService) { }
44 |
45 | ngOnInit() {
46 | this.route.params
47 | .subscribe(params => {
48 | this.sessionId = params['id'];
49 | this.initEditor();
50 | this.collaboration.restoreBuffer();
51 | });
52 | }
53 |
54 | resetEditor(): void {
55 | this.editor.setValue(this.defaultContent[this.language]);
56 | this.editor.getSession().setMode("ace/mode/" + this.language.toLowerCase());
57 | }
58 |
59 | setLanguage(language: string): void {
60 | this.language = language;
61 | this.resetEditor();
62 | }
63 |
64 | submit(): void {
65 | let user_code = this.editor.getValue();
66 | console.log(user_code);
67 |
68 | const data = {
69 | code: user_code,
70 | lang: this.language.toLocaleLowerCase()
71 | };
72 |
73 | this.dataService.buildAndRun(data)
74 | .then(res => this.output = res);
75 | }
76 |
77 | initEditor(): void {
78 | // editor basic setting
79 | this.editor = ace.edit("editor");
80 | this.editor.setTheme("ace/theme/eclipse");
81 | this.resetEditor();
82 |
83 | // initialize collaborationService
84 | this.subscriptionUsers = this.collaboration.init(this.editor, this.sessionId)
85 | .subscribe(users => this.users = users);
86 | this.editor.lastAppliedChange = null;
87 |
88 | // register change callback
89 | this.editor.on("change", e => {
90 | console.log('editor changes: ' + JSON.stringify(e));
91 | // if the change is the same as the last one, then skip
92 | if(this.editor.lastAppliedChange != e){
93 | this.collaboration.change(JSON.stringify(e));
94 | }
95 | });
96 | }
97 | }
98 |
--------------------------------------------------------------------------------
/executor/executor_utils.py:
--------------------------------------------------------------------------------
1 | import docker
2 | import os, sys
3 | import shutil
4 | import uuid
5 |
6 | from docker.errors import APIError
7 | from docker.errors import ContainerError
8 | from docker.errors import ImageNotFound
9 |
10 | # get current directory
11 | CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
12 | IMAGE_NAME = 'qichen90/cs503_1801'
13 |
14 | client = docker.from_env()
15 |
16 | #store the code in tmp folder
17 | TEMP_BUILD_DIR = "%s/tmp" % CURRENT_DIR
18 | CONTAINER_NAME = "%s:latest" % IMAGE_NAME
19 |
20 | SOURCE_FILE_NAMES = {
21 | "java": "Solution.java",
22 | "python": "solution.py",
23 | "c++": "solution.cpp"
24 | }
25 |
26 | BINARY_NAMES = {
27 | "java": "Solution",
28 | "python": "solution.py",
29 | "c++": "./a.out"
30 | }
31 |
32 | BUILD_COMMANDS = {
33 | "java": "javac",
34 | "python": "python3",
35 | "c++": "g++"
36 | }
37 |
38 | EXECUTE_COMMANDS = {
39 | "java": "java",
40 | "python": "python3",
41 | "c++": ""
42 | }
43 |
44 | # load docker image
45 | def load_image():
46 | try:
47 | client.images.get(IMAGE_NAME)
48 | print("Docker image exists locally...")
49 | except ImageNotFound:
50 | # load from hub
51 | print("Loading image from docker hub....")
52 | client.image.pull(IMAGE_NAME)
53 | except APIError:
54 | # fail to connect to docker
55 | print("Cannot connect to docker")
56 | return
57 |
58 | def make_dir(dir):
59 | try:
60 | os.makedirs(dir)
61 | except OSError:
62 | print("cannot create directory")
63 |
64 | def build_and_run(code, lang):
65 | result = {'build': None, 'run': None, 'error': None}
66 | # use the uuid to create unique file name
67 | source_file_parent_dir_name = uuid.uuid4()
68 | source_file_host_dir = "%s/%s" % (TEMP_BUILD_DIR, source_file_parent_dir_name)
69 | source_file_guest_dir = "/test/%s" % (source_file_parent_dir_name)
70 | make_dir(source_file_host_dir)
71 |
72 | # write code into source file
73 | with open("%s/%s" % (source_file_host_dir, SOURCE_FILE_NAMES[lang]), 'w') as source_file:
74 | source_file.write(code)
75 |
76 | # build code
77 | try:
78 | client.containers.run(
79 | image=IMAGE_NAME,
80 | command="%s %s" % (BUILD_COMMANDS[lang], SOURCE_FILE_NAMES[lang]),
81 | volumes={source_file_host_dir:{'bind': source_file_guest_dir, 'mode': 'rw'}},
82 | working_dir=source_file_guest_dir
83 | )
84 | print("source built")
85 | result['build'] = 'OK'
86 | except ContainerError as e:
87 | print("error")
88 | result['build'] = str(e.stderr, 'utf-8')
89 | # remove host dir
90 | shutil.rmtree(source_file_host_dir)
91 | return result
92 |
93 | # run code
94 | try:
95 | log = client.containers.run(
96 | image=IMAGE_NAME,
97 | command="%s %s" % (EXECUTE_COMMANDS[lang], BINARY_NAMES[lang]),
98 | volumes={source_file_host_dir:{'bind': source_file_guest_dir, 'mode': 'rw'}},
99 | working_dir=source_file_guest_dir
100 | )
101 |
102 | log = str(log, 'utf-8')
103 | result['run'] = log
104 | print("code run")
105 | except ContainerError as e:
106 | result['run'] = str(e.stderr, 'utf-8')
107 | shutil.rmtree(source_file_host_dir)
108 | return result
109 |
110 | shutil.rmtree(source_file_host_dir)
111 | return result
--------------------------------------------------------------------------------
/oj-client/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rulesDirectory": [
3 | "node_modules/codelyzer"
4 | ],
5 | "rules": {
6 | "arrow-return-shorthand": true,
7 | "callable-types": true,
8 | "class-name": true,
9 | "comment-format": [
10 | true,
11 | "check-space"
12 | ],
13 | "curly": true,
14 | "deprecation": {
15 | "severity": "warn"
16 | },
17 | "eofline": true,
18 | "forin": true,
19 | "import-blacklist": [
20 | true,
21 | "rxjs",
22 | "rxjs/Rx"
23 | ],
24 | "import-spacing": true,
25 | "indent": [
26 | true,
27 | "spaces"
28 | ],
29 | "interface-over-type-literal": true,
30 | "label-position": true,
31 | "max-line-length": [
32 | true,
33 | 140
34 | ],
35 | "member-access": false,
36 | "member-ordering": [
37 | true,
38 | {
39 | "order": [
40 | "static-field",
41 | "instance-field",
42 | "static-method",
43 | "instance-method"
44 | ]
45 | }
46 | ],
47 | "no-arg": true,
48 | "no-bitwise": true,
49 | "no-console": [
50 | true,
51 | "debug",
52 | "info",
53 | "time",
54 | "timeEnd",
55 | "trace"
56 | ],
57 | "no-construct": true,
58 | "no-debugger": true,
59 | "no-duplicate-super": true,
60 | "no-empty": false,
61 | "no-empty-interface": true,
62 | "no-eval": true,
63 | "no-inferrable-types": [
64 | true,
65 | "ignore-params"
66 | ],
67 | "no-misused-new": true,
68 | "no-non-null-assertion": true,
69 | "no-shadowed-variable": true,
70 | "no-string-literal": false,
71 | "no-string-throw": true,
72 | "no-switch-case-fall-through": true,
73 | "no-trailing-whitespace": true,
74 | "no-unnecessary-initializer": true,
75 | "no-unused-expression": true,
76 | "no-use-before-declare": true,
77 | "no-var-keyword": true,
78 | "object-literal-sort-keys": false,
79 | "one-line": [
80 | true,
81 | "check-open-brace",
82 | "check-catch",
83 | "check-else",
84 | "check-whitespace"
85 | ],
86 | "prefer-const": true,
87 | "quotemark": [
88 | true,
89 | "single"
90 | ],
91 | "radix": true,
92 | "semicolon": [
93 | true,
94 | "always"
95 | ],
96 | "triple-equals": [
97 | true,
98 | "allow-null-check"
99 | ],
100 | "typedef-whitespace": [
101 | true,
102 | {
103 | "call-signature": "nospace",
104 | "index-signature": "nospace",
105 | "parameter": "nospace",
106 | "property-declaration": "nospace",
107 | "variable-declaration": "nospace"
108 | }
109 | ],
110 | "unified-signatures": true,
111 | "variable-name": false,
112 | "whitespace": [
113 | true,
114 | "check-branch",
115 | "check-decl",
116 | "check-operator",
117 | "check-separator",
118 | "check-type"
119 | ],
120 | "directive-selector": [
121 | true,
122 | "attribute",
123 | "app",
124 | "camelCase"
125 | ],
126 | "component-selector": [
127 | true,
128 | "element",
129 | "app",
130 | "kebab-case"
131 | ],
132 | "no-output-on-prefix": true,
133 | "use-input-property-decorator": true,
134 | "use-output-property-decorator": true,
135 | "use-host-property-decorator": true,
136 | "no-input-rename": true,
137 | "no-output-rename": true,
138 | "use-life-cycle-interface": true,
139 | "use-pipe-transform-interface": true,
140 | "component-class-suffix": true,
141 | "directive-class-suffix": true
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/public/inline.bundle.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["webpack/bootstrap 02c288825ed0b877ec73"],"names":[],"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA,gBAAQ,oBAAoB;AAC5B;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,oBAAY,2BAA2B;AACvC;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA,kDAA0C,WAAW,EAAE;AACvD;;AAEA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA,YAAI;AACJ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,aAAK;AACL;AACA;;AAEA;AACA;AACA;AACA,mCAA2B,0BAA0B,EAAE;AACvD,yCAAiC,eAAe;AAChD;AACA;AACA;;AAEA;AACA,8DAAsD,+DAA+D;;AAErH;AACA;;AAEA;AACA,kDAA0C,oBAAoB,WAAW","file":"inline.bundle.js","sourcesContent":[" \t// install a JSONP callback for chunk loading\n \tvar parentJsonpFunction = window[\"webpackJsonp\"];\n \twindow[\"webpackJsonp\"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {\n \t\t// add \"moreModules\" to the modules object,\n \t\t// then flag all \"chunkIds\" as loaded and fire callback\n \t\tvar moduleId, chunkId, i = 0, resolves = [], result;\n \t\tfor(;i < chunkIds.length; i++) {\n \t\t\tchunkId = chunkIds[i];\n \t\t\tif(installedChunks[chunkId]) {\n \t\t\t\tresolves.push(installedChunks[chunkId][0]);\n \t\t\t}\n \t\t\tinstalledChunks[chunkId] = 0;\n \t\t}\n \t\tfor(moduleId in moreModules) {\n \t\t\tif(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {\n \t\t\t\tmodules[moduleId] = moreModules[moduleId];\n \t\t\t}\n \t\t}\n \t\tif(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);\n \t\twhile(resolves.length) {\n \t\t\tresolves.shift()();\n \t\t}\n \t\tif(executeModules) {\n \t\t\tfor(i=0; i < executeModules.length; i++) {\n \t\t\t\tresult = __webpack_require__(__webpack_require__.s = executeModules[i]);\n \t\t\t}\n \t\t}\n \t\treturn result;\n \t};\n\n \t// The module cache\n \tvar installedModules = {};\n\n \t// objects to store loaded and loading chunks\n \tvar installedChunks = {\n \t\t\"inline\": 0\n \t};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId]) {\n \t\t\treturn installedModules[moduleId].exports;\n \t\t}\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\ti: moduleId,\n \t\t\tl: false,\n \t\t\texports: {}\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.l = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n \t// This file contains only the entry chunk.\n \t// The chunk loading function for additional chunks\n \t__webpack_require__.e = function requireEnsure(chunkId) {\n \t\tvar installedChunkData = installedChunks[chunkId];\n \t\tif(installedChunkData === 0) {\n \t\t\treturn new Promise(function(resolve) { resolve(); });\n \t\t}\n\n \t\t// a Promise means \"currently loading\".\n \t\tif(installedChunkData) {\n \t\t\treturn installedChunkData[2];\n \t\t}\n\n \t\t// setup Promise in chunk cache\n \t\tvar promise = new Promise(function(resolve, reject) {\n \t\t\tinstalledChunkData = installedChunks[chunkId] = [resolve, reject];\n \t\t});\n \t\tinstalledChunkData[2] = promise;\n\n \t\t// start chunk loading\n \t\tvar head = document.getElementsByTagName('head')[0];\n \t\tvar script = document.createElement('script');\n \t\tscript.type = 'text/javascript';\n \t\tscript.charset = 'utf-8';\n \t\tscript.async = true;\n \t\tscript.timeout = 120000;\n\n \t\tif (__webpack_require__.nc) {\n \t\t\tscript.setAttribute(\"nonce\", __webpack_require__.nc);\n \t\t}\n \t\tscript.src = __webpack_require__.p + \"\" + chunkId + \".chunk.js\";\n \t\tvar timeout = setTimeout(onScriptComplete, 120000);\n \t\tscript.onerror = script.onload = onScriptComplete;\n \t\tfunction onScriptComplete() {\n \t\t\t// avoid mem leaks in IE.\n \t\t\tscript.onerror = script.onload = null;\n \t\t\tclearTimeout(timeout);\n \t\t\tvar chunk = installedChunks[chunkId];\n \t\t\tif(chunk !== 0) {\n \t\t\t\tif(chunk) {\n \t\t\t\t\tchunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));\n \t\t\t\t}\n \t\t\t\tinstalledChunks[chunkId] = undefined;\n \t\t\t}\n \t\t};\n \t\thead.appendChild(script);\n\n \t\treturn promise;\n \t};\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// define getter function for harmony exports\n \t__webpack_require__.d = function(exports, name, getter) {\n \t\tif(!__webpack_require__.o(exports, name)) {\n \t\t\tObject.defineProperty(exports, name, {\n \t\t\t\tconfigurable: false,\n \t\t\t\tenumerable: true,\n \t\t\t\tget: getter\n \t\t\t});\n \t\t}\n \t};\n\n \t// getDefaultExport function for compatibility with non-harmony modules\n \t__webpack_require__.n = function(module) {\n \t\tvar getter = module && module.__esModule ?\n \t\t\tfunction getDefault() { return module['default']; } :\n \t\t\tfunction getModuleExports() { return module; };\n \t\t__webpack_require__.d(getter, 'a', getter);\n \t\treturn getter;\n \t};\n\n \t// Object.prototype.hasOwnProperty.call\n \t__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// on error function for async loading\n \t__webpack_require__.oe = function(err) { console.error(err); throw err; };\n\n\n\n// WEBPACK FOOTER //\n// webpack/bootstrap 02c288825ed0b877ec73"],"sourceRoot":"webpack:///"}
--------------------------------------------------------------------------------
/oj-server/services/editorSocketService.js:
--------------------------------------------------------------------------------
1 | var redisClient = require('../module/redisClient');
2 | const TIMEOUT_IN_SECONDS = 3600;
3 |
4 | module.exports = function(io) {
5 | //collaboration sessions
6 | //record all the participants in each session so that server can send changes to all cparticipants in a session
7 | var collaborations = {};
8 |
9 | // map from socketId to sessionId
10 | var socketId2SessionId = {};
11 |
12 | // each application has their own session
13 | var sessionPath = '/temp_session';
14 |
15 | // wait for the connection
16 | io.on('connection', socket => {
17 | let sessionId = socket.handshake.query['sessionId'];
18 | socketId2SessionId[socket.id] = sessionId;
19 |
20 | if(sessionId in collaborations){
21 | collaborations[sessionId]['participants'].push(socket.id);
22 |
23 | let participants = collaborations[sessionId]['participants'];
24 | for(let i = 0; i < participants.length; i++){
25 | io.to(participants[i]).emit('userchange', participants);
26 | }
27 | }else{
28 | // not in memory then check in redis
29 | redisClient.get(sessionPath + '/' + sessionId, function(data) {
30 | if(data){
31 | console.log("get session data back from redis");
32 | collaborations[sessionId] = {
33 | 'cachedInstructions': JSON.parse(data),
34 | 'participants': []
35 | }
36 | }else{
37 | console.log("create new session");
38 | collaborations[sessionId] = {
39 | 'cachedInstructions': [],
40 | 'participants': []
41 | };
42 | }
43 | collaborations[sessionId]['participants'].push(socket.id);
44 | io.to(socket.id).emit('userchange', socket.id);
45 | });
46 | }
47 |
48 | // collaborations[sessionId]['participants'].push(socket.id);
49 |
50 | // socket event listeners
51 | // delta is the change info
52 | // it records the row and cloumn of the changes
53 | socket.on('change', delta => {
54 | // for debugging
55 | console.log("change " + socketId2SessionId[socket.id] + " " + delta);
56 |
57 | // get session id based on socket.id
58 | let sessionId = socketId2SessionId[socket.id];
59 | if(sessionId in collaborations){
60 | collaborations[sessionId]['cachedInstructions'].push(['change', delta, Date.now()]);
61 | let participants = collaborations[sessionId]['participants'];
62 | // send changes to all participants
63 | for(let i = 0; i < participants.length; i++){
64 | // skip the one who created this change
65 | if(socket.id != participants[i]){
66 | io.to(participants[i]).emit('change', delta);
67 | }
68 | }
69 | }else{
70 | console.log("cound not tie socket id to any collaboration");
71 | }
72 | });
73 |
74 | // show all stored data
75 | socket.on('restoreBuffer', () => {
76 | let sessionId = socketId2SessionId[socket.id];
77 | console.log('restore buffer for session ' + sessionId + ', socket id: ' + socket.id);
78 |
79 | if(sessionId in collaborations){
80 | let instructions = collaborations[sessionId]['cachedInstructions'];
81 | for(let i = 0; i < instructions.length; i++){
82 | socket.emit(instructions[i][0], instructions[i][1]); // change + delta
83 | }
84 | }else{
85 | console.log('could not find any collcation for this session');
86 | }
87 | });
88 |
89 | socket.on('disconnect', function(){
90 | let sessionId = socketId2SessionId[socket.id];
91 | console.log('disconnect session ' + sessionId + ', socket id: ' + socket.id);
92 |
93 | let foundAndRemoved = false;
94 |
95 | if(sessionId in collaborations){
96 | let participants = collaborations[sessionId]['participants'];
97 | let index = participants.indexOf(socket.id);
98 |
99 | if(index >= 0){
100 | participants.splice(index, 1);
101 | foundAndRemoved = true;
102 |
103 | if(participants.length == 0){
104 | console.log('last participant left, committing to redis and remove from memory');
105 | let key = sessionPath + '/' + sessionId;
106 | let value = JSON.stringify(collaborations[sessionId]['cachedInstructions']);
107 |
108 | redisClient.set(key, value, redisClient.redisPrint);
109 | redisClient.expire(key, TIMEOUT_IN_SECONDS);
110 | delete collaborations[sessionId];
111 | }
112 | }
113 | // emit the new user list
114 | for(let i = 0; i < participants.length; i++){
115 | io.to(participants[i]).emit('userchange', participants);
116 | }
117 | }
118 |
119 | if(!foundAndRemoved){
120 | console.log('Could not find the socket.id in collaboration');
121 | }
122 | });
123 |
124 | // reply to socket.id, emit 'message' event so that client side can get the message
125 | // io.to(socket.id).emit('message', 'here from server');
126 | });
127 | }
--------------------------------------------------------------------------------
/public/inline.bundle.js:
--------------------------------------------------------------------------------
1 | /******/ (function(modules) { // webpackBootstrap
2 | /******/ // install a JSONP callback for chunk loading
3 | /******/ var parentJsonpFunction = window["webpackJsonp"];
4 | /******/ window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) {
5 | /******/ // add "moreModules" to the modules object,
6 | /******/ // then flag all "chunkIds" as loaded and fire callback
7 | /******/ var moduleId, chunkId, i = 0, resolves = [], result;
8 | /******/ for(;i < chunkIds.length; i++) {
9 | /******/ chunkId = chunkIds[i];
10 | /******/ if(installedChunks[chunkId]) {
11 | /******/ resolves.push(installedChunks[chunkId][0]);
12 | /******/ }
13 | /******/ installedChunks[chunkId] = 0;
14 | /******/ }
15 | /******/ for(moduleId in moreModules) {
16 | /******/ if(Object.prototype.hasOwnProperty.call(moreModules, moduleId)) {
17 | /******/ modules[moduleId] = moreModules[moduleId];
18 | /******/ }
19 | /******/ }
20 | /******/ if(parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules);
21 | /******/ while(resolves.length) {
22 | /******/ resolves.shift()();
23 | /******/ }
24 | /******/ if(executeModules) {
25 | /******/ for(i=0; i < executeModules.length; i++) {
26 | /******/ result = __webpack_require__(__webpack_require__.s = executeModules[i]);
27 | /******/ }
28 | /******/ }
29 | /******/ return result;
30 | /******/ };
31 | /******/
32 | /******/ // The module cache
33 | /******/ var installedModules = {};
34 | /******/
35 | /******/ // objects to store loaded and loading chunks
36 | /******/ var installedChunks = {
37 | /******/ "inline": 0
38 | /******/ };
39 | /******/
40 | /******/ // The require function
41 | /******/ function __webpack_require__(moduleId) {
42 | /******/
43 | /******/ // Check if module is in cache
44 | /******/ if(installedModules[moduleId]) {
45 | /******/ return installedModules[moduleId].exports;
46 | /******/ }
47 | /******/ // Create a new module (and put it into the cache)
48 | /******/ var module = installedModules[moduleId] = {
49 | /******/ i: moduleId,
50 | /******/ l: false,
51 | /******/ exports: {}
52 | /******/ };
53 | /******/
54 | /******/ // Execute the module function
55 | /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
56 | /******/
57 | /******/ // Flag the module as loaded
58 | /******/ module.l = true;
59 | /******/
60 | /******/ // Return the exports of the module
61 | /******/ return module.exports;
62 | /******/ }
63 | /******/
64 | /******/ // This file contains only the entry chunk.
65 | /******/ // The chunk loading function for additional chunks
66 | /******/ __webpack_require__.e = function requireEnsure(chunkId) {
67 | /******/ var installedChunkData = installedChunks[chunkId];
68 | /******/ if(installedChunkData === 0) {
69 | /******/ return new Promise(function(resolve) { resolve(); });
70 | /******/ }
71 | /******/
72 | /******/ // a Promise means "currently loading".
73 | /******/ if(installedChunkData) {
74 | /******/ return installedChunkData[2];
75 | /******/ }
76 | /******/
77 | /******/ // setup Promise in chunk cache
78 | /******/ var promise = new Promise(function(resolve, reject) {
79 | /******/ installedChunkData = installedChunks[chunkId] = [resolve, reject];
80 | /******/ });
81 | /******/ installedChunkData[2] = promise;
82 | /******/
83 | /******/ // start chunk loading
84 | /******/ var head = document.getElementsByTagName('head')[0];
85 | /******/ var script = document.createElement('script');
86 | /******/ script.type = 'text/javascript';
87 | /******/ script.charset = 'utf-8';
88 | /******/ script.async = true;
89 | /******/ script.timeout = 120000;
90 | /******/
91 | /******/ if (__webpack_require__.nc) {
92 | /******/ script.setAttribute("nonce", __webpack_require__.nc);
93 | /******/ }
94 | /******/ script.src = __webpack_require__.p + "" + chunkId + ".chunk.js";
95 | /******/ var timeout = setTimeout(onScriptComplete, 120000);
96 | /******/ script.onerror = script.onload = onScriptComplete;
97 | /******/ function onScriptComplete() {
98 | /******/ // avoid mem leaks in IE.
99 | /******/ script.onerror = script.onload = null;
100 | /******/ clearTimeout(timeout);
101 | /******/ var chunk = installedChunks[chunkId];
102 | /******/ if(chunk !== 0) {
103 | /******/ if(chunk) {
104 | /******/ chunk[1](new Error('Loading chunk ' + chunkId + ' failed.'));
105 | /******/ }
106 | /******/ installedChunks[chunkId] = undefined;
107 | /******/ }
108 | /******/ };
109 | /******/ head.appendChild(script);
110 | /******/
111 | /******/ return promise;
112 | /******/ };
113 | /******/
114 | /******/ // expose the modules object (__webpack_modules__)
115 | /******/ __webpack_require__.m = modules;
116 | /******/
117 | /******/ // expose the module cache
118 | /******/ __webpack_require__.c = installedModules;
119 | /******/
120 | /******/ // define getter function for harmony exports
121 | /******/ __webpack_require__.d = function(exports, name, getter) {
122 | /******/ if(!__webpack_require__.o(exports, name)) {
123 | /******/ Object.defineProperty(exports, name, {
124 | /******/ configurable: false,
125 | /******/ enumerable: true,
126 | /******/ get: getter
127 | /******/ });
128 | /******/ }
129 | /******/ };
130 | /******/
131 | /******/ // getDefaultExport function for compatibility with non-harmony modules
132 | /******/ __webpack_require__.n = function(module) {
133 | /******/ var getter = module && module.__esModule ?
134 | /******/ function getDefault() { return module['default']; } :
135 | /******/ function getModuleExports() { return module; };
136 | /******/ __webpack_require__.d(getter, 'a', getter);
137 | /******/ return getter;
138 | /******/ };
139 | /******/
140 | /******/ // Object.prototype.hasOwnProperty.call
141 | /******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
142 | /******/
143 | /******/ // __webpack_public_path__
144 | /******/ __webpack_require__.p = "";
145 | /******/
146 | /******/ // on error function for async loading
147 | /******/ __webpack_require__.oe = function(err) { console.error(err); throw err; };
148 | /******/ })
149 | /************************************************************************/
150 | /******/ ([]);
151 | //# sourceMappingURL=inline.bundle.js.map
--------------------------------------------------------------------------------
/oj-server/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "oj-server",
3 | "version": "1.0.0",
4 | "lockfileVersion": 1,
5 | "requires": true,
6 | "dependencies": {
7 | "accepts": {
8 | "version": "1.3.4",
9 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.4.tgz",
10 | "integrity": "sha1-hiRnWMfdbSGmR0/whKR0DsBesh8=",
11 | "requires": {
12 | "mime-types": "2.1.17",
13 | "negotiator": "0.6.1"
14 | }
15 | },
16 | "after": {
17 | "version": "0.8.2",
18 | "resolved": "https://registry.npmjs.org/after/-/after-0.8.2.tgz",
19 | "integrity": "sha1-/ts5T58OAqqXaOcCvaI7UF+ufh8="
20 | },
21 | "array-flatten": {
22 | "version": "1.1.1",
23 | "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
24 | "integrity": "sha1-ml9pkFGx5wczKPKgCJaLZOopVdI="
25 | },
26 | "arraybuffer.slice": {
27 | "version": "0.0.7",
28 | "resolved": "https://registry.npmjs.org/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz",
29 | "integrity": "sha512-wGUIVQXuehL5TCqQun8OW81jGzAWycqzFF8lFp+GOM5BXLYj3bKNsYC4daB7n6XjCqxQA/qgTJ+8ANR3acjrog=="
30 | },
31 | "async": {
32 | "version": "2.1.4",
33 | "resolved": "https://registry.npmjs.org/async/-/async-2.1.4.tgz",
34 | "integrity": "sha1-LSFgx3iAMuTdbL4lAvH5osj2zeQ=",
35 | "requires": {
36 | "lodash": "4.17.5"
37 | }
38 | },
39 | "async-limiter": {
40 | "version": "1.0.0",
41 | "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
42 | "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
43 | },
44 | "backo2": {
45 | "version": "1.0.2",
46 | "resolved": "https://registry.npmjs.org/backo2/-/backo2-1.0.2.tgz",
47 | "integrity": "sha1-MasayLEpNjRj41s+u2n038+6eUc="
48 | },
49 | "base64-arraybuffer": {
50 | "version": "0.1.5",
51 | "resolved": "https://registry.npmjs.org/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz",
52 | "integrity": "sha1-c5JncZI7Whl0etZmqlzUv5xunOg="
53 | },
54 | "base64id": {
55 | "version": "1.0.0",
56 | "resolved": "https://registry.npmjs.org/base64id/-/base64id-1.0.0.tgz",
57 | "integrity": "sha1-R2iMuZu2gE8OBtPnY7HDLlfY5rY="
58 | },
59 | "better-assert": {
60 | "version": "1.0.2",
61 | "resolved": "https://registry.npmjs.org/better-assert/-/better-assert-1.0.2.tgz",
62 | "integrity": "sha1-QIZrnhueC1W0gYlDEeaPr/rrxSI=",
63 | "requires": {
64 | "callsite": "1.0.0"
65 | }
66 | },
67 | "blob": {
68 | "version": "0.0.4",
69 | "resolved": "https://registry.npmjs.org/blob/-/blob-0.0.4.tgz",
70 | "integrity": "sha1-vPEwUspURj8w+fx+lbmkdjCpSSE="
71 | },
72 | "bluebird": {
73 | "version": "3.5.0",
74 | "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.0.tgz",
75 | "integrity": "sha1-eRQg1/VR7qKJdFOop3ZT+WYG1nw="
76 | },
77 | "body-parser": {
78 | "version": "1.18.2",
79 | "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.18.2.tgz",
80 | "integrity": "sha1-h2eKGdhLR9hZuDGZvVm84iKxBFQ=",
81 | "requires": {
82 | "bytes": "3.0.0",
83 | "content-type": "1.0.4",
84 | "debug": "2.6.9",
85 | "depd": "1.1.2",
86 | "http-errors": "1.6.2",
87 | "iconv-lite": "0.4.19",
88 | "on-finished": "2.3.0",
89 | "qs": "6.5.1",
90 | "raw-body": "2.3.2",
91 | "type-is": "1.6.15"
92 | }
93 | },
94 | "bson": {
95 | "version": "1.0.4",
96 | "resolved": "https://registry.npmjs.org/bson/-/bson-1.0.4.tgz",
97 | "integrity": "sha1-k8ENOeqltYQVy8QFLz5T5WKwtyw="
98 | },
99 | "bytes": {
100 | "version": "3.0.0",
101 | "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
102 | "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg="
103 | },
104 | "callsite": {
105 | "version": "1.0.0",
106 | "resolved": "https://registry.npmjs.org/callsite/-/callsite-1.0.0.tgz",
107 | "integrity": "sha1-KAOY5dZkvXQDi28JBRU+borxvCA="
108 | },
109 | "component-bind": {
110 | "version": "1.0.0",
111 | "resolved": "https://registry.npmjs.org/component-bind/-/component-bind-1.0.0.tgz",
112 | "integrity": "sha1-AMYIq33Nk4l8AAllGx06jh5zu9E="
113 | },
114 | "component-emitter": {
115 | "version": "1.2.1",
116 | "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz",
117 | "integrity": "sha1-E3kY1teCg/ffemt8WmPhQOaUJeY="
118 | },
119 | "component-inherit": {
120 | "version": "0.0.3",
121 | "resolved": "https://registry.npmjs.org/component-inherit/-/component-inherit-0.0.3.tgz",
122 | "integrity": "sha1-ZF/ErfWLcrZJ1crmUTVhnbJv8UM="
123 | },
124 | "content-disposition": {
125 | "version": "0.5.2",
126 | "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz",
127 | "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ="
128 | },
129 | "content-type": {
130 | "version": "1.0.4",
131 | "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.4.tgz",
132 | "integrity": "sha512-hIP3EEPs8tB9AT1L+NUqtwOAps4mk2Zob89MWXMHjHWg9milF/j4osnnQLXBCBFBk/tvIG/tUc9mOUJiPBhPXA=="
133 | },
134 | "cookie": {
135 | "version": "0.3.1",
136 | "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.3.1.tgz",
137 | "integrity": "sha1-5+Ch+e9DtMi6klxcWpboBtFoc7s="
138 | },
139 | "cookie-signature": {
140 | "version": "1.0.6",
141 | "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
142 | "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw="
143 | },
144 | "debug": {
145 | "version": "2.6.9",
146 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
147 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==",
148 | "requires": {
149 | "ms": "2.0.0"
150 | }
151 | },
152 | "depd": {
153 | "version": "1.1.2",
154 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.2.tgz",
155 | "integrity": "sha1-m81S4UwJd2PnSbJ0xDRu0uVgtak="
156 | },
157 | "destroy": {
158 | "version": "1.0.4",
159 | "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.0.4.tgz",
160 | "integrity": "sha1-l4hXRCxEdJ5CBmE+N5RiBYJqvYA="
161 | },
162 | "double-ended-queue": {
163 | "version": "2.1.0-0",
164 | "resolved": "https://registry.npmjs.org/double-ended-queue/-/double-ended-queue-2.1.0-0.tgz",
165 | "integrity": "sha1-ED01J/0xUo9AGIEwyEHv3XgmTlw="
166 | },
167 | "ee-first": {
168 | "version": "1.1.1",
169 | "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
170 | "integrity": "sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0="
171 | },
172 | "encodeurl": {
173 | "version": "1.0.2",
174 | "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-1.0.2.tgz",
175 | "integrity": "sha1-rT/0yG7C0CkyL1oCw6mmBslbP1k="
176 | },
177 | "engine.io": {
178 | "version": "3.1.4",
179 | "resolved": "https://registry.npmjs.org/engine.io/-/engine.io-3.1.4.tgz",
180 | "integrity": "sha1-PQIRtwpVLOhB/8fahiezAamkFi4=",
181 | "requires": {
182 | "accepts": "1.3.3",
183 | "base64id": "1.0.0",
184 | "cookie": "0.3.1",
185 | "debug": "2.6.9",
186 | "engine.io-parser": "2.1.2",
187 | "uws": "0.14.5",
188 | "ws": "3.3.3"
189 | },
190 | "dependencies": {
191 | "accepts": {
192 | "version": "1.3.3",
193 | "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.3.tgz",
194 | "integrity": "sha1-w8p0NJOGSMPg2cHjKN1otiLChMo=",
195 | "requires": {
196 | "mime-types": "2.1.17",
197 | "negotiator": "0.6.1"
198 | }
199 | }
200 | }
201 | },
202 | "engine.io-client": {
203 | "version": "3.1.4",
204 | "resolved": "https://registry.npmjs.org/engine.io-client/-/engine.io-client-3.1.4.tgz",
205 | "integrity": "sha1-T88TcLRxY70s6b4nM5ckMDUNTqE=",
206 | "requires": {
207 | "component-emitter": "1.2.1",
208 | "component-inherit": "0.0.3",
209 | "debug": "2.6.9",
210 | "engine.io-parser": "2.1.2",
211 | "has-cors": "1.1.0",
212 | "indexof": "0.0.1",
213 | "parseqs": "0.0.5",
214 | "parseuri": "0.0.5",
215 | "ws": "3.3.3",
216 | "xmlhttprequest-ssl": "1.5.5",
217 | "yeast": "0.1.2"
218 | }
219 | },
220 | "engine.io-parser": {
221 | "version": "2.1.2",
222 | "resolved": "https://registry.npmjs.org/engine.io-parser/-/engine.io-parser-2.1.2.tgz",
223 | "integrity": "sha512-dInLFzr80RijZ1rGpx1+56/uFoH7/7InhH3kZt+Ms6hT8tNx3NGW/WNSA/f8As1WkOfkuyb3tnRyuXGxusclMw==",
224 | "requires": {
225 | "after": "0.8.2",
226 | "arraybuffer.slice": "0.0.7",
227 | "base64-arraybuffer": "0.1.5",
228 | "blob": "0.0.4",
229 | "has-binary2": "1.0.2"
230 | }
231 | },
232 | "escape-html": {
233 | "version": "1.0.3",
234 | "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
235 | "integrity": "sha1-Aljq5NPQwJdN4cFpGI7wBR0dGYg="
236 | },
237 | "etag": {
238 | "version": "1.8.1",
239 | "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
240 | "integrity": "sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc="
241 | },
242 | "express": {
243 | "version": "4.16.2",
244 | "resolved": "https://registry.npmjs.org/express/-/express-4.16.2.tgz",
245 | "integrity": "sha1-41xt/i1kt9ygpc1PIXgb4ymeB2w=",
246 | "requires": {
247 | "accepts": "1.3.4",
248 | "array-flatten": "1.1.1",
249 | "body-parser": "1.18.2",
250 | "content-disposition": "0.5.2",
251 | "content-type": "1.0.4",
252 | "cookie": "0.3.1",
253 | "cookie-signature": "1.0.6",
254 | "debug": "2.6.9",
255 | "depd": "1.1.2",
256 | "encodeurl": "1.0.2",
257 | "escape-html": "1.0.3",
258 | "etag": "1.8.1",
259 | "finalhandler": "1.1.0",
260 | "fresh": "0.5.2",
261 | "merge-descriptors": "1.0.1",
262 | "methods": "1.1.2",
263 | "on-finished": "2.3.0",
264 | "parseurl": "1.3.2",
265 | "path-to-regexp": "0.1.7",
266 | "proxy-addr": "2.0.2",
267 | "qs": "6.5.1",
268 | "range-parser": "1.2.0",
269 | "safe-buffer": "5.1.1",
270 | "send": "0.16.1",
271 | "serve-static": "1.13.1",
272 | "setprototypeof": "1.1.0",
273 | "statuses": "1.3.1",
274 | "type-is": "1.6.15",
275 | "utils-merge": "1.0.1",
276 | "vary": "1.1.2"
277 | }
278 | },
279 | "finalhandler": {
280 | "version": "1.1.0",
281 | "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.1.0.tgz",
282 | "integrity": "sha1-zgtoVbRYU+eRsvzGgARtiCU91/U=",
283 | "requires": {
284 | "debug": "2.6.9",
285 | "encodeurl": "1.0.2",
286 | "escape-html": "1.0.3",
287 | "on-finished": "2.3.0",
288 | "parseurl": "1.3.2",
289 | "statuses": "1.3.1",
290 | "unpipe": "1.0.0"
291 | }
292 | },
293 | "follow-redirects": {
294 | "version": "1.4.1",
295 | "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.4.1.tgz",
296 | "integrity": "sha512-uxYePVPogtya1ktGnAAXOacnbIuRMB4dkvqeNz2qTtTQsuzSfbDolV+wMMKxAmCx0bLgAKLbBOkjItMbbkR1vg==",
297 | "requires": {
298 | "debug": "3.1.0"
299 | },
300 | "dependencies": {
301 | "debug": {
302 | "version": "3.1.0",
303 | "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
304 | "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
305 | "requires": {
306 | "ms": "2.0.0"
307 | }
308 | }
309 | }
310 | },
311 | "forwarded": {
312 | "version": "0.1.2",
313 | "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.1.2.tgz",
314 | "integrity": "sha1-mMI9qxF1ZXuMBXPozszZGw/xjIQ="
315 | },
316 | "fresh": {
317 | "version": "0.5.2",
318 | "resolved": "https://registry.npmjs.org/fresh/-/fresh-0.5.2.tgz",
319 | "integrity": "sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac="
320 | },
321 | "has-binary2": {
322 | "version": "1.0.2",
323 | "resolved": "https://registry.npmjs.org/has-binary2/-/has-binary2-1.0.2.tgz",
324 | "integrity": "sha1-6D26SfC5vk0CbSc2U1DZ8D9Uvpg=",
325 | "requires": {
326 | "isarray": "2.0.1"
327 | }
328 | },
329 | "has-cors": {
330 | "version": "1.1.0",
331 | "resolved": "https://registry.npmjs.org/has-cors/-/has-cors-1.1.0.tgz",
332 | "integrity": "sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk="
333 | },
334 | "http-errors": {
335 | "version": "1.6.2",
336 | "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-1.6.2.tgz",
337 | "integrity": "sha1-CgAsyFcHGSp+eUbO7cERVfYOxzY=",
338 | "requires": {
339 | "depd": "1.1.1",
340 | "inherits": "2.0.3",
341 | "setprototypeof": "1.0.3",
342 | "statuses": "1.3.1"
343 | },
344 | "dependencies": {
345 | "depd": {
346 | "version": "1.1.1",
347 | "resolved": "https://registry.npmjs.org/depd/-/depd-1.1.1.tgz",
348 | "integrity": "sha1-V4O04cRZ8G+lyif5kfPQbnoxA1k="
349 | },
350 | "setprototypeof": {
351 | "version": "1.0.3",
352 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.0.3.tgz",
353 | "integrity": "sha1-ZlZ+NwQ+608E2RvWWMDL77VbjgQ="
354 | }
355 | }
356 | },
357 | "iconv-lite": {
358 | "version": "0.4.19",
359 | "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.19.tgz",
360 | "integrity": "sha512-oTZqweIP51xaGPI4uPa56/Pri/480R+mo7SeU+YETByQNhDG55ycFyNLIgta9vXhILrxXDmF7ZGhqZIcuN0gJQ=="
361 | },
362 | "indexof": {
363 | "version": "0.0.1",
364 | "resolved": "https://registry.npmjs.org/indexof/-/indexof-0.0.1.tgz",
365 | "integrity": "sha1-gtwzbSMrkGIXnQWrMpOmYFn9Q10="
366 | },
367 | "inherits": {
368 | "version": "2.0.3",
369 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
370 | "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4="
371 | },
372 | "ipaddr.js": {
373 | "version": "1.5.2",
374 | "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.5.2.tgz",
375 | "integrity": "sha1-1LUFvemUaYfM8PxY2QEP+WB+P6A="
376 | },
377 | "isarray": {
378 | "version": "2.0.1",
379 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.1.tgz",
380 | "integrity": "sha1-o32U7ZzaLVmGXJ92/llu4fM4dB4="
381 | },
382 | "kareem": {
383 | "version": "2.0.3",
384 | "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.0.3.tgz",
385 | "integrity": "sha512-WloXk3nyByx9FEB5WY7WFEXIZB/QA+zy7c2kJMjnZCebjepEyQcJzazgLiKcTS/ltZeEoeEQ1A1pau1fEDlnIA=="
386 | },
387 | "lodash": {
388 | "version": "4.17.5",
389 | "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.5.tgz",
390 | "integrity": "sha512-svL3uiZf1RwhH+cWrfZn3A4+U58wbP0tGVTLQPbjplZxZ8ROD9VLuNgsRniTlLe7OlSqR79RUehXgpBW/s0IQw=="
391 | },
392 | "lodash.get": {
393 | "version": "4.4.2",
394 | "resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
395 | "integrity": "sha1-LRd/ZS+jHpObRDjVNBSZ36OCXpk="
396 | },
397 | "media-typer": {
398 | "version": "0.3.0",
399 | "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz",
400 | "integrity": "sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g="
401 | },
402 | "merge-descriptors": {
403 | "version": "1.0.1",
404 | "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.1.tgz",
405 | "integrity": "sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E="
406 | },
407 | "methods": {
408 | "version": "1.1.2",
409 | "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz",
410 | "integrity": "sha1-VSmk1nZUE07cxSZmVoNbD4Ua/O4="
411 | },
412 | "mime": {
413 | "version": "1.4.1",
414 | "resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
415 | "integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ=="
416 | },
417 | "mime-db": {
418 | "version": "1.30.0",
419 | "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.30.0.tgz",
420 | "integrity": "sha1-dMZD2i3Z1qRTmZY0ZbJtXKfXHwE="
421 | },
422 | "mime-types": {
423 | "version": "2.1.17",
424 | "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.17.tgz",
425 | "integrity": "sha1-Cdejk/A+mVp5+K+Fe3Cp4KsWVXo=",
426 | "requires": {
427 | "mime-db": "1.30.0"
428 | }
429 | },
430 | "mongodb": {
431 | "version": "3.0.2",
432 | "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.0.2.tgz",
433 | "integrity": "sha512-E50FmpSQchZAimn2uPIegoNoH9UQYR1yiGHtQPmmg8/Ekc97w6owHoqaBoz+assnd9V5LxMzmQ/VEWMsQMgZhQ==",
434 | "requires": {
435 | "mongodb-core": "3.0.2"
436 | }
437 | },
438 | "mongodb-core": {
439 | "version": "3.0.2",
440 | "resolved": "https://registry.npmjs.org/mongodb-core/-/mongodb-core-3.0.2.tgz",
441 | "integrity": "sha512-p1B0qwFQUw6C1OlFJnrOJp8KaX7MuGoogRbTaupRt0y+pPRkMllHWtE9V6i1CDtTvI3/3sy2sQwqWez7zuXEAA==",
442 | "requires": {
443 | "bson": "1.0.4",
444 | "require_optional": "1.0.1"
445 | }
446 | },
447 | "mongoose": {
448 | "version": "5.0.3",
449 | "resolved": "https://registry.npmjs.org/mongoose/-/mongoose-5.0.3.tgz",
450 | "integrity": "sha512-y4NlLzZaQe5vJHjcEjHLKK6utjs7sVEPN971+d1vVJJGrmA+zeeFA1MEmC1J0ujD34eOSghnExXJPwCrxHHZCw==",
451 | "requires": {
452 | "async": "2.1.4",
453 | "bson": "1.0.4",
454 | "kareem": "2.0.3",
455 | "lodash.get": "4.4.2",
456 | "mongodb": "3.0.2",
457 | "mongoose-legacy-pluralize": "1.0.2",
458 | "mpath": "0.3.0",
459 | "mquery": "3.0.0",
460 | "ms": "2.0.0",
461 | "regexp-clone": "0.0.1",
462 | "sliced": "1.0.1"
463 | }
464 | },
465 | "mongoose-legacy-pluralize": {
466 | "version": "1.0.2",
467 | "resolved": "https://registry.npmjs.org/mongoose-legacy-pluralize/-/mongoose-legacy-pluralize-1.0.2.tgz",
468 | "integrity": "sha512-Yo/7qQU4/EyIS8YDFSeenIvXxZN+ld7YdV9LqFVQJzTLye8unujAWPZ4NWKfFA+RNjh+wvTWKY9Z3E5XM6ZZiQ=="
469 | },
470 | "mpath": {
471 | "version": "0.3.0",
472 | "resolved": "https://registry.npmjs.org/mpath/-/mpath-0.3.0.tgz",
473 | "integrity": "sha1-elj3iem1/TyUUgY0FXlg8mvV70Q="
474 | },
475 | "mquery": {
476 | "version": "3.0.0",
477 | "resolved": "https://registry.npmjs.org/mquery/-/mquery-3.0.0.tgz",
478 | "integrity": "sha512-WL1Lk8v4l8VFSSwN3yCzY9TXw+fKVYKn6f+w86TRzOLSE8k1yTgGaLBPUByJQi8VcLbOdnUneFV/y3Kv874pnQ==",
479 | "requires": {
480 | "bluebird": "3.5.0",
481 | "debug": "2.6.9",
482 | "regexp-clone": "0.0.1",
483 | "sliced": "0.0.5"
484 | },
485 | "dependencies": {
486 | "sliced": {
487 | "version": "0.0.5",
488 | "resolved": "https://registry.npmjs.org/sliced/-/sliced-0.0.5.tgz",
489 | "integrity": "sha1-XtwETKTrb3gW1Qui/GPiXY/kcH8="
490 | }
491 | }
492 | },
493 | "ms": {
494 | "version": "2.0.0",
495 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
496 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g="
497 | },
498 | "negotiator": {
499 | "version": "0.6.1",
500 | "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.1.tgz",
501 | "integrity": "sha1-KzJxhOiZIQEXeyhWP7XnECrNDKk="
502 | },
503 | "node-rest-client": {
504 | "version": "3.1.0",
505 | "resolved": "https://registry.npmjs.org/node-rest-client/-/node-rest-client-3.1.0.tgz",
506 | "integrity": "sha1-4L623aeyDMC2enhHzxLF/EGcN8M=",
507 | "requires": {
508 | "debug": "2.2.0",
509 | "follow-redirects": "1.4.1",
510 | "xml2js": "0.4.19"
511 | },
512 | "dependencies": {
513 | "debug": {
514 | "version": "2.2.0",
515 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.2.0.tgz",
516 | "integrity": "sha1-+HBX6ZWxofauaklgZkE3vFbwOdo=",
517 | "requires": {
518 | "ms": "0.7.1"
519 | }
520 | },
521 | "ms": {
522 | "version": "0.7.1",
523 | "resolved": "https://registry.npmjs.org/ms/-/ms-0.7.1.tgz",
524 | "integrity": "sha1-nNE8A62/8ltl7/3nzoZO6VIBcJg="
525 | }
526 | }
527 | },
528 | "object-component": {
529 | "version": "0.0.3",
530 | "resolved": "https://registry.npmjs.org/object-component/-/object-component-0.0.3.tgz",
531 | "integrity": "sha1-8MaapQ78lbhmwYb0AKM3acsvEpE="
532 | },
533 | "on-finished": {
534 | "version": "2.3.0",
535 | "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
536 | "integrity": "sha1-IPEzZIGwg811M3mSoWlxqi2QaUc=",
537 | "requires": {
538 | "ee-first": "1.1.1"
539 | }
540 | },
541 | "parseqs": {
542 | "version": "0.0.5",
543 | "resolved": "https://registry.npmjs.org/parseqs/-/parseqs-0.0.5.tgz",
544 | "integrity": "sha1-1SCKNzjkZ2bikbouoXNoSSGouJ0=",
545 | "requires": {
546 | "better-assert": "1.0.2"
547 | }
548 | },
549 | "parseuri": {
550 | "version": "0.0.5",
551 | "resolved": "https://registry.npmjs.org/parseuri/-/parseuri-0.0.5.tgz",
552 | "integrity": "sha1-gCBKUNTbt3m/3G6+J3jZDkvOMgo=",
553 | "requires": {
554 | "better-assert": "1.0.2"
555 | }
556 | },
557 | "parseurl": {
558 | "version": "1.3.2",
559 | "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.2.tgz",
560 | "integrity": "sha1-/CidTtiZMRlGDBViUyYs3I3mW/M="
561 | },
562 | "path-to-regexp": {
563 | "version": "0.1.7",
564 | "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
565 | "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
566 | },
567 | "proxy-addr": {
568 | "version": "2.0.2",
569 | "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.2.tgz",
570 | "integrity": "sha1-ZXFQT0e7mI7IGAJT+F3X4UlSvew=",
571 | "requires": {
572 | "forwarded": "0.1.2",
573 | "ipaddr.js": "1.5.2"
574 | }
575 | },
576 | "qs": {
577 | "version": "6.5.1",
578 | "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.1.tgz",
579 | "integrity": "sha512-eRzhrN1WSINYCDCbrz796z37LOe3m5tmW7RQf6oBntukAG1nmovJvhnwHHRMAfeoItc1m2Hk02WER2aQ/iqs+A=="
580 | },
581 | "range-parser": {
582 | "version": "1.2.0",
583 | "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz",
584 | "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4="
585 | },
586 | "raw-body": {
587 | "version": "2.3.2",
588 | "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.3.2.tgz",
589 | "integrity": "sha1-vNYMd9Prk83gBQKVw/N5OJvIj4k=",
590 | "requires": {
591 | "bytes": "3.0.0",
592 | "http-errors": "1.6.2",
593 | "iconv-lite": "0.4.19",
594 | "unpipe": "1.0.0"
595 | }
596 | },
597 | "redis": {
598 | "version": "2.8.0",
599 | "resolved": "https://registry.npmjs.org/redis/-/redis-2.8.0.tgz",
600 | "integrity": "sha512-M1OkonEQwtRmZv4tEWF2VgpG0JWJ8Fv1PhlgT5+B+uNq2cA3Rt1Yt/ryoR+vQNOQcIEgdCdfH0jr3bDpihAw1A==",
601 | "requires": {
602 | "double-ended-queue": "2.1.0-0",
603 | "redis-commands": "1.3.1",
604 | "redis-parser": "2.6.0"
605 | }
606 | },
607 | "redis-commands": {
608 | "version": "1.3.1",
609 | "resolved": "https://registry.npmjs.org/redis-commands/-/redis-commands-1.3.1.tgz",
610 | "integrity": "sha1-gdgm9F+pyLIBH0zXoP5ZfSQdRCs="
611 | },
612 | "redis-parser": {
613 | "version": "2.6.0",
614 | "resolved": "https://registry.npmjs.org/redis-parser/-/redis-parser-2.6.0.tgz",
615 | "integrity": "sha1-Uu0J2srBCPGmMcB+m2mUHnoZUEs="
616 | },
617 | "regexp-clone": {
618 | "version": "0.0.1",
619 | "resolved": "https://registry.npmjs.org/regexp-clone/-/regexp-clone-0.0.1.tgz",
620 | "integrity": "sha1-p8LgmJH9vzj7sQ03b7cwA+aKxYk="
621 | },
622 | "require_optional": {
623 | "version": "1.0.1",
624 | "resolved": "https://registry.npmjs.org/require_optional/-/require_optional-1.0.1.tgz",
625 | "integrity": "sha512-qhM/y57enGWHAe3v/NcwML6a3/vfESLe/sGM2dII+gEO0BpKRUkWZow/tyloNqJyN6kXSl3RyyM8Ll5D/sJP8g==",
626 | "requires": {
627 | "resolve-from": "2.0.0",
628 | "semver": "5.5.0"
629 | }
630 | },
631 | "resolve-from": {
632 | "version": "2.0.0",
633 | "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-2.0.0.tgz",
634 | "integrity": "sha1-lICrIOlP+h2egKgEx+oUdhGWa1c="
635 | },
636 | "safe-buffer": {
637 | "version": "5.1.1",
638 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.1.tgz",
639 | "integrity": "sha512-kKvNJn6Mm93gAczWVJg7wH+wGYWNrDHdWvpUmHyEsgCtIwwo3bqPtV4tR5tuPaUhTOo/kvhVwd8XwwOllGYkbg=="
640 | },
641 | "sax": {
642 | "version": "1.2.4",
643 | "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
644 | "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw=="
645 | },
646 | "semver": {
647 | "version": "5.5.0",
648 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.5.0.tgz",
649 | "integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA=="
650 | },
651 | "send": {
652 | "version": "0.16.1",
653 | "resolved": "https://registry.npmjs.org/send/-/send-0.16.1.tgz",
654 | "integrity": "sha512-ElCLJdJIKPk6ux/Hocwhk7NFHpI3pVm/IZOYWqUmoxcgeyM+MpxHHKhb8QmlJDX1pU6WrgaHBkVNm73Sv7uc2A==",
655 | "requires": {
656 | "debug": "2.6.9",
657 | "depd": "1.1.2",
658 | "destroy": "1.0.4",
659 | "encodeurl": "1.0.2",
660 | "escape-html": "1.0.3",
661 | "etag": "1.8.1",
662 | "fresh": "0.5.2",
663 | "http-errors": "1.6.2",
664 | "mime": "1.4.1",
665 | "ms": "2.0.0",
666 | "on-finished": "2.3.0",
667 | "range-parser": "1.2.0",
668 | "statuses": "1.3.1"
669 | }
670 | },
671 | "serve-static": {
672 | "version": "1.13.1",
673 | "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.13.1.tgz",
674 | "integrity": "sha512-hSMUZrsPa/I09VYFJwa627JJkNs0NrfL1Uzuup+GqHfToR2KcsXFymXSV90hoyw3M+msjFuQly+YzIH/q0MGlQ==",
675 | "requires": {
676 | "encodeurl": "1.0.2",
677 | "escape-html": "1.0.3",
678 | "parseurl": "1.3.2",
679 | "send": "0.16.1"
680 | }
681 | },
682 | "setprototypeof": {
683 | "version": "1.1.0",
684 | "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.1.0.tgz",
685 | "integrity": "sha512-BvE/TwpZX4FXExxOxZyRGQQv651MSwmWKZGqvmPcRIjDqWub67kTKuIMx43cZZrS/cBBzwBcNDWoFxt2XEFIpQ=="
686 | },
687 | "sliced": {
688 | "version": "1.0.1",
689 | "resolved": "https://registry.npmjs.org/sliced/-/sliced-1.0.1.tgz",
690 | "integrity": "sha1-CzpmK10Ewxd7GSa+qCsD+Dei70E="
691 | },
692 | "socket.io": {
693 | "version": "2.0.4",
694 | "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-2.0.4.tgz",
695 | "integrity": "sha1-waRZDO/4fs8TxyZS8Eb3FrKeYBQ=",
696 | "requires": {
697 | "debug": "2.6.9",
698 | "engine.io": "3.1.4",
699 | "socket.io-adapter": "1.1.1",
700 | "socket.io-client": "2.0.4",
701 | "socket.io-parser": "3.1.2"
702 | }
703 | },
704 | "socket.io-adapter": {
705 | "version": "1.1.1",
706 | "resolved": "https://registry.npmjs.org/socket.io-adapter/-/socket.io-adapter-1.1.1.tgz",
707 | "integrity": "sha1-KoBeihTWNyEk3ZFZrUUC+MsH8Gs="
708 | },
709 | "socket.io-client": {
710 | "version": "2.0.4",
711 | "resolved": "https://registry.npmjs.org/socket.io-client/-/socket.io-client-2.0.4.tgz",
712 | "integrity": "sha1-CRilUkBtxeVAs4Dc2Xr8SmQzL44=",
713 | "requires": {
714 | "backo2": "1.0.2",
715 | "base64-arraybuffer": "0.1.5",
716 | "component-bind": "1.0.0",
717 | "component-emitter": "1.2.1",
718 | "debug": "2.6.9",
719 | "engine.io-client": "3.1.4",
720 | "has-cors": "1.1.0",
721 | "indexof": "0.0.1",
722 | "object-component": "0.0.3",
723 | "parseqs": "0.0.5",
724 | "parseuri": "0.0.5",
725 | "socket.io-parser": "3.1.2",
726 | "to-array": "0.1.4"
727 | }
728 | },
729 | "socket.io-parser": {
730 | "version": "3.1.2",
731 | "resolved": "https://registry.npmjs.org/socket.io-parser/-/socket.io-parser-3.1.2.tgz",
732 | "integrity": "sha1-28IoIVH8T6675Aru3Ady66YZ9/I=",
733 | "requires": {
734 | "component-emitter": "1.2.1",
735 | "debug": "2.6.9",
736 | "has-binary2": "1.0.2",
737 | "isarray": "2.0.1"
738 | }
739 | },
740 | "statuses": {
741 | "version": "1.3.1",
742 | "resolved": "https://registry.npmjs.org/statuses/-/statuses-1.3.1.tgz",
743 | "integrity": "sha1-+vUbnrdKrvOzrPStX2Gr8ky3uT4="
744 | },
745 | "to-array": {
746 | "version": "0.1.4",
747 | "resolved": "https://registry.npmjs.org/to-array/-/to-array-0.1.4.tgz",
748 | "integrity": "sha1-F+bBH3PdTz10zaek/zI46a2b+JA="
749 | },
750 | "type-is": {
751 | "version": "1.6.15",
752 | "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.15.tgz",
753 | "integrity": "sha1-yrEPtJCeRByChC6v4a1kbIGARBA=",
754 | "requires": {
755 | "media-typer": "0.3.0",
756 | "mime-types": "2.1.17"
757 | }
758 | },
759 | "ultron": {
760 | "version": "1.1.1",
761 | "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
762 | "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og=="
763 | },
764 | "unpipe": {
765 | "version": "1.0.0",
766 | "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
767 | "integrity": "sha1-sr9O6FFKrmFltIF4KdIbLvSZBOw="
768 | },
769 | "utils-merge": {
770 | "version": "1.0.1",
771 | "resolved": "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz",
772 | "integrity": "sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM="
773 | },
774 | "uws": {
775 | "version": "0.14.5",
776 | "resolved": "https://registry.npmjs.org/uws/-/uws-0.14.5.tgz",
777 | "integrity": "sha1-Z6rzPEaypYel9mZtAPdpEyjxSdw=",
778 | "optional": true
779 | },
780 | "vary": {
781 | "version": "1.1.2",
782 | "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
783 | "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw="
784 | },
785 | "ws": {
786 | "version": "3.3.3",
787 | "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
788 | "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
789 | "requires": {
790 | "async-limiter": "1.0.0",
791 | "safe-buffer": "5.1.1",
792 | "ultron": "1.1.1"
793 | }
794 | },
795 | "xml2js": {
796 | "version": "0.4.19",
797 | "resolved": "https://registry.npmjs.org/xml2js/-/xml2js-0.4.19.tgz",
798 | "integrity": "sha512-esZnJZJOiJR9wWKMyuvSE1y6Dq5LCuJanqhxslH2bxM6duahNZ+HMpCLhBQGZkbX6xRf8x1Y2eJlgt2q3qo49Q==",
799 | "requires": {
800 | "sax": "1.2.4",
801 | "xmlbuilder": "9.0.7"
802 | }
803 | },
804 | "xmlbuilder": {
805 | "version": "9.0.7",
806 | "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-9.0.7.tgz",
807 | "integrity": "sha1-Ey7mPS7FVlxVfiD0wi35rKaGsQ0="
808 | },
809 | "xmlhttprequest-ssl": {
810 | "version": "1.5.5",
811 | "resolved": "https://registry.npmjs.org/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz",
812 | "integrity": "sha1-wodrBhaKrcQOV9l+gRkayPQ5iz4="
813 | },
814 | "yeast": {
815 | "version": "0.1.2",
816 | "resolved": "https://registry.npmjs.org/yeast/-/yeast-0.1.2.tgz",
817 | "integrity": "sha1-AI4G2AlDIMNy28L47XagymyKxBk="
818 | }
819 | }
820 | }
821 |
--------------------------------------------------------------------------------
/public/main.bundle.js.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/$_lazy_route_resource lazy","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/app.component.css","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/app.component.html","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/app.component.ts","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/app.module.ts","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/app.routes.ts","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/editor/editor.component.css","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/editor/editor.component.html","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/editor/editor.component.ts","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/navbar/navbar.component.css","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/navbar/navbar.component.html","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/navbar/navbar.component.ts","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/new-problem/new-problem.component.css","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/new-problem/new-problem.component.html","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/new-problem/new-problem.component.ts","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/problem-detail/problem-detail.component.css","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/problem-detail/problem-detail.component.html","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/problem-detail/problem-detail.component.ts","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/problem-list/problem-list.component.css","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/problem-list/problem-list.component.html","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/problem-list/problem-list.component.ts","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/pipes/search.pipe.ts","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/services/collaboration.service.ts","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/services/data.service.ts","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/services/input.service.ts","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/environments/environment.ts","/Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/main.ts"],"names":[],"mappings":"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","file":"main.bundle.js","sourcesContent":["function webpackEmptyAsyncContext(req) {\n\t// Here Promise.resolve().then() is used instead of new Promise() to prevent\n\t// uncatched exception popping up in devtools\n\treturn Promise.resolve().then(function() {\n\t\tthrow new Error(\"Cannot find module '\" + req + \"'.\");\n\t});\n}\nwebpackEmptyAsyncContext.keys = function() { return []; };\nwebpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext;\nmodule.exports = webpackEmptyAsyncContext;\nwebpackEmptyAsyncContext.id = \"../../../../../src/$$_lazy_route_resource lazy recursive\";\n\n\n//////////////////\n// WEBPACK FOOTER\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/$$_lazy_route_resource lazy\n// module id = ../../../../../src/$$_lazy_route_resource lazy recursive\n// module chunks = main","exports = module.exports = require(\"../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\", \"\"]);\n\n// exports\n\n\n/*** EXPORTS FROM exports-loader ***/\nmodule.exports = module.exports.toString();\n\n\n//////////////////\n// WEBPACK FOOTER\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/app.component.css\n// module id = ../../../../../src/app/app.component.css\n// module chunks = main","module.exports = \" \\n \\n\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/app.component.html\n// module id = ../../../../../src/app/app.component.html\n// module chunks = main","import { Component } from '@angular/core';\n\n@Component({\n selector: 'app-root',\n templateUrl: './app.component.html',\n styleUrls: ['./app.component.css']\n})\nexport class AppComponent {\n title = 'app';\n}\n\n\n\n// WEBPACK FOOTER //\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/app.component.ts","import { BrowserModule } from '@angular/platform-browser';\nimport { NgModule } from '@angular/core';\nimport { FormsModule, ReactiveFormsModule } from '@angular/forms';\nimport { HttpClientModule } from '@angular/common/http';\nimport { CollaborationService } from './services/collaboration.service';\n\n\nimport { AppComponent } from './app.component';\nimport { ProblemListComponent } from './components/problem-list/problem-list.component';\n\nimport { DataService } from './services/data.service';\nimport { ProblemDetailComponent } from './components/problem-detail/problem-detail.component';\nimport { InputService } from './services/input.service';\n\nimport { routing } from './app.routes';\nimport { NewProblemComponent } from './components/new-problem/new-problem.component';\nimport { NavbarComponent } from './components/navbar/navbar.component';\nimport { EditorComponent } from './components/editor/editor.component';\nimport { SearchPipe } from './pipes/search.pipe'\n\n\n@NgModule({\n declarations: [\n AppComponent,\n ProblemListComponent,\n ProblemDetailComponent,\n NewProblemComponent,\n NavbarComponent,\n EditorComponent,\n SearchPipe\n ],\n imports: [\n BrowserModule,\n routing,\n FormsModule,\n HttpClientModule,\n ReactiveFormsModule\n ],\n providers: [DataService,\n CollaborationService,\n InputService\n ],\n bootstrap: [AppComponent]\n})\nexport class AppModule { }\n\n\n\n// WEBPACK FOOTER //\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/app.module.ts","import { Routes, RouterModule} from '@angular/router';\nimport { ProblemListComponent } from './components/problem-list/problem-list.component';\nimport { ProblemDetailComponent } from './components/problem-detail/problem-detail.component';\n\nconst routes: Routes = [\n {\n path: '',\n redirectTo: 'problems',\n pathMatch: 'full'//exactly match\n },\n {\n path: 'problems',\n component: ProblemListComponent\n },\n {\n path: 'problems/:id',\n component: ProblemDetailComponent\n },\n {\n path: '**',\n redirectTo: 'problems'\n }\n]\n\nexport const routing = RouterModule.forRoot(routes);\n\n\n// WEBPACK FOOTER //\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/app.routes.ts","exports = module.exports = require(\"../../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"@media screen {\\n\\t#editor {\\n\\t\\theight: 600px;\\n\\t}\\n\\t.lang-select {\\n\\t\\twidth: 100px;\\n\\t\\tmargin-right: 10px;\\n\\t}\\n\\theader .btn {\\n\\t\\tmargin: 0 5px;\\n\\t}\\n\\tfooter .btn {\\n\\t\\tmargin: 0 5px;\\n\\t}\\n\\t.editor-footer, .editor-header {\\n\\t\\tmargin: 10px 0;\\n\\t}\\n\\t.cursor {\\n\\t\\t/*position:absolute;*/\\n\\t\\tbackground: rgba(0, 250, 0, 0.5);\\n\\t\\tz-index: 40;\\n\\t\\twidth: 2px !important;\\n\\t}\\n}\", \"\"]);\n\n// exports\n\n\n/*** EXPORTS FROM exports-loader ***/\nmodule.exports = module.exports.toString();\n\n\n//////////////////\n// WEBPACK FOOTER\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/editor/editor.component.css\n// module id = ../../../../../src/app/components/editor/editor.component.css\n// module chunks = main","module.exports = \"\\n \\n \\n
\\n
\\n
\\n Output: {{output}}\\n
\\n
\\n Users: {{users}}\\n
\\n
\\n \\n \"\n\n\n//////////////////\n// WEBPACK FOOTER\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/editor/editor.component.html\n// module id = ../../../../../src/app/components/editor/editor.component.html\n// module chunks = main","import { Component, OnInit } from '@angular/core';\nimport { CollaborationService } from '../../services/collaboration.service';\nimport { ActivatedRoute, Params } from '@angular/router';\nimport { DataService } from '../../services/data.service';\nimport { Subscription } from 'rxjs/Subscription';\n\ndeclare var ace: any;// must be declared\n@Component({\n selector: 'app-editor',\n templateUrl: './editor.component.html',\n styleUrls: ['./editor.component.css']\n})\nexport class EditorComponent implements OnInit {\n editor: any;\n\n defaultContent = {\n 'Java': `public class Solution{\n public static void main(String[] args){\n // Please type your code here...\n }\n }`,\n 'Python': `class Solution:\n def example():\n # Please type your code here...\n `,\n 'C++':`int main(){\n /* Please type your code here... */\n }`\n }\n\n languages: string[] = ['Java', 'Python', 'C++'];\n language: string = 'Java';\n sessionId: string;\n\n output: string;\n\n users: string;\n subscriptionUsers: Subscription;\n\n // inject route service and collaborationService\n constructor(private collaboration: CollaborationService,\n private route: ActivatedRoute,\n private dataService: DataService) { }\n\n ngOnInit() {\n this.route.params\n .subscribe(params => {\n this.sessionId = params['id'];\n this.initEditor();\n this.collaboration.restoreBuffer();\n });\n }\n\n resetEditor(): void {\n this.editor.setValue(this.defaultContent[this.language]);\n this.editor.getSession().setMode(\"ace/mode/\" + this.language.toLowerCase()); \n }\n\n setLanguage(language: string): void {\n this.language = language;\n this.resetEditor();\n }\n\n submit(): void {\n let user_code = this.editor.getValue();\n console.log(user_code);\n\n const data = {\n code: user_code,\n lang: this.language.toLocaleLowerCase()\n };\n\n this.dataService.buildAndRun(data)\n .then(res => this.output = res);\n }\n\n initEditor(): void {\n // editor basic setting\n this.editor = ace.edit(\"editor\");\n this.editor.setTheme(\"ace/theme/eclipse\");\n this.resetEditor();\n\n // initialize collaborationService\n this.subscriptionUsers = this.collaboration.init(this.editor, this.sessionId)\n .subscribe(users => this.users = users);\n this.editor.lastAppliedChange = null;\n\n // register change callback\n this.editor.on(\"change\", e => {\n console.log('editor changes: ' + JSON.stringify(e));\n // if the change is the same as the last one, then skip\n if(this.editor.lastAppliedChange != e){\n this.collaboration.change(JSON.stringify(e));\n }\n }); \n }\n}\n\n\n\n// WEBPACK FOOTER //\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/editor/editor.component.ts","exports = module.exports = require(\"../../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\", \"\"]);\n\n// exports\n\n\n/*** EXPORTS FROM exports-loader ***/\nmodule.exports = module.exports.toString();\n\n\n//////////////////\n// WEBPACK FOOTER\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/navbar/navbar.component.css\n// module id = ../../../../../src/app/components/navbar/navbar.component.css\n// module chunks = main","module.exports = \"\\n \\n \"\n\n\n//////////////////\n// WEBPACK FOOTER\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/navbar/navbar.component.html\n// module id = ../../../../../src/app/components/navbar/navbar.component.html\n// module chunks = main","import { Component, OnInit } from '@angular/core';\nimport { FormControl } from '@angular/forms';\nimport { Subscription } from 'rxjs/Subscription';\nimport { Router } from '@angular/router';\nimport { InputService } from '../../services/input.service';\nimport 'rxjs/add/operator/debounceTime'; \n\n@Component({\n selector: 'app-navbar',\n templateUrl: './navbar.component.html',\n styleUrls: ['./navbar.component.css']\n})\nexport class NavbarComponent implements OnInit {\n title = 'LabCode';\n searchBox: FormControl = new FormControl();\n subscription: Subscription;\n\n constructor(private inputService: InputService,\n private router: Router) { }\n\n ngOnInit() {\n this.subscription = this.searchBox\n .valueChanges\n .debounceTime(200)\n .subscribe(term => {this.inputService.changeInput(term)});\n }\n\n ngOnDestroy() {\n this.subscription.unsubscribe();\n }\n\n searchProblem(): void {\n this.router.navigate(['/problems']);\n }\n} \n\n\n\n// WEBPACK FOOTER //\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/navbar/navbar.component.ts","exports = module.exports = require(\"../../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\", \"\"]);\n\n// exports\n\n\n/*** EXPORTS FROM exports-loader ***/\nmodule.exports = module.exports.toString();\n\n\n//////////////////\n// WEBPACK FOOTER\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/new-problem/new-problem.component.css\n// module id = ../../../../../src/app/components/new-problem/new-problem.component.css\n// module chunks = main","module.exports = \"\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/new-problem/new-problem.component.html\n// module id = ../../../../../src/app/components/new-problem/new-problem.component.html\n// module chunks = main","import { Component, OnInit } from '@angular/core';\nimport { Problem } from '../../models/problem.model';\nimport { DataService } from '../../services/data.service';\n\nconst DEFAULT_PROBLEM: Problem = Object.freeze({\n id: 0,\n name: '',\n desc: '',\n difficulty: 'easy'\n})\n\n@Component({\n selector: 'app-new-problem',\n templateUrl: './new-problem.component.html',\n styleUrls: ['./new-problem.component.css']\n})\nexport class NewProblemComponent implements OnInit {\n // create a shadow copy of problem and assign it to newProblem\n // Object.assign() copies property values. If the source value is a reference to an object, it only copies that reference value.\n newProblem: Problem = Object.assign({}, DEFAULT_PROBLEM);\n difficulties: string[] = ['easy', 'medium', 'hard', 'super'];\n\n constructor(private dataService: DataService) { }\n\n ngOnInit() {\n }\n \n addProblem(){\n this.dataService.addProblem(this.newProblem);\n // assign newProblem a new problem instance\n // Otherwise newProblem have same reference as the one we added to the list\n // then when next time add new problem, it will override the problem we have already add into the problem list.\n this.newProblem = Object.assign({}, DEFAULT_PROBLEM);\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/new-problem/new-problem.component.ts","exports = module.exports = require(\"../../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \"\", \"\"]);\n\n// exports\n\n\n/*** EXPORTS FROM exports-loader ***/\nmodule.exports = module.exports.toString();\n\n\n//////////////////\n// WEBPACK FOOTER\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/problem-detail/problem-detail.component.css\n// module id = ../../../../../src/app/components/problem-detail/problem-detail.component.css\n// module chunks = main","module.exports = \"\\n \\n
\\n
\\n
\\n {{problem.id}}. {{problem.name}}\\n \\n
\\n {{problem.desc}}\\n
\\n
\\n
\\n
\\n
\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/problem-detail/problem-detail.component.html\n// module id = ../../../../../src/app/components/problem-detail/problem-detail.component.html\n// module chunks = main","import { Component, OnInit } from '@angular/core';\nimport { DataService } from '../../services/data.service';\nimport { Problem } from '../../models/problem.model';\nimport { ActivatedRoute, Params } from '@angular/router';\n\n@Component({\n selector: 'app-problem-detail',\n templateUrl: './problem-detail.component.html',\n styleUrls: ['./problem-detail.component.css']\n})\nexport class ProblemDetailComponent implements OnInit {\n problem: Problem;\n\n constructor(private dataService: DataService,\n private route: ActivatedRoute) { }\n\n ngOnInit() {\n // subscribe: when params changes, this.problem will be updated\n // +: conver string to int\n this.route.params.subscribe(params => {\n this.dataService.getProblem(+params['id'])\n .then(problem => this.problem = problem);\n });\n }\n\n}\n\n\n\n// WEBPACK FOOTER //\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/problem-detail/problem-detail.component.ts","exports = module.exports = require(\"../../../../node_modules/css-loader/lib/css-base.js\")(false);\n// imports\n\n\n// module\nexports.push([module.id, \".difficulty {\\n min-width: 65px;\\n margin-right: 10px;\\n}\\n\\n.label.difficulty {\\n padding-top: 0.6em;\\n color: #fbfdfa;\\n font-size: 12px;\\n}\\n\\n.title {\\n font-size: 1.2em;\\n}\\n\\n.diff-easy {\\n background-color: #42ebf4;\\n}\\n\\n.diff-medium {\\n background-color: #92cf5c;\\n}\\n\\n.diff-hard {\\n background-color: #dd0d1e;\\n}\\n\\n.diff-super {\\n background-color: #8d16e2;\\n}\", \"\"]);\n\n// exports\n\n\n/*** EXPORTS FROM exports-loader ***/\nmodule.exports = module.exports.toString();\n\n\n//////////////////\n// WEBPACK FOOTER\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/problem-list/problem-list.component.css\n// module id = ../../../../../src/app/components/problem-list/problem-list.component.css\n// module chunks = main","module.exports = \"\\n\"\n\n\n//////////////////\n// WEBPACK FOOTER\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/problem-list/problem-list.component.html\n// module id = ../../../../../src/app/components/problem-list/problem-list.component.html\n// module chunks = main","import { Component, OnInit } from '@angular/core';\nimport { Problem } from '../../models/problem.model';\nimport { DataService } from '../../services/data.service';\nimport { Subscription } from 'rxjs/Subscription';\nimport { InputService } from '../../services/input.service';\n\n@Component({\n selector: 'app-problem-list',\n templateUrl: './problem-list.component.html',\n styleUrls: ['./problem-list.component.css']\n})\nexport class ProblemListComponent implements OnInit {\n problems: Problem[];\n subcriptionProblems: Subscription;\n // for navbar\n searchTerm: String = '';\n subscriptionInput: Subscription;\n\n constructor(private dataService: DataService,\n private inputService: InputService) { }\n\n ngOnInit() {\n this.getProblems();\n this.getSearchTerm();\n }\n ngOnDestroy() {\n this.subcriptionProblems.unsubscribe();\n }\n \n getProblems() {\n this.subcriptionProblems = this.dataService.getProblems()\n .subscribe(problems => {\n this.problems = problems;\n });\n }\n\n getSearchTerm(): void { \n this.subscriptionInput = this.inputService.getInput()\n .subscribe(term => this.searchTerm = term);\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/components/problem-list/problem-list.component.ts","import { Pipe, PipeTransform } from '@angular/core';\nimport { Problem } from '../models/problem.model';\n\n@Pipe({\n name: 'search'\n})\nexport class SearchPipe implements PipeTransform {\n\n transform(problems: Problem[], term: string): Problem[] {\n // get filtered problem list\n return problems.filter(\n problem => problem.name.toLowerCase().includes(term));\n }\n\n}\n\n\n\n// WEBPACK FOOTER //\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/pipes/search.pipe.ts","import { Injectable } from '@angular/core';\nimport { Observable } from 'rxjs/Observable';\nimport { Subject } from 'rxjs/Subject';\n\ndeclare var io: any; // io is already imported in angular.cli.json\n\n@Injectable()\nexport class CollaborationService {\n collaborationSocket: any;\n private _userSource = new Subject();\n constructor() { }\n\n init(editor: any, sessionId: string): Observable {\n // send to server\n this.collaborationSocket = io(window.location.origin, {query: 'sessionId=' + sessionId});\n // //wait for 'message' event from server\n // this.collaborationSocket.on(\"message\", (message) => {\n // console.log('message received from the server: ' + message);\n // })\n \n // handle the changes from server\n this.collaborationSocket.on('change', (delta: string) => {\n console.log('collaboration: editor changes by ' + delta);\n delta = JSON.parse(delta);\n editor.lastAppliedChange = delta;\n // apply the changes on editor\n editor.getSession().getDocument().applyDeltas([delta]);\n });\n // handle user changes\n this.collaborationSocket.on('userchange', (users: string[]) => {\n console.log('user changed: ' + users);\n this._userSource.next(users.toString());\n })\n\n return this._userSource.asObservable();\n }\n\n // emit event to make changes and inform server and other collaborators\n change(delta: string): void {\n // emit \"change\" event\n this.collaborationSocket.emit('change', delta);\n }\n\n restoreBuffer(): void {\n // let the server handle the event\n this.collaborationSocket.emit('restoreBuffer');\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/services/collaboration.service.ts","import { Injectable } from '@angular/core';\nimport { Problem } from '../models/problem.model';\nimport { HttpClient, HttpRequest, HttpResponse } from '@angular/common/http';\nimport { Observable } from 'rxjs/Rx';\nimport { BehaviorSubject } from 'rxjs/BehaviorSubject';\nimport { HttpHeaders } from '@angular/common/http';\n\n@Injectable()\nexport class DataService {\n private _problemSource = new BehaviorSubject([]);\n\n constructor(private httpClient: HttpClient) { }\n \n // return a list of problems\n getProblems(): Observable {\n this.httpClient.get('api/v1/problems')\n .toPromise()\n .then((res: any) => {\n this._problemSource.next(res);\n })\n .catch(this.handleError);\n return this._problemSource.asObservable();\n\n }\n //use subscribe\n // getProblems(): Observable {\n // this.httpClient.get('api/v1/problems')\n // .subscribe((res:any) => this._problemSource.next(res));\n // return this._problemSource.asObservable();\n\n // }\n\n // return a problem by id\n getProblem(id: number): Promise {\n return this.httpClient.get(`api/v1/problems/${id}`)\n .toPromise()\n .then((res: any) => res)\n .catch(this.handleError);\n }\n\n // add problem\n addProblem(problem: Problem){\n const options = {headers: new HttpHeaders({'Content-Type': 'application/json'})};\n return this.httpClient.post('api/v1/problems', problem, options)\n .toPromise()\n .then((res: any) => {\n this.getProblems();\n return res;\n })\n .catch(this.handleError);\n }\n\n // build and run: POST\n buildAndRun(data): Promise{\n const options = {headers: new HttpHeaders({'Content-Type': 'application/json'})};\n return this.httpClient.post('api/v1/build_and_run', data, options)\n .toPromise()\n .then(res => {\n console.log(res);\n return res;\n })\n .catch(this.handleError);\n }\n\n // // modify problem\n // editProblem(problem: Problem) {\n // const options = {headers: new HttpHeaders({'Content-Type': 'application/json'})};\n // return this.httpClient.post('api/v1/problems', problem, options)\n // .toPromise()\n // .\n // }\n\n // handle errors\n private handleError(error: any): Promise{\n console.error('Error reference', error);\n return Promise.reject(error.body || error);\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/services/data.service.ts","import { Injectable } from '@angular/core';\nimport { BehaviorSubject } from 'rxjs/BehaviorSubject';\nimport { Observable } from 'rxjs/Rx';\n\n@Injectable()\nexport class InputService {\n private inputSubject$ = new BehaviorSubject('');\n constructor() { }\n\n changeInput(term) {\n this.inputSubject$.next(term);\n }\n\n getInput(): Observable {\n return this.inputSubject$.asObservable();\n }\n}\n\n\n\n// WEBPACK FOOTER //\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/app/services/input.service.ts","// The file contents for the current environment will overwrite these during build.\n// The build system defaults to the dev environment which uses `environment.ts`, but if you do\n// `ng build --env=prod` then `environment.prod.ts` will be used instead.\n// The list of which env maps to which file can be found in `.angular-cli.json`.\n\nexport const environment = {\n production: false\n};\n\n\n\n// WEBPACK FOOTER //\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/environments/environment.ts","import { enableProdMode } from '@angular/core';\nimport { platformBrowserDynamic } from '@angular/platform-browser-dynamic';\n\nimport { AppModule } from './app/app.module';\nimport { environment } from './environments/environment';\n\nif (environment.production) {\n enableProdMode();\n}\n\nplatformBrowserDynamic().bootstrapModule(AppModule)\n .catch(err => console.log(err));\n\n\n\n// WEBPACK FOOTER //\n// /Users/ChenQi/BitTiger-CS503-1801/week3/oj-client/src/main.ts"],"sourceRoot":"webpack:///"}
--------------------------------------------------------------------------------
/public/main.bundle.js:
--------------------------------------------------------------------------------
1 | webpackJsonp(["main"],{
2 |
3 | /***/ "../../../../../src/$$_lazy_route_resource lazy recursive":
4 | /***/ (function(module, exports) {
5 |
6 | function webpackEmptyAsyncContext(req) {
7 | // Here Promise.resolve().then() is used instead of new Promise() to prevent
8 | // uncatched exception popping up in devtools
9 | return Promise.resolve().then(function() {
10 | throw new Error("Cannot find module '" + req + "'.");
11 | });
12 | }
13 | webpackEmptyAsyncContext.keys = function() { return []; };
14 | webpackEmptyAsyncContext.resolve = webpackEmptyAsyncContext;
15 | module.exports = webpackEmptyAsyncContext;
16 | webpackEmptyAsyncContext.id = "../../../../../src/$$_lazy_route_resource lazy recursive";
17 |
18 | /***/ }),
19 |
20 | /***/ "../../../../../src/app/app.component.css":
21 | /***/ (function(module, exports, __webpack_require__) {
22 |
23 | exports = module.exports = __webpack_require__("../../../../css-loader/lib/css-base.js")(false);
24 | // imports
25 |
26 |
27 | // module
28 | exports.push([module.i, "", ""]);
29 |
30 | // exports
31 |
32 |
33 | /*** EXPORTS FROM exports-loader ***/
34 | module.exports = module.exports.toString();
35 |
36 | /***/ }),
37 |
38 | /***/ "../../../../../src/app/app.component.html":
39 | /***/ (function(module, exports) {
40 |
41 | module.exports = " \n \n\n"
42 |
43 | /***/ }),
44 |
45 | /***/ "../../../../../src/app/app.component.ts":
46 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
47 |
48 | "use strict";
49 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return AppComponent; });
50 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__angular_core__ = __webpack_require__("../../../core/esm5/core.js");
51 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
52 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
53 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
54 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
55 | return c > 3 && r && Object.defineProperty(target, key, r), r;
56 | };
57 |
58 | var AppComponent = /** @class */ (function () {
59 | function AppComponent() {
60 | this.title = 'app';
61 | }
62 | AppComponent = __decorate([
63 | Object(__WEBPACK_IMPORTED_MODULE_0__angular_core__["n" /* Component */])({
64 | selector: 'app-root',
65 | template: __webpack_require__("../../../../../src/app/app.component.html"),
66 | styles: [__webpack_require__("../../../../../src/app/app.component.css")]
67 | })
68 | ], AppComponent);
69 | return AppComponent;
70 | }());
71 |
72 |
73 |
74 | /***/ }),
75 |
76 | /***/ "../../../../../src/app/app.module.ts":
77 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
78 |
79 | "use strict";
80 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return AppModule; });
81 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__angular_platform_browser__ = __webpack_require__("../../../platform-browser/esm5/platform-browser.js");
82 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__angular_core__ = __webpack_require__("../../../core/esm5/core.js");
83 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__angular_forms__ = __webpack_require__("../../../forms/esm5/forms.js");
84 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__angular_common_http__ = __webpack_require__("../../../common/esm5/http.js");
85 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__services_collaboration_service__ = __webpack_require__("../../../../../src/app/services/collaboration.service.ts");
86 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__app_component__ = __webpack_require__("../../../../../src/app/app.component.ts");
87 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__components_problem_list_problem_list_component__ = __webpack_require__("../../../../../src/app/components/problem-list/problem-list.component.ts");
88 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__services_data_service__ = __webpack_require__("../../../../../src/app/services/data.service.ts");
89 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__components_problem_detail_problem_detail_component__ = __webpack_require__("../../../../../src/app/components/problem-detail/problem-detail.component.ts");
90 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__services_input_service__ = __webpack_require__("../../../../../src/app/services/input.service.ts");
91 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__app_routes__ = __webpack_require__("../../../../../src/app/app.routes.ts");
92 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__components_new_problem_new_problem_component__ = __webpack_require__("../../../../../src/app/components/new-problem/new-problem.component.ts");
93 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_12__components_navbar_navbar_component__ = __webpack_require__("../../../../../src/app/components/navbar/navbar.component.ts");
94 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_13__components_editor_editor_component__ = __webpack_require__("../../../../../src/app/components/editor/editor.component.ts");
95 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_14__pipes_search_pipe__ = __webpack_require__("../../../../../src/app/pipes/search.pipe.ts");
96 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
97 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
98 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
99 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
100 | return c > 3 && r && Object.defineProperty(target, key, r), r;
101 | };
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 | var AppModule = /** @class */ (function () {
118 | function AppModule() {
119 | }
120 | AppModule = __decorate([
121 | Object(__WEBPACK_IMPORTED_MODULE_1__angular_core__["I" /* NgModule */])({
122 | declarations: [
123 | __WEBPACK_IMPORTED_MODULE_5__app_component__["a" /* AppComponent */],
124 | __WEBPACK_IMPORTED_MODULE_6__components_problem_list_problem_list_component__["a" /* ProblemListComponent */],
125 | __WEBPACK_IMPORTED_MODULE_8__components_problem_detail_problem_detail_component__["a" /* ProblemDetailComponent */],
126 | __WEBPACK_IMPORTED_MODULE_11__components_new_problem_new_problem_component__["a" /* NewProblemComponent */],
127 | __WEBPACK_IMPORTED_MODULE_12__components_navbar_navbar_component__["a" /* NavbarComponent */],
128 | __WEBPACK_IMPORTED_MODULE_13__components_editor_editor_component__["a" /* EditorComponent */],
129 | __WEBPACK_IMPORTED_MODULE_14__pipes_search_pipe__["a" /* SearchPipe */]
130 | ],
131 | imports: [
132 | __WEBPACK_IMPORTED_MODULE_0__angular_platform_browser__["a" /* BrowserModule */],
133 | __WEBPACK_IMPORTED_MODULE_10__app_routes__["a" /* routing */],
134 | __WEBPACK_IMPORTED_MODULE_2__angular_forms__["b" /* FormsModule */],
135 | __WEBPACK_IMPORTED_MODULE_3__angular_common_http__["b" /* HttpClientModule */],
136 | __WEBPACK_IMPORTED_MODULE_2__angular_forms__["c" /* ReactiveFormsModule */]
137 | ],
138 | providers: [__WEBPACK_IMPORTED_MODULE_7__services_data_service__["a" /* DataService */],
139 | __WEBPACK_IMPORTED_MODULE_4__services_collaboration_service__["a" /* CollaborationService */],
140 | __WEBPACK_IMPORTED_MODULE_9__services_input_service__["a" /* InputService */]
141 | ],
142 | bootstrap: [__WEBPACK_IMPORTED_MODULE_5__app_component__["a" /* AppComponent */]]
143 | })
144 | ], AppModule);
145 | return AppModule;
146 | }());
147 |
148 |
149 |
150 | /***/ }),
151 |
152 | /***/ "../../../../../src/app/app.routes.ts":
153 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
154 |
155 | "use strict";
156 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return routing; });
157 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__angular_router__ = __webpack_require__("../../../router/esm5/router.js");
158 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__components_problem_list_problem_list_component__ = __webpack_require__("../../../../../src/app/components/problem-list/problem-list.component.ts");
159 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__components_problem_detail_problem_detail_component__ = __webpack_require__("../../../../../src/app/components/problem-detail/problem-detail.component.ts");
160 |
161 |
162 |
163 | var routes = [
164 | {
165 | path: '',
166 | redirectTo: 'problems',
167 | pathMatch: 'full' //exactly match
168 | },
169 | {
170 | path: 'problems',
171 | component: __WEBPACK_IMPORTED_MODULE_1__components_problem_list_problem_list_component__["a" /* ProblemListComponent */]
172 | },
173 | {
174 | path: 'problems/:id',
175 | component: __WEBPACK_IMPORTED_MODULE_2__components_problem_detail_problem_detail_component__["a" /* ProblemDetailComponent */]
176 | },
177 | {
178 | path: '**',
179 | redirectTo: 'problems'
180 | }
181 | ];
182 | var routing = __WEBPACK_IMPORTED_MODULE_0__angular_router__["c" /* RouterModule */].forRoot(routes);
183 |
184 |
185 | /***/ }),
186 |
187 | /***/ "../../../../../src/app/components/editor/editor.component.css":
188 | /***/ (function(module, exports, __webpack_require__) {
189 |
190 | exports = module.exports = __webpack_require__("../../../../css-loader/lib/css-base.js")(false);
191 | // imports
192 |
193 |
194 | // module
195 | exports.push([module.i, "@media screen {\n\t#editor {\n\t\theight: 600px;\n\t}\n\t.lang-select {\n\t\twidth: 100px;\n\t\tmargin-right: 10px;\n\t}\n\theader .btn {\n\t\tmargin: 0 5px;\n\t}\n\tfooter .btn {\n\t\tmargin: 0 5px;\n\t}\n\t.editor-footer, .editor-header {\n\t\tmargin: 10px 0;\n\t}\n\t.cursor {\n\t\t/*position:absolute;*/\n\t\tbackground: rgba(0, 250, 0, 0.5);\n\t\tz-index: 40;\n\t\twidth: 2px !important;\n\t}\n}", ""]);
196 |
197 | // exports
198 |
199 |
200 | /*** EXPORTS FROM exports-loader ***/
201 | module.exports = module.exports.toString();
202 |
203 | /***/ }),
204 |
205 | /***/ "../../../../../src/app/components/editor/editor.component.html":
206 | /***/ (function(module, exports) {
207 |
208 | module.exports = "\n \n \n
\n
\n
\n Output: {{output}}\n
\n
\n Users: {{users}}\n
\n
\n \n "
209 |
210 | /***/ }),
211 |
212 | /***/ "../../../../../src/app/components/editor/editor.component.ts":
213 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
214 |
215 | "use strict";
216 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return EditorComponent; });
217 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__angular_core__ = __webpack_require__("../../../core/esm5/core.js");
218 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__services_collaboration_service__ = __webpack_require__("../../../../../src/app/services/collaboration.service.ts");
219 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__angular_router__ = __webpack_require__("../../../router/esm5/router.js");
220 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__services_data_service__ = __webpack_require__("../../../../../src/app/services/data.service.ts");
221 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
222 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
223 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
224 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
225 | return c > 3 && r && Object.defineProperty(target, key, r), r;
226 | };
227 | var __metadata = (this && this.__metadata) || function (k, v) {
228 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
229 | };
230 |
231 |
232 |
233 |
234 | var EditorComponent = /** @class */ (function () {
235 | // inject route service and collaborationService
236 | function EditorComponent(collaboration, route, dataService) {
237 | this.collaboration = collaboration;
238 | this.route = route;
239 | this.dataService = dataService;
240 | this.defaultContent = {
241 | 'Java': "public class Solution{\n public static void main(String[] args){\n // Please type your code here...\n }\n }",
242 | 'Python': "class Solution:\n def example():\n # Please type your code here...\n ",
243 | 'C++': "int main(){\n /* Please type your code here... */\n }"
244 | };
245 | this.languages = ['Java', 'Python', 'C++'];
246 | this.language = 'Java';
247 | }
248 | EditorComponent.prototype.ngOnInit = function () {
249 | var _this = this;
250 | this.route.params
251 | .subscribe(function (params) {
252 | _this.sessionId = params['id'];
253 | _this.initEditor();
254 | _this.collaboration.restoreBuffer();
255 | });
256 | };
257 | EditorComponent.prototype.resetEditor = function () {
258 | this.editor.setValue(this.defaultContent[this.language]);
259 | this.editor.getSession().setMode("ace/mode/" + this.language.toLowerCase());
260 | };
261 | EditorComponent.prototype.setLanguage = function (language) {
262 | this.language = language;
263 | this.resetEditor();
264 | };
265 | EditorComponent.prototype.submit = function () {
266 | var _this = this;
267 | var user_code = this.editor.getValue();
268 | console.log(user_code);
269 | var data = {
270 | code: user_code,
271 | lang: this.language.toLocaleLowerCase()
272 | };
273 | this.dataService.buildAndRun(data)
274 | .then(function (res) { return _this.output = res; });
275 | };
276 | EditorComponent.prototype.initEditor = function () {
277 | var _this = this;
278 | // editor basic setting
279 | this.editor = ace.edit("editor");
280 | this.editor.setTheme("ace/theme/eclipse");
281 | this.resetEditor();
282 | // initialize collaborationService
283 | this.subscriptionUsers = this.collaboration.init(this.editor, this.sessionId)
284 | .subscribe(function (users) { return _this.users = users; });
285 | this.editor.lastAppliedChange = null;
286 | // register change callback
287 | this.editor.on("change", function (e) {
288 | console.log('editor changes: ' + JSON.stringify(e));
289 | // if the change is the same as the last one, then skip
290 | if (_this.editor.lastAppliedChange != e) {
291 | _this.collaboration.change(JSON.stringify(e));
292 | }
293 | });
294 | };
295 | EditorComponent = __decorate([
296 | Object(__WEBPACK_IMPORTED_MODULE_0__angular_core__["n" /* Component */])({
297 | selector: 'app-editor',
298 | template: __webpack_require__("../../../../../src/app/components/editor/editor.component.html"),
299 | styles: [__webpack_require__("../../../../../src/app/components/editor/editor.component.css")]
300 | }),
301 | __metadata("design:paramtypes", [__WEBPACK_IMPORTED_MODULE_1__services_collaboration_service__["a" /* CollaborationService */],
302 | __WEBPACK_IMPORTED_MODULE_2__angular_router__["a" /* ActivatedRoute */],
303 | __WEBPACK_IMPORTED_MODULE_3__services_data_service__["a" /* DataService */]])
304 | ], EditorComponent);
305 | return EditorComponent;
306 | }());
307 |
308 |
309 |
310 | /***/ }),
311 |
312 | /***/ "../../../../../src/app/components/navbar/navbar.component.css":
313 | /***/ (function(module, exports, __webpack_require__) {
314 |
315 | exports = module.exports = __webpack_require__("../../../../css-loader/lib/css-base.js")(false);
316 | // imports
317 |
318 |
319 | // module
320 | exports.push([module.i, "", ""]);
321 |
322 | // exports
323 |
324 |
325 | /*** EXPORTS FROM exports-loader ***/
326 | module.exports = module.exports.toString();
327 |
328 | /***/ }),
329 |
330 | /***/ "../../../../../src/app/components/navbar/navbar.component.html":
331 | /***/ (function(module, exports) {
332 |
333 | module.exports = "\n \n "
334 |
335 | /***/ }),
336 |
337 | /***/ "../../../../../src/app/components/navbar/navbar.component.ts":
338 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
339 |
340 | "use strict";
341 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return NavbarComponent; });
342 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__angular_core__ = __webpack_require__("../../../core/esm5/core.js");
343 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__angular_forms__ = __webpack_require__("../../../forms/esm5/forms.js");
344 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__angular_router__ = __webpack_require__("../../../router/esm5/router.js");
345 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__services_input_service__ = __webpack_require__("../../../../../src/app/services/input.service.ts");
346 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_4_rxjs_add_operator_debounceTime__ = __webpack_require__("../../../../rxjs/_esm5/add/operator/debounceTime.js");
347 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
348 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
349 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
350 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
351 | return c > 3 && r && Object.defineProperty(target, key, r), r;
352 | };
353 | var __metadata = (this && this.__metadata) || function (k, v) {
354 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
355 | };
356 |
357 |
358 |
359 |
360 |
361 | var NavbarComponent = /** @class */ (function () {
362 | function NavbarComponent(inputService, router) {
363 | this.inputService = inputService;
364 | this.router = router;
365 | this.title = 'LabCode';
366 | this.searchBox = new __WEBPACK_IMPORTED_MODULE_1__angular_forms__["a" /* FormControl */]();
367 | }
368 | NavbarComponent.prototype.ngOnInit = function () {
369 | var _this = this;
370 | this.subscription = this.searchBox
371 | .valueChanges
372 | .debounceTime(200)
373 | .subscribe(function (term) { _this.inputService.changeInput(term); });
374 | };
375 | NavbarComponent.prototype.ngOnDestroy = function () {
376 | this.subscription.unsubscribe();
377 | };
378 | NavbarComponent.prototype.searchProblem = function () {
379 | this.router.navigate(['/problems']);
380 | };
381 | NavbarComponent = __decorate([
382 | Object(__WEBPACK_IMPORTED_MODULE_0__angular_core__["n" /* Component */])({
383 | selector: 'app-navbar',
384 | template: __webpack_require__("../../../../../src/app/components/navbar/navbar.component.html"),
385 | styles: [__webpack_require__("../../../../../src/app/components/navbar/navbar.component.css")]
386 | }),
387 | __metadata("design:paramtypes", [__WEBPACK_IMPORTED_MODULE_3__services_input_service__["a" /* InputService */],
388 | __WEBPACK_IMPORTED_MODULE_2__angular_router__["b" /* Router */]])
389 | ], NavbarComponent);
390 | return NavbarComponent;
391 | }());
392 |
393 |
394 |
395 | /***/ }),
396 |
397 | /***/ "../../../../../src/app/components/new-problem/new-problem.component.css":
398 | /***/ (function(module, exports, __webpack_require__) {
399 |
400 | exports = module.exports = __webpack_require__("../../../../css-loader/lib/css-base.js")(false);
401 | // imports
402 |
403 |
404 | // module
405 | exports.push([module.i, "", ""]);
406 |
407 | // exports
408 |
409 |
410 | /*** EXPORTS FROM exports-loader ***/
411 | module.exports = module.exports.toString();
412 |
413 | /***/ }),
414 |
415 | /***/ "../../../../../src/app/components/new-problem/new-problem.component.html":
416 | /***/ (function(module, exports) {
417 |
418 | module.exports = ""
419 |
420 | /***/ }),
421 |
422 | /***/ "../../../../../src/app/components/new-problem/new-problem.component.ts":
423 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
424 |
425 | "use strict";
426 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return NewProblemComponent; });
427 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__angular_core__ = __webpack_require__("../../../core/esm5/core.js");
428 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__services_data_service__ = __webpack_require__("../../../../../src/app/services/data.service.ts");
429 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
430 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
431 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
432 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
433 | return c > 3 && r && Object.defineProperty(target, key, r), r;
434 | };
435 | var __metadata = (this && this.__metadata) || function (k, v) {
436 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
437 | };
438 |
439 |
440 | var DEFAULT_PROBLEM = Object.freeze({
441 | id: 0,
442 | name: '',
443 | desc: '',
444 | difficulty: 'easy'
445 | });
446 | var NewProblemComponent = /** @class */ (function () {
447 | function NewProblemComponent(dataService) {
448 | this.dataService = dataService;
449 | // create a shadow copy of problem and assign it to newProblem
450 | // Object.assign() copies property values. If the source value is a reference to an object, it only copies that reference value.
451 | this.newProblem = Object.assign({}, DEFAULT_PROBLEM);
452 | this.difficulties = ['easy', 'medium', 'hard', 'super'];
453 | }
454 | NewProblemComponent.prototype.ngOnInit = function () {
455 | };
456 | NewProblemComponent.prototype.addProblem = function () {
457 | this.dataService.addProblem(this.newProblem);
458 | // assign newProblem a new problem instance
459 | // Otherwise newProblem have same reference as the one we added to the list
460 | // then when next time add new problem, it will override the problem we have already add into the problem list.
461 | this.newProblem = Object.assign({}, DEFAULT_PROBLEM);
462 | };
463 | NewProblemComponent = __decorate([
464 | Object(__WEBPACK_IMPORTED_MODULE_0__angular_core__["n" /* Component */])({
465 | selector: 'app-new-problem',
466 | template: __webpack_require__("../../../../../src/app/components/new-problem/new-problem.component.html"),
467 | styles: [__webpack_require__("../../../../../src/app/components/new-problem/new-problem.component.css")]
468 | }),
469 | __metadata("design:paramtypes", [__WEBPACK_IMPORTED_MODULE_1__services_data_service__["a" /* DataService */]])
470 | ], NewProblemComponent);
471 | return NewProblemComponent;
472 | }());
473 |
474 |
475 |
476 | /***/ }),
477 |
478 | /***/ "../../../../../src/app/components/problem-detail/problem-detail.component.css":
479 | /***/ (function(module, exports, __webpack_require__) {
480 |
481 | exports = module.exports = __webpack_require__("../../../../css-loader/lib/css-base.js")(false);
482 | // imports
483 |
484 |
485 | // module
486 | exports.push([module.i, "", ""]);
487 |
488 | // exports
489 |
490 |
491 | /*** EXPORTS FROM exports-loader ***/
492 | module.exports = module.exports.toString();
493 |
494 | /***/ }),
495 |
496 | /***/ "../../../../../src/app/components/problem-detail/problem-detail.component.html":
497 | /***/ (function(module, exports) {
498 |
499 | module.exports = "\n \n
\n
\n
\n {{problem.id}}. {{problem.name}}\n \n
\n {{problem.desc}}\n
\n
\n
\n
\n
"
500 |
501 | /***/ }),
502 |
503 | /***/ "../../../../../src/app/components/problem-detail/problem-detail.component.ts":
504 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
505 |
506 | "use strict";
507 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return ProblemDetailComponent; });
508 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__angular_core__ = __webpack_require__("../../../core/esm5/core.js");
509 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__services_data_service__ = __webpack_require__("../../../../../src/app/services/data.service.ts");
510 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__angular_router__ = __webpack_require__("../../../router/esm5/router.js");
511 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
512 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
513 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
514 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
515 | return c > 3 && r && Object.defineProperty(target, key, r), r;
516 | };
517 | var __metadata = (this && this.__metadata) || function (k, v) {
518 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
519 | };
520 |
521 |
522 |
523 | var ProblemDetailComponent = /** @class */ (function () {
524 | function ProblemDetailComponent(dataService, route) {
525 | this.dataService = dataService;
526 | this.route = route;
527 | }
528 | ProblemDetailComponent.prototype.ngOnInit = function () {
529 | var _this = this;
530 | // subscribe: when params changes, this.problem will be updated
531 | // +: conver string to int
532 | this.route.params.subscribe(function (params) {
533 | _this.dataService.getProblem(+params['id'])
534 | .then(function (problem) { return _this.problem = problem; });
535 | });
536 | };
537 | ProblemDetailComponent = __decorate([
538 | Object(__WEBPACK_IMPORTED_MODULE_0__angular_core__["n" /* Component */])({
539 | selector: 'app-problem-detail',
540 | template: __webpack_require__("../../../../../src/app/components/problem-detail/problem-detail.component.html"),
541 | styles: [__webpack_require__("../../../../../src/app/components/problem-detail/problem-detail.component.css")]
542 | }),
543 | __metadata("design:paramtypes", [__WEBPACK_IMPORTED_MODULE_1__services_data_service__["a" /* DataService */],
544 | __WEBPACK_IMPORTED_MODULE_2__angular_router__["a" /* ActivatedRoute */]])
545 | ], ProblemDetailComponent);
546 | return ProblemDetailComponent;
547 | }());
548 |
549 |
550 |
551 | /***/ }),
552 |
553 | /***/ "../../../../../src/app/components/problem-list/problem-list.component.css":
554 | /***/ (function(module, exports, __webpack_require__) {
555 |
556 | exports = module.exports = __webpack_require__("../../../../css-loader/lib/css-base.js")(false);
557 | // imports
558 |
559 |
560 | // module
561 | exports.push([module.i, ".difficulty {\n min-width: 65px;\n margin-right: 10px;\n}\n\n.label.difficulty {\n padding-top: 0.6em;\n color: #fbfdfa;\n font-size: 12px;\n}\n\n.title {\n font-size: 1.2em;\n}\n\n.diff-easy {\n background-color: #42ebf4;\n}\n\n.diff-medium {\n background-color: #92cf5c;\n}\n\n.diff-hard {\n background-color: #dd0d1e;\n}\n\n.diff-super {\n background-color: #8d16e2;\n}", ""]);
562 |
563 | // exports
564 |
565 |
566 | /*** EXPORTS FROM exports-loader ***/
567 | module.exports = module.exports.toString();
568 |
569 | /***/ }),
570 |
571 | /***/ "../../../../../src/app/components/problem-list/problem-list.component.html":
572 | /***/ (function(module, exports) {
573 |
574 | module.exports = "\n"
575 |
576 | /***/ }),
577 |
578 | /***/ "../../../../../src/app/components/problem-list/problem-list.component.ts":
579 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
580 |
581 | "use strict";
582 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return ProblemListComponent; });
583 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__angular_core__ = __webpack_require__("../../../core/esm5/core.js");
584 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__services_data_service__ = __webpack_require__("../../../../../src/app/services/data.service.ts");
585 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__services_input_service__ = __webpack_require__("../../../../../src/app/services/input.service.ts");
586 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
587 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
588 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
589 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
590 | return c > 3 && r && Object.defineProperty(target, key, r), r;
591 | };
592 | var __metadata = (this && this.__metadata) || function (k, v) {
593 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
594 | };
595 |
596 |
597 |
598 | var ProblemListComponent = /** @class */ (function () {
599 | function ProblemListComponent(dataService, inputService) {
600 | this.dataService = dataService;
601 | this.inputService = inputService;
602 | // for navbar
603 | this.searchTerm = '';
604 | }
605 | ProblemListComponent.prototype.ngOnInit = function () {
606 | this.getProblems();
607 | this.getSearchTerm();
608 | };
609 | ProblemListComponent.prototype.ngOnDestroy = function () {
610 | this.subcriptionProblems.unsubscribe();
611 | };
612 | ProblemListComponent.prototype.getProblems = function () {
613 | var _this = this;
614 | this.subcriptionProblems = this.dataService.getProblems()
615 | .subscribe(function (problems) {
616 | _this.problems = problems;
617 | });
618 | };
619 | ProblemListComponent.prototype.getSearchTerm = function () {
620 | var _this = this;
621 | this.subscriptionInput = this.inputService.getInput()
622 | .subscribe(function (term) { return _this.searchTerm = term; });
623 | };
624 | ProblemListComponent = __decorate([
625 | Object(__WEBPACK_IMPORTED_MODULE_0__angular_core__["n" /* Component */])({
626 | selector: 'app-problem-list',
627 | template: __webpack_require__("../../../../../src/app/components/problem-list/problem-list.component.html"),
628 | styles: [__webpack_require__("../../../../../src/app/components/problem-list/problem-list.component.css")]
629 | }),
630 | __metadata("design:paramtypes", [__WEBPACK_IMPORTED_MODULE_1__services_data_service__["a" /* DataService */],
631 | __WEBPACK_IMPORTED_MODULE_2__services_input_service__["a" /* InputService */]])
632 | ], ProblemListComponent);
633 | return ProblemListComponent;
634 | }());
635 |
636 |
637 |
638 | /***/ }),
639 |
640 | /***/ "../../../../../src/app/pipes/search.pipe.ts":
641 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
642 |
643 | "use strict";
644 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return SearchPipe; });
645 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__angular_core__ = __webpack_require__("../../../core/esm5/core.js");
646 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
647 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
648 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
649 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
650 | return c > 3 && r && Object.defineProperty(target, key, r), r;
651 | };
652 |
653 | var SearchPipe = /** @class */ (function () {
654 | function SearchPipe() {
655 | }
656 | SearchPipe.prototype.transform = function (problems, term) {
657 | // get filtered problem list
658 | return problems.filter(function (problem) { return problem.name.toLowerCase().includes(term); });
659 | };
660 | SearchPipe = __decorate([
661 | Object(__WEBPACK_IMPORTED_MODULE_0__angular_core__["T" /* Pipe */])({
662 | name: 'search'
663 | })
664 | ], SearchPipe);
665 | return SearchPipe;
666 | }());
667 |
668 |
669 |
670 | /***/ }),
671 |
672 | /***/ "../../../../../src/app/services/collaboration.service.ts":
673 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
674 |
675 | "use strict";
676 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return CollaborationService; });
677 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__angular_core__ = __webpack_require__("../../../core/esm5/core.js");
678 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_rxjs_Subject__ = __webpack_require__("../../../../rxjs/_esm5/Subject.js");
679 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
680 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
681 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
682 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
683 | return c > 3 && r && Object.defineProperty(target, key, r), r;
684 | };
685 | var __metadata = (this && this.__metadata) || function (k, v) {
686 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
687 | };
688 |
689 |
690 | var CollaborationService = /** @class */ (function () {
691 | function CollaborationService() {
692 | this._userSource = new __WEBPACK_IMPORTED_MODULE_1_rxjs_Subject__["a" /* Subject */]();
693 | }
694 | CollaborationService.prototype.init = function (editor, sessionId) {
695 | var _this = this;
696 | // send to server
697 | this.collaborationSocket = io(window.location.origin, { query: 'sessionId=' + sessionId });
698 | // //wait for 'message' event from server
699 | // this.collaborationSocket.on("message", (message) => {
700 | // console.log('message received from the server: ' + message);
701 | // })
702 | // handle the changes from server
703 | this.collaborationSocket.on('change', function (delta) {
704 | console.log('collaboration: editor changes by ' + delta);
705 | delta = JSON.parse(delta);
706 | editor.lastAppliedChange = delta;
707 | // apply the changes on editor
708 | editor.getSession().getDocument().applyDeltas([delta]);
709 | });
710 | // handle user changes
711 | this.collaborationSocket.on('userchange', function (users) {
712 | console.log('user changed: ' + users);
713 | _this._userSource.next(users.toString());
714 | });
715 | return this._userSource.asObservable();
716 | };
717 | // emit event to make changes and inform server and other collaborators
718 | CollaborationService.prototype.change = function (delta) {
719 | // emit "change" event
720 | this.collaborationSocket.emit('change', delta);
721 | };
722 | CollaborationService.prototype.restoreBuffer = function () {
723 | // let the server handle the event
724 | this.collaborationSocket.emit('restoreBuffer');
725 | };
726 | CollaborationService = __decorate([
727 | Object(__WEBPACK_IMPORTED_MODULE_0__angular_core__["A" /* Injectable */])(),
728 | __metadata("design:paramtypes", [])
729 | ], CollaborationService);
730 | return CollaborationService;
731 | }());
732 |
733 |
734 |
735 | /***/ }),
736 |
737 | /***/ "../../../../../src/app/services/data.service.ts":
738 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
739 |
740 | "use strict";
741 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return DataService; });
742 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__angular_core__ = __webpack_require__("../../../core/esm5/core.js");
743 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__angular_common_http__ = __webpack_require__("../../../common/esm5/http.js");
744 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2_rxjs_BehaviorSubject__ = __webpack_require__("../../../../rxjs/_esm5/BehaviorSubject.js");
745 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
746 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
747 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
748 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
749 | return c > 3 && r && Object.defineProperty(target, key, r), r;
750 | };
751 | var __metadata = (this && this.__metadata) || function (k, v) {
752 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
753 | };
754 |
755 |
756 |
757 |
758 | var DataService = /** @class */ (function () {
759 | function DataService(httpClient) {
760 | this.httpClient = httpClient;
761 | this._problemSource = new __WEBPACK_IMPORTED_MODULE_2_rxjs_BehaviorSubject__["a" /* BehaviorSubject */]([]);
762 | }
763 | // return a list of problems
764 | DataService.prototype.getProblems = function () {
765 | var _this = this;
766 | this.httpClient.get('api/v1/problems')
767 | .toPromise()
768 | .then(function (res) {
769 | _this._problemSource.next(res);
770 | })
771 | .catch(this.handleError);
772 | return this._problemSource.asObservable();
773 | };
774 | //use subscribe
775 | // getProblems(): Observable {
776 | // this.httpClient.get('api/v1/problems')
777 | // .subscribe((res:any) => this._problemSource.next(res));
778 | // return this._problemSource.asObservable();
779 | // }
780 | // return a problem by id
781 | DataService.prototype.getProblem = function (id) {
782 | return this.httpClient.get("api/v1/problems/" + id)
783 | .toPromise()
784 | .then(function (res) { return res; })
785 | .catch(this.handleError);
786 | };
787 | // add problem
788 | DataService.prototype.addProblem = function (problem) {
789 | var _this = this;
790 | var options = { headers: new __WEBPACK_IMPORTED_MODULE_1__angular_common_http__["c" /* HttpHeaders */]({ 'Content-Type': 'application/json' }) };
791 | return this.httpClient.post('api/v1/problems', problem, options)
792 | .toPromise()
793 | .then(function (res) {
794 | _this.getProblems();
795 | return res;
796 | })
797 | .catch(this.handleError);
798 | };
799 | // build and run: POST
800 | DataService.prototype.buildAndRun = function (data) {
801 | var options = { headers: new __WEBPACK_IMPORTED_MODULE_1__angular_common_http__["c" /* HttpHeaders */]({ 'Content-Type': 'application/json' }) };
802 | return this.httpClient.post('api/v1/build_and_run', data, options)
803 | .toPromise()
804 | .then(function (res) {
805 | console.log(res);
806 | return res;
807 | })
808 | .catch(this.handleError);
809 | };
810 | // // modify problem
811 | // editProblem(problem: Problem) {
812 | // const options = {headers: new HttpHeaders({'Content-Type': 'application/json'})};
813 | // return this.httpClient.post('api/v1/problems', problem, options)
814 | // .toPromise()
815 | // .
816 | // }
817 | // handle errors
818 | DataService.prototype.handleError = function (error) {
819 | console.error('Error reference', error);
820 | return Promise.reject(error.body || error);
821 | };
822 | DataService = __decorate([
823 | Object(__WEBPACK_IMPORTED_MODULE_0__angular_core__["A" /* Injectable */])(),
824 | __metadata("design:paramtypes", [__WEBPACK_IMPORTED_MODULE_1__angular_common_http__["a" /* HttpClient */]])
825 | ], DataService);
826 | return DataService;
827 | }());
828 |
829 |
830 |
831 | /***/ }),
832 |
833 | /***/ "../../../../../src/app/services/input.service.ts":
834 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
835 |
836 | "use strict";
837 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return InputService; });
838 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__angular_core__ = __webpack_require__("../../../core/esm5/core.js");
839 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_rxjs_BehaviorSubject__ = __webpack_require__("../../../../rxjs/_esm5/BehaviorSubject.js");
840 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
841 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
842 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
843 | else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
844 | return c > 3 && r && Object.defineProperty(target, key, r), r;
845 | };
846 | var __metadata = (this && this.__metadata) || function (k, v) {
847 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
848 | };
849 |
850 |
851 | var InputService = /** @class */ (function () {
852 | function InputService() {
853 | this.inputSubject$ = new __WEBPACK_IMPORTED_MODULE_1_rxjs_BehaviorSubject__["a" /* BehaviorSubject */]('');
854 | }
855 | InputService.prototype.changeInput = function (term) {
856 | this.inputSubject$.next(term);
857 | };
858 | InputService.prototype.getInput = function () {
859 | return this.inputSubject$.asObservable();
860 | };
861 | InputService = __decorate([
862 | Object(__WEBPACK_IMPORTED_MODULE_0__angular_core__["A" /* Injectable */])(),
863 | __metadata("design:paramtypes", [])
864 | ], InputService);
865 | return InputService;
866 | }());
867 |
868 |
869 |
870 | /***/ }),
871 |
872 | /***/ "../../../../../src/environments/environment.ts":
873 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
874 |
875 | "use strict";
876 | /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return environment; });
877 | // The file contents for the current environment will overwrite these during build.
878 | // The build system defaults to the dev environment which uses `environment.ts`, but if you do
879 | // `ng build --env=prod` then `environment.prod.ts` will be used instead.
880 | // The list of which env maps to which file can be found in `.angular-cli.json`.
881 | var environment = {
882 | production: false
883 | };
884 |
885 |
886 | /***/ }),
887 |
888 | /***/ "../../../../../src/main.ts":
889 | /***/ (function(module, __webpack_exports__, __webpack_require__) {
890 |
891 | "use strict";
892 | Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
893 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__angular_core__ = __webpack_require__("../../../core/esm5/core.js");
894 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__angular_platform_browser_dynamic__ = __webpack_require__("../../../platform-browser-dynamic/esm5/platform-browser-dynamic.js");
895 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__app_app_module__ = __webpack_require__("../../../../../src/app/app.module.ts");
896 | /* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__environments_environment__ = __webpack_require__("../../../../../src/environments/environment.ts");
897 |
898 |
899 |
900 |
901 | if (__WEBPACK_IMPORTED_MODULE_3__environments_environment__["a" /* environment */].production) {
902 | Object(__WEBPACK_IMPORTED_MODULE_0__angular_core__["_13" /* enableProdMode */])();
903 | }
904 | Object(__WEBPACK_IMPORTED_MODULE_1__angular_platform_browser_dynamic__["a" /* platformBrowserDynamic */])().bootstrapModule(__WEBPACK_IMPORTED_MODULE_2__app_app_module__["a" /* AppModule */])
905 | .catch(function (err) { return console.log(err); });
906 |
907 |
908 | /***/ }),
909 |
910 | /***/ 0:
911 | /***/ (function(module, exports, __webpack_require__) {
912 |
913 | module.exports = __webpack_require__("../../../../../src/main.ts");
914 |
915 |
916 | /***/ })
917 |
918 | },[0]);
919 | //# sourceMappingURL=main.bundle.js.map
--------------------------------------------------------------------------------