diff --git a/.gitignore b/.gitignore index 05a92b9..c188cf5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules package-lock.json -*.log \ No newline at end of file +*.log +.DS_Store diff --git a/app/e2e/app.e2e-spec.ts b/app/e2e/app.e2e-spec.ts index d1e06d8..4b8a378 100644 --- a/app/e2e/app.e2e-spec.ts +++ b/app/e2e/app.e2e-spec.ts @@ -7,17 +7,13 @@ describe('InsightApp', () => { }); it('should have a title', () => { - expect(browser.getTitle()).toEqual('Blocks'); + expect(browser.getTitle()).toEqual('Home'); }); it('should have {nav}', () => { expect(element(by.css('ion-navbar')).isPresent()).toEqual(true); }); - it('should have correct nav text for Home', () => { - expect(element(by.css('ion-navbar:first-child')).getText()).toContain('Blocks'); - }); - it('has a menu button that displays the left menu', () => { element(by.css('.bar-button-menutoggle')).click() .then(() => { @@ -26,11 +22,11 @@ describe('InsightApp', () => { }); }); - it('the left menu has a link with title Blocks', () => { + it('the left menu has a link with title Home', () => { element(by.css('.bar-button-menutoggle')).click() .then(() => { browser.driver.sleep(2000); // wait for the animation - expect(element.all(by.css('ion-label')).first().getText()).toEqual('Blocks'); + expect(element.all(by.css('ion-label')).first().getText()).toEqual('Home'); }); }); }); diff --git a/app/e2e/broadcastTxPage.e2e-spec.ts b/app/e2e/broadcastTxPage.e2e-spec.ts index 11943c5..70c34fe 100644 --- a/app/e2e/broadcastTxPage.e2e-spec.ts +++ b/app/e2e/broadcastTxPage.e2e-spec.ts @@ -10,7 +10,7 @@ describe('BroadcastTxPage', () => { element(by.css('.bar-button-menutoggle')).click().then(() => { browser.driver.sleep(2000); // wait for the animation element.all(by.className('input-wrapper')).then((items) => { - items[1].click(); + items[2].click(); browser.driver.sleep(2000); // wait for the animation let theElem = element.all(by.css('ion-label')).first; console.log(theElem); diff --git a/app/ionic.config.json b/app/ionic.config.json index 1c03d6d..a7bf4dd 100644 --- a/app/ionic.config.json +++ b/app/ionic.config.json @@ -2,5 +2,7 @@ "name": "insight-ui", "app_id": "", "type": "ionic-angular", - "integrations": {} + "integrations": { + "cordova": {} + } } diff --git a/app/package.json b/app/package.json index 8bee14f..bb7407e 100644 --- a/app/package.json +++ b/app/package.json @@ -27,6 +27,7 @@ "@ionic-native/splash-screen": "3.10.2", "@ionic-native/status-bar": "3.10.2", "@ionic/storage": "2.0.1", + "angular2-moment": "^1.6.0", "angular2-qrcode": "^2.0.1", "ionic-angular": "3.4.2", "ionicons": "3.0.0", @@ -42,7 +43,7 @@ "@types/jasmine": "2.5.41", "@types/node": "7.0.4", "codecov": "2.2.0", - "ionic": "3.8.1", + "ionic": "3.9.1", "jasmine-core": "2.5.2", "jasmine-spec-reporter": "3.2.0", "karma": "1.4.1", diff --git a/app/src/app/app.component.ts b/app/src/app/app.component.ts index fb4dd6e..f089c75 100644 --- a/app/src/app/app.component.ts +++ b/app/src/app/app.component.ts @@ -3,6 +3,7 @@ import { Platform, MenuController, Nav } from 'ionic-angular'; import { StatusBar } from '@ionic-native/status-bar'; import { SplashScreen } from '@ionic-native/splash-screen'; import { + HomePage, BlocksPage, BroadcastTxPage, NodeStatusPage, @@ -31,11 +32,12 @@ export class InsightApp { this.splash = splash; this.status = status; - this.rootPage = BlocksPage; + this.rootPage = HomePage; this.initializeApp(); // set our app's pages this.pages = [ + { title: 'Home', component: HomePage }, { title: 'Blocks', component: BlocksPage }, { title: 'Broadcast Transaction', component: BroadcastTxPage }, { title: 'Verify Signed Message', component: VerifyMessagePage }, diff --git a/app/src/app/app.module.ts b/app/src/app/app.module.ts index c0b673b..7d0c351 100644 --- a/app/src/app/app.module.ts +++ b/app/src/app/app.module.ts @@ -5,10 +5,11 @@ import { IonicApp, IonicModule, IonicErrorHandler } from 'ionic-angular'; import { StatusBar } from '@ionic-native/status-bar'; import { SplashScreen } from '@ionic-native/splash-screen'; import { InsightApp } from './app.component'; -import { PagesModule, BlocksPage, BroadcastTxPage, NodeStatusPage, VerifyMessagePage } from '../pages'; +import { PagesModule, HomePage, BlocksPage, BroadcastTxPage, NodeStatusPage, VerifyMessagePage } from '../pages'; import { BlocksService, StorageService } from '../services'; import { ApiProvider } from '../providers/api/api'; import { CurrencyProvider } from '../providers/currency/currency'; +import { BlocksProvider } from '../providers/blocks/blocks'; @NgModule({ declarations: [ @@ -23,6 +24,7 @@ import { CurrencyProvider } from '../providers/currency/currency'; bootstrap: [IonicApp], entryComponents: [ InsightApp, + HomePage, BlocksPage, BroadcastTxPage, NodeStatusPage, @@ -35,7 +37,8 @@ import { CurrencyProvider } from '../providers/currency/currency'; BlocksService, {provide: ErrorHandler, useClass: IonicErrorHandler}, ApiProvider, - CurrencyProvider + CurrencyProvider, + BlocksProvider ] }) diff --git a/app/src/assets/img/angularjs.png b/app/src/assets/img/angularjs.png new file mode 100644 index 0000000..21aefd4 Binary files /dev/null and b/app/src/assets/img/angularjs.png differ diff --git a/app/src/assets/img/bitcore.svg b/app/src/assets/img/bitcore.svg new file mode 100644 index 0000000..856b0a1 --- /dev/null +++ b/app/src/assets/img/bitcore.svg @@ -0,0 +1,29 @@ + + + Group copy + bitcore copy@2x + Created with Sketch (http://www.bohemiancoding.com/sketch) + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/assets/img/leveldb.png b/app/src/assets/img/leveldb.png new file mode 100644 index 0000000..da13a67 Binary files /dev/null and b/app/src/assets/img/leveldb.png differ diff --git a/app/src/assets/img/nodejs.png b/app/src/assets/img/nodejs.png new file mode 100644 index 0000000..4cba6f8 Binary files /dev/null and b/app/src/assets/img/nodejs.png differ diff --git a/app/src/components/latest-blocks/latest-blocks.html b/app/src/components/latest-blocks/latest-blocks.html new file mode 100644 index 0000000..8268be4 --- /dev/null +++ b/app/src/components/latest-blocks/latest-blocks.html @@ -0,0 +1,45 @@ + +
+
+ +
+ +
+ + + + Height + Age + Timestamp + Transactions + Mined By + Size + + + + {{block.height}} + + + {{ block.time | amFromUnix | amTimeAgo }} + + + {{ block.time * 1000 | date:'medium' }} + + + {{block.txlength}} + + + {{block.poolInfo.poolName}} + + + {{ block.size }} + + + + + + + + +
+
diff --git a/app/src/components/latest-blocks/latest-blocks.module.ts b/app/src/components/latest-blocks/latest-blocks.module.ts new file mode 100644 index 0000000..f2086b9 --- /dev/null +++ b/app/src/components/latest-blocks/latest-blocks.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from '@angular/core'; +import { IonicModule } from 'ionic-angular'; +import { LatestBlocksComponent } from './latest-blocks'; +import { MomentModule } from 'angular2-moment'; + +@NgModule({ + declarations: [ + LatestBlocksComponent + ], + imports: [ + IonicModule, + MomentModule + ], + exports: [ + LatestBlocksComponent + ] +}) +export class LatestBlocksComponentModule {} diff --git a/app/src/components/latest-blocks/latest-blocks.scss b/app/src/components/latest-blocks/latest-blocks.scss new file mode 100644 index 0000000..0ae897d --- /dev/null +++ b/app/src/components/latest-blocks/latest-blocks.scss @@ -0,0 +1,23 @@ +latest-blocks { + ion-grid { + // border: 2px solid green; + margin: 10px 0 20px; + + ion-row { + border-top: 1px solid #ccc; + } + + ion-row:nth-child(even) { + background-color: #f4f4f4; + } + + ion-row:first-child { + background-color: white; + border-top: none; + } + + ion-row:last-child { + background-color: white; + } + } +} diff --git a/app/src/components/latest-blocks/latest-blocks.ts b/app/src/components/latest-blocks/latest-blocks.ts new file mode 100644 index 0000000..21fc1e4 --- /dev/null +++ b/app/src/components/latest-blocks/latest-blocks.ts @@ -0,0 +1,65 @@ +import { Component, NgZone, Input } from '@angular/core'; +import { BlocksProvider } from '../../providers/blocks/blocks'; +import { NavController } from 'ionic-angular'; + +/** + * Generated class for the LatestBlocksComponent component. + * + * See https://angular.io/docs/ts/latest/api/core/index/ComponentMetadata-class.html + * for more info on Angular Components. + */ +@Component({ + selector: 'latest-blocks', + templateUrl: 'latest-blocks.html' +}) +export class LatestBlocksComponent { + + public loading: boolean = true; + public blocks: Array = []; + @Input() public numBlocks: number; + @Input() public showAllBlocksButton: boolean; + @Input() public showTimeAs: string; + + constructor(private blocksProvider: BlocksProvider, private navCtrl: NavController, ngZone: NgZone) { + this.loadBlocks(); + ngZone.runOutsideAngular(() => { + setInterval( + function (): void { + ngZone.run(function (): void { + this.loadBlocks.call(this); + }.bind(this)); + }.bind(this), + 1000 * 30 + ); + }); + } + + private loadBlocks(): void { + this.blocksProvider.getBlocks().subscribe( + (data) => { + this.blocks = JSON.parse(data['_body']).blocks; + this.loading = false; + }, + (err) => { + console.log('err', err); + this.loading = false; + } + ); + } + + public goToBlock(blockHash: string): void { + this.navCtrl.push('block-detail', { + 'blockHash': blockHash + }); + } + + public getBlocks(): Array { + /* tslint:disable:no-unused-variable */ + return this.blocks.filter((block, index) => index < this.numBlocks); + /* tslint:enable:no-unused-variable */ + } + + public goToBlocks(): void { + this.navCtrl.push('blocks'); + } +} diff --git a/app/src/components/latest-transactions/latest-transactions.html b/app/src/components/latest-transactions/latest-transactions.html new file mode 100644 index 0000000..948536e --- /dev/null +++ b/app/src/components/latest-transactions/latest-transactions.html @@ -0,0 +1,4 @@ + +
+ {{text}} +
diff --git a/app/src/components/latest-transactions/latest-transactions.module.ts b/app/src/components/latest-transactions/latest-transactions.module.ts new file mode 100644 index 0000000..7eb0b92 --- /dev/null +++ b/app/src/components/latest-transactions/latest-transactions.module.ts @@ -0,0 +1,16 @@ +import { NgModule } from '@angular/core'; +import { IonicModule } from 'ionic-angular'; +import { LatestTransactionsComponent } from './latest-transactions'; + +@NgModule({ + declarations: [ + LatestTransactionsComponent + ], + imports: [ + IonicModule + ], + exports: [ + LatestTransactionsComponent + ] +}) +export class LatestTransactionsComponentModule {} diff --git a/app/src/components/latest-transactions/latest-transactions.scss b/app/src/components/latest-transactions/latest-transactions.scss new file mode 100644 index 0000000..570ea96 --- /dev/null +++ b/app/src/components/latest-transactions/latest-transactions.scss @@ -0,0 +1,3 @@ +latest-transactions { + +} diff --git a/app/src/components/latest-transactions/latest-transactions.ts b/app/src/components/latest-transactions/latest-transactions.ts new file mode 100644 index 0000000..4650fff --- /dev/null +++ b/app/src/components/latest-transactions/latest-transactions.ts @@ -0,0 +1,52 @@ +import { Component } from '@angular/core'; +// import { Http } from '@angular/http'; +// import { ApiProvider } from '../../providers/api/api'; + +/** + * Generated class for the LatestTransactionsComponent component. + * + * See https://angular.io/docs/ts/latest/api/core/index/ComponentMetadata-class.html + * for more info on Angular Components. + */ +@Component({ + selector: 'latest-transactions', + templateUrl: 'latest-transactions.html' +}) +export class LatestTransactionsComponent { + + private text: string; + + constructor(/*private http: Http, private api: ApiProvider*/) { + console.log('Hello LatestTransactionsComponent Component'); + this.text = 'Hello Latest Transactions'; + + /* + let url: string = this.api.apiPrefix + 'txs?' + this.queryType + '=' + this.queryValue; + + this.http.get(url).subscribe( + (data) => { + this.transactions = JSON.parse(data['_body']); + this.loading = false; + }, + (err) => { + console.log('err is', err); + this.loading = false; + } + ); + */ + + /* + this.http.get(this.api.apiPrefix + 'tx/' + this.txId).subscribe( + (data) => { + this.tx = JSON.parse(data['_body']); + this.loading = false; + }, + (err) => { + console.log('err is', err); + this.loading = false; + } + ); + */ + } + +} diff --git a/app/src/components/transaction/transaction.scss b/app/src/components/transaction/transaction.scss index 59fc005..40a22fb 100644 --- a/app/src/components/transaction/transaction.scss +++ b/app/src/components/transaction/transaction.scss @@ -1,4 +1,7 @@ transaction { + // TODO Customize the grid to have 13 columns so that we have 6-col inputs, 6-col outputs, 1 col arrow + // See http://ionicframework.com/docs/api/components/grid/Grid/#customizing-the-grid + ion-grid { background-color: #F4F4F4; border: 1px solid #eee; diff --git a/app/src/pages/blocks/blocks.html b/app/src/pages/blocks/blocks.html new file mode 100644 index 0000000..54d52dc --- /dev/null +++ b/app/src/pages/blocks/blocks.html @@ -0,0 +1,14 @@ + + + + + +
+ +
+ +
+

Blocks

+ +
+
diff --git a/app/src/pages/blocks/blocks.module.ts b/app/src/pages/blocks/blocks.module.ts new file mode 100644 index 0000000..521ae44 --- /dev/null +++ b/app/src/pages/blocks/blocks.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; +import { IonicPageModule } from 'ionic-angular'; +import { BlocksPage } from './blocks'; +import { HeadNavComponentModule } from '../../components/head-nav/head-nav.module'; +import { LatestBlocksComponentModule } from '../../components/latest-blocks/latest-blocks.module'; + +@NgModule({ + declarations: [ + BlocksPage + ], + imports: [ + IonicPageModule.forChild(BlocksPage), + HeadNavComponentModule, + LatestBlocksComponentModule + ], + exports: [ + BlocksPage + ] +}) +export class BlocksPageModule {} diff --git a/app/src/pages/blocks/blocks.scss b/app/src/pages/blocks/blocks.scss new file mode 100644 index 0000000..563b211 --- /dev/null +++ b/app/src/pages/blocks/blocks.scss @@ -0,0 +1,23 @@ +page-blocks { + ion-grid { + // border: 2px solid green; + margin: 10px 0 20px; + + ion-row { + border-top: 1px solid #ccc; + } + + ion-row:nth-child(even) { + background-color: #f4f4f4; + } + + ion-row:first-child { + background-color: white; + border-top: none; + } + + ion-row:last-child { + background-color: white; + } + } +} diff --git a/app/src/pages/blocks/blocks.ts b/app/src/pages/blocks/blocks.ts new file mode 100644 index 0000000..5dcf67c --- /dev/null +++ b/app/src/pages/blocks/blocks.ts @@ -0,0 +1,37 @@ +import { Component } from '@angular/core'; +import { IonicPage, NavController, NavParams } from 'ionic-angular'; +import { BlocksProvider } from '../../providers/blocks/blocks'; + +/** + * Generated class for the BlocksPage page. + * + * See http://ionicframework.com/docs/components/#navigation for more info + * on Ionic pages and navigation. + */ +@IonicPage({ + name: 'blocks', + segment: 'blocks/' +}) +@Component({ + selector: 'page-blocks', + templateUrl: 'blocks.html' +}) +export class BlocksPage { + + public loading: boolean = true; + public blocks: Array = []; + + constructor(public navCtrl: NavController, public navParams: NavParams, private blocksProvider: BlocksProvider) { + this.blocksProvider.getBlocks().subscribe( + (data) => { + this.blocks = JSON.parse(data['_body']).blocks; + console.log('this.blocks', this.blocks); + this.loading = false; + }, + (err) => { + console.log('err', err); + this.loading = false; + } + ); + } +} diff --git a/app/src/pages/blocksPage/blocksPage.ts b/app/src/pages/blocksPage/blocksPage.ts index 5f2eeaf..e5273a4 100644 --- a/app/src/pages/blocksPage/blocksPage.ts +++ b/app/src/pages/blocksPage/blocksPage.ts @@ -4,16 +4,20 @@ import { Observable } from 'rxjs'; import { Block } from '../../models'; import { BlocksService } from '../../services'; +/** + * @deprecated Use BlocksPage from ../blocks/blocks + */ @Component({ templateUrl: './blocksPage.html' }) - export class BlocksPage { public title: string; public blocks: Observable; constructor(private navCtrl: NavController, private blocksService: BlocksService) { + // TODO Put loading spinner on page + this.title = 'Blocks'; this.blocks = blocksService.latestBlocks; this.blocks.subscribe((blocks) => { diff --git a/app/src/pages/home/home.html b/app/src/pages/home/home.html new file mode 100644 index 0000000..ad57d6d --- /dev/null +++ b/app/src/pages/home/home.html @@ -0,0 +1,39 @@ + + + + + + + + +
+

Latest Blocks

+ +
+ +
+

Latest Transactions

+ +
+ +
+

About

+

insight is an open-source Bitcoin blockchain explorer with complete REST and websocket APIs that can be used for writing web wallets and other apps that need more advanced blockchain queries than provided by bitcoind RPC. Check out the source code.

+

insight is still in development, so be sure to report any bugs and provide feedback for improvement at our github issue tracker.

+
+
+ Powered by +
+ + + + +
+
+
diff --git a/app/src/pages/home/home.module.ts b/app/src/pages/home/home.module.ts new file mode 100644 index 0000000..b3d3a15 --- /dev/null +++ b/app/src/pages/home/home.module.ts @@ -0,0 +1,20 @@ +import { NgModule } from '@angular/core'; +import { IonicPageModule } from 'ionic-angular'; +import { HomePage } from './home'; +import { HeadNavComponentModule } from '../../components/head-nav/head-nav.module'; +import { LatestTransactionsComponentModule } from '../../components/latest-transactions/latest-transactions.module'; + +@NgModule({ + declarations: [ + HomePage + ], + imports: [ + IonicPageModule.forChild(HomePage), + HeadNavComponentModule, + LatestTransactionsComponentModule + ], + exports: [ + HomePage + ] +}) +export class HomePageModule {} diff --git a/app/src/pages/home/home.scss b/app/src/pages/home/home.scss new file mode 100644 index 0000000..91b4923 --- /dev/null +++ b/app/src/pages/home/home.scss @@ -0,0 +1,50 @@ +page-home { + .about { + background-color: #F4F4F4; + border: 1px solid #eee; + border-radius: 5px; + padding: 14px; + } + + #powered .powered-text { + border-top: 1px solid #ddd; + margin: 30px auto 0; + text-align: center; + width: 90%; + } + #powered .powered-text small { + background-color: #f4f4f4; + padding: 4px; + position: relative; + top: -12px; + } + + #powered a { + background-repeat: no-repeat; + background-position: center center; + display: inline-block; + float: left; + height: 45px; + } + #powered a.bitcore { + background-image: url('../../assets/img/bitcore.svg'); + background-size: 80px; + width: 30%; + } + #powered a.nodejs { + background-image: url('../../assets/img/nodejs.png'); + background-size: 80px; + width: 30%; + } + #powered a.angularjs { + background-image: url('../../assets/img/angularjs.png'); + background-size: 50px; + width: 20%; + } + #powered a.leveldb { + background-image: url('../../assets/img/leveldb.png'); + background-size: 50px; + width: 20%; + } + +} diff --git a/app/src/pages/home/home.ts b/app/src/pages/home/home.ts new file mode 100644 index 0000000..5880022 --- /dev/null +++ b/app/src/pages/home/home.ts @@ -0,0 +1,27 @@ +import { Component } from '@angular/core'; +import { IonicPage, NavController, NavParams } from 'ionic-angular'; + +/** + * Generated class for the HomePage page. + * + * See http://ionicframework.com/docs/components/#navigation for more info + * on Ionic pages and navigation. + */ +@IonicPage({ + name: 'home', + segment: 'home' +}) +@Component({ + selector: 'page-home', + templateUrl: 'home.html' +}) +export class HomePage { + + constructor(public navCtrl: NavController, public navParams: NavParams) { + } + + public ionViewDidLoad(): void { + console.log('ionViewDidLoad HomePage'); + } + +} diff --git a/app/src/pages/index.ts b/app/src/pages/index.ts index a449179..67a109d 100644 --- a/app/src/pages/index.ts +++ b/app/src/pages/index.ts @@ -1,5 +1,6 @@ -export * from './blocksPage/blocksPage'; export * from './broadcastTxPage/broadcastTxPage'; export * from './nodeStatusPage/nodeStatusPage'; export * from './verifyMessagePage/verifyMessagePage'; +export * from './home/home'; +export * from './blocks/blocks'; export * from './pages.module'; diff --git a/app/src/pages/pages.module.ts b/app/src/pages/pages.module.ts index 2da0e6a..6156b14 100644 --- a/app/src/pages/pages.module.ts +++ b/app/src/pages/pages.module.ts @@ -1,9 +1,12 @@ import { NgModule } from '@angular/core'; import { IonicModule } from 'ionic-angular'; import { ComponentsModule } from '../components'; +import { BlocksPageModule } from '../pages/blocks/blocks.module'; import { HeadNavComponentModule } from '../components/head-nav/head-nav.module'; +import { LatestTransactionsComponentModule } from '../components/latest-transactions/latest-transactions.module'; +import { LatestBlocksComponentModule } from '../components/latest-blocks/latest-blocks.module'; import { - BlocksPage, + HomePage, BroadcastTxPage, NodeStatusPage, VerifyMessagePage @@ -11,12 +14,19 @@ import { @NgModule({ declarations: [ - BlocksPage, + HomePage, BroadcastTxPage, NodeStatusPage, VerifyMessagePage ], - imports: [ IonicModule, ComponentsModule, HeadNavComponentModule ], + imports: [ + IonicModule, + ComponentsModule, + BlocksPageModule, + HeadNavComponentModule, + LatestTransactionsComponentModule, + LatestBlocksComponentModule + ], exports: [ // CustomComponent, ], diff --git a/app/src/providers/blocks/blocks.ts b/app/src/providers/blocks/blocks.ts new file mode 100644 index 0000000..6ab163c --- /dev/null +++ b/app/src/providers/blocks/blocks.ts @@ -0,0 +1,23 @@ +import { Injectable } from '@angular/core'; +import { Http } from '@angular/http'; +import 'rxjs/add/operator/map'; +import { ApiProvider } from '../../providers/api/api'; + +/* + Generated class for the BlocksProvider provider. + + See https://angular.io/docs/ts/latest/guide/dependency-injection.html + for more info on providers and Angular DI. +*/ +@Injectable() +export class BlocksProvider { + + constructor(public http: Http, private api: ApiProvider) { + console.log('Hello BlocksProvider Provider'); + } + + public getBlocks(): any { + return this.http.get(this.api.apiPrefix + 'blocks'); + } + +} diff --git a/app/yarn.lock b/app/yarn.lock index 53191d9..575bfc5 100644 --- a/app/yarn.lock +++ b/app/yarn.lock @@ -200,6 +200,39 @@ uuid "^3.0.1" wrap-ansi "^3.0.1" +"@ionic/cli-utils@1.9.1": + version "1.9.1" + resolved "https://registry.yarnpkg.com/@ionic/cli-utils/-/cli-utils-1.9.1.tgz#a0118819cb8de1f3bc4bc5b401e5b61d7f41d5b5" + dependencies: + "@types/gulp" "^3.8.33" + archiver "^2.0.0" + chalk "^2.0.0" + chokidar "^1.7.0" + ci-info "^1.0.0" + cross-spawn "^5.1.0" + dargs "^5.1.0" + diff "^3.3.0" + elementtree "^0.1.7" + express "^4.15.4" + inquirer "^3.2.1" + leek "0.0.24" + lodash "^4.17.4" + minimist "^1.2.0" + ncp "^2.0.0" + opn "^5.1.0" + proxy-middleware "^0.15.0" + semver "^5.4.1" + slice-ansi "^1.0.0" + ssh-config "^1.0.1" + string-width "^2.1.1" + strip-ansi "^4.0.0" + superagent "^3.5.2" + tar "^2.2.1" + tiny-lr "^1.0.5" + tslib "^1.7.1" + uuid "^3.0.1" + wrap-ansi "^3.0.1" + "@ionic/storage@2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@ionic/storage/-/storage-2.0.1.tgz#bb1a8c276007d008d7acdda426b56065b0fd3c0b" @@ -221,6 +254,14 @@ magic-string "^0.19.0" source-map "^0.5.6" +"@types/gulp@^3.8.33": + version "3.8.33" + resolved "https://registry.yarnpkg.com/@types/gulp/-/gulp-3.8.33.tgz#b1b076820738c9c4eb7808cd926bff1683e1c2ab" + dependencies: + "@types/node" "*" + "@types/orchestrator" "*" + "@types/vinyl" "*" + "@types/jasmine@2.5.41": version "2.5.41" resolved "https://registry.yarnpkg.com/@types/jasmine/-/jasmine-2.5.41.tgz#d5e86161a0af80d52062b310a33ed65b051a0713" @@ -229,6 +270,10 @@ version "0.0.30" resolved "https://registry.yarnpkg.com/@types/localforage/-/localforage-0.0.30.tgz#3d60a6bf6dda38e3f8a469611598379f1f649509" +"@types/node@*": + version "8.0.24" + resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.24.tgz#06c580084d9add1fb40c1510ef0b448961246fb1" + "@types/node@7.0.4": version "7.0.4" resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.4.tgz#9aabc135979ded383325749f508894c662948c8b" @@ -237,6 +282,17 @@ version "6.0.79" resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.79.tgz#5efe7d4a6d8c453c7e9eaf55d931f4a22fac5169" +"@types/orchestrator@*": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@types/orchestrator/-/orchestrator-0.3.0.tgz#bf84a1699c9330d4fe89cd81263e8fc09fb32978" + dependencies: + "@types/node" "*" + "@types/q" "^0" + +"@types/q@^0": + version "0.0.36" + resolved "https://registry.yarnpkg.com/@types/q/-/q-0.0.36.tgz#97d786389641bcbd0e22bfc729a534175976371d" + "@types/q@^0.0.32": version "0.0.32" resolved "https://registry.yarnpkg.com/@types/q/-/q-0.0.32.tgz#bd284e57c84f1325da702babfc82a5328190c0c5" @@ -245,6 +301,12 @@ version "2.53.42" resolved "https://registry.yarnpkg.com/@types/selenium-webdriver/-/selenium-webdriver-2.53.42.tgz#74cb77fb6052edaff2a8984ddafd88d419f25cac" +"@types/vinyl@*": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/vinyl/-/vinyl-2.0.0.tgz#fd213bf7f4136dde21fe1895500b12c186f8c268" + dependencies: + "@types/node" "*" + abbrev@1: version "1.1.0" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" @@ -335,6 +397,12 @@ amdefine@>=0.0.4: version "1.0.1" resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" +angular2-moment@^1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/angular2-moment/-/angular2-moment-1.6.0.tgz#2be11b63d9cbdff8fee06f575c1beee2d863d62b" + dependencies: + moment "^2.16.0" + angular2-qrcode@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/angular2-qrcode/-/angular2-qrcode-2.0.1.tgz#1b4e65c302694b5078ca06f71138f7e4367754dc" @@ -1256,7 +1324,7 @@ chokidar@1.6.1: optionalDependencies: fsevents "^1.0.0" -chokidar@^1.4.1, chokidar@^1.4.3, chokidar@^1.6.0, chokidar@^1.6.1: +chokidar@^1.4.1, chokidar@^1.4.3, chokidar@^1.6.0, chokidar@^1.6.1, chokidar@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.7.0.tgz#798e689778151c8076b4b360e5edd28cda2bb468" dependencies: @@ -1800,7 +1868,7 @@ date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" -debug@*, debug@2, debug@2.6.8, debug@^2.1.0, debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.6.3, debug@^2.6.8: +debug@*, debug@2, debug@2.6.8, debug@^2.1.0, debug@^2.1.1, debug@^2.1.3, debug@^2.2.0, debug@^2.6.3, debug@^2.6.8, debug@~2.6.7: version "2.6.8" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc" dependencies: @@ -1880,6 +1948,10 @@ depd@1.1.0, depd@~1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3" +depd@1.1.1, depd@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.1.tgz#5783b4e1c459f06fa5ca27f991f3d06e7a310359" + des.js@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" @@ -1917,6 +1989,10 @@ diff@^3.1.0, diff@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9" +diff@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.3.0.tgz#056695150d7aa93237ca7e378ac3b1682b7963b9" + diffie-hellman@^5.0.0: version "5.0.2" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e" @@ -2327,6 +2403,39 @@ express@^4.13.3: utils-merge "1.0.0" vary "~1.1.1" +express@^4.15.4: + version "4.15.4" + resolved "https://registry.yarnpkg.com/express/-/express-4.15.4.tgz#032e2253489cf8fce02666beca3d11ed7a2daed1" + dependencies: + accepts "~1.3.3" + array-flatten "1.1.1" + content-disposition "0.5.2" + content-type "~1.0.2" + cookie "0.3.1" + cookie-signature "1.0.6" + debug "2.6.8" + depd "~1.1.1" + encodeurl "~1.0.1" + escape-html "~1.0.3" + etag "~1.8.0" + finalhandler "~1.0.4" + fresh "0.5.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.1" + path-to-regexp "0.1.7" + proxy-addr "~1.1.5" + qs "6.5.0" + range-parser "~1.2.0" + send "0.15.4" + serve-static "1.12.4" + setprototypeof "1.0.3" + statuses "~1.3.1" + type-is "~1.6.15" + utils-merge "1.0.0" + vary "~1.1.1" + extend@3, extend@^3.0.0, extend@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" @@ -2446,6 +2555,18 @@ finalhandler@1.0.3, finalhandler@~1.0.3: statuses "~1.3.1" unpipe "~1.0.0" +finalhandler@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.4.tgz#18574f2e7c4b98b8ae3b230c21f201f31bdb3fb7" + dependencies: + debug "2.6.8" + encodeurl "~1.0.1" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.1" + statuses "~1.3.1" + unpipe "~1.0.0" + find-up@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" @@ -2913,6 +3034,15 @@ http-errors@~1.6.1: setprototypeof "1.0.3" statuses ">= 1.3.1 < 2" +http-errors@~1.6.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.2.tgz#0a002cc85707192a7e7946ceedc11155f60ec736" + dependencies: + depd "1.1.1" + inherits "2.0.3" + setprototypeof "1.0.3" + statuses ">= 1.3.1 < 2" + http-proxy-middleware@~0.17.4: version "0.17.4" resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz#642e8848851d66f09d4f124912846dbaeb41b833" @@ -3093,20 +3223,16 @@ ionic-angular@3.4.2: version "3.4.2" resolved "https://registry.yarnpkg.com/ionic-angular/-/ionic-angular-3.4.2.tgz#762631f1af78a5ae1c0aa0f4d23b31435142abe1" -ionic@3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/ionic/-/ionic-3.7.0.tgz#a3c32174c6d5455c3bc74b6b9152e0f97dce23c8" +ionic@3.9.1: + version "3.9.1" + resolved "https://registry.yarnpkg.com/ionic/-/ionic-3.9.1.tgz#be50eea2f55bad40574772ecaeaf5a460fd16330" dependencies: - "@ionic/cli-utils" "1.7.0" + "@ionic/cli-utils" "1.9.1" chalk "^2.0.0" - diff "^3.2.0" - minimist "^1.2.0" opn "^5.1.0" os-name "^2.0.1" rimraf "^2.6.1" semver "^5.3.0" - ssh-config "^1.0.1" - tar "^2.2.1" tslib "^1.7.1" ionicons@3.0.0: @@ -3121,6 +3247,10 @@ ipaddr.js@1.3.0: version "1.3.0" resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.3.0.tgz#1e03a52fdad83a8bbb2b25cbf4998b4cffcd3dec" +ipaddr.js@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.4.0.tgz#296aca878a821816e5b85d0a285a99bcff4582f0" + is-absolute-url@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-absolute-url/-/is-absolute-url-2.1.0.tgz#50530dfb84fcc9aa7dbe7852e83a37b93b9f2aa6" @@ -4106,6 +4236,10 @@ mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkd dependencies: minimist "0.0.8" +moment@^2.16.0: + version "2.18.1" + resolved "https://registry.yarnpkg.com/moment/-/moment-2.18.1.tgz#c36193dd3ce1c2eed2adb7c802dbbc77a81b1c0f" + ms@0.7.1: version "0.7.1" resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" @@ -5004,7 +5138,14 @@ proxy-addr@~1.1.3, proxy-addr@~1.1.4: forwarded "~0.1.0" ipaddr.js "1.3.0" -proxy-middleware@0.15.0: +proxy-addr@~1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.5.tgz#71c0ee3b102de3f202f3b64f608d173fcba1a918" + dependencies: + forwarded "~0.1.0" + ipaddr.js "1.4.0" + +proxy-middleware@0.15.0, proxy-middleware@^0.15.0: version "0.15.0" resolved "https://registry.yarnpkg.com/proxy-middleware/-/proxy-middleware-0.15.0.tgz#a3fdf1befb730f951965872ac2f6074c61477a56" @@ -5060,7 +5201,7 @@ qs@6.4.0, qs@~6.4.0: version "6.4.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" -qs@^6.1.0, qs@^6.2.0: +qs@6.5.0, qs@^6.1.0, qs@^6.2.0, qs@^6.4.0: version "6.5.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.0.tgz#8d04954d364def3efc55b5a0793e1e2c8b1e6e49" @@ -5645,6 +5786,24 @@ send@0.15.3: range-parser "~1.2.0" statuses "~1.3.1" +send@0.15.4: + version "0.15.4" + resolved "https://registry.yarnpkg.com/send/-/send-0.15.4.tgz#985faa3e284b0273c793364a35c6737bd93905b9" + dependencies: + debug "2.6.8" + depd "~1.1.1" + destroy "~1.0.4" + encodeurl "~1.0.1" + escape-html "~1.0.3" + etag "~1.8.0" + fresh "0.5.0" + http-errors "~1.6.2" + mime "1.3.4" + ms "2.0.0" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.3.1" + serve-index@^1.7.2: version "1.9.0" resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.9.0.tgz#d2b280fc560d616ee81b48bf0fa82abed2485ce7" @@ -5666,6 +5825,15 @@ serve-static@1.12.3: parseurl "~1.3.1" send "0.15.3" +serve-static@1.12.4: + version "1.12.4" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.12.4.tgz#9b6aa98eeb7253c4eedc4c1f6fdbca609901a961" + dependencies: + encodeurl "~1.0.1" + escape-html "~1.0.3" + parseurl "~1.3.1" + send "0.15.4" + serve-static@~1.11.2: version "1.11.2" resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.11.2.tgz#2cf9889bd4435a320cc36895c9aa57bd662e6ac7" @@ -6203,6 +6371,17 @@ tiny-lr@1.0.3: object-assign "^4.1.0" qs "^6.2.0" +tiny-lr@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/tiny-lr/-/tiny-lr-1.0.5.tgz#21f40bf84ebd1f853056680375eef1670c334112" + dependencies: + body "^5.1.0" + debug "~2.6.7" + faye-websocket "~0.10.0" + livereload-js "^2.2.2" + object-assign "^4.1.0" + qs "^6.4.0" + tmp@0.0.24: version "0.0.24" resolved "https://registry.yarnpkg.com/tmp/-/tmp-0.0.24.tgz#d6a5e198d14a9835cc6f2d7c3d9e302428c8cf12"