MAJOR changes to login

This commit is contained in:
Nikolaos Laskaris 2017-11-01 19:18:27 +02:00
parent 1e06430280
commit c20d2fa87a
40 changed files with 1320 additions and 88 deletions

View File

@ -23,6 +23,9 @@ export class AppComponent {
showLogin : boolean = false;
login(){
//redirect to login page
}
logout(){
this.tokenService.logout();

Binary file not shown.

View File

@ -24,8 +24,8 @@
"angular-2-data-table": "^0.1.2",
"angular-4-data-table-bootstrap-4": "^0.2.0",
"angular-google-signin": "^0.1.5",
"angular2-draggable": "^1.0.7",
"angular2-datatable": "^0.6.0",
"angular2-draggable": "^1.0.7",
"bootstrap": "^3.3.7",
"core-js": "^2.4.1",
"flat": "^4.0.0",

View File

@ -2,17 +2,26 @@ import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { PageNotFoundComponent } from './not-found.component';
import { DynamicFormComponent } from './form/dynamic-form.component';
import { LoginComponent } from './login/login-page';
import { AuthGuard } from './guards/auth.guard';
import { ProjectsComponent } from './projects/projects.component';
import { DatasetsComponent } from './datasets/dataset.component';
import { DmpComponent } from './dmps/dmp.component';
import { AppComponent } from './app.component';
import { MainSignInComponent } from './login/main-sign-in/main-sign-in.component';
const appRoutes: Routes = [
{ path: 'dynamic-form', component: DynamicFormComponent, canActivate: [AuthGuard] },
{ path: 'login-page', component: LoginComponent },
//{ path: 'projects', component: ProjectsComponent},
{ path: 'login-page', component: MainSignInComponent},
{ path: 'projects', component: ProjectsComponent},
{ path: 'dmps', component: DmpComponent},
{ path: '', redirectTo: '/login-page', pathMatch: 'full' },
{ path: '**', component: PageNotFoundComponent }
{ path: '**', component: PageNotFoundComponent },
{
path: '',
redirectTo: 'app-root',
pathMatch: 'full'
}
];
@NgModule({
@ -29,4 +38,5 @@ const appRoutes: Routes = [
]
})
export class AppRoutingModule { }
export class AppRoutingModule { }

View File

@ -13,4 +13,25 @@
.ng-invalid:not(form) {
border-left: 5px solid #a94442; /* red */
}
.navbar-center {
position: absolute;
width: 100%;
left: 0;
text-align: center;
vertical-align: middle;
margin:0 auto;
}
.invisible {
display:none;
}
.visible {
display:block;
}
.cursor{
cursor: pointer;
}

View File

@ -0,0 +1,56 @@
<div>
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<div class="nav navbar-nav">
</div>
<div class="navbar-left">
</div>
<div class="navbar-center">
<h3>Digital Management Plans</h3>
</div>
<ul class="nav navbar-nav navbar-right">
<li class="dropdown" [ngClass]="{true:'invisible'}[loggedInAs == null]">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Quick links <span class="caret"></span></a>
<ul class="dropdown-menu">
<li><a href="#">Action</a></li>
<li><a href="#">Another action</a></li>
<li><a href="#">Something else here</a></li>
<li role="separator" class="divider"></li>
<li><a href="#">Separated link</a></li>
</ul>
</li>
<li [ngClass]="{false:'invisible'}[tokenService.isLoggedIn() == true]"><a>{{tokenService.getEmail()}}</a></li>
<li class="cursor" [ngClass]="{false:'invisible'}[tokenService.isLoggedIn() == true]" (click)="logout()"><a>Logout</a></li>
<li class="cursor" [ngClass]="{true:'invisible'}[tokenService.isLoggedIn() == true]" (click)="login()" ><a>Login</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
<!--
-->
<router-outlet ></router-outlet>
<!--
<main-window [ngClass]="{false:'invisible'}[tokenService.isLoggedIn() == true]"></main-window>
-->
<!--
<app-main-sign-in [ngClass]="{true:'invisible'}[tokenService.isLoggedIn() == true]"></app-main-sign-in>
-->
<!--
<router-outlet></router-outlet>
-->
</div>

View File

@ -2,24 +2,41 @@ import { Component } from '@angular/core';
import { ServerService } from './services/server.service';
import { FieldBase } from '../app/form/fields/field-base';
import { JsonObjest } from '../app/entities/JsonObject.class';
import { TokenService, TokenProvider } from './services/login/token.service';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { MainSignInComponent } from './login/main-sign-in/main-sign-in.component';
@Component({
selector: 'app-root',
template: `
<router-outlet></router-outlet>
`,
// template: `
// <div>
// <login-page></login-page>
// </div>
// `,
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
providers: []
})
export class AppComponent {
fields: any[];
constructor(private tokenService : TokenService, private router: Router) {
}
//loggedInAs : string = null;
showLogin : boolean = false;
login(){
//redirect to login page
this.router.navigate(['/login-page'], { queryParams: { /*returnUrl: this.state.url*/ }});
}
logout(){
this.tokenService.logout();
this.router.navigate(['/login-page'], { queryParams: { /*returnUrl: this.state.url*/ }});
}
}
//<dynamic-form></dynamic-form>

View File

@ -14,12 +14,11 @@ import { RestBase } from './services/rest-base';
import { DynamicFormComponent } from './form/dynamic-form.component';
import { DynamicFormFieldComponent } from './form/fields/dynamic-form-field.component';
import { ServerService } from './services/server.service';
import { TokenService, TokenProvider } from './services/token.service';
import { TokenService, TokenProvider } from './services/login/token.service';
import { LocalStorageService } from 'ngx-webstorage';
import { dataModelBuilder } from './services/dataModelBuilder.service';
import { DynamicFormGroupComponent } from './form/dynamic-form-group/dynamic-form-group.component';
import { LoginComponent } from './login/login-page';
import {GoogleSignInComponent} from 'angular-google-signin';
//import { LoginComponent } from './login/login-page';
import { AppRoutingModule } from './app-routing.module';
import { AuthGuard } from './guards/auth.guard';
import { PageNotFoundComponent } from './not-found.component';
@ -33,6 +32,10 @@ import { DmpModule } from './dmps/dmp.module';
import { TabModule } from './tabs/tab.module';
import { AngularDraggableModule } from 'angular2-draggable';
import { NativeLoginService } from './services/login/native-login.service';
import { GooggleSignInComponent } from './login/googgle-sign-in/googgle-sign-in.component';
import { MainSignInComponent } from './login/main-sign-in/main-sign-in.component';
import { HTTP_INTERCEPTORS } from '@angular/common/http';
@ -43,8 +46,9 @@ import { HTTP_INTERCEPTORS } from '@angular/common/http';
DynamicFormFieldComponent,
DynamicFormGroupComponent,
TocComponent,
LoginComponent,
GoogleSignInComponent,
//LoginComponent,
GooggleSignInComponent,
MainSignInComponent,
PageNotFoundComponent
],
imports: [
@ -67,7 +71,8 @@ import { HTTP_INTERCEPTORS } from '@angular/common/http';
useClass: GlobalInterceptor,
multi: true,
},
ServerService, dataModelBuilder, AuthGuard, PaginationService, TokenService, LocalStorageService, RestBase, EestoreService
ServerService, dataModelBuilder, AuthGuard, PaginationService, TokenService, LocalStorageService, RestBase, EestoreService,NativeLoginService
],
bootstrap: [AppComponent]
})

View File

@ -11,7 +11,7 @@ import { dataModelBuilder } from '../../app/services/dataModelBuilder.service';
import { DataModel } from '../entities/DataModel';
import { GroupBase } from './dynamic-form-group/group-base';
import { PaginationService } from '../../app/services/pagination.service';
import { TokenService, TokenProvider } from '../services/token.service';
import { TokenService, TokenProvider } from '../services/login/token.service';
import { AngularDraggableModule } from 'angular2-draggable';

View File

@ -1,6 +1,6 @@
import { Injectable } from '@angular/core';
import { Router, CanActivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
import { TokenService, TokenProvider } from '../services/token.service';
import { TokenService, TokenProvider } from '../services/login/token.service';
@Injectable()
export class AuthGuard implements CanActivate {
@ -8,14 +8,13 @@ export class AuthGuard implements CanActivate {
constructor(private router: Router, private tokenService: TokenService) { }
canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {
//if (localStorage.getItem('currentUser')) { it always returns true
if(this.tokenService.getToken()!=null){
// logged in so return true
return true;
}
if(this.tokenService.isLoggedIn() == true){
return true;
}
// not logged in so redirect to login page with the return url
this.router.navigate(['/login-page'], { queryParams: { returnUrl: state.url }});
return false;
}
}
}

View File

@ -1,7 +1,7 @@
import { Component, OnInit, NgZone, AfterViewInit, ElementRef } from '@angular/core';
import { GoogleSignInSuccess } from 'angular-google-signin';
import { Router, ActivatedRoute } from '@angular/router';
import { TokenService, TokenProvider } from '../services/token.service';
import { TokenService, TokenProvider } from '../services/login/token.service';
@Component({
selector: 'login-page',

View File

@ -0,0 +1,11 @@
.nomargin{
margin-top: 0px;
margin-bottom: 0px;
margin-left: 0px;
margin-right: 0px;
}
.width-range {
max-width: 500px;
min-width: 300px;
}

View File

@ -0,0 +1,12 @@
<table class="table">
<tbody>
<tr align="center">
<div class="g-signin2" id="googleBtn"></div>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { GooggleSignInComponent } from './googgle-sign-in.component';
describe('GooggleSignInComponent', () => {
let component: GooggleSignInComponent;
let fixture: ComponentFixture<GooggleSignInComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ GooggleSignInComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(GooggleSignInComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,86 @@
import { Component, OnInit, ElementRef, AfterViewInit, VERSION } from '@angular/core';
import { TokenService, TokenProvider } from '../../services/login/token.service';
import {Router} from '@angular/router';
declare const gapi: any;
var $ = require("jquery");
import '../../../assets/custom.js';
declare function simple_notifier(type: string, title: string, message:string): any;
@Component({
selector: 'googgle-sign-in',
templateUrl: './googgle-sign-in.component.html',
styleUrls: ['./googgle-sign-in.component.css']
})
export class GooggleSignInComponent implements OnInit, AfterViewInit {
//token:any;
constructor(private element: ElementRef, private tokenService : TokenService, private router : Router) {
}
ngOnInit() {
}
private clientId:string = '1010962018903-glegmqudqtl1lub0150vacopbu06lgsg.apps.googleusercontent.com';
private scope = [
'profile',
'email'
//,
//'https://www.googleapis.com/auth/plus.me',
//'https://www.googleapis.com/auth/contacts.readonly',
//'https://www.googleapis.com/auth/admin.directory.user.readonly'
].join(' ');
public auth2: any;
public googleInit() {
gapi.load('auth2', () => {
this.auth2 = gapi.auth2.init({
client_id: this.clientId,
cookiepolicy: 'single_host_origin',
scope: this.scope
});
var buttonElement = this.element.nativeElement.querySelector('#googleBtn');
this.attachSignin(buttonElement);
});
}
public attachSignin(element) {
this.auth2.attachClickHandler(element, {},
(googleUser) => {
//simple_notifier("success",null,"Successful login");
let profile = googleUser.getBasicProfile();
this.tokenService.login(googleUser.getAuthResponse().id_token, TokenProvider.google, profile.getName(), profile.getEmail());
this.router.navigate(['/dmps'], { queryParams: { /*returnUrl: this.state.url*/ }});
},
function (error) {
simple_notifier("danger",null,"Failed to login");
console.log(JSON.stringify(error, undefined, 2));
});
}
ngAfterViewInit() {
this.googleInit();
}
/*
signOut() {
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
console.log('User signed out.');
});
}
*/
}

View File

@ -0,0 +1,75 @@
.form-signin
{
max-width: 330px;
padding: 15px;
margin: 0 auto;
}
.form-signin .form-signin-heading, .form-signin .checkbox
{
margin-bottom: 10px;
}
.form-signin .checkbox
{
font-weight: normal;
}
.form-signin .form-control
{
position: relative;
font-size: 16px;
height: auto;
padding: 10px;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
.form-signin .form-control:focus
{
z-index: 2;
}
.form-signin input[type="text"]
{
margin-bottom: -1px;
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
.form-signin input[type="password"]
{
margin-bottom: 10px;
border-top-left-radius: 0;
border-top-right-radius: 0;
}
.account-wall
{
margin-top: 20px;
padding: 40px 0px 20px 0px;
background-color: #f7f7f7;
-moz-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
-webkit-box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
box-shadow: 0px 2px 2px rgba(0, 0, 0, 0.3);
}
.login-title
{
color: #555;
font-size: 18px;
font-weight: 400;
display: block;
}
.profile-img
{
width: 96px;
height: 96px;
margin: 0 auto 10px;
display: block;
-moz-border-radius: 50%;
-webkit-border-radius: 50%;
border-radius: 50%;
}
.need-help
{
margin-top: 10px;
}
.new-account
{
display: block;
margin-top: 10px;
}

View File

@ -0,0 +1,43 @@
<div class="container">
<div class="row">
<div class="col-sm-6 col-md-4 col-md-offset-4">
<h1 class="text-center login-title"></h1>
<div class="account-wall">
<img class="profile-img" src="/assets/icons/user-icon.png">
<form class="form-signin" [formGroup]="nativeLoginForm">
<input type="text" class="form-control" [(ngModel)]="creds.username" formControlName="username" placeholder="Username or Email" required autofocus>
<input type="password" class="form-control" [(ngModel)]="creds.password" formControlName="password" placeholder="Password" required>
<button class="btn btn-lg btn-primary btn-block" type="submit" (click)="login()">
Sign in
</button>
<label class="checkbox pull-left">
<input type="checkbox" value="remember-me">
Remember me
</label>
<a href="#" class="pull-right need-help">Need help? </a><span class="clearfix"></span>
</form>
<!--
<p>Form value: {{ nativeLoginForm.value | json }}</p>
-->
<a href="#" class="text-center new-account">Create an account </a>
</div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-sm-6 col-md-4 col-md-offset-4">
<div class="account-wall">
<h1 class="text-center login-title"></h1>
<h4 class="text-center">Sign in with social</h4>
<googgle-sign-in></googgle-sign-in>
</div>
</div>
</div>
</div>

View File

@ -0,0 +1,25 @@
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
import { MainSignInComponent } from './main-sign-in.component';
describe('MainSignInComponent', () => {
let component: MainSignInComponent;
let fixture: ComponentFixture<MainSignInComponent>;
beforeEach(async(() => {
TestBed.configureTestingModule({
declarations: [ MainSignInComponent ]
})
.compileComponents();
}));
beforeEach(() => {
fixture = TestBed.createComponent(MainSignInComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should be created', () => {
expect(component).toBeTruthy();
});
});

View File

@ -0,0 +1,61 @@
import { Component, OnInit } from '@angular/core';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { NativeLoginService } from '../../services/login/native-login.service';
import { TokenService, TokenProvider } from '../../services/login/token.service';
import {Router} from '@angular/router';
import '../../../assets/custom.js';
declare function simple_notifier(type: string, title: string, message:string): any;
@Component({
selector: 'app-main-sign-in',
templateUrl: './main-sign-in.component.html',
styleUrls: ['./main-sign-in.component.css']
})
export class MainSignInComponent implements OnInit {
nativeLoginForm : any;
creds : any = {"username":"","password":""};
constructor( private fb: FormBuilder, private nativeLogin : NativeLoginService, private tokenService : TokenService, private router : Router) {
}
createProjectEditorForm(){
this.nativeLoginForm = this.fb.group({
username: ['', Validators.required ],
password: ['', Validators.required ]
});
}
ngOnInit() {
this.createProjectEditorForm();
}
login(){
//login using the credentials
this.nativeLogin.login(this.creds.username, this.creds.password).subscribe(
response => {
simple_notifier("success",null,"Successful login");
this.tokenService.login(response['token'], TokenProvider.native, this.creds.username, response['email']);
this.router.navigate(['/dmps'], { queryParams: { /*returnUrl: this.state.url*/ }});
},
err => {
simple_notifier("danger",null,"Failed to login");
}
);
}
}

View File

@ -13,7 +13,6 @@ import { ModalComponent } from '../modal/modal.component';
import { HttpErrorResponse } from '@angular/common/http';
import { FormGroup, FormControl } from '@angular/forms'; //na dw an xreiazontai
import { NgForm } from '@angular/forms';
import { TokenService, TokenProvider } from '../services/token.service';
declare var $ :any;
@ -67,7 +66,7 @@ export class ProjectsComponent implements OnInit{
constructor(
private serverService: ServerService,
private route: ActivatedRoute,
private router: Router, private tokenService: TokenService){
private router: Router){
this.datasetDropDown = new DropdownField();
this.datasetDropDown.options = [];
this.datasets = [];

View File

@ -1,15 +1,13 @@
import {Injectable} from '@angular/core';
import {Observable} from 'rxjs/Observable';
import {HttpEvent, HttpInterceptor, HttpHandler, HttpRequest, HttpResponse, HttpErrorResponse} from '@angular/common/http';
import { TokenService, TokenProvider } from './token.service';
import { TokenService, TokenProvider } from './login/token.service';
@Injectable()
export class GlobalInterceptor implements HttpInterceptor {
constructor(private tokenService: TokenService) {
}
constructor(public tokenService: TokenService) {}
intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
@ -20,19 +18,14 @@ export class GlobalInterceptor implements HttpInterceptor {
}
*/
}, (err: any) => {
if (err instanceof HttpErrorResponse) {debugger;
if (err instanceof HttpErrorResponse) {
if (err.status === 401) {
var auth2 = gapi.auth2.getAuthInstance();
    auth2.signOut().then(function () {
      console.log('User signed out.');
localStorage.removeItem('currentUser');
this.router.navigate(['/login-page']);
    });
this.tokenService.setToken(null);
//EDW VALE TO KWDIKA GIA TO LOGOUT KAI SXOLIASE TON OPOU ALLOU TON EXEIS
this.tokenService.logout();
}
}
});
//return next.handle(req);
}
}

View File

@ -0,0 +1,31 @@
import { Injectable, OnInit } from '@angular/core';
import { Observable } from 'rxjs';
import { TokenService, TokenProvider } from '../login/token.service'
import { HttpClient , HttpHeaders, HttpParams} from '@angular/common/http';
import {RestBase} from '../rest-base';
@Injectable()
export class NativeLoginService implements OnInit {
constructor(private restBase: RestBase) {
}
ngOnInit(){
}
login(username, password){
var credentials = {"username": username, "password":password};
return this.restBase.login("nativeLogin", credentials);
}
}

View File

@ -4,12 +4,15 @@ import {LocalStorageService} from 'ngx-webstorage';
import 'rxjs/add/operator/map';
import { DOCUMENT } from '@angular/platform-browser';
declare var jQuery : any;
import '../../../assets/custom.js';
declare function sign_out_google(): any;
@Injectable()
export class TokenService {
constructor (private storage : LocalStorageService, @Inject(DOCUMENT) private document) {
//var csrfToken : string = jQuery(document).find('meta[name="csrf-token"]').attr('content');
//this.setCSRFToken(csrfToken);
@ -66,12 +69,37 @@ export class TokenService {
}
login(token: string, provider: TokenProvider, username: string, email: string){
this.setLoggedIn(true);
this.setToken(token);
this.setProvider(provider);
this.setUsername(username);
this.setEmail(email);
window.location.reload();
}
logout(){
//set the log out actions here
this.setLoggedIn(false);
this.setEmail(null);
this.setUsername(null);
this.setToken(null);
if(this.getProvider() == TokenProvider.google){
sign_out_google();
}
this.setProvider(null);
}
}
export enum TokenProvider {
native,
google
}

View File

@ -1,5 +1,5 @@
import { HttpClient , HttpHeaders, HttpParams } from '@angular/common/http';
import { TokenService, TokenProvider } from './token.service'
import { TokenService, TokenProvider } from './login/token.service'
import 'rxjs/Rx';

View File

@ -6,8 +6,8 @@ import {dataModelBuilder} from '../../app/services/dataModelBuilder.service';
import { DatasetProfile } from '../entities/datasetprofile';
import {DataModel} from '../entities/DataModel';
import {Project} from '../entities/model/project';
import {LoginComponent} from '../../app/login/login-page';
import { TokenService, TokenProvider } from './token.service';
//import {LoginComponent} from '../../app/login/login-page';
import { TokenService, TokenProvider } from './login/token.service';
import {RestBase} from './rest-base';
import 'rxjs/Rx';
@ -130,14 +130,8 @@ public updateDatsetsProfile(data:any){
logOut() {
    var auth2 = gapi.auth2.getAuthInstance();
    auth2.signOut().then(function () {
      console.log('User signed out.');
localStorage.removeItem('currentUser');
    });
this.tokenService.setToken(null); //kanonika prepei na mpei mesa sthn function.....
  }
this.tokenService.logout();
}
getData() {

File diff suppressed because one or more lines are too long

View File

View File

@ -0,0 +1,38 @@
var sign_out_google = (function() {
var auth2 = gapi.auth2.getAuthInstance();
auth2.signOut().then(function () {
console.log('User signed out from google.');
});
});
var simple_notifier = (function(type, title, message) {
return notify(type, title, message, null, null, null, null, null, null, null, null, null, null);
});
function notify(type, title, message, delay, icon, url, target, allow_dismiss, offset_x, offset_y, animate_enter, animate_exit, newest_on_top){
var options = {};
if(icon!=null) options.icon = icon;
if(title!=null) options.title = title;
if(message!=null) options.message = message;
if(url!=null) options.url = url;
if(target!=null) options.target = target;
var settings = {};
if(type!=null) settings.type = type;
if(allow_dismiss!=null) settings.allow_dismiss = allow_dismiss;
if(delay!=null) settings.delay = delay;
//settings.delay = -1;
return $.notify(options,settings, delay);
}

View File

@ -0,0 +1 @@
<svg width="2443" height="2500" viewBox="0 0 256 262" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMidYMid"><path d="M255.878 133.451c0-10.734-.871-18.567-2.756-26.69H130.55v48.448h71.947c-1.45 12.04-9.283 30.172-26.69 42.356l-.244 1.622 38.755 30.023 2.685.268c24.659-22.774 38.875-56.282 38.875-96.027" fill="#4285F4"/><path d="M130.55 261.1c35.248 0 64.839-11.605 86.453-31.622l-41.196-31.913c-11.024 7.688-25.82 13.055-45.257 13.055-34.523 0-63.824-22.773-74.269-54.25l-1.531.13-40.298 31.187-.527 1.465C35.393 231.798 79.49 261.1 130.55 261.1" fill="#34A853"/><path d="M56.281 156.37c-2.756-8.123-4.351-16.827-4.351-25.82 0-8.994 1.595-17.697 4.206-25.82l-.073-1.73L15.26 71.312l-1.335.635C5.077 89.644 0 109.517 0 130.55s5.077 40.905 13.925 58.602l42.356-32.782" fill="#FBBC05"/><path d="M130.55 50.479c24.514 0 41.05 10.589 50.479 19.438l36.844-35.974C195.245 12.91 165.798 0 130.55 0 79.49 0 35.393 29.301 13.925 71.947l42.211 32.783c10.59-31.477 39.891-54.251 74.414-54.251" fill="#EB4335"/></svg>

After

Width:  |  Height:  |  Size: 1018 B

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="2500" height="857" viewBox="0.512 0.511 748.99 256.61"><g transform="translate(4636.413 -2865.209)"><linearGradient id="a" gradientUnits="userSpaceOnUse" x1="-11445.563" y1="603.918" x2="-11445.563" y2="465.768" gradientTransform="matrix(1.3509 0 0 -1.3509 10917.478 3681.026)"><stop offset="0" stop-color="#196eef"/><stop offset=".5" stop-color="#186dee"/><stop offset="1" stop-color="#1065e7"/></linearGradient><path d="M-4520.08 2990.41h32.21v45.24c-10.05 3.229-22.74 5-35.931 5-53.46 0-84.88-45.78-84.88-90.49 0-43.851 28.42-74.61 68.07-74.61 25.09 0 39.689 8.5 52.75 20.34v14.76l24.49-24.49c-15.49-10.48-37.92-20.44-69.98-20.44-70.38 0-102.55 50.351-102.55 91.73 0 58.899 42.9 94.38 96.811 94.38 26.14 0 49.35-3.99 76.16-11.45v-46.74c0-2.39 1.05-4.03 2.62-5.47l8.46-8.46h-57.45l-10.78 10.7z" fill="url(#a)"/><linearGradient id="b" gradientUnits="userSpaceOnUse" x1="-11323.519" y1="556.948" x2="-11323.519" y2="467.618" gradientTransform="matrix(1.3509 0 0 -1.3509 10917.478 3681.026)"><stop offset="0" stop-color="#de5744"/><stop offset=".5" stop-color="#db4632"/><stop offset="1" stop-color="#d13d29"/></linearGradient><path d="M-4375.79 2928.93c-40.51 0-65.61 29.601-65.61 61.021 0 27.12 20.221 59.319 61.19 59.319 39.41 0 63.59-29.659 63.59-61.629 0-29.78-23.63-58.7-59.17-58.7v-.011zm-6.721 8.63c28.561 0 41.28 37.21 41.28 63.75 0 39.47-29.61 40.25-33.15 40.25-13.55 0-23.02-8.189-30.109-18.93-6.24-9.899-12.34-28.29-12.34-46.26 0-17.9 5.859-26.64 15.08-33.07 7.54-4.82 14.6-5.74 19.229-5.74h.01z" fill="url(#b)"/><linearGradient id="c" gradientUnits="userSpaceOnUse" x1="-11130.575" y1="556.948" x2="-11130.575" y2="413.518" gradientTransform="matrix(1.3509 0 0 -1.3509 10917.478 3681.026)"><stop offset="0" stop-color="#1a6fef"/><stop offset=".25" stop-color="#1e72ef"/><stop offset=".5" stop-color="#166bec"/><stop offset=".75" stop-color="#1267e9"/><stop offset="1" stop-color="#1063e5" stop-opacity=".87"/></linearGradient><path d="M-4110.979 2928.92c-35.381 0-54.521 22.4-54.521 47.41 0 19.04 13.64 40.52 41.78 40.52h7.119s-1.939 4.71-1.949 9.26c0 6.711 2.41 10.48 7.529 16.28-48.42 2.95-67.88 22.48-67.88 43.47 0 18.381 17.601 36.471 54.59 36.471 43.79 0 66.47-24.311 66.47-48.17 0-16.82-8.38-26.04-29.6-41.94-6.24-4.85-7.45-7.939-7.45-11.569 0-5.2 3.11-8.641 4.25-9.94 2.01-2.12 5.49-4.54 6.79-5.7 7.13-6.04 17.2-14.979 17.2-32.82 0-12.24-5.091-22.77-16.69-32.63h14.16l10.64-10.64h-52.438zm-9.76 7.96c6.42 0 11.779 2.27 17.439 6.98 6.279 5.66 16.311 20.87 16.311 39.69 0 20.31-15.78 25.87-24.32 25.87-4.18 0-9.189-1.17-13.43-4.07-9.42-6.109-18.771-22.37-18.771-41.72 0-17.46 10.4-26.75 22.771-26.75zm14.01 113.22c2.699 0 4.64.221 4.64.221s6.37 4.55 10.82 7.949c10.36 8.19 16.819 14.45 16.819 25.601 0 15.33-14.22 27.35-37.25 27.35-25.279 0-44.6-11.77-44.6-30.989 0-15.921 13.24-29.623 49.571-30.132z" fill="url(#c)"/><linearGradient id="d" gradientUnits="userSpaceOnUse" x1="-11061.771" y1="601.408" x2="-11061.771" y2="470.128" gradientTransform="matrix(1.3509 0 0 -1.3509 10917.478 3681.026)"><stop offset="0" stop-color="#0aa561"/><stop offset=".5" stop-color="#009b58"/><stop offset="1" stop-color="#00914b"/></linearGradient><path d="M-4050.88 3045.76h48.57l7.399-7.399-13.93-1.74c-3.75-.46-5.979-3.7-5.979-6.84v-146.71c0-2.89 1.34-4.37 2.319-5.311l8.761-8.76h-41.42l-10.78 10.78h16.1v151.97c0 2.16-.68 3.63-2.14 5.14l-8.9 8.87z" fill="url(#d)"/><linearGradient id="e" gradientUnits="userSpaceOnUse" x1="-10998.289" y1="556.948" x2="-10998.289" y2="467.864" gradientTransform="matrix(1.3509 0 0 -1.3509 10917.478 3681.026)"><stop offset="0" stop-color="#de5644"/><stop offset=".5" stop-color="#da4531"/><stop offset="1" stop-color="#ce3a28"/></linearGradient><path d="M-3936.5 2928.93c-27.12 0-55.93 20.67-55.93 57.78 0 30.649 20.67 62.56 59.29 62.56 9.63 0 17.56-1.239 24.99-4.649 7.97-3.67 15.64-9.63 21.239-17.12-10.569 5.33-19.189 8.83-30.64 8.83-21.76 0-42.74-15.7-50.08-44.56l76.87-31.07c-4.44-15.83-16.96-31.771-45.729-31.771h-.01zm-5.021 8.49c14.551 0 25.07 11.97 25.07 21.34 0 3.03-1.899 4.63-5.66 6.11l-47.25 19.11s-1.279-5.95-1.279-12.38c0-26.97 19.5-34.18 29.119-34.18z" fill="url(#e)"/><linearGradient id="f" gradientUnits="userSpaceOnUse" x1="-11221.762" y1="556.754" x2="-11221.762" y2="467.795" gradientTransform="matrix(1.3509 0 0 -1.3509 10917.478 3681.026)"><stop offset="0" stop-color="#ffc01a"/><stop offset=".5" stop-color="#ffba03"/><stop offset="1" stop-color="#ffb300"/></linearGradient><path d="M-4238.33 2928.93c-40.51 0-65.61 29.601-65.61 61.021 0 27.12 20.221 59.319 61.19 59.319 39.41 0 63.59-29.659 63.59-61.629 0-29.78-23.63-58.7-59.17-58.7v-.011zm-6.721 8.63c28.561 0 41.28 37.21 41.28 63.75 0 39.47-29.61 40.25-33.15 40.25-13.55 0-23.02-8.189-30.109-18.93-6.24-9.899-12.34-28.29-12.34-46.26 0-17.9 5.859-26.64 15.08-33.07 7.54-4.82 14.6-5.74 19.229-5.74h.01z" fill="url(#f)"/></g></svg>

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

View File

@ -0,0 +1,3 @@
<svg class="lds-gears" width="80px" height="80px" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 100 100" preserveAspectRatio="xMidYMid"><g transform="translate(50 50)"> <g transform="translate(-19 -19) scale(0.6)"> <g transform="rotate(90)">
<animateTransform attributeName="transform" type="rotate" values="0;360" keyTimes="0;1" dur="2s" begin="0s" repeatCount="indefinite"></animateTransform><path d="M37.3496987939662 -7 L47.3496987939662 -7 L47.3496987939662 7 L37.3496987939662 7 A38 38 0 0 1 31.359972760794346 21.46047782418268 L31.359972760794346 21.46047782418268 L38.431040572659825 28.531545636048154 L28.531545636048154 38.431040572659825 L21.46047782418268 31.359972760794346 A38 38 0 0 1 7.0000000000000036 37.3496987939662 L7.0000000000000036 37.3496987939662 L7.000000000000004 47.3496987939662 L-6.999999999999999 47.3496987939662 L-7 37.3496987939662 A38 38 0 0 1 -21.46047782418268 31.35997276079435 L-21.46047782418268 31.35997276079435 L-28.531545636048154 38.431040572659825 L-38.43104057265982 28.531545636048158 L-31.359972760794346 21.460477824182682 A38 38 0 0 1 -37.3496987939662 7.000000000000007 L-37.3496987939662 7.000000000000007 L-47.3496987939662 7.000000000000008 L-47.3496987939662 -6.9999999999999964 L-37.3496987939662 -6.999999999999997 A38 38 0 0 1 -31.35997276079435 -21.460477824182675 L-31.35997276079435 -21.460477824182675 L-38.431040572659825 -28.531545636048147 L-28.53154563604818 -38.4310405726598 L-21.4604778241827 -31.35997276079433 A38 38 0 0 1 -6.999999999999992 -37.3496987939662 L-6.999999999999992 -37.3496987939662 L-6.999999999999994 -47.3496987939662 L6.999999999999977 -47.3496987939662 L6.999999999999979 -37.3496987939662 A38 38 0 0 1 21.460477824182686 -31.359972760794342 L21.460477824182686 -31.359972760794342 L28.531545636048158 -38.43104057265982 L38.4310405726598 -28.53154563604818 L31.35997276079433 -21.4604778241827 A38 38 0 0 1 37.3496987939662 -6.999999999999995 M0 -23A23 23 0 1 0 0 23 A23 23 0 1 0 0 -23" fill="#9b8b69"></path></g></g> <g transform="translate(19 19) scale(0.6)"> <g transform="rotate(247.5)">
<animateTransform attributeName="transform" type="rotate" values="360;0" keyTimes="0;1" dur="2s" begin="-0.125s" repeatCount="indefinite"></animateTransform><path d="M37.3496987939662 -7 L47.3496987939662 -7 L47.3496987939662 7 L37.3496987939662 7 A38 38 0 0 1 31.359972760794346 21.46047782418268 L31.359972760794346 21.46047782418268 L38.431040572659825 28.531545636048154 L28.531545636048154 38.431040572659825 L21.46047782418268 31.359972760794346 A38 38 0 0 1 7.0000000000000036 37.3496987939662 L7.0000000000000036 37.3496987939662 L7.000000000000004 47.3496987939662 L-6.999999999999999 47.3496987939662 L-7 37.3496987939662 A38 38 0 0 1 -21.46047782418268 31.35997276079435 L-21.46047782418268 31.35997276079435 L-28.531545636048154 38.431040572659825 L-38.43104057265982 28.531545636048158 L-31.359972760794346 21.460477824182682 A38 38 0 0 1 -37.3496987939662 7.000000000000007 L-37.3496987939662 7.000000000000007 L-47.3496987939662 7.000000000000008 L-47.3496987939662 -6.9999999999999964 L-37.3496987939662 -6.999999999999997 A38 38 0 0 1 -31.35997276079435 -21.460477824182675 L-31.35997276079435 -21.460477824182675 L-38.431040572659825 -28.531545636048147 L-28.53154563604818 -38.4310405726598 L-21.4604778241827 -31.35997276079433 A38 38 0 0 1 -6.999999999999992 -37.3496987939662 L-6.999999999999992 -37.3496987939662 L-6.999999999999994 -47.3496987939662 L6.999999999999977 -47.3496987939662 L6.999999999999979 -37.3496987939662 A38 38 0 0 1 21.460477824182686 -31.359972760794342 L21.460477824182686 -31.359972760794342 L28.531545636048158 -38.43104057265982 L38.4310405726598 -28.53154563604818 L31.35997276079433 -21.4604778241827 A38 38 0 0 1 37.3496987939662 -6.999999999999995 M0 -23A23 23 0 1 0 0 23 A23 23 0 1 0 0 -23" fill="#a1a6a8"></path></g></g></g></svg>

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

View File

@ -0,0 +1,47 @@
/* Syntax highlighting for JSON objects */
ul.json-dict, ol.json-array {
list-style-type: none;
margin: 0 0 0 1px;
border-left: 1px dotted #ccc;
padding-left: 2em;
}
.json-string {
color: #0B7500;
}
.json-literal {
color: #1A01CC;
font-weight: bold;
}
/* Toggle button */
a.json-toggle {
position: relative;
color: inherit;
text-decoration: none;
}
a.json-toggle:focus {
outline: none;
}
a.json-toggle:before {
color: #aaa;
content: "\25BC"; /* down arrow */
position: absolute;
display: inline-block;
width: 1em;
left: -1em;
}
a.json-toggle.collapsed:before {
transform: rotate(-90deg); /* Use rotated down arrow, prevents right arrow appearing smaller than down arrow in some browsers */
-ms-transform: rotate(-90deg);
-webkit-transform: rotate(-90deg);
}
/* Collapsable placeholder links */
a.json-placeholder {
color: #aaa;
padding: 0 1em;
text-decoration: none;
}
a.json-placeholder:hover {
text-decoration: underline;
}

View File

@ -0,0 +1,148 @@
/**
* jQuery json-viewer
* @author: Alexandre Bodelot <alexandre.bodelot@gmail.com>
*/
(function($){
/**
* Check if arg is either an array with at least 1 element, or a dict with at least 1 key
* @return boolean
*/
function isCollapsable(arg) {
return arg instanceof Object && Object.keys(arg).length > 0;
}
/**
* Check if a string represents a valid url
* @return boolean
*/
function isUrl(string) {
var regexp = /^(ftp|http|https):\/\/(\w+:{0,1}\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;
return regexp.test(string);
}
/**
* Transform a json object into html representation
* @return string
*/
function json2html(json, options) {
var html = '';
if (typeof json === 'string') {
/* Escape tags */
json = json.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
if (isUrl(json))
html += '<a href="' + json + '" class="json-string">' + json + '</a>';
else
html += '<span class="json-string">"' + json + '"</span>';
}
else if (typeof json === 'number') {
html += '<span class="json-literal">' + json + '</span>';
}
else if (typeof json === 'boolean') {
html += '<span class="json-literal">' + json + '</span>';
}
else if (json === null) {
html += '<span class="json-literal">null</span>';
}
else if (json instanceof Array) {
if (json.length > 0) {
html += '[<ol class="json-array">';
for (var i = 0; i < json.length; ++i) {
html += '<li>';
/* Add toggle button if item is collapsable */
if (isCollapsable(json[i])) {
html += '<a href class="json-toggle"></a>';
}
html += json2html(json[i], options);
/* Add comma if item is not last */
if (i < json.length - 1) {
html += ',';
}
html += '</li>';
}
html += '</ol>]';
}
else {
html += '[]';
}
}
else if (typeof json === 'object') {
var key_count = Object.keys(json).length;
if (key_count > 0) {
html += '{<ul class="json-dict">';
for (var key in json) {
if (json.hasOwnProperty(key)) {
html += '<li>';
var keyRepr = options.withQuotes ?
'<span class="json-string">"' + key + '"</span>' : key;
/* Add toggle button if item is collapsable */
if (isCollapsable(json[key])) {
html += '<a href class="json-toggle">' + keyRepr + '</a>';
}
else {
html += keyRepr;
}
html += ': ' + json2html(json[key], options);
/* Add comma if item is not last */
if (--key_count > 0)
html += ',';
html += '</li>';
}
}
html += '</ul>}';
}
else {
html += '{}';
}
}
return html;
}
/**
* jQuery plugin method
* @param json: a javascript object
* @param options: an optional options hash
*/
$.fn.jsonViewer = function(json, options) {
options = options || {};
/* jQuery chaining */
return this.each(function() {
/* Transform to HTML */
var html = json2html(json, options);
if (isCollapsable(json))
html = '<a href class="json-toggle"></a>' + html;
/* Insert HTML in target DOM element */
$(this).html(html);
/* Bind click on toggle buttons */
$(this).off('click');
$(this).on('click', 'a.json-toggle', function() {
var target = $(this).toggleClass('collapsed').siblings('ul.json-dict, ol.json-array');
target.toggle();
if (target.is(':visible')) {
target.siblings('.json-placeholder').remove();
}
else {
var count = target.children('li').length;
var placeholder = count + (count > 1 ? ' items' : ' item');
target.after('<a href class="json-placeholder">' + placeholder + '</a>');
}
return false;
});
/* Simulate click on toggle button when placeholder is clicked */
$(this).on('click', 'a.json-placeholder', function() {
$(this).siblings('a.json-toggle').click();
return false;
});
if (options.collapsed == true) {
/* Trigger click to collapse all nodes */
$(this).find('a.json-toggle').click();
}
});
};
})(jQuery);

View File

@ -0,0 +1,122 @@
/*!
* Start Bootstrap - Simple Sidebar (https://startbootstrap.com/template-overviews/simple-sidebar)
* Copyright 2013-2017 Start Bootstrap
* Licensed under MIT (https://github.com/BlackrockDigital/startbootstrap-simple-sidebar/blob/master/LICENSE)
*/
body {
overflow-x: hidden;
}
#wrapper {
padding-left: 0;
-webkit-transition: all 0.5s ease;
-moz-transition: all 0.5s ease;
-o-transition: all 0.5s ease;
transition: all 0.5s ease;
}
#wrapper.toggled {
padding-left: 250px;
}
#sidebar-wrapper {
z-index: 1000;
position: fixed;
left: 250px;
width: 0;
height: 100%;
margin-left: -250px;
overflow-y: auto;
background: #000;
-webkit-transition: all 0.5s ease;
-moz-transition: all 0.5s ease;
-o-transition: all 0.5s ease;
transition: all 0.5s ease;
}
#wrapper.toggled #sidebar-wrapper {
width: 250px;
}
#page-content-wrapper {
width: 100%;
position: absolute;
padding: 15px;
}
#wrapper.toggled #page-content-wrapper {
position: absolute;
margin-right: -250px;
}
/* Sidebar Styles */
.sidebar-nav {
position: absolute;
top: 0;
width: 250px;
margin: 0;
padding: 0;
list-style: none;
}
.sidebar-nav li {
text-indent: 20px;
line-height: 40px;
}
.sidebar-nav li a {
display: block;
text-decoration: none;
color: #999999;
}
.sidebar-nav li a:hover {
text-decoration: none;
color: #fff;
background: rgba(255, 255, 255, 0.2);
}
.sidebar-nav li a:active, .sidebar-nav li a:focus {
text-decoration: none;
}
.sidebar-nav>.sidebar-brand {
height: 65px;
font-size: 18px;
line-height: 60px;
}
.sidebar-nav>.sidebar-brand a {
color: #999999;
}
.sidebar-nav>.sidebar-brand a:hover {
color: #fff;
background: none;
}
@media(min-width:768px) {
#wrapper {
padding-left: 0;
}
#wrapper.toggled {
padding-left: 250px;
}
#sidebar-wrapper {
width: 0;
}
#wrapper.toggled #sidebar-wrapper {
width: 250px;
}
#page-content-wrapper {
padding: 20px;
position: relative;
}
#wrapper.toggled #page-content-wrapper {
position: relative;
margin-right: 0;
}
}

View File

@ -0,0 +1,358 @@
/**
* vkBeautify - javascript plugin to pretty-print or minify text in XML, JSON, CSS and SQL formats.
*
* Version - 0.99.00.beta
* Copyright (c) 2012 Vadim Kiryukhin
* vkiryukhin @ gmail.com
* http://www.eslinstructor.net/vkbeautify/
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* Pretty print
*
* vkbeautify.xml(text [,indent_pattern]);
* vkbeautify.json(text [,indent_pattern]);
* vkbeautify.css(text [,indent_pattern]);
* vkbeautify.sql(text [,indent_pattern]);
*
* @text - String; text to beatufy;
* @indent_pattern - Integer | String;
* Integer: number of white spaces;
* String: character string to visualize indentation ( can also be a set of white spaces )
* Minify
*
* vkbeautify.xmlmin(text [,preserve_comments]);
* vkbeautify.jsonmin(text);
* vkbeautify.cssmin(text [,preserve_comments]);
* vkbeautify.sqlmin(text);
*
* @text - String; text to minify;
* @preserve_comments - Bool; [optional];
* Set this flag to true to prevent removing comments from @text ( minxml and mincss functions only. )
*
* Examples:
* vkbeautify.xml(text); // pretty print XML
* vkbeautify.json(text, 4 ); // pretty print JSON
* vkbeautify.css(text, '. . . .'); // pretty print CSS
* vkbeautify.sql(text, '----'); // pretty print SQL
*
* vkbeautify.xmlmin(text, true);// minify XML, preserve comments
* vkbeautify.jsonmin(text);// minify JSON
* vkbeautify.cssmin(text);// minify CSS, remove comments ( default )
* vkbeautify.sqlmin(text);// minify SQL
*
*/
(function() {
function createShiftArr(step) {
var space = ' ';
if ( isNaN(parseInt(step)) ) { // argument is string
space = step;
} else { // argument is integer
switch(step) {
case 1: space = ' '; break;
case 2: space = ' '; break;
case 3: space = ' '; break;
case 4: space = ' '; break;
case 5: space = ' '; break;
case 6: space = ' '; break;
case 7: space = ' '; break;
case 8: space = ' '; break;
case 9: space = ' '; break;
case 10: space = ' '; break;
case 11: space = ' '; break;
case 12: space = ' '; break;
}
}
var shift = ['\n']; // array of shifts
for(ix=0;ix<100;ix++){
shift.push(shift[ix]+space);
}
return shift;
}
function vkbeautify(){
this.step = ' '; // 4 spaces
this.shift = createShiftArr(this.step);
};
vkbeautify.prototype.xml = function(text,step) {
var ar = text.replace(/>\s{0,}</g,"><")
.replace(/</g,"~::~<")
.replace(/\s*xmlns\:/g,"~::~xmlns:")
.replace(/\s*xmlns\=/g,"~::~xmlns=")
.split('~::~'),
len = ar.length,
inComment = false,
deep = 0,
str = '',
ix = 0,
shift = step ? createShiftArr(step) : this.shift;
for(ix=0;ix<len;ix++) {
// start comment or <![CDATA[...]]> or <!DOCTYPE //
if(ar[ix].search(/<!/) > -1) {
str += shift[deep]+ar[ix];
inComment = true;
// end comment or <![CDATA[...]]> //
if(ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1 || ar[ix].search(/!DOCTYPE/) > -1 ) {
inComment = false;
}
} else
// end comment or <![CDATA[...]]> //
if(ar[ix].search(/-->/) > -1 || ar[ix].search(/\]>/) > -1) {
str += ar[ix];
inComment = false;
} else
// <elm></elm> //
if( /^<\w/.exec(ar[ix-1]) && /^<\/\w/.exec(ar[ix]) &&
/^<[\w:\-\.\,]+/.exec(ar[ix-1]) == /^<\/[\w:\-\.\,]+/.exec(ar[ix])[0].replace('/','')) {
str += ar[ix];
if(!inComment) deep--;
} else
// <elm> //
if(ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) == -1 && ar[ix].search(/\/>/) == -1 ) {
str = !inComment ? str += shift[deep++]+ar[ix] : str += ar[ix];
} else
// <elm>...</elm> //
if(ar[ix].search(/<\w/) > -1 && ar[ix].search(/<\//) > -1) {
str = !inComment ? str += shift[deep]+ar[ix] : str += ar[ix];
} else
// </elm> //
if(ar[ix].search(/<\//) > -1) {
str = !inComment ? str += shift[--deep]+ar[ix] : str += ar[ix];
} else
// <elm/> //
if(ar[ix].search(/\/>/) > -1 ) {
str = !inComment ? str += shift[deep]+ar[ix] : str += ar[ix];
} else
// <? xml ... ?> //
if(ar[ix].search(/<\?/) > -1) {
str += shift[deep]+ar[ix];
} else
// xmlns //
if( ar[ix].search(/xmlns\:/) > -1 || ar[ix].search(/xmlns\=/) > -1) {
str += shift[deep]+ar[ix];
}
else {
str += ar[ix];
}
}
return (str[0] == '\n') ? str.slice(1) : str;
}
vkbeautify.prototype.json = function(text,step) {
var step = step ? step : this.step;
if (typeof JSON === 'undefined' ) return text;
if ( typeof text === "string" ) return JSON.stringify(JSON.parse(text), null, step);
if ( typeof text === "object" ) return JSON.stringify(text, null, step);
return text; // text is not string nor object
}
vkbeautify.prototype.css = function(text, step) {
var ar = text.replace(/\s{1,}/g,' ')
.replace(/\{/g,"{~::~")
.replace(/\}/g,"~::~}~::~")
.replace(/\;/g,";~::~")
.replace(/\/\*/g,"~::~/*")
.replace(/\*\//g,"*/~::~")
.replace(/~::~\s{0,}~::~/g,"~::~")
.split('~::~'),
len = ar.length,
deep = 0,
str = '',
ix = 0,
shift = step ? createShiftArr(step) : this.shift;
for(ix=0;ix<len;ix++) {
if( /\{/.exec(ar[ix])) {
str += shift[deep++]+ar[ix];
} else
if( /\}/.exec(ar[ix])) {
str += shift[--deep]+ar[ix];
} else
if( /\*\\/.exec(ar[ix])) {
str += shift[deep]+ar[ix];
}
else {
str += shift[deep]+ar[ix];
}
}
return str.replace(/^\n{1,}/,'');
}
//----------------------------------------------------------------------------
function isSubquery(str, parenthesisLevel) {
return parenthesisLevel - (str.replace(/\(/g,'').length - str.replace(/\)/g,'').length )
}
function split_sql(str, tab) {
return str.replace(/\s{1,}/g," ")
.replace(/ AND /ig,"~::~"+tab+tab+"AND ")
.replace(/ BETWEEN /ig,"~::~"+tab+"BETWEEN ")
.replace(/ CASE /ig,"~::~"+tab+"CASE ")
.replace(/ ELSE /ig,"~::~"+tab+"ELSE ")
.replace(/ END /ig,"~::~"+tab+"END ")
.replace(/ FROM /ig,"~::~FROM ")
.replace(/ GROUP\s{1,}BY/ig,"~::~GROUP BY ")
.replace(/ HAVING /ig,"~::~HAVING ")
//.replace(/ SET /ig," SET~::~")
.replace(/ IN /ig," IN ")
.replace(/ JOIN /ig,"~::~JOIN ")
.replace(/ CROSS~::~{1,}JOIN /ig,"~::~CROSS JOIN ")
.replace(/ INNER~::~{1,}JOIN /ig,"~::~INNER JOIN ")
.replace(/ LEFT~::~{1,}JOIN /ig,"~::~LEFT JOIN ")
.replace(/ RIGHT~::~{1,}JOIN /ig,"~::~RIGHT JOIN ")
.replace(/ ON /ig,"~::~"+tab+"ON ")
.replace(/ OR /ig,"~::~"+tab+tab+"OR ")
.replace(/ ORDER\s{1,}BY/ig,"~::~ORDER BY ")
.replace(/ OVER /ig,"~::~"+tab+"OVER ")
.replace(/\(\s{0,}SELECT /ig,"~::~(SELECT ")
.replace(/\)\s{0,}SELECT /ig,")~::~SELECT ")
.replace(/ THEN /ig," THEN~::~"+tab+"")
.replace(/ UNION /ig,"~::~UNION~::~")
.replace(/ USING /ig,"~::~USING ")
.replace(/ WHEN /ig,"~::~"+tab+"WHEN ")
.replace(/ WHERE /ig,"~::~WHERE ")
.replace(/ WITH /ig,"~::~WITH ")
//.replace(/\,\s{0,}\(/ig,",~::~( ")
//.replace(/\,/ig,",~::~"+tab+tab+"")
.replace(/ ALL /ig," ALL ")
.replace(/ AS /ig," AS ")
.replace(/ ASC /ig," ASC ")
.replace(/ DESC /ig," DESC ")
.replace(/ DISTINCT /ig," DISTINCT ")
.replace(/ EXISTS /ig," EXISTS ")
.replace(/ NOT /ig," NOT ")
.replace(/ NULL /ig," NULL ")
.replace(/ LIKE /ig," LIKE ")
.replace(/\s{0,}SELECT /ig,"SELECT ")
.replace(/\s{0,}UPDATE /ig,"UPDATE ")
.replace(/ SET /ig," SET ")
.replace(/~::~{1,}/g,"~::~")
.split('~::~');
}
vkbeautify.prototype.sql = function(text,step) {
var ar_by_quote = text.replace(/\s{1,}/g," ")
.replace(/\'/ig,"~::~\'")
.split('~::~'),
len = ar_by_quote.length,
ar = [],
deep = 0,
tab = this.step,//+this.step,
inComment = true,
inQuote = false,
parenthesisLevel = 0,
str = '',
ix = 0,
shift = step ? createShiftArr(step) : this.shift;;
for(ix=0;ix<len;ix++) {
if(ix%2) {
ar = ar.concat(ar_by_quote[ix]);
} else {
ar = ar.concat(split_sql(ar_by_quote[ix], tab) );
}
}
len = ar.length;
for(ix=0;ix<len;ix++) {
parenthesisLevel = isSubquery(ar[ix], parenthesisLevel);
if( /\s{0,}\s{0,}SELECT\s{0,}/.exec(ar[ix])) {
ar[ix] = ar[ix].replace(/\,/g,",\n"+tab+tab+"")
}
if( /\s{0,}\s{0,}SET\s{0,}/.exec(ar[ix])) {
ar[ix] = ar[ix].replace(/\,/g,",\n"+tab+tab+"")
}
if( /\s{0,}\(\s{0,}SELECT\s{0,}/.exec(ar[ix])) {
deep++;
str += shift[deep]+ar[ix];
} else
if( /\'/.exec(ar[ix]) ) {
if(parenthesisLevel<1 && deep) {
deep--;
}
str += ar[ix];
}
else {
str += shift[deep]+ar[ix];
if(parenthesisLevel<1 && deep) {
deep--;
}
}
var junk = 0;
}
str = str.replace(/^\n{1,}/,'').replace(/\n{1,}/g,"\n");
return str;
}
vkbeautify.prototype.xmlmin = function(text, preserveComments) {
var str = preserveComments ? text
: text.replace(/\<![ \r\n\t]*(--([^\-]|[\r\n]|-[^\-])*--[ \r\n\t]*)\>/g,"")
.replace(/[ \r\n\t]{1,}xmlns/g, ' xmlns');
return str.replace(/>\s{0,}</g,"><");
}
vkbeautify.prototype.jsonmin = function(text) {
if (typeof JSON === 'undefined' ) return text;
return JSON.stringify(JSON.parse(text), null, 0);
}
vkbeautify.prototype.cssmin = function(text, preserveComments) {
var str = preserveComments ? text
: text.replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*+\//g,"") ;
return str.replace(/\s{1,}/g,' ')
.replace(/\{\s{1,}/g,"{")
.replace(/\}\s{1,}/g,"}")
.replace(/\;\s{1,}/g,";")
.replace(/\/\*\s{1,}/g,"/*")
.replace(/\*\/\s{1,}/g,"*/");
}
vkbeautify.prototype.sqlmin = function(text) {
return text.replace(/\s{1,}/g," ").replace(/\s{1,}\(/,"(").replace(/\s{1,}\)/,")");
}
window.vkbeautify = new vkbeautify();
})();

View File

@ -1,22 +1,49 @@
<!doctype html>
<html lang="en">
<script src="https://apis.google.com/js/platform.js" ></script>
<head>
<meta charset="utf-8">
<title>Digital Management Plans Creator APP</title>
<base href="/">
<meta name="csrf-token" content="2c64def7de30197c40276fe1a7ea874ca8871f70be7d7dc3305465a4d5c565e4">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<meta name="google-signin-client_id" content="524432312250-vhgidft856v8qftsc81kls4c74v87d8o.apps.googleusercontent.com">
<link rel="stylesheet" href="https://cdn.rawgit.com/afeld/bootstrap-toc/v0.4.1/dist/bootstrap-toc.min.css"><!--bootstrap plugin for ToC-->
<!-- add after bootstrap.min.js -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" />
<script src="https://cdn.rawgit.com/afeld/bootstrap-toc/v0.4.1/dist/bootstrap-toc.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.4/jquery.min.js"></script>
<head>
<meta charset="utf-8">
<title>Data Management Plans - Manager</title>
<base href="/">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/x-icon" href="favicon.ico">
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<!--
<script src="https://apis.google.com/js/platform.js" ></script>
-->
<link rel="stylesheet" href="https://cdn.rawgit.com/afeld/bootstrap-toc/v0.4.1/dist/bootstrap-toc.min.css"><!--bootstrap plugin for ToC-->
<script src="https://cdn.rawgit.com/afeld/bootstrap-toc/v0.4.1/dist/bootstrap-toc.min.js"></script>
<!-- XML to json and vice versa lib -->
<script src="assets/xml2json.min.js"></script>
<!-- Json formatter lib -->
<link rel="stylesheet" type="text/css" href="assets/jquery.json-viewer.css">
<script src="assets/jquery.json-viewer.js"></script>
<!-- lib 4 pretty-printing xml and json -->
<script src="assets/vkbeautify.0.99.00.js"></script>
<!-- Nice BS notifications -->
<script src="assets/bootstrap-notify.min.js"></script>
<!-- that's google sign in library -->
<script src="https://apis.google.com/js/platform.js"></script>
<!-- font-awesome css -->
<link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css">
<!-- my custom global code and css -->
<link rel="stylesheet" type="text/css" href="assets/custom.css">
<script src="assets/custom.js"></script>
</head>
@ -31,15 +58,7 @@
  }
</script>
<div class="panel panel-default" style="margin-top: 30px; margin-bottom: 30px; margin-right: 30px; margin-left: 30px;">
<div class="panel-heading">
<h3 class="panel-title" style="text-align: center;">Data Management Plan</h3>
</div>
<div class="panel-body">
<app-root></app-root>
</div>
</div>
<app-root></app-root>
</body>
</html>

View File

@ -1,11 +1,11 @@
/* You can add global styles to this file, and also import other style files */
/*
body {
padding-top: 40px;
padding-bottom: 40px;
background-color: #eee;
}
*/
.form-signin {
max-width: 330px;
padding: 15px;