diff --git a/docs/GUIDELINES.md b/docs/GUIDELINES.md index c24b375cb..8876b0805 100644 --- a/docs/GUIDELINES.md +++ b/docs/GUIDELINES.md @@ -12,17 +12,6 @@ Please see `docs/BUILD.md` and `docs/TEST.md` -## Directory Layout - -* `docs` Documentation for developers. -* `landing` Source code for our [landing page](http://loophabits.org/). -* `uhabits-android` Android-specific code. -* `uhabits-core` Common code used by all platforms (Android, iOS). -* `uhabits-core-legacy` Proof-of-concept module, developed to evaluate the feasibility of using Kotlin multiplatform for the app; not currently used, and it will be removed soon, once all useful code is ported to the other modules. -* `uhabits-ios` Experimental iOS port of Loop. Not currently used in production. -* `uhabits-server` Source code for any server-side components the app (for example, device sync). -* `uhabits-web` Experimental web port of Loop. Not currently used in production. - ## Branching Policy This repository uses the [git-flow branching model](https://nvie.com/posts/a-successful-git-branching-model/). Basically, there are two main branches, `dev` and `master`. All the development takes place in the `dev` branch. After the new features have been implemented and tested, they are merged into the `master` branch and a new version of the app is released. Please submit your pull requests against the `dev` branch. diff --git a/tools/androidStringsToKt.sh b/tools/androidStringsToKt.sh deleted file mode 100755 index b1ed51dcf..000000000 --- a/tools/androidStringsToKt.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/bash -input=$1 -locale_name=$2 - -cat <\([^<]*\)<.*/ '"$prefix"'val \1 = "\2"/' - -echo "}" diff --git a/tools/convertAllStrings.sh b/tools/convertAllStrings.sh deleted file mode 100755 index fba8830b9..000000000 --- a/tools/convertAllStrings.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash - -INPUT_DIR=../android/uhabits-android/src/main/res/ -OUTPUT_DIR=../core/src/commonMain/kotlin/org/isoron/uhabits/i18n/ - -convert() { - ./androidStringsToKt.sh $INPUT_DIR/$1/strings.xml "$2" > $OUTPUT_DIR/Strings$2.kt -} - -#convert values "" -convert values-ar Arabic -convert values-bg Bulgarian -convert values-ca Catalan -convert values-cs Czech -convert values-da Danish -convert values-de German -convert values-el Greek -convert values-eo Esperanto -convert values-es Spanish -convert values-eu Basque -convert values-fa Persian -convert values-fi Finnish -convert values-fr French -convert values-hi Hindi -convert values-hr Croatian -convert values-hu Hungarian -convert values-in Indonesian -convert values-it Italian -convert values-iw Hebrew -convert values-ja Japanese -convert values-ko Korean -convert values-nl Dutch -convert values-no-rNO Norwegian -convert values-pl Polish -convert values-pt-rBR PortugueseBR -convert values-pt-rPT PortuguesePT -convert values-ro Romanian -convert values-ru Russian -convert values-sl Slovak -convert values-sr Serbian -convert values-sv Swedish -convert values-tr Turkish -convert values-uk Ukrainian -convert values-vi Vietnamese -convert values-zh-rCN ChineseCN -convert values-zh-rTW ChineseTW diff --git a/uhabits-core-legacy/assets/main/databases/template.db b/uhabits-core-legacy/assets/main/databases/template.db deleted file mode 100644 index 5e920e8d7..000000000 Binary files a/uhabits-core-legacy/assets/main/databases/template.db and /dev/null differ diff --git a/uhabits-core-legacy/assets/main/fonts/FontAwesome.ttf b/uhabits-core-legacy/assets/main/fonts/FontAwesome.ttf deleted file mode 100644 index bc640928c..000000000 Binary files a/uhabits-core-legacy/assets/main/fonts/FontAwesome.ttf and /dev/null differ diff --git a/uhabits-core-legacy/assets/main/fonts/NotoSans-Bold.ttf b/uhabits-core-legacy/assets/main/fonts/NotoSans-Bold.ttf deleted file mode 100755 index 987da8c9b..000000000 Binary files a/uhabits-core-legacy/assets/main/fonts/NotoSans-Bold.ttf and /dev/null differ diff --git a/uhabits-core-legacy/assets/main/fonts/NotoSans-Regular.ttf b/uhabits-core-legacy/assets/main/fonts/NotoSans-Regular.ttf deleted file mode 100755 index 79a438a53..000000000 Binary files a/uhabits-core-legacy/assets/main/fonts/NotoSans-Regular.ttf and /dev/null differ diff --git a/uhabits-core-legacy/assets/main/migrations/001.sql b/uhabits-core-legacy/assets/main/migrations/001.sql deleted file mode 100644 index e69de29bb..000000000 diff --git a/uhabits-core-legacy/assets/main/migrations/002.sql b/uhabits-core-legacy/assets/main/migrations/002.sql deleted file mode 100644 index e69de29bb..000000000 diff --git a/uhabits-core-legacy/assets/main/migrations/003.sql b/uhabits-core-legacy/assets/main/migrations/003.sql deleted file mode 100644 index e69de29bb..000000000 diff --git a/uhabits-core-legacy/assets/main/migrations/004.sql b/uhabits-core-legacy/assets/main/migrations/004.sql deleted file mode 100644 index e69de29bb..000000000 diff --git a/uhabits-core-legacy/assets/main/migrations/005.sql b/uhabits-core-legacy/assets/main/migrations/005.sql deleted file mode 100644 index e69de29bb..000000000 diff --git a/uhabits-core-legacy/assets/main/migrations/006.sql b/uhabits-core-legacy/assets/main/migrations/006.sql deleted file mode 100644 index e69de29bb..000000000 diff --git a/uhabits-core-legacy/assets/main/migrations/007.sql b/uhabits-core-legacy/assets/main/migrations/007.sql deleted file mode 100644 index e69de29bb..000000000 diff --git a/uhabits-core-legacy/assets/main/migrations/008.sql b/uhabits-core-legacy/assets/main/migrations/008.sql deleted file mode 100644 index e69de29bb..000000000 diff --git a/uhabits-core-legacy/assets/main/migrations/009.sql b/uhabits-core-legacy/assets/main/migrations/009.sql deleted file mode 100644 index 5a4afd962..000000000 --- a/uhabits-core-legacy/assets/main/migrations/009.sql +++ /dev/null @@ -1,5 +0,0 @@ -create table Habits ( id integer primary key autoincrement, archived integer, color integer, description text, freq_den integer, freq_num integer, highlight integer, name text, position integer, reminder_hour integer, reminder_min integer ) -create table Checkmarks ( id integer primary key autoincrement, habit integer references habits(id), timestamp integer, value integer ) -create table Repetitions ( id integer primary key autoincrement, habit integer references habits(id), timestamp integer ) -create table Streak ( id integer primary key autoincrement, end integer, habit integer references habits(id), length integer, start integer ) -create table Score ( id integer primary key autoincrement, habit integer references habits(id), score integer, timestamp integer ) diff --git a/uhabits-core-legacy/assets/main/migrations/010.sql b/uhabits-core-legacy/assets/main/migrations/010.sql deleted file mode 100644 index afae84e20..000000000 --- a/uhabits-core-legacy/assets/main/migrations/010.sql +++ /dev/null @@ -1,3 +0,0 @@ -delete from Score -delete from Streak -delete from Checkmarks \ No newline at end of file diff --git a/uhabits-core-legacy/assets/main/migrations/011.sql b/uhabits-core-legacy/assets/main/migrations/011.sql deleted file mode 100644 index 6ea4e2390..000000000 --- a/uhabits-core-legacy/assets/main/migrations/011.sql +++ /dev/null @@ -1 +0,0 @@ -alter table Habits add column reminder_days integer not null default 127 \ No newline at end of file diff --git a/uhabits-core-legacy/assets/main/migrations/012.sql b/uhabits-core-legacy/assets/main/migrations/012.sql deleted file mode 100644 index afae84e20..000000000 --- a/uhabits-core-legacy/assets/main/migrations/012.sql +++ /dev/null @@ -1,3 +0,0 @@ -delete from Score -delete from Streak -delete from Checkmarks \ No newline at end of file diff --git a/uhabits-core-legacy/assets/main/migrations/013.sql b/uhabits-core-legacy/assets/main/migrations/013.sql deleted file mode 100644 index dbb9b4438..000000000 --- a/uhabits-core-legacy/assets/main/migrations/013.sql +++ /dev/null @@ -1,4 +0,0 @@ -create index idx_score_habit_timestamp on Score(habit, timestamp) -create index idx_checkmark_habit_timestamp on Checkmarks(habit, timestamp) -create index idx_repetitions_habit_timestamp on Repetitions(habit, timestamp) -create index idx_streak_habit_end on Streak(habit, end) \ No newline at end of file diff --git a/uhabits-core-legacy/assets/main/migrations/014.sql b/uhabits-core-legacy/assets/main/migrations/014.sql deleted file mode 100644 index 6eecfc046..000000000 --- a/uhabits-core-legacy/assets/main/migrations/014.sql +++ /dev/null @@ -1,14 +0,0 @@ -update habits set color=0 where color=-2937041 -update habits set color=1 where color=-1684967 -update habits set color=2 where color=-415707 -update habits set color=3 where color=-5262293 -update habits set color=4 where color=-13070788 -update habits set color=5 where color=-16742021 -update habits set color=6 where color=-16732991 -update habits set color=7 where color=-16540699 -update habits set color=8 where color=-10603087 -update habits set color=9 where color=-7461718 -update habits set color=10 where color=-2614432 -update habits set color=11 where color=-13619152 -update habits set color=12 where color=-5592406 -update habits set color=0 where color<0 or color>12 \ No newline at end of file diff --git a/uhabits-core-legacy/assets/main/migrations/015.sql b/uhabits-core-legacy/assets/main/migrations/015.sql deleted file mode 100644 index afae84e20..000000000 --- a/uhabits-core-legacy/assets/main/migrations/015.sql +++ /dev/null @@ -1,3 +0,0 @@ -delete from Score -delete from Streak -delete from Checkmarks \ No newline at end of file diff --git a/uhabits-core-legacy/assets/main/migrations/016.sql b/uhabits-core-legacy/assets/main/migrations/016.sql deleted file mode 100644 index 059f2016b..000000000 --- a/uhabits-core-legacy/assets/main/migrations/016.sql +++ /dev/null @@ -1,2 +0,0 @@ -alter table Habits add column type integer not null default 0 -alter table Repetitions add column value integer not null default 2 \ No newline at end of file diff --git a/uhabits-core-legacy/assets/main/migrations/017.sql b/uhabits-core-legacy/assets/main/migrations/017.sql deleted file mode 100644 index 15430d771..000000000 --- a/uhabits-core-legacy/assets/main/migrations/017.sql +++ /dev/null @@ -1,5 +0,0 @@ -drop table Score -create table Score ( id integer primary key autoincrement, habit integer references habits(id), score real, timestamp integer) -create index idx_score_habit_timestamp on Score(habit, timestamp) -delete from streak -delete from checkmarks \ No newline at end of file diff --git a/uhabits-core-legacy/assets/main/migrations/018.sql b/uhabits-core-legacy/assets/main/migrations/018.sql deleted file mode 100644 index 4cdc9cc8d..000000000 --- a/uhabits-core-legacy/assets/main/migrations/018.sql +++ /dev/null @@ -1,3 +0,0 @@ -alter table Habits add column target_type integer not null default 0 -alter table Habits add column target_value real not null default 0 -alter table Habits add column unit text not null default "" \ No newline at end of file diff --git a/uhabits-core-legacy/assets/main/migrations/019.sql b/uhabits-core-legacy/assets/main/migrations/019.sql deleted file mode 100644 index 0569ea531..000000000 --- a/uhabits-core-legacy/assets/main/migrations/019.sql +++ /dev/null @@ -1 +0,0 @@ -create table Events ( id integer primary key autoincrement, timestamp integer, message text, server_id integer ) \ No newline at end of file diff --git a/uhabits-core-legacy/assets/main/migrations/020.sql b/uhabits-core-legacy/assets/main/migrations/020.sql deleted file mode 100644 index 254bb7b80..000000000 --- a/uhabits-core-legacy/assets/main/migrations/020.sql +++ /dev/null @@ -1,3 +0,0 @@ -drop table checkmarks -drop table streak -drop table score diff --git a/uhabits-core-legacy/assets/main/migrations/021.sql b/uhabits-core-legacy/assets/main/migrations/021.sql deleted file mode 100644 index 547b6759d..000000000 --- a/uhabits-core-legacy/assets/main/migrations/021.sql +++ /dev/null @@ -1,12 +0,0 @@ -update habits set color=19 where color=12 -update habits set color=17 where color=11 -update habits set color=15 where color=10 -update habits set color=14 where color=9 -update habits set color=13 where color=8 -update habits set color=10 where color=7 -update habits set color=9 where color=6 -update habits set color=8 where color=5 -update habits set color=7 where color=4 -update habits set color=5 where color=3 -update habits set color=4 where color=2 -update habits set color=0 where color<0 or color>19 \ No newline at end of file diff --git a/uhabits-core-legacy/assets/main/migrations/022.sql b/uhabits-core-legacy/assets/main/migrations/022.sql deleted file mode 100644 index b9ca2ba5a..000000000 --- a/uhabits-core-legacy/assets/main/migrations/022.sql +++ /dev/null @@ -1,11 +0,0 @@ -delete from repetitions where habit not in (select id from habits) -delete from repetitions where timestamp is null -delete from repetitions where habit is null -delete from repetitions where rowid not in ( select min(rowid) from repetitions group by habit, timestamp ) -alter table Repetitions rename to RepetitionsBak -create table Repetitions ( id integer primary key autoincrement, habit integer not null references habits(id), timestamp integer not null, value integer not null) -drop index if exists idx_repetitions_habit_timestamp -create unique index idx_repetitions_habit_timestamp on Repetitions( habit, timestamp) -insert into Repetitions select * from RepetitionsBak -drop table RepetitionsBak -pragma foreign_keys=ON \ No newline at end of file diff --git a/uhabits-core-legacy/assets/main/migrations/023.sql b/uhabits-core-legacy/assets/main/migrations/023.sql deleted file mode 100644 index 456a4d071..000000000 --- a/uhabits-core-legacy/assets/main/migrations/023.sql +++ /dev/null @@ -1 +0,0 @@ -create table Preferences(key text unique not null, value text not null) \ No newline at end of file diff --git a/uhabits-core-legacy/assets/test/components/BarChart/2-series.png b/uhabits-core-legacy/assets/test/components/BarChart/2-series.png deleted file mode 100644 index 833e4b19c..000000000 Binary files a/uhabits-core-legacy/assets/test/components/BarChart/2-series.png and /dev/null differ diff --git a/uhabits-core-legacy/assets/test/components/BarChart/axis-monthly.png b/uhabits-core-legacy/assets/test/components/BarChart/axis-monthly.png deleted file mode 100644 index 1313b4f94..000000000 Binary files a/uhabits-core-legacy/assets/test/components/BarChart/axis-monthly.png and /dev/null differ diff --git a/uhabits-core-legacy/assets/test/components/BarChart/axis-weekly.png b/uhabits-core-legacy/assets/test/components/BarChart/axis-weekly.png deleted file mode 100644 index 330923a42..000000000 Binary files a/uhabits-core-legacy/assets/test/components/BarChart/axis-weekly.png and /dev/null differ diff --git a/uhabits-core-legacy/assets/test/components/BarChart/axis-yearly.png b/uhabits-core-legacy/assets/test/components/BarChart/axis-yearly.png deleted file mode 100644 index ec97df8a1..000000000 Binary files a/uhabits-core-legacy/assets/test/components/BarChart/axis-yearly.png and /dev/null differ diff --git a/uhabits-core-legacy/assets/test/components/BarChart/base.png b/uhabits-core-legacy/assets/test/components/BarChart/base.png deleted file mode 100644 index 54d6862d7..000000000 Binary files a/uhabits-core-legacy/assets/test/components/BarChart/base.png and /dev/null differ diff --git a/uhabits-core-legacy/assets/test/components/CalendarChart/base.png b/uhabits-core-legacy/assets/test/components/CalendarChart/base.png deleted file mode 100644 index 762877164..000000000 Binary files a/uhabits-core-legacy/assets/test/components/CalendarChart/base.png and /dev/null differ diff --git a/uhabits-core-legacy/assets/test/components/CalendarChart/scroll.png b/uhabits-core-legacy/assets/test/components/CalendarChart/scroll.png deleted file mode 100644 index 16744a297..000000000 Binary files a/uhabits-core-legacy/assets/test/components/CalendarChart/scroll.png and /dev/null differ diff --git a/uhabits-core-legacy/assets/test/components/CanvasTest.png b/uhabits-core-legacy/assets/test/components/CanvasTest.png deleted file mode 100644 index 75b3d8f20..000000000 Binary files a/uhabits-core-legacy/assets/test/components/CanvasTest.png and /dev/null differ diff --git a/uhabits-core-legacy/assets/test/components/CheckmarkButton/explicit.png b/uhabits-core-legacy/assets/test/components/CheckmarkButton/explicit.png deleted file mode 100644 index c2b66f74e..000000000 Binary files a/uhabits-core-legacy/assets/test/components/CheckmarkButton/explicit.png and /dev/null differ diff --git a/uhabits-core-legacy/assets/test/components/CheckmarkButton/implicit.png b/uhabits-core-legacy/assets/test/components/CheckmarkButton/implicit.png deleted file mode 100644 index acc067024..000000000 Binary files a/uhabits-core-legacy/assets/test/components/CheckmarkButton/implicit.png and /dev/null differ diff --git a/uhabits-core-legacy/assets/test/components/CheckmarkButton/unchecked.png b/uhabits-core-legacy/assets/test/components/CheckmarkButton/unchecked.png deleted file mode 100644 index 283f32d40..000000000 Binary files a/uhabits-core-legacy/assets/test/components/CheckmarkButton/unchecked.png and /dev/null differ diff --git a/uhabits-core-legacy/assets/test/components/HabitListHeader/light.png b/uhabits-core-legacy/assets/test/components/HabitListHeader/light.png deleted file mode 100644 index c146b916d..000000000 Binary files a/uhabits-core-legacy/assets/test/components/HabitListHeader/light.png and /dev/null differ diff --git a/uhabits-core-legacy/assets/test/components/NumberButton/render_above.png b/uhabits-core-legacy/assets/test/components/NumberButton/render_above.png deleted file mode 100644 index 4673ef0f3..000000000 Binary files a/uhabits-core-legacy/assets/test/components/NumberButton/render_above.png and /dev/null differ diff --git a/uhabits-core-legacy/assets/test/components/NumberButton/render_below.png b/uhabits-core-legacy/assets/test/components/NumberButton/render_below.png deleted file mode 100644 index c3ffb68de..000000000 Binary files a/uhabits-core-legacy/assets/test/components/NumberButton/render_below.png and /dev/null differ diff --git a/uhabits-core-legacy/assets/test/components/NumberButton/render_zero.png b/uhabits-core-legacy/assets/test/components/NumberButton/render_zero.png deleted file mode 100644 index 235de2f62..000000000 Binary files a/uhabits-core-legacy/assets/test/components/NumberButton/render_zero.png and /dev/null differ diff --git a/uhabits-core-legacy/assets/test/components/Ring/draw1.png b/uhabits-core-legacy/assets/test/components/Ring/draw1.png deleted file mode 100644 index d5e80f455..000000000 Binary files a/uhabits-core-legacy/assets/test/components/Ring/draw1.png and /dev/null differ diff --git a/uhabits-core-legacy/assets/test/hello.txt b/uhabits-core-legacy/assets/test/hello.txt deleted file mode 100644 index e432ffe94..000000000 --- a/uhabits-core-legacy/assets/test/hello.txt +++ /dev/null @@ -1,2 +0,0 @@ -Hello World! -This is a resource. \ No newline at end of file diff --git a/uhabits-core-legacy/build.gradle b/uhabits-core-legacy/build.gradle deleted file mode 100644 index dc545c340..000000000 --- a/uhabits-core-legacy/build.gradle +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -plugins { - id 'kotlin-multiplatform' version "1.3.72" -} - -repositories { - mavenCentral() -} - -kotlin { - targets { - def sdkName = System.getenv('SDK_NAME') - def isIphone = sdkName?.startsWith("iphoneos") - def iosPreset = isIphone ? presets.iosArm64 : presets.iosX64 - - fromPreset(iosPreset, 'ios') { - binaries { - framework { - baseName = "LoopHabitTracker" - } - } - compilations.main { - cinterops { - sqlite3 { - defFile project.file("src/main/c_interop/sqlite3.def") - } - } - } - } - - fromPreset(presets.jvm, 'jvm') { - - } - - fromPreset(presets.js, 'js') { - compilations.main.kotlinOptions { - moduleKind = "commonjs" - } - compilations.test.kotlinOptions { - moduleKind = "commonjs" - } - } - } - - sourceSets { - commonMain { - kotlin { srcDir "src/main/common" } - dependencies { - implementation kotlin('stdlib-common') - implementation "$KX_COROUTINES-core-common:$KX_COROUTINES_VERSION" - } - } - - commonTest { - kotlin { srcDir "src/test/common" } - dependencies { - implementation kotlin('test-common') - implementation kotlin('test-annotations-common') - } - } - - jvmMain { - kotlin { srcDir "src/main/jvm" } - dependencies { - implementation kotlin('stdlib-jdk8') - implementation "$KX_COROUTINES-core:$KX_COROUTINES_VERSION" - } - } - - jvmTest { - kotlin { srcDir "src/test/jvm" } - dependencies { - implementation kotlin('test') - implementation kotlin('test-junit') - implementation 'org.xerial:sqlite-jdbc:3.25.2' - } - } - - jsMain { - kotlin { srcDir "src/main/js" } - dependencies { - implementation kotlin('stdlib-js') - implementation "$KX_COROUTINES-core-js:$KX_COROUTINES_VERSION" - } - } - - jsTest { - kotlin { srcDir "src/test/js" } - dependencies { - implementation kotlin('test-js') - } - } - - iosMain { - kotlin { srcDir "src/main/ios" } - dependencies { - implementation "$KX_COROUTINES-core-native:$KX_COROUTINES_VERSION" - } - } - - iosTest { - kotlin { srcDir "src/test/ios" } - dependencies { - implementation "$KX_COROUTINES-core-native:$KX_COROUTINES_VERSION" - } - } - } - - task iosTestCopyResources(type: Copy) { - from 'assets/test/' - from 'assets/main/' - into 'build/bin/ios/debugTest' - } - - if (project.tasks.findByName('iosTest')) { - iosTest.dependsOn(iosTestCopyResources) - } -} diff --git a/uhabits-core-legacy/gradle.properties b/uhabits-core-legacy/gradle.properties deleted file mode 100644 index fae8ffca6..000000000 --- a/uhabits-core-legacy/gradle.properties +++ /dev/null @@ -1,2 +0,0 @@ -KX_COROUTINES_VERSION=1.3.6 -KX_COROUTINES=org.jetbrains.kotlinx:kotlinx-coroutines \ No newline at end of file diff --git a/uhabits-core-legacy/settings.gradle b/uhabits-core-legacy/settings.gradle deleted file mode 100644 index 20ee303a3..000000000 --- a/uhabits-core-legacy/settings.gradle +++ /dev/null @@ -1,9 +0,0 @@ -pluginManagement { - resolutionStrategy { - eachPlugin { - if (requested.id.id == "kotlin-multiplatform") { - useModule("org.jetbrains.kotlin:kotlin-gradle-plugin:${requested.version}") - } - } - } -} diff --git a/uhabits-core-legacy/src/main/c_interop/sqlite3.def b/uhabits-core-legacy/src/main/c_interop/sqlite3.def deleted file mode 100644 index 08646e486..000000000 --- a/uhabits-core-legacy/src/main/c_interop/sqlite3.def +++ /dev/null @@ -1,25 +0,0 @@ -package = sqlite3 -headers = sqlite3.h -headerFilter = sqlite3*.h -compilerOpts = -std=c11 -linkerOpts.ios = -lsqlite3 -excludedFunctions = sqlite3_mutex_held \ - sqlite3_mutex_notheld \ - sqlite3_snapshot_cmp \ - sqlite3_snapshot_free \ - sqlite3_snapshot_get \ - sqlite3_snapshot_open \ - sqlite3_snapshot_recover \ - sqlite3_set_last_insert_rowid \ - sqlite3_stmt_scanstatus \ - sqlite3_stmt_scanstatus_reset \ - sqlite3_column_database_name \ - sqlite3_column_database_name16 \ - sqlite3_column_origin_name \ - sqlite3_column_origin_name16 \ - sqlite3_column_table_name \ - sqlite3_column_table_name16 \ - sqlite3_enable_load_extension \ - sqlite3_load_extension \ - sqlite3_unlock_notify -noStringConversion = sqlite3_prepare_v2 sqlite3_prepare_v3 diff --git a/uhabits-core-legacy/src/main/common/org/isoron/platform/concurrency/Observable.kt b/uhabits-core-legacy/src/main/common/org/isoron/platform/concurrency/Observable.kt deleted file mode 100644 index 9aa11a5e6..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/platform/concurrency/Observable.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.concurrency - -class Observable { - private val listeners = mutableListOf() - - fun addListener(listener: T) { - listeners.add(listener) - } - - fun notifyListeners(action: (T) -> Unit) { - for (l in listeners) action.invoke(l) - } - - fun removeListener(listener: T) { - listeners.remove(listener) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/platform/gui/Canvas.kt b/uhabits-core-legacy/src/main/common/org/isoron/platform/gui/Canvas.kt deleted file mode 100644 index b397febb4..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/platform/gui/Canvas.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.gui - -enum class TextAlign { - LEFT, CENTER, RIGHT -} - -enum class Font { - REGULAR, - BOLD, - FONT_AWESOME -} - -interface Canvas { - fun setColor(color: Color) - fun drawLine(x1: Double, y1: Double, x2: Double, y2: Double) - fun drawText(text: String, x: Double, y: Double) - fun fillRect(x: Double, y: Double, width: Double, height: Double) - fun drawRect(x: Double, y: Double, width: Double, height: Double) - fun getHeight(): Double - fun getWidth(): Double - fun setFont(font: Font) - fun setFontSize(size: Double) - fun setStrokeWidth(size: Double) - fun fillArc(centerX: Double, - centerY: Double, - radius: Double, - startAngle: Double, - swipeAngle: Double) - fun fillCircle(centerX: Double, centerY: Double, radius: Double) - fun setTextAlign(align: TextAlign) - fun toImage(): Image -} - diff --git a/uhabits-core-legacy/src/main/common/org/isoron/platform/gui/Colors.kt b/uhabits-core-legacy/src/main/common/org/isoron/platform/gui/Colors.kt deleted file mode 100644 index 4161c1218..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/platform/gui/Colors.kt +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.gui - -data class PaletteColor(val index: Int) - -data class Color(val red: Double, - val green: Double, - val blue: Double, - val alpha: Double) { - - val luminosity: Double - get() { - return 0.21 * red + 0.72 * green + 0.07 * blue - } - - constructor(rgb: Int) : this(((rgb shr 16) and 0xFF) / 255.0, - ((rgb shr 8) and 0xFF) / 255.0, - ((rgb shr 0) and 0xFF) / 255.0, - 1.0) - - fun blendWith(other: Color, weight: Double): Color { - return Color(red * (1 - weight) + other.red * weight, - green * (1 - weight) + other.green * weight, - blue * (1 - weight) + other.blue * weight, - alpha * (1 - weight) + other.alpha * weight) - } -} diff --git a/uhabits-core-legacy/src/main/common/org/isoron/platform/gui/Component.kt b/uhabits-core-legacy/src/main/common/org/isoron/platform/gui/Component.kt deleted file mode 100644 index d7ab56a68..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/platform/gui/Component.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.gui - -interface Component { - fun draw(canvas: Canvas) -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/platform/gui/FontAwesome.kt b/uhabits-core-legacy/src/main/common/org/isoron/platform/gui/FontAwesome.kt deleted file mode 100644 index 3791228df..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/platform/gui/FontAwesome.kt +++ /dev/null @@ -1,27 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.gui - -class FontAwesome { - companion object { - val CHECK = "\uf00c" - val TIMES = "\uf00d" - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/platform/gui/Image.kt b/uhabits-core-legacy/src/main/common/org/isoron/platform/gui/Image.kt deleted file mode 100644 index 044df1c6f..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/platform/gui/Image.kt +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.gui - -import kotlin.math.* - -interface Image { - val width: Int - val height: Int - - fun getPixel(x: Int, y: Int): Color - fun setPixel(x: Int, y: Int, color: Color) - - suspend fun export(path: String) - - fun diff(other: Image) { - if (width != other.width) error("Width must match: $width !== ${other.width}") - if (height != other.height) error("Height must match: $height !== ${other.height}") - - for (x in 0 until width) { - for (y in 0 until height) { - val p1 = getPixel(x, y) - var l = 1.0 - for (dx in -2..2) { - if (x + dx < 0 || x + dx >= width) continue - for (dy in -2..2) { - if (y + dy < 0 || y + dy >= height) continue - val p2 = other.getPixel(x + dx, y + dy) - l = min(l, abs(p1.luminosity - p2.luminosity)) - } - } - setPixel(x, y, Color(l, l, l, 1.0)) - } - } - } - - val averageLuminosity: Double - get() { - var luminosity = 0.0 - for (x in 0 until width) { - for (y in 0 until height) { - luminosity += getPixel(x, y).luminosity - } - } - return luminosity / (width * height) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/platform/io/Database.kt b/uhabits-core-legacy/src/main/common/org/isoron/platform/io/Database.kt deleted file mode 100644 index ab0409214..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/platform/io/Database.kt +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.io - -interface PreparedStatement { - fun step(): StepResult - fun finalize() - fun getInt(index: Int): Int - fun getLong(index: Int): Long - fun getText(index: Int): String - fun getReal(index: Int): Double - fun bindInt(index: Int, value: Int) - fun bindLong(index: Int, value: Long) - fun bindText(index: Int, value: String) - fun bindReal(index: Int, value: Double) - fun reset() -} - -enum class StepResult { - ROW, - DONE -} - -interface DatabaseOpener { - fun open(file: UserFile): Database -} - -interface Database { - fun prepareStatement(sql: String): PreparedStatement - fun close() -} - -fun Database.run(sql: String) { - val stmt = prepareStatement(sql) - stmt.step() - stmt.finalize() -} - -fun Database.queryInt(sql: String): Int { - val stmt = prepareStatement(sql) - stmt.step() - val result = stmt.getInt(0) - stmt.finalize() - return result -} - -fun Database.nextId(tableName: String): Int { - val stmt = prepareStatement("select seq from sqlite_sequence where name='$tableName'") - if (stmt.step() == StepResult.ROW) { - val result = stmt.getInt(0) - stmt.finalize() - return result + 1 - } else { - return 0 - } -} - -fun Database.begin() = run("begin") - -fun Database.commit() = run("commit") - -fun Database.getVersion() = queryInt("pragma user_version") - -fun Database.setVersion(v: Int) = run("pragma user_version = $v") - -suspend fun Database.migrateTo(newVersion: Int, - fileOpener: FileOpener, - log: Log) { - val currentVersion = getVersion() - log.debug("Database", "Current database version: $currentVersion") - - if (currentVersion == newVersion) return - log.debug("Database", "Upgrading to version: $newVersion") - - if (currentVersion > newVersion) - throw RuntimeException("database produced by future version of the application") - - begin() - for (v in (currentVersion + 1)..newVersion) { - val sv = if (v < 10) "00$v" else if (v < 100) "0$v" else "$v" - val filename = "migrations/$sv.sql" - val migrationFile = fileOpener.openResourceFile(filename) - for (line in migrationFile.lines()) { - if (line.isEmpty()) continue - run(line) - } - setVersion(v) - } - commit() -} diff --git a/uhabits-core-legacy/src/main/common/org/isoron/platform/io/Files.kt b/uhabits-core-legacy/src/main/common/org/isoron/platform/io/Files.kt deleted file mode 100644 index babecf082..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/platform/io/Files.kt +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.io - -import org.isoron.platform.gui.* - -interface FileOpener { - /** - * Opens a file which was shipped bundled with the application, such as a - * migration file. - * - * The path is relative to the assets folder. For example, to open - * assets/main/migrations/09.sql you should provide migrations/09.sql - * as the path. - * - * This function always succeed, even if the file does not exist. - */ - fun openResourceFile(path: String): ResourceFile - - /** - * Opens a file which was not shipped with the application, such as - * databases and logs. - * - * The path is relative to the user folder. For example, if the application - * stores the user data at /home/user/.loop/ and you wish to open the file - * /home/user/.loop/crash.log, you should provide crash.log as the path. - * - * This function always succeed, even if the file does not exist. - */ - fun openUserFile(path: String): UserFile -} - -/** - * Represents a file that was created after the application was installed, as a - * result of some user action, such as databases and logs. - */ -interface UserFile { - /** - * Deletes the user file. If the file does not exist, nothing happens. - */ - suspend fun delete() - - /** - * Returns true if the file exists. - */ - suspend fun exists(): Boolean - - /** - * Returns the lines of the file. If the file does not exist, throws an - * exception. - */ - suspend fun lines(): List -} - -/** - * Represents a file that was shipped with the application, such as migration - * files or database templates. - */ -interface ResourceFile { - /** - * Copies the resource file to the specified user file. If the user file - * already exists, it is replaced. If not, a new file is created. - */ - suspend fun copyTo(dest: UserFile) - - /** - * Returns the lines of the resource file. If the file does not exist, - * throws an exception. - */ - suspend fun lines(): List - - /** - * Returns true if the file exists. - */ - suspend fun exists(): Boolean - - /** - * Loads resource file as an image. - */ - suspend fun toImage(): Image -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/platform/io/Log.kt b/uhabits-core-legacy/src/main/common/org/isoron/platform/io/Log.kt deleted file mode 100644 index 60c372237..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/platform/io/Log.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.io - -interface Log { - fun info(tag: String, msg: String) - fun debug(tag: String, msg: String) - fun warn(tag: String, msg: String) -} - -/** - * A Log that prints to the standard output. - */ -class StandardLog : Log { - override fun warn(tag: String, msg: String) { - val ftag = format("%-20s", tag) - println("W $ftag $msg") - } - - override fun info(tag: String, msg: String) { - val ftag = format("%-20s", tag) - println("I $ftag $msg") - } - - override fun debug(tag: String, msg: String) { - val ftag = format("%-20s", tag) - println("D $ftag $msg") - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/platform/io/Strings.kt b/uhabits-core-legacy/src/main/common/org/isoron/platform/io/Strings.kt deleted file mode 100644 index 1a631e131..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/platform/io/Strings.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.io - -expect fun format(format: String, arg: String): String -expect fun format(format: String, arg: Int): String -expect fun format(format: String, arg: Double): String \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/platform/time/Dates.kt b/uhabits-core-legacy/src/main/common/org/isoron/platform/time/Dates.kt deleted file mode 100644 index ea102004f..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/platform/time/Dates.kt +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.time - -import kotlin.math.* - -enum class DayOfWeek(val index: Int) { - SUNDAY(0), - MONDAY(1), - TUESDAY(2), - WEDNESDAY(3), - THURSDAY(4), - FRIDAY(5), - SATURDAY(6), -} - -data class Timestamp(val millisSince1970: Long) { - val localDate: LocalDate - get() { - val millisSince2000 = millisSince1970 - 946684800000 - val daysSince2000 = millisSince2000 / 86400000 - return LocalDate(daysSince2000.toInt()) - } -} - -data class LocalDate(val daysSince2000: Int) { - - var yearCache = -1 - var monthCache = -1 - var dayCache = -1 - -// init { -// if (daysSince2000 < 0) -// throw IllegalArgumentException("$daysSince2000 < 0") -// } - - constructor(year: Int, month: Int, day: Int) : - this(daysSince2000(year, month, day)) - - val dayOfWeek: DayOfWeek - get() { - return when (daysSince2000 % 7) { - 0 -> DayOfWeek.SATURDAY - 1 -> DayOfWeek.SUNDAY - 2 -> DayOfWeek.MONDAY - 3 -> DayOfWeek.TUESDAY - 4 -> DayOfWeek.WEDNESDAY - 5 -> DayOfWeek.THURSDAY - else -> DayOfWeek.FRIDAY - } - } - - val timestamp: Timestamp - get() { - return Timestamp(946684800000 + daysSince2000.toLong() * 86400000) - } - - val year: Int - get() { - if (yearCache < 0) updateYearMonthDayCache() - return yearCache - } - - val month: Int - get() { - if (monthCache < 0) updateYearMonthDayCache() - return monthCache - } - - val day: Int - get() { - if (dayCache < 0) updateYearMonthDayCache() - return dayCache - } - - private fun updateYearMonthDayCache() { - var currYear = 2000 - var currDay = 0 - - while (true) { - val currYearLength = if (isLeapYear(currYear)) 366 else 365 - if (daysSince2000 < currDay + currYearLength) { - yearCache = currYear - break - } else { - currYear++ - currDay += currYearLength - } - } - - var currMonth = 1 - val monthOffset = if (isLeapYear(currYear)) leapOffset else nonLeapOffset - - while (true) { - if (daysSince2000 < currDay + monthOffset[currMonth]) { - monthCache = currMonth - break - } else { - currMonth++ - } - } - - currDay += monthOffset[currMonth - 1] - dayCache = daysSince2000 - currDay + 1 - - } - - fun isOlderThan(other: LocalDate): Boolean { - return daysSince2000 < other.daysSince2000 - } - - fun isNewerThan(other: LocalDate): Boolean { - return daysSince2000 > other.daysSince2000 - } - - fun plus(days: Int): LocalDate { - return LocalDate(daysSince2000 + days) - } - - fun minus(days: Int): LocalDate { - return LocalDate(daysSince2000 - days) - } - - fun distanceTo(other: LocalDate): Int { - return abs(daysSince2000 - other.daysSince2000) - } -} - -interface LocalDateFormatter { - fun shortWeekdayName(date: LocalDate): String - fun shortMonthName(date: LocalDate): String -} - -private fun isLeapYear(year: Int): Boolean { - return (year % 4 == 0 && year % 100 != 0) || year % 400 == 0 -} - -val leapOffset = arrayOf(0, 31, 60, 91, 121, 152, 182, - 213, 244, 274, 305, 335, 366) -val nonLeapOffset = arrayOf(0, 31, 59, 90, 120, 151, 181, - 212, 243, 273, 304, 334, 365) - -private fun daysSince2000(year: Int, month: Int, day: Int): Int { - - var result = 365 * (year - 2000) - result += ceil((year - 2000) / 4.0).toInt() - result -= ceil((year - 2000) / 100.0).toInt() - result += ceil((year - 2000) / 400.0).toInt() - if (isLeapYear(year)) { - result += leapOffset[month - 1] - } else { - result += nonLeapOffset[month - 1] - } - result += (day - 1) - return result -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/Config.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/Config.kt deleted file mode 100644 index fe543e044..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/Config.kt +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits - -const val LOOP_DATABASE_VERSION = 23 \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/backend/Backend.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/backend/Backend.kt deleted file mode 100644 index 0137d3463..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/backend/Backend.kt +++ /dev/null @@ -1,136 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.backend - -import kotlinx.coroutines.* -import org.isoron.platform.concurrency.* -import org.isoron.platform.io.* -import org.isoron.uhabits.* -import org.isoron.uhabits.components.* -import org.isoron.uhabits.i18n.* -import org.isoron.uhabits.models.* -import kotlin.coroutines.* - - -open class BackendScope(private val ctx: CoroutineContext, - private val log: Log) : CoroutineScope { - - private val job = Job() - - private val exceptionHandler = CoroutineExceptionHandler { _, throwable -> - log.info("Coroutine", throwable.toString()) - } - - override val coroutineContext: CoroutineContext - get() = ctx + job + exceptionHandler -} - -class Backend(private val databaseName: String, - private val databaseOpener: DatabaseOpener, - private val fileOpener: FileOpener, - private val localeHelper: LocaleHelper, - private val log: Log, - private val scope: CoroutineContext - ) : CoroutineScope by BackendScope(scope, log) { - - - private lateinit var database: Database - private lateinit var habitsRepository: HabitRepository - private lateinit var checkmarkRepository: CheckmarkRepository - lateinit var preferences: Preferences - - lateinit var mainScreenDataSource: MainScreenDataSource - - private val habits = mutableMapOf() - private val checkmarks = mutableMapOf() - private val scores = mutableMapOf() - - var strings = localeHelper.getStringsForCurrentLocale() - var theme: Theme = LightTheme() - - val observable = Observable() - - fun init() { - launch { - initDatabase() - initRepositories() - initDataSources() - observable.notifyListeners { it.onReady() } - } - } - - private fun initRepositories() { - preferences = Preferences(PreferencesRepository(database)) - habitsRepository = HabitRepository(database) - checkmarkRepository = CheckmarkRepository(database) - habits.putAll(habitsRepository.findAll()) - log.info("Backend", "${habits.size} habits loaded") - for ((key, habit) in habits) { - val checks = checkmarkRepository.findAll(key) - checkmarks[habit] = CheckmarkList(habit.frequency, habit.type) - checkmarks[habit]?.setManualCheckmarks(checks) - scores[habit] = ScoreList(checkmarks[habit]!!) - } - } - - private fun initDataSources() { - mainScreenDataSource = - MainScreenDataSource(preferences, habits, checkmarks, scores) - } - - private suspend fun initDatabase() { - val dbFile = fileOpener.openUserFile(databaseName) - if (!dbFile.exists()) { - val templateFile = fileOpener.openResourceFile("databases/template.db") - templateFile.copyTo(dbFile) - } - database = databaseOpener.open(dbFile) - database.migrateTo(LOOP_DATABASE_VERSION, fileOpener, log) - } - - fun createHabit(habit: Habit) { - val id = habitsRepository.nextId() - habit.id = id - habit.position = habits.size - habits[id] = habit - checkmarks[habit] = CheckmarkList(habit.frequency, habit.type) - habitsRepository.insert(habit) - mainScreenDataSource.requestData() - } - - fun deleteHabit(id: Int) { - habits[id]?.let { habit -> - habitsRepository.delete(habit) - habits.remove(id) - mainScreenDataSource.requestData() - } - } - - fun updateHabit(modified: Habit) { - habits[modified.id]?.let { existing -> - modified.position = existing.position - habitsRepository.update(modified) - } - } - - interface Listener { - fun onReady() - } -} diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/backend/MainScreenDataSource.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/backend/MainScreenDataSource.kt deleted file mode 100644 index 9cadb8cb3..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/backend/MainScreenDataSource.kt +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.backend - -import org.isoron.platform.concurrency.* -import org.isoron.platform.time.* -import org.isoron.uhabits.models.* -import org.isoron.uhabits.models.Checkmark.Companion.UNCHECKED - -class MainScreenDataSource(val preferences: Preferences, - val habits: MutableMap, - val checkmarks: MutableMap, - val scores: MutableMap) { - - val maxNumberOfButtons = 60 - private val today = LocalDate(2019, 3, 30) /* TODO */ - - data class Data(val habits: List, - val scores: Map, - val checkmarks: Map>) - - val observable = Observable() - - interface Listener { - fun onDataChanged(newData: Data) - } - - fun requestData() { - var filtered = habits.values.toList() - - if (!preferences.showArchived) { - filtered = filtered.filter { !it.isArchived } - } - - val checkmarks = filtered.associate { habit -> - val allValues = checkmarks.getValue(habit).getUntil(today) - if (allValues.size <= maxNumberOfButtons) habit to allValues - else habit to allValues.subList(0, maxNumberOfButtons) - } - - if (!preferences.showCompleted) { - filtered = filtered.filter { habit -> - (habit.type == HabitType.BOOLEAN_HABIT && checkmarks.getValue(habit)[0].value == UNCHECKED) || - (habit.type == HabitType.NUMERICAL_HABIT && checkmarks.getValue(habit)[0].value * 1000 < habit.target) - } - } - - val scores = filtered.associate { habit -> - habit to scores[habit]!!.getAt(today) - } - - observable.notifyListeners { listener -> - val data = Data(filtered, scores, checkmarks) - listener.onDataChanged(data) - } - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/BarChart.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/BarChart.kt deleted file mode 100644 index ba3f631a2..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/BarChart.kt +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.components - -import org.isoron.platform.gui.* -import org.isoron.platform.time.* -import kotlin.math.* - -class BarChart(var theme: Theme, - var dateFormatter: LocalDateFormatter) : Component { - - // Data - var series = mutableListOf>() - var colors = mutableListOf() - var axis = listOf() - - // Style - var paddingTop = 20.0 - var paddingLeft = 5.0 - var paddingRight = 5.0 - var footerHeight = 40.0 - var barGroupMargin = 4.0 - var barMargin = 4.0 - var barWidth = 20.0 - var nGridlines = 6 - var backgroundColor = theme.cardBackgroundColor - - override fun draw(canvas: Canvas) { - val width = canvas.getWidth() - val height = canvas.getHeight() - - val n = series.size - val barGroupWidth = 2 * barGroupMargin + n * (barWidth + 2 * barMargin) - val safeWidth = width - paddingLeft - paddingRight - val nColumns = floor((safeWidth) / barGroupWidth).toInt() - val marginLeft = (safeWidth - nColumns * barGroupWidth) / 2 - val maxBarHeight = height - footerHeight - paddingTop - var maxValue = series.map { it.max()!! }.max()!! - maxValue = max(maxValue, 1.0) - - canvas.setColor(backgroundColor) - canvas.fillRect(0.0, 0.0, width, height) - - fun barGroupOffset(c: Int) = marginLeft + paddingLeft + - (c) * barGroupWidth - - fun barOffset(c: Int, s: Int) = barGroupOffset(c) + - barGroupMargin + - s * (barWidth + 2 * barMargin) + - barMargin - - fun drawColumn(s: Int, c: Int) { - val value = if (c < series[s].size) series[s][c] else 0.0 - val perc = value / maxValue - val barColorPerc = if (n > 1) 1.0 else round(perc / 0.20) * 0.20 - val barColor = theme.lowContrastTextColor.blendWith(colors[s], - barColorPerc) - val barHeight = round(maxBarHeight * perc) - val x = barOffset(c, s) - val y = height - footerHeight - barHeight - canvas.setColor(barColor) - val r = round(barWidth * 0.33) - canvas.fillRect(x, y + r, barWidth, barHeight - r) - canvas.fillRect(x + r, y, barWidth - 2 * r, r) - canvas.fillCircle(x + r, y + r, r) - canvas.fillCircle(x + barWidth - r, y + r, r) - canvas.setFontSize(theme.smallTextSize) - canvas.setTextAlign(TextAlign.CENTER) - canvas.setColor(backgroundColor) - canvas.fillRect(x - barMargin, - y - theme.smallTextSize * 1.25, - barWidth + 2 * barMargin, - theme.smallTextSize * 1.0) - canvas.setColor(theme.mediumContrastTextColor) - canvas.drawText(value.toShortString(), - x + barWidth / 2, - y - theme.smallTextSize * 0.80) - } - - fun drawSeries(s: Int) { - for (c in 0 until nColumns) drawColumn(s, c) - } - - fun drawMajorGrid() { - canvas.setStrokeWidth(1.0) - if (n > 1) { - canvas.setColor(backgroundColor.blendWith( - theme.lowContrastTextColor, - 0.5)) - for (c in 0 until nColumns - 1) { - val x = barGroupOffset(c) - canvas.drawLine(x, paddingTop, x, paddingTop + maxBarHeight) - } - } - for (k in 1 until nGridlines) { - val pct = 1.0 - (k.toDouble() / (nGridlines - 1)) - val y = paddingTop + maxBarHeight * pct - canvas.setColor(theme.lowContrastTextColor) - canvas.drawLine(0.0, y, width, y) - } - } - - fun drawFooter() { - val y = paddingTop + maxBarHeight - canvas.setColor(backgroundColor) - canvas.fillRect(0.0, y, width, height - y) - canvas.setColor(theme.lowContrastTextColor) - canvas.drawLine(0.0, y, width, y) - canvas.setColor(theme.mediumContrastTextColor) - canvas.setTextAlign(TextAlign.CENTER) - var prevMonth = -1 - var prevYear = -1 - val isLargeInterval = (axis[0].distanceTo(axis[1]) > 300) - - for (c in 0 until nColumns) { - val x = barGroupOffset(c) - val date = axis[c] - if(isLargeInterval) { - canvas.drawText(date.year.toString(), - x + barGroupWidth / 2, - y + theme.smallTextSize * 1.0) - } else { - if (date.month != prevMonth) { - canvas.drawText(dateFormatter.shortMonthName(date), - x + barGroupWidth / 2, - y + theme.smallTextSize * 1.0) - } else { - canvas.drawText(date.day.toString(), - x + barGroupWidth / 2, - y + theme.smallTextSize * 1.0) - } - if (date.year != prevYear) { - canvas.drawText(date.year.toString(), - x + barGroupWidth / 2, - y + theme.smallTextSize * 2.3) - } - } - prevMonth = date.month - prevYear = date.year - } - } - - drawMajorGrid() - for (k in 0 until n) drawSeries(k) - drawFooter() - } -} diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/CalendarChart.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/CalendarChart.kt deleted file mode 100644 index 20594df19..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/CalendarChart.kt +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.components - -import org.isoron.platform.gui.* -import org.isoron.platform.time.* -import kotlin.math.* - -class CalendarChart(var today: LocalDate, - var color: Color, - var theme: Theme, - var dateFormatter: LocalDateFormatter) : Component { - - var padding = 5.0 - var backgroundColor = Color(0xFFFFFF) - var squareSpacing = 1.0 - var series = listOf() - var scrollPosition = 0 - private var squareSize = 0.0 - - override fun draw(canvas: Canvas) { - val width = canvas.getWidth() - val height = canvas.getHeight() - canvas.setColor(backgroundColor) - canvas.fillRect(0.0, 0.0, width, height) - squareSize = round((height - 2 * padding) / 8.0) - canvas.setFontSize(height * 0.06) - - val nColumns = floor((width - 2 * padding) / squareSize).toInt() - 2 - val todayWeekday = today.dayOfWeek - val topLeftOffset = (nColumns - 1 + scrollPosition) * 7 + todayWeekday.index - val topLeftDate = today.minus(topLeftOffset) - - repeat(nColumns) { column -> - val topOffset = topLeftOffset - 7 * column - val topDate = topLeftDate.plus(7 * column) - drawColumn(canvas, column, topDate, topOffset) - } - - canvas.setColor(theme.mediumContrastTextColor) - repeat(7) { row -> - val date = topLeftDate.plus(row) - canvas.setTextAlign(TextAlign.LEFT) - canvas.drawText(dateFormatter.shortWeekdayName(date), - padding + nColumns * squareSize + padding, - padding + squareSize * (row+1) + squareSize / 2) - } - } - - private fun drawColumn(canvas: Canvas, - column: Int, - topDate: LocalDate, - topOffset: Int) { - drawHeader(canvas, column, topDate) - repeat(7) { row -> - val offset = topOffset - row - val date = topDate.plus(row) - if (offset < 0) return - drawSquare(canvas, - padding + column * squareSize, - padding + (row + 1) * squareSize, - squareSize - squareSpacing, - squareSize - squareSpacing, - date, - offset) - } - } - - private fun drawHeader(canvas: Canvas, column: Int, date: LocalDate) { - if (date.day >= 8) return - - canvas.setColor(theme.mediumContrastTextColor) - if (date.month == 1) { - canvas.drawText(date.year.toString(), - padding + column * squareSize + squareSize / 2, - padding + squareSize / 2) - - } else { - canvas.drawText(dateFormatter.shortMonthName(date), - padding + column * squareSize + squareSize / 2, - padding + squareSize / 2) - } - } - - private fun drawSquare(canvas: Canvas, - x: Double, - y: Double, - width: Double, - height: Double, - date: LocalDate, - offset: Int) { - - var value = if (offset >= series.size) 0.0 else series[offset] - value = round(value * 5.0) / 5.0 - - var squareColor = color.blendWith(backgroundColor, 1 - value) - var textColor = backgroundColor - - if (value == 0.0) squareColor = theme.lowContrastTextColor - if (squareColor.luminosity > 0.8) - textColor = squareColor.blendWith(theme.highContrastTextColor, 0.5) - - canvas.setColor(squareColor) - canvas.fillRect(x, y, width, height) - canvas.setColor(textColor) - canvas.drawText(date.day.toString(), x + width / 2, y + width / 2) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/CheckmarkButton.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/CheckmarkButton.kt deleted file mode 100644 index 5fdf99de0..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/CheckmarkButton.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.components - -import org.isoron.platform.gui.* - -class CheckmarkButton(private val value: Int, - private val color: Color, - private val theme: Theme) : Component { - override fun draw(canvas: Canvas) { - canvas.setFont(Font.FONT_AWESOME) - canvas.setFontSize(theme.smallTextSize * 1.5) - canvas.setColor(when (value) { - 2 -> color - else -> theme.lowContrastTextColor - }) - val text = when (value) { - 0 -> FontAwesome.TIMES - else -> FontAwesome.CHECK - } - canvas.drawText(text, canvas.getWidth() / 2.0, canvas.getHeight() / 2.0) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/HabitListHeader.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/HabitListHeader.kt deleted file mode 100644 index f3e401fa4..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/HabitListHeader.kt +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.components - -import org.isoron.platform.gui.* -import org.isoron.platform.time.* - -class HabitListHeader(private val today: LocalDate, - private val nButtons: Int, - private val theme: Theme, - private val fmt: LocalDateFormatter) : Component { - - override fun draw(canvas: Canvas) { - val width = canvas.getWidth() - val height = canvas.getHeight() - val buttonSize = theme.checkmarkButtonSize - canvas.setColor(theme.headerBackgroundColor) - canvas.fillRect(0.0, 0.0, width, height) - - canvas.setColor(theme.headerBorderColor) - canvas.setStrokeWidth(0.5) - canvas.drawLine(0.0, height - 0.5, width, height - 0.5) - - canvas.setColor(theme.headerTextColor) - canvas.setFont(Font.BOLD) - canvas.setFontSize(theme.smallTextSize) - - repeat(nButtons) { index -> - val date = today.minus(nButtons - index - 1) - val name = fmt.shortWeekdayName(date).toUpperCase() - val number = date.day.toString() - - val x = width - (index + 1) * buttonSize + buttonSize / 2 - val y = height / 2 - canvas.drawText(name, x, y - theme.smallTextSize * 0.6) - canvas.drawText(number, x, y + theme.smallTextSize * 0.6) - } - } -} diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/NumberButton.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/NumberButton.kt deleted file mode 100644 index 313d6f22d..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/NumberButton.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.components - -import org.isoron.platform.gui.* -import org.isoron.platform.io.* -import kotlin.math.* - -fun Double.toShortString(): String = when { - this >= 1e9 -> format("%.1fG", this / 1e9) - this >= 1e8 -> format("%.0fM", this / 1e6) - this >= 1e7 -> format("%.1fM", this / 1e6) - this >= 1e6 -> format("%.1fM", this / 1e6) - this >= 1e5 -> format("%.0fk", this / 1e3) - this >= 1e4 -> format("%.1fk", this / 1e3) - this >= 1e3 -> format("%.1fk", this / 1e3) - this >= 1e2 -> format("%.0f", this) - this >= 1e1 -> when { - round(this) == this -> format("%.0f", this) - else -> format("%.1f", this) - } - else -> when { - round(this) == this -> format("%.0f", this) - round(this * 10) == this * 10 -> format("%.1f", this) - else -> format("%.2f", this) - } -} - -class NumberButton(val color: Color, - val value: Double, - val threshold: Double, - val units: String, - val theme: Theme) : Component { - - override fun draw(canvas: Canvas) { - val width = canvas.getWidth() - val height = canvas.getHeight() - val em = theme.smallTextSize - - canvas.setColor(when { - value >= threshold -> color - value >= 0.01 -> theme.mediumContrastTextColor - else -> theme.lowContrastTextColor - }) - - canvas.setFontSize(theme.regularTextSize) - canvas.setFont(Font.BOLD) - canvas.drawText(value.toShortString(), width / 2, height / 2 - 0.6 * em) - - canvas.setFontSize(theme.smallTextSize) - canvas.setFont(Font.REGULAR) - canvas.drawText(units, width / 2, height / 2 + 0.6 * em) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/Ring.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/Ring.kt deleted file mode 100644 index 806770163..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/Ring.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.components - -import org.isoron.platform.gui.* -import org.isoron.platform.io.* -import kotlin.math.* - -class Ring(val color: Color, - val percentage: Double, - val thickness: Double, - val radius: Double, - val theme: Theme, - val label: Boolean = false) : Component { - - override fun draw(canvas: Canvas) { - val width = canvas.getWidth() - val height = canvas.getHeight() - val angle = 360.0 * max(0.0, min(360.0, percentage)) - - canvas.setColor(theme.lowContrastTextColor) - canvas.fillCircle(width/2, height/2, radius) - - canvas.setColor(color) - canvas.fillArc(width/2, height/2, radius, 90.0, -angle) - - canvas.setColor(theme.cardBackgroundColor) - canvas.fillCircle(width/2, height/2, radius - thickness) - - if(label) { - canvas.setColor(color) - canvas.setFontSize(radius * 0.4) - canvas.drawText(format("%.0f%%", percentage * 100), width / 2, height / 2) - } - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/Themes.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/Themes.kt deleted file mode 100644 index a2d5eedc0..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/components/Themes.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.components - -import org.isoron.platform.gui.* - -abstract class Theme { - val toolbarColor = Color(0xffffff) - - val lowContrastTextColor = Color(0xe0e0e0) - val mediumContrastTextColor = Color(0x808080) - val highContrastTextColor = Color(0x202020) - - val cardBackgroundColor = Color(0xFFFFFF) - val appBackgroundColor = Color(0xf4f4f4) - val toolbarBackgroundColor = Color(0xf4f4f4) - val statusBarBackgroundColor = Color(0x333333) - - val headerBackgroundColor = Color(0xeeeeee) - val headerBorderColor = Color(0xcccccc) - val headerTextColor = mediumContrastTextColor - - val itemBackgroundColor = Color(0xffffff) - - fun color(paletteIndex: Int): Color { - return when (paletteIndex) { - 0 -> Color(0xD32F2F) - 1 -> Color(0x512DA8) - 2 -> Color(0xF57C00) - 3 -> Color(0xFF8F00) - 4 -> Color(0xF9A825) - 5 -> Color(0xAFB42B) - 6 -> Color(0x7CB342) - 7 -> Color(0x388E3C) - 8 -> Color(0x00897B) - 9 -> Color(0x00ACC1) - 10 -> Color(0x039BE5) - 11 -> Color(0x1976D2) - 12 -> Color(0x303F9F) - 13 -> Color(0x5E35B1) - 14 -> Color(0x8E24AA) - 15 -> Color(0xD81B60) - 16 -> Color(0x5D4037) - else -> Color(0x000000) - } - } - - val checkmarkButtonSize = 48.0 - val smallTextSize = 12.0 - val regularTextSize = 17.0 -} - -class LightTheme : Theme() \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/i18n/LocaleHelper.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/i18n/LocaleHelper.kt deleted file mode 100644 index a73af82a3..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/i18n/LocaleHelper.kt +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.i18n - -interface LocaleHelper { - fun getStringsForCurrentLocale(): Strings -} diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/i18n/Strings.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/i18n/Strings.kt deleted file mode 100644 index 823ac364c..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/i18n/Strings.kt +++ /dev/null @@ -1,190 +0,0 @@ -package org.isoron.uhabits.i18n - -@Suppress("PropertyName", "unused") -open class Strings() { - open val about = "About" - open val action = "Action" - open val action_settings = "Settings" - open val add_habit = "Add habit" - open val all_time = "All time" - open val any_day = "Any day of the week" - open val any_weekday = "Monday to Friday" - open val app_name = "Loop Habit Tracker" - open val archive = "Archive" - open val behavior = "Behavior" - open val best_streaks = "Best streaks" - open val bug_report_failed = "Failed to generate bug report." - open val by_color = "By color" - open val by_name = "By name" - open val by_score = "By score" - open val calendar = "Calendar" - open val cancel = "Cancel" - open val change_value = "Change value" - open val check = "Check" - open val checkmark = "Checkmark" - open val checkmark_stack_widget = "Checkmark Stack Widget" - open val clear = "Clear" - open val clear_label = "Clear" - open val color_picker_default_title = "Change color" - open val could_not_export = "Failed to export data." - open val could_not_import = "Failed to import data." - open val count = "Count" - open val create_habit = "Create habit" - open val create_stackview_widget_button = "StackView Widget For All Habits" - open val current_streaks = "Current streak" - open val custom_frequency = "Custom …" - open val customize_notification = "Customize notifications" - open val customize_notification_summary = "Change sound, vibration, light and other notification settings" - open val database_repaired = "Database repaired." - open val day = "Day" - open val days = "days" - open val delete = "Delete" - open val delete_habits = "Delete Habits" - open val delete_habits_message = "The habits will be permanently deleted. This action cannot be undone." - open val description_hint = "Question (Did you … today?)" - open val developers = "Developers" - open val discard = "Discard" - open val done_label = "Done" - open val download = "Download" - open val edit = "Edit" - open val edit_habit = "Edit habit" - open val every_day = "Every day" - open val every_week = "Every week" - open val every_x_days = "Every %d days" - open val every_x_months = "Every %d months" - open val every_x_weeks = "Every %d weeks" - open val example_question_boolean = "e.g. Did you exercise today?" - open val example_question_numerical = "e.g. How many steps did you walk today?" - open val example_units = "e.g. steps" - open val export = "Export" - open val export_as_csv_summary = "Generates files that can be opened by spreadsheet software such as Microsoft Excel or OpenOffice Calc. This file cannot be imported back." - open val export_full_backup = "Export full backup" - open val export_full_backup_summary = "Generates a file that contains all your data. This file can be imported back." - open val export_to_csv = "Export as CSV" - open val file_not_recognized = "File not recognized." - open val filter = "Filter" - open val five_times_per_week = "5 times per week" - open val frequency = "Frequency" - open val frequency_stack_widget = "Frequency Stack Widget" - open val full_backup_success = "Full backup successfully exported." - open val generate_bug_report = "Generate bug report" - open val habit = "Habit" - open val habit_not_found = "Habit deleted / not found" - open val habit_strength = "Habit strength" - open val habits_imported = "Habits imported successfully." - open val help = "Help & FAQ" - open val help_translate = "Help translate this app" - open val hide_archived = "Hide archived" - open val hide_completed = "Hide completed" - open val hint_drag = "To rearrange the entries, press-and-hold on the name of the habit, then drag it to the correct place." - open val hint_landscape = "You can see more days by putting your phone in landscape mode." - open val hint_title = "Did you know?" - open val history = "History" - open val history_stack_widget = "History Stack Widget" - open val import_data = "Import data" - open val import_data_summary = "Supports full backups exported by this app, as well as files generated by Tickmate, HabitBull or Rewire. See FAQ for more information." - open val interface_preferences = "Interface" - open val interval_15_minutes = "15 minutes" - open val interval_1_hour = "1 hour" - open val interval_24_hour = "24 hours" - open val interval_2_hour = "2 hours" - open val interval_30_minutes = "30 minutes" - open val interval_4_hour = "4 hours" - open val interval_8_hour = "8 hours" - open val interval_always_ask = "Always ask" - open val interval_custom = "Custom..." - open val intro_description_1 = "Loop Habit Tracker helps you create and maintain good habits." - open val intro_description_2 = "Every day, after performing your habit, put a checkmark on the app." - open val intro_description_3 = "Habits performed consistently for a long time will earn a full star." - open val intro_description_4 = "Detailed graphs show you how your habits improved over time." - open val intro_title_1 = "Welcome" - open val intro_title_2 = "Create some new habits" - open val intro_title_3 = "Keep doing it" - open val intro_title_4 = "Track your progress" - open val last_x_days = "Last %d days" - open val last_x_months = "Last %d months" - open val last_x_weeks = "Last %d weeks" - open val last_x_years = "Last %d years" - open val led_notifications = "Notification light" - open val led_notifications_description = "Shows a blinking light for reminders. Only available in phones with LED notification lights." - open val links = "Links" - open val long_press_to_edit = "Press-and-hold to change the value" - open val long_press_to_toggle = "Press-and-hold to check or uncheck" - open val main_activity_title = "Habits" - open val manually = "Manually" - open val month = "Month" - open val name = "Name" - open val night_mode = "Night mode" - open val no = "No" - open val no_habits_found = "You have no active habits" - open val none = "None" - open val number_of_repetitions = "Number of repetitions" - open val overview = "Overview" - open val pref_rate_this_app = "Rate this app on Google Play" - open val pref_send_feedback = "Send feedback to developer" - open val pref_snooze_interval_title = "Snooze interval on reminders" - open val pref_toggle_description = "Put checkmarks with a single tap instead of press-and-hold. More convenient, but might cause accidental toggles." - open val pref_toggle_title = "Toggle with short press" - open val pref_view_app_introduction = "View app introduction" - open val pref_view_source_code = "View source code at GitHub" - open val pure_black_description = "Replaces gray backgrounds with pure black in night mode. Reduces battery usage in phones with AMOLED display." - open val quarter = "Quarter" - open val question = "Question" - open val reminder = "Reminder" - open val reminder_off = "Off" - open val reminder_sound = "Reminder sound" - open val repair_database = "Repair database" - open val repeat = "Repeat" - open val reverse_days = "Reverse order of days" - open val reverse_days_description = "Show days in reverse order on the main screen." - open val save = "Save" - open val score = "Score" - open val score_stack_widget = "Score Stack Widget" - open val select_habit_requirement_prompt = "Please select at least one habit" - open val select_hours = "Select hours" - open val select_minutes = "Select minutes" - open val select_snooze_delay = "Select snooze delay" - open val select_weekdays = "Select days" - open val settings = "Settings" - open val show_archived = "Show archived" - open val show_completed = "Show completed" - open val snooze = "Later" - open val snooze_interval = "Snooze interval" - open val sort = "Sort" - open val sticky_notifications = "Make notifications sticky" - open val sticky_notifications_description = "Prevents notifications from being swiped away." - open val streaks = "Streaks" - open val streaks_stack_widget = "Streaks Stack Widget" - open val strength = "Strength" - open val target = "Target" - open val time_every = "time in" - open val times_every = "times in" - open val toast_habit_archived = "Habits archived" - open val toast_habit_changed = "Habit changed" - open val toast_habit_changed_back = "Habit changed back" - open val toast_habit_created = "Habit created" - open val toast_habit_deleted = "Habits deleted" - open val toast_habit_restored = "Habits restored" - open val toast_habit_unarchived = "Habits unarchived" - open val toast_nothing_to_redo = "Nothing to redo" - open val toast_nothing_to_undo = "Nothing to undo" - open val toggle = "Toggle" - open val total = "Total" - open val translators = "Translators" - open val troubleshooting = "Troubleshooting" - open val two_times_per_week = "2 times per week" - open val unarchive = "Unarchive" - open val uncheck = "Uncheck" - open val unit = "Unit" - open val use_pure_black = "Use pure black in night mode" - open val validation_at_most_one_rep_per_day = "You can have at most one repetition per day" - open val validation_name_should_not_be_blank = "Name cannot be blank." - open val validation_number_should_be_positive = "Number must be positive." - open val validation_show_not_be_blank = "This field should not be blank" - open val version_n = "Version %s" - open val week = "Week" - open val weekends = "Weekends" - open val year = "Year" - open val yes = "Yes" - open val day_mode = "Day mode" -} diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/Checkmark.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/Checkmark.kt deleted file mode 100644 index f2fd97673..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/Checkmark.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models - -import org.isoron.platform.time.* - -data class Checkmark(var date: LocalDate, - var value: Int) { - - companion object { - /** - * Value assigned when the user has explicitly marked the habit as - * completed. - */ - const val CHECKED_MANUAL = 2 - - /** - * Value assigned when the user has not explicitly marked the habit as - * completed, however, due to the frequency of the habit, an automatic - * checkmark was added. - */ - const val CHECKED_AUTOMATIC = 1 - - /** - * Value assigned when the user has not completed the habit, and the app - * has not automatically a checkmark. - */ - const val UNCHECKED = 0 - } -} diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/CheckmarkList.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/CheckmarkList.kt deleted file mode 100644 index 55eda4ae8..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/CheckmarkList.kt +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models - -import org.isoron.platform.time.* -import org.isoron.uhabits.models.Checkmark.Companion.CHECKED_AUTOMATIC -import org.isoron.uhabits.models.Checkmark.Companion.CHECKED_MANUAL -import org.isoron.uhabits.models.Checkmark.Companion.UNCHECKED - -class CheckmarkList(val frequency: Frequency, - val habitType: HabitType) { - - private val manualCheckmarks = mutableListOf() - private val computedCheckmarks = mutableListOf() - - /** - * Replaces the entire list of manual checkmarks by the ones provided. The - * list of automatic checkmarks will be automatically updated. - */ - fun setManualCheckmarks(checks: List) { - manualCheckmarks.clear() - computedCheckmarks.clear() - manualCheckmarks.addAll(checks) - if (habitType == HabitType.NUMERICAL_HABIT) { - computedCheckmarks.addAll(checks) - } else { - val computed = computeCheckmarks(checks, frequency) - computedCheckmarks.addAll(computed) - } - } - - /** - * Returns values of all checkmarks (manual and automatic) from the oldest - * entry until the date provided. - * - * The interval is inclusive, and the list is sorted from newest to oldest. - * That is, the first element of the returned list corresponds to the date - * provided. - */ - fun getUntil(date: LocalDate): List { - if (computedCheckmarks.isEmpty()) return listOf() - - val result = mutableListOf() - val newest = computedCheckmarks.first().date - val distToNewest = newest.distanceTo(date) - - var k = 0 - var fromIndex = 0 - val toIndex = computedCheckmarks.size - if (newest.isOlderThan(date)) { - repeat(distToNewest) { result.add(Checkmark(date.minus(k++), UNCHECKED)) } - } else { - fromIndex = distToNewest - } - val subList = computedCheckmarks.subList(fromIndex, toIndex) - result.addAll(subList.map { Checkmark(date.minus(k++), it.value) }) - return result - } - - companion object { - /** - * Computes the list of automatic checkmarks a list of manual ones. - */ - fun computeCheckmarks(checks: List, - frequency: Frequency - ): MutableList { - - val intervals = buildIntervals(checks, frequency) - snapIntervalsTogether(intervals) - return buildCheckmarksFromIntervals(checks, intervals) - } - - /** - * Modifies the intervals so that gaps between intervals are eliminated. - * - * More specifically, this function shifts the beginning and the end of - * intervals so that they overlap the least as possible. The center of - * the interval, however, still falls within the interval. The length of - * the intervals are also not modified. - */ - fun snapIntervalsTogether(intervals: MutableList) { - - for (i in 1 until intervals.size) { - val (begin, center, end) = intervals[i] - val (_, _, prevEnd) = intervals[i - 1] - - val gap = prevEnd.distanceTo(begin) - 1 - if (gap <= 0 || end.minus(gap).isOlderThan(center)) continue - intervals[i] = Interval(begin.minus(gap), - center, - end.minus(gap)) - } - } - - /** - * Converts a list of (manually checked) checkmarks and computed - * intervals into a list of unchecked, manually checked and - * automatically checked checkmarks. - * - * Manual checkmarks are simply copied over to the output list. Days - * that are an interval, but which do not have manual checkmarks receive - * automatic checkmarks. Days that fall in the gaps between intervals - * receive unchecked checkmarks. - */ - fun buildCheckmarksFromIntervals(checks: List, - intervals: List - ): MutableList { - - if (checks.isEmpty()) throw IllegalArgumentException() - if (intervals.isEmpty()) throw IllegalArgumentException() - - var oldest = intervals[0].begin - var newest = intervals[0].end - for (interval in intervals) { - if (interval.begin.isOlderThan(oldest)) oldest = interval.begin - if (interval.end.isNewerThan(newest)) newest = interval.end - } - for (check in checks) { - if (check.date.isOlderThan(oldest)) oldest = check.date - if (check.date.isNewerThan(newest)) newest = check.date - } - - val distance = oldest.distanceTo(newest) - val checkmarks = mutableListOf() - for (offset in 0..distance) - checkmarks.add(Checkmark(newest.minus(offset), - UNCHECKED)) - - for (interval in intervals) { - val beginOffset = newest.distanceTo(interval.begin) - val endOffset = newest.distanceTo(interval.end) - - for (offset in endOffset..beginOffset) { - checkmarks.set(offset, - Checkmark(newest.minus(offset), - CHECKED_AUTOMATIC)) - } - } - - for (check in checks) { - val offset = newest.distanceTo(check.date) - checkmarks.set(offset, Checkmark(check.date, CHECKED_MANUAL)) - } - - return checkmarks - } - - /** - * Constructs a list of intervals based on a list of (manual) - * checkmarks. - */ - fun buildIntervals(checks: List, - frequency: Frequency): MutableList { - - val num = frequency.numerator - val den = frequency.denominator - - val intervals = mutableListOf() - for (i in 0..(checks.size - num)) { - val first = checks[i] - val last = checks[i + num - 1] - - if (first.date.distanceTo(last.date) >= den) continue - - val end = first.date.plus(den - 1) - intervals.add(Interval(first.date, last.date, end)) - } - - return intervals - } - } - - /* - * For non-daily habits, some groups of repetitions generate many - * automatic checkmarks. For weekly habits, each repetition generates - * seven checkmarks. For twice-a-week habits, two repetitions that are close - * enough together also generate seven checkmarks. This group of generated - * checkmarks is represented by an interval. - * - * The fields `begin` and `end` indicate the length of the interval, and are - * inclusive. The field `center` indicates the newest day within the interval - * that has a manual checkmark. - */ - data class Interval(val begin: LocalDate, - val center: LocalDate, - val end: LocalDate) -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/CheckmarkRepository.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/CheckmarkRepository.kt deleted file mode 100644 index 0b35bc275..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/CheckmarkRepository.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models - -import org.isoron.platform.io.* -import org.isoron.platform.time.* - -class CheckmarkRepository(db: Database) { - - private val findStatement = db.prepareStatement("select timestamp, value from Repetitions where habit = ? order by timestamp desc") - private val insertStatement = db.prepareStatement("insert into Repetitions(habit, timestamp, value) values (?, ?, ?)") - private val deleteStatement = db.prepareStatement("delete from Repetitions where habit=? and timestamp=?") - - fun findAll(habitId: Int): List { - findStatement.bindInt(0, habitId) - val result = mutableListOf() - while (findStatement.step() == StepResult.ROW) { - val date = Timestamp(findStatement.getLong(0)).localDate - val value = findStatement.getInt(1) - result.add(Checkmark(date, value)) - } - findStatement.reset() - return result - } - - fun insert(habitId: Int, checkmark: Checkmark) { - val timestamp = checkmark.date.timestamp - insertStatement.bindInt(0, habitId) - insertStatement.bindLong(1, timestamp.millisSince1970) - insertStatement.bindInt(2, checkmark.value) - insertStatement.step() - insertStatement.reset() - } - - fun delete(habitId: Int, date: LocalDate) { - val timestamp = date.timestamp - deleteStatement.bindInt(0, habitId) - deleteStatement.bindLong(1, timestamp.millisSince1970) - deleteStatement.step() - deleteStatement.reset() - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/Frequency.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/Frequency.kt deleted file mode 100644 index f09a32a51..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/Frequency.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models - -data class Frequency(val numerator: Int, - val denominator: Int) { - - fun toDouble(): Double { - return numerator.toDouble() / denominator - } - - companion object { - val WEEKLY = Frequency(1, 7) - val DAILY = Frequency(1, 1) - val TWO_TIMES_PER_WEEK = Frequency(2, 7) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/Habit.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/Habit.kt deleted file mode 100644 index 7ddfa6188..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/Habit.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models - -import org.isoron.platform.gui.* - -data class Habit(var id: Int, - var name: String, - var description: String, - var frequency: Frequency, - var color: PaletteColor, - var isArchived: Boolean, - var position: Int, - var unit: String, - var target: Double, - var type: HabitType) \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/HabitRepository.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/HabitRepository.kt deleted file mode 100644 index 961956f51..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/HabitRepository.kt +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models - -import org.isoron.platform.gui.* -import org.isoron.platform.io.Database -import org.isoron.platform.io.PreparedStatement -import org.isoron.platform.io.StepResult -import org.isoron.platform.io.nextId - -class HabitRepository(var db: Database) { - - companion object { - const val SELECT_COLUMNS = "id, name, description, freq_num, freq_den, color, archived, position, unit, target_value, type" - const val SELECT_PLACEHOLDERS = "?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?" - const val UPDATE_COLUMNS = "id=?, name=?, description=?, freq_num=?, freq_den=?, color=?, archived=?, position=?, unit=?, target_value=?, type=?" - } - - private val findAllStatement = db.prepareStatement("select $SELECT_COLUMNS from habits order by position") - private val insertStatement = db.prepareStatement("insert into Habits($SELECT_COLUMNS) values ($SELECT_PLACEHOLDERS)") - private val updateStatement = db.prepareStatement("update Habits set $UPDATE_COLUMNS where id=?") - private val deleteStatement = db.prepareStatement("delete from Habits where id=?") - - fun nextId(): Int { - return db.nextId("Habits") - } - - fun findAll(): MutableMap { - val result = mutableMapOf() - while (findAllStatement.step() == StepResult.ROW) { - val habit = buildHabitFromStatement(findAllStatement) - result[habit.id] = habit - } - findAllStatement.reset() - return result - } - - fun insert(habit: Habit) { - bindHabitToStatement(habit, insertStatement) - insertStatement.step() - insertStatement.reset() - } - - fun update(habit: Habit) { - bindHabitToStatement(habit, updateStatement) - updateStatement.bindInt(11, habit.id) - updateStatement.step() - updateStatement.reset() - } - - private fun buildHabitFromStatement(stmt: PreparedStatement): Habit { - return Habit(id = stmt.getInt(0), - name = stmt.getText(1), - description = stmt.getText(2), - frequency = Frequency(stmt.getInt(3), stmt.getInt(4)), - color = PaletteColor(stmt.getInt(5)), - isArchived = stmt.getInt(6) != 0, - position = stmt.getInt(7), - unit = stmt.getText(8), - target = stmt.getReal(9), - type = if (stmt.getInt(10) == 0) HabitType.BOOLEAN_HABIT else HabitType.NUMERICAL_HABIT) - } - - private fun bindHabitToStatement(habit: Habit, statement: PreparedStatement) { - statement.bindInt(0, habit.id) - statement.bindText(1, habit.name) - statement.bindText(2, habit.description) - statement.bindInt(3, habit.frequency.numerator) - statement.bindInt(4, habit.frequency.denominator) - statement.bindInt(5, habit.color.index) - statement.bindInt(6, if (habit.isArchived) 1 else 0) - statement.bindInt(7, habit.position) - statement.bindText(8, habit.unit) - statement.bindReal(9, habit.target) - statement.bindInt(10, habit.type.code) - } - - fun delete(habit: Habit) { - deleteStatement.bindInt(0, habit.id) - deleteStatement.step() - deleteStatement.reset() - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/HabitType.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/HabitType.kt deleted file mode 100644 index a02beff5c..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/HabitType.kt +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models - -enum class HabitType(val code: Int) { - BOOLEAN_HABIT(0), - NUMERICAL_HABIT(1), -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/Preferences.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/Preferences.kt deleted file mode 100644 index 2c5e51449..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/Preferences.kt +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models - -class Preferences(private val repository: PreferencesRepository) { - var showArchived = repository.getBoolean("show_archived", false) - set(value) { - repository.putBoolean("show_archived", value) - field = value - } - - var showCompleted = repository.getBoolean("show_completed", true) - set(value) { - repository.putBoolean("show_completed", value) - field = value - } - - var nightMode = repository.getBoolean("night_mode", false) - set(value) { - repository.putBoolean("night_mode", value) - field = value - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/PreferencesRepository.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/PreferencesRepository.kt deleted file mode 100644 index 8c0d77f06..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/PreferencesRepository.kt +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models - -import org.isoron.platform.io.* - -class PreferencesRepository(private val db: Database) { - - private val insertStatement = db.prepareStatement("insert into Preferences(key, value) values (?, ?)") - private val deleteStatement = db.prepareStatement("delete from Preferences where key=?") - private val selectStatement = db.prepareStatement("select value from Preferences where key=?") - - fun putBoolean(key: String, value: Boolean) { - putString(key, value.toString()) - } - - fun getBoolean(key: String, default: Boolean): Boolean { - val value = getString(key, "NULL") - return if (value == "NULL") default else value.toBoolean() - } - - fun putLong(key: String, value: Long) { - putString(key, value.toString()) - } - - fun getLong(key: String, default: Long): Long { - val value = getString(key, "NULL") - return if (value == "NULL") default else value.toLong() - } - - fun putString(key: String, value: String) { - deleteStatement.bindText(0, key) - deleteStatement.step() - deleteStatement.reset() - insertStatement.bindText(0, key) - insertStatement.bindText(1, value) - insertStatement.step() - insertStatement.reset() - } - - fun getString(key: String, default: String): String { - selectStatement.bindText(0, key) - if (selectStatement.step() == StepResult.DONE) { - selectStatement.reset() - return default - } else { - val value = selectStatement.getText(0) - selectStatement.reset() - return value - } - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/Score.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/Score.kt deleted file mode 100644 index 35382dc8a..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/Score.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models - -import org.isoron.platform.time.* - -/** - * A Score is a number which indicates how strong the habit is at a given date. - * - * Scores are computed by taking an exponential moving average of the values of - * the checkmarks in preceding days. For boolean habits, when computing the - * average, each checked day (whether the check was manual or automatic) has - * value as 1, while days without checkmarks have value 0. - * - * For numerical habits, each day that exceeded the target has value 1, while - * days which failed to exceed the target receive a partial value, based on the - * proportion that was completed. For example, if the target is 100 units and - * the user completed 70 units, then the value for that day is 0.7 when - * computing the average. - */ -data class Score(val date: LocalDate, - val value: Double) \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/ScoreList.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/ScoreList.kt deleted file mode 100644 index 46fb993d7..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/ScoreList.kt +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models - -import org.isoron.platform.time.* -import kotlin.math.* - -class ScoreList(private val checkmarkList: CheckmarkList) { - /** - * Returns a list of all scores, from the beginning of the habit history - * until the specified date. - * - * The interval is inclusive, and the list is sorted from newest to oldest. - * That is, the first element of the returned list corresponds to the date - * provided. - */ - fun getUntil(date: LocalDate): List { - val frequency = checkmarkList.frequency - val checks = checkmarkList.getUntil(date) - val scores = mutableListOf() - val type = checkmarkList.habitType - - var currentScore = 0.0 - checks.reversed().forEach { check -> - val value = if (type == HabitType.BOOLEAN_HABIT) { - min(1, check.value) - } else { - check.value - } - currentScore = compute(frequency, currentScore, value) - scores.add(Score(check.date, currentScore)) - } - return scores.reversed() - } - - fun getAt(date: LocalDate): Score { - return getUntil(date)[0] - } - - companion object { - /** - * Given the frequency of the habit, the previous score, and the value of - * the current checkmark, computes the current score for the habit. - */ - fun compute(frequency: Frequency, - previousScore: Double, - checkmarkValue: Int): Double { - val multiplier = 0.5.pow(frequency.toDouble() / 13.0) - val score = previousScore * multiplier + checkmarkValue * (1 - multiplier) - return floor(score * 1e6) / 1e6 - } - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/Streak.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/Streak.kt deleted file mode 100644 index 1bcdc2d37..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/Streak.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models - -import org.isoron.platform.time.* - -/** - * A streak is an uninterrupted sequence of days where the habit was performed. - * - * For daily boolean habits, the definition is straightforward: a streak is a - * sequence of days that have checkmarks. For non-daily habits, note - * that automatic checkmarks (the ones added by the app) can also keep the - * streak going. For numerical habits, a streak is a sequence of days where the - * user has consistently exceeded the target for the habit. - */ -data class Streak(val start: LocalDate, - val end: LocalDate) \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/StreakList.kt b/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/StreakList.kt deleted file mode 100644 index 0d037b6c8..000000000 --- a/uhabits-core-legacy/src/main/common/org/isoron/uhabits/models/StreakList.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models - -class StreakList(private val checkmarkList: CheckmarkList) { - - /** - * Returns the longest streaks. - * - * The argument specifies the maximum number of streaks to find. The - * returned list is sorted by date (descending). That is, the first element - * corresponds to the most recent streak. - */ - fun getBest(limit: Int): List { - TODO() - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/ios/org/isoron/platform/concurrency/UIDispatcher.kt b/uhabits-core-legacy/src/main/ios/org/isoron/platform/concurrency/UIDispatcher.kt deleted file mode 100644 index d4aece983..000000000 --- a/uhabits-core-legacy/src/main/ios/org/isoron/platform/concurrency/UIDispatcher.kt +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.concurrency - -import kotlinx.coroutines.* -import platform.darwin.* -import kotlin.coroutines.* - -class UIDispatcher : CoroutineDispatcher() { - override fun dispatch(context: CoroutineContext, block: Runnable) { - val queue = dispatch_get_main_queue() - dispatch_async(queue) { - block.run() - } - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/ios/org/isoron/platform/gui/IosCanvas.kt b/uhabits-core-legacy/src/main/ios/org/isoron/platform/gui/IosCanvas.kt deleted file mode 100644 index 085021dc2..000000000 --- a/uhabits-core-legacy/src/main/ios/org/isoron/platform/gui/IosCanvas.kt +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.gui - -import kotlinx.cinterop.* -import platform.CoreGraphics.* -import platform.Foundation.* -import platform.UIKit.* -import kotlin.math.* - -val Color.uicolor: UIColor - get() = UIColor.colorWithRed(this.red, this.green, this.blue, this.alpha) - -val Color.cgcolor: CGColorRef? - get() = uicolor.CGColor - -class IosCanvas(val width: Double, - val height: Double, - val scale: Double = 2.0 - ) : Canvas { - - var textColor = UIColor.blackColor - var font = Font.REGULAR - var fontSize = 12.0 - var textAlign = TextAlign.CENTER - val ctx = UIGraphicsGetCurrentContext()!! - - override fun setColor(color: Color) { - CGContextSetStrokeColorWithColor(ctx, color.cgcolor) - CGContextSetFillColorWithColor(ctx, color.cgcolor) - textColor = color.uicolor - } - - override fun drawLine(x1: Double, y1: Double, x2: Double, y2: Double) { - CGContextMoveToPoint(ctx, x1 * scale, y1 * scale) - CGContextAddLineToPoint(ctx, x2 * scale, y2 * scale) - CGContextStrokePath(ctx) - } - - @Suppress("CAST_NEVER_SUCCEEDS") - override fun drawText(text: String, x: Double, y: Double) { - val sx = scale * x - val sy = scale * y - val nsText = (text as NSString) - val uiFont = when (font) { - Font.REGULAR -> UIFont.systemFontOfSize(fontSize) - Font.BOLD -> UIFont.boldSystemFontOfSize(fontSize) - Font.FONT_AWESOME -> UIFont.fontWithName("FontAwesome", fontSize) - } - val size = nsText.sizeWithFont(uiFont) - val width = size.useContents { width } - val height = size.useContents { height } - val origin = when (textAlign) { - TextAlign.CENTER -> CGPointMake(sx - width / 2, sy - height / 2) - TextAlign.LEFT -> CGPointMake(sx, sy - height / 2) - TextAlign.RIGHT -> CGPointMake(sx - width, sy - height / 2) - } - nsText.drawAtPoint(origin, uiFont) - } - - override fun fillRect(x: Double, y: Double, width: Double, height: Double) { - CGContextFillRect(ctx, - CGRectMake(x * scale, - y * scale, - width * scale, - height * scale)) - } - - override fun drawRect(x: Double, y: Double, width: Double, height: Double) { - CGContextStrokeRect(ctx, - CGRectMake(x * scale, - y * scale, - width * scale, - height * scale)) - } - - override fun getHeight(): Double { - return height - } - - override fun getWidth(): Double { - return width - } - - override fun setFont(font: Font) { - this.font = font - } - - override fun setFontSize(size: Double) { - this.fontSize = size * scale - } - - override fun setStrokeWidth(size: Double) { - CGContextSetLineWidth(ctx, size * scale) - } - - override fun fillArc(centerX: Double, - centerY: Double, - radius: Double, - startAngle: Double, - swipeAngle: Double) { - val a1 = startAngle / 180 * PI * (-1) - val a2 = a1 - swipeAngle / 180 * PI - CGContextBeginPath(ctx) - CGContextMoveToPoint(ctx, centerX * scale, centerY * scale) - CGContextAddArc(ctx, - centerX * scale, - centerY * scale, - radius * scale, - a1, - a2, - if (swipeAngle > 0) 1 else 0) - CGContextClosePath(ctx) - CGContextFillPath(ctx) - } - - override fun fillCircle(centerX: Double, centerY: Double, radius: Double) { - val rect = CGRectMake(scale * (centerX - radius), - scale * (centerY - radius), - scale * radius * 2.0, - scale * radius * 2.0) - CGContextFillEllipseInRect(ctx, rect) - } - - override fun setTextAlign(align: TextAlign) { - this.textAlign = align - } - - override fun toImage(): Image { - return IosImage(UIGraphicsGetImageFromCurrentImageContext()!!) - } -} diff --git a/uhabits-core-legacy/src/main/ios/org/isoron/platform/gui/IosImage.kt b/uhabits-core-legacy/src/main/ios/org/isoron/platform/gui/IosImage.kt deleted file mode 100644 index 33e1c2254..000000000 --- a/uhabits-core-legacy/src/main/ios/org/isoron/platform/gui/IosImage.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.gui - -import platform.UIKit.* -import platform.CoreGraphics.* -import platform.Foundation.* - -class IosImage(val image: UIImage) : Image { - - override val width: Int - get() { - return CGImageGetWidth(image.CGImage).toInt() - } - - override val height: Int - get() { - return CGImageGetHeight(image.CGImage).toInt() - } - - override fun getPixel(x: Int, y: Int): Color { - return Color(1.0, 0.0, 0.0, 1.0) - } - - override fun setPixel(x: Int, y: Int, color: Color) { - } - - @Suppress("CAST_NEVER_SUCCEEDS") - override suspend fun export(path: String) { - val tmpPath = "${NSTemporaryDirectory()}/$path" - val dir = (tmpPath as NSString).stringByDeletingLastPathComponent - NSFileManager.defaultManager.createDirectoryAtPath(dir, true, null, null) - val data = UIImagePNGRepresentation(image)!! - val success = data.writeToFile(tmpPath, true) - if (!success) throw RuntimeException("could not write to $tmpPath") - println(tmpPath) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/ios/org/isoron/platform/io/IosDatabase.kt b/uhabits-core-legacy/src/main/ios/org/isoron/platform/io/IosDatabase.kt deleted file mode 100644 index 34a12376f..000000000 --- a/uhabits-core-legacy/src/main/ios/org/isoron/platform/io/IosDatabase.kt +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.io - -import kotlinx.cinterop.* -import platform.Foundation.* -import sqlite3.* - -fun sqlite3_errstr(db: CPointer): String { - return "SQLite3 error: " + sqlite3_errmsg(db).toString() -} - -@Suppress("CAST_NEVER_SUCCEEDS") -class IosDatabaseOpener : DatabaseOpener { - override fun open(file: UserFile): Database = memScoped { - val path = (file as IosFile).path - val dirname = (path as NSString).stringByDeletingLastPathComponent - NSFileManager.defaultManager.createDirectoryAtPath(dirname, true, null, null) - - val db = alloc>() - val result = sqlite3_open(path, db.ptr) - if (result != SQLITE_OK) - throw Exception("sqlite3_open failed (code $result)") - - return IosDatabase(db.value!!) - } -} - -class IosDatabase(val db: CPointer) : Database { - override fun prepareStatement(sql: String): PreparedStatement = memScoped { - if (sql.isEmpty()) throw Exception("empty SQL query") - val stmt = alloc>() - val result = sqlite3_prepare_v2(db, sql.cstr, -1, stmt.ptr, null) - if (result != SQLITE_OK) - throw Exception("sqlite3_prepare_v2 failed (code $result)") - return IosPreparedStatement(db, stmt.value!!) - } - override fun close() { - sqlite3_close(db) - } -} - -class IosPreparedStatement(val db: CPointer, - val stmt: CPointer) : PreparedStatement { - override fun step(): StepResult { - when (sqlite3_step(stmt)) { - SQLITE_ROW -> return StepResult.ROW - SQLITE_DONE -> return StepResult.DONE - else -> throw Exception(sqlite3_errstr(db)) - } - } - - override fun finalize() { - sqlite3_finalize(stmt) - } - - override fun getInt(index: Int): Int { - return sqlite3_column_int(stmt, index) - } - - override fun getLong(index: Int): Long { - return sqlite3_column_int64(stmt, index) - } - - override fun getText(index: Int): String { - return sqlite3_column_text(stmt, index)!! - .reinterpret() - .toKString() - } - - override fun getReal(index: Int): Double { - return sqlite3_column_double(stmt, index) - } - - override fun bindInt(index: Int, value: Int) { - sqlite3_bind_int(stmt, index + 1, value) - } - - override fun bindLong(index: Int, value: Long) { - sqlite3_bind_int64(stmt, index + 1, value) - } - - override fun bindText(index: Int, value: String) { - sqlite3_bind_text(stmt, index + 1, value, -1, SQLITE_TRANSIENT) - } - - override fun bindReal(index: Int, value: Double) { - sqlite3_bind_double(stmt, index + 1, value) - } - - override fun reset() { - sqlite3_reset(stmt) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/ios/org/isoron/platform/io/IosFiles.kt b/uhabits-core-legacy/src/main/ios/org/isoron/platform/io/IosFiles.kt deleted file mode 100644 index 16d189133..000000000 --- a/uhabits-core-legacy/src/main/ios/org/isoron/platform/io/IosFiles.kt +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - - -package org.isoron.platform.io - -import org.isoron.platform.gui.* -import platform.Foundation.* -import platform.UIKit.* - -class IosFileOpener : FileOpener { - override fun openResourceFile(path: String): ResourceFile { - val resPath = NSBundle.mainBundle.resourcePath!! - return IosFile("$resPath/$path") - } - - override fun openUserFile(path: String): UserFile { - val manager = NSFileManager.defaultManager - val basePath = manager.URLsForDirectory(NSDocumentDirectory, NSUserDomainMask) - val filePath = (basePath.first() as NSURL).URLByAppendingPathComponent(path)!!.path!! - return IosFile(filePath) - } -} - -class IosFile(val path: String) : UserFile, ResourceFile { - override suspend fun delete() { - NSFileManager.defaultManager.removeItemAtPath(path, null) - } - - override suspend fun exists(): Boolean { - return NSFileManager.defaultManager.fileExistsAtPath(path) - } - - override suspend fun lines(): List { - if (!exists()) throw Exception("File not found: $path") - val contents = NSString.stringWithContentsOfFile(path) - return contents.toString().lines() - } - - @Suppress("CAST_NEVER_SUCCEEDS") - override suspend fun copyTo(dest: UserFile) { - val destPath = (dest as IosFile).path - val manager = NSFileManager.defaultManager - val destParentPath = (destPath as NSString).stringByDeletingLastPathComponent - NSFileManager.defaultManager.createDirectoryAtPath(destParentPath, true, null, null) - manager.copyItemAtPath(path, destPath, null) - } - - override suspend fun toImage(): Image { - return IosImage(UIImage.imageWithContentsOfFile(path)!!) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/ios/org/isoron/platform/io/Strings.kt b/uhabits-core-legacy/src/main/ios/org/isoron/platform/io/Strings.kt deleted file mode 100644 index e774348ea..000000000 --- a/uhabits-core-legacy/src/main/ios/org/isoron/platform/io/Strings.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.io - -import kotlinx.cinterop.* - -// Although the three following methods have exactly the same implementation, -// replacing them all by a single format(format: String, arg: Any) breaks -// everything, as of Kotlin/Native 1.3.72. Apparently, Kotlin/Native is not -// able to do proper type conversions for variables of type Any when calling -// C functions. - -actual fun format(format: String, arg: String): String { - val buffer = ByteArray(1000) - buffer.usePinned { p -> platform.posix.sprintf(p.addressOf(0), format, arg) } - return buffer.toKString() -} - -actual fun format(format: String, arg: Int): String { - val buffer = ByteArray(1000) - buffer.usePinned { p -> platform.posix.sprintf(p.addressOf(0), format, arg) } - return buffer.toKString() -} - -actual fun format(format: String, arg: Double): String { - val buffer = ByteArray(1000) - buffer.usePinned { p -> platform.posix.sprintf(p.addressOf(0), format, arg) } - return buffer.toKString() -} diff --git a/uhabits-core-legacy/src/main/ios/org/isoron/platform/time/IosDates.kt b/uhabits-core-legacy/src/main/ios/org/isoron/platform/time/IosDates.kt deleted file mode 100644 index 424d6db92..000000000 --- a/uhabits-core-legacy/src/main/ios/org/isoron/platform/time/IosDates.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.time - -import platform.Foundation.* - -fun LocalDate.toNsDate(): NSDate { - val calendar = NSCalendar.calendarWithIdentifier(NSCalendarIdentifierGregorian)!! - val dc = NSDateComponents() - dc.year = year.toLong() - dc.month = month.toLong() - dc.day = day.toLong() - dc.hour = 13 - dc.minute = 0 - return calendar.dateFromComponents(dc)!! -} - -class IosLocalDateFormatter(val locale: String) : LocalDateFormatter { - - constructor() : this(NSLocale.preferredLanguages[0] as String) - - private val fmt = NSDateFormatter() - - init { - fmt.setLocale(NSLocale.localeWithLocaleIdentifier(locale)) - } - - override fun shortWeekdayName(date: LocalDate): String { - fmt.dateFormat = "EEE" - return fmt.stringFromDate(date.toNsDate()) - } - - override fun shortMonthName(date: LocalDate): String { - fmt.dateFormat = "MMM" - return fmt.stringFromDate(date.toNsDate()) - } - -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/ios/org/isoron/uhabits/IosLocaleHelper.kt b/uhabits-core-legacy/src/main/ios/org/isoron/uhabits/IosLocaleHelper.kt deleted file mode 100644 index 4937339f6..000000000 --- a/uhabits-core-legacy/src/main/ios/org/isoron/uhabits/IosLocaleHelper.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -@file:Suppress("UNCHECKED_CAST") - -package org.isoron.uhabits - -import org.isoron.platform.io.* -import org.isoron.uhabits.i18n.* -import platform.Foundation.* - -class IosLocaleHelper(private val log: Log) : LocaleHelper { - override fun getStringsForCurrentLocale(): Strings { - val pref = NSLocale.preferredLanguages as List - val lang = if (pref.isEmpty()) "en-US" else pref[0] - log.info("IosLocaleHelper", lang) - return when { - else -> Strings() - } - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/js/org/isoron/platform/gui/JsCanvas.kt b/uhabits-core-legacy/src/main/js/org/isoron/platform/gui/JsCanvas.kt deleted file mode 100644 index 33a42a7f5..000000000 --- a/uhabits-core-legacy/src/main/js/org/isoron/platform/gui/JsCanvas.kt +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.gui - -import kotlinx.coroutines.* -import org.w3c.dom.* -import kotlin.js.* -import kotlin.math.* - -class JsCanvas(val element: HTMLCanvasElement, - val pixelScale: Double) : Canvas { - - - val ctx = element.getContext("2d") as CanvasRenderingContext2D - var fontSize = 12.0 - var fontFamily = "NotoRegular" - var align = CanvasTextAlign.CENTER - - private fun toPixel(x: Double): Double { - return pixelScale * x - } - - private fun toDp(x: Int): Double { - return x / pixelScale - } - - override fun setColor(color: Color) { - val c = "rgb(${color.red * 255}, ${color.green * 255}, ${color.blue * 255})" - ctx.fillStyle = c; - ctx.strokeStyle = c; - } - - override fun drawLine(x1: Double, y1: Double, x2: Double, y2: Double) { - ctx.beginPath() - ctx.moveTo(toPixel(x1), toPixel(y1)) - ctx.lineTo(toPixel(x2), toPixel(y2)) - ctx.stroke() - } - - override fun drawText(text: String, x: Double, y: Double) { - ctx.font = "${fontSize}px ${fontFamily}" - ctx.textAlign = align - ctx.textBaseline = CanvasTextBaseline.MIDDLE - ctx.fillText(text, toPixel(x), toPixel(y + fontSize * 0.025)) - } - - override fun fillRect(x: Double, y: Double, width: Double, height: Double) { - ctx.fillRect(toPixel(x), - toPixel(y), - toPixel(width), - toPixel(height)) - } - - override fun drawRect(x: Double, y: Double, width: Double, height: Double) { - ctx.strokeRect(toPixel(x), - toPixel(y), - toPixel(width), - toPixel(height)) - } - - override fun getHeight(): Double { - return toDp(element.height) - } - - override fun getWidth(): Double { - return toDp(element.width) - } - - override fun setFont(font: Font) { - fontFamily = when (font) { - Font.REGULAR -> "NotoRegular" - Font.BOLD -> "NotoBold" - Font.FONT_AWESOME -> "FontAwesome" - } - } - - override fun setFontSize(size: Double) { - fontSize = size * pixelScale - } - - override fun setStrokeWidth(size: Double) { - ctx.lineWidth = size * pixelScale - } - - override fun fillArc(centerX: Double, - centerY: Double, - radius: Double, - startAngle: Double, - swipeAngle: Double) { - val x = toPixel(centerX) - val y = toPixel(centerY) - val from = startAngle / 180 * PI - val to = (startAngle + swipeAngle) / 180 * PI - ctx.beginPath() - ctx.moveTo(x, y) - ctx.arc(x, y, toPixel(radius), -from, -to, swipeAngle >= 0) - ctx.lineTo(x, y) - ctx.fill() - } - - override fun fillCircle(centerX: Double, centerY: Double, radius: Double) { - ctx.beginPath() - ctx.arc(toPixel(centerX), - toPixel(centerY), - toPixel(radius), - 0.0, - 2 * PI) - ctx.fill() - } - - override fun setTextAlign(align: TextAlign) { - this.align = when (align) { - TextAlign.LEFT -> CanvasTextAlign.LEFT - TextAlign.CENTER -> CanvasTextAlign.CENTER - TextAlign.RIGHT -> CanvasTextAlign.RIGHT - } - } - - override fun toImage(): Image { - return JsImage(this, - ctx.getImageData(0.0, - 0.0, - element.width.toDouble(), - element.height.toDouble())) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/js/org/isoron/platform/gui/JsImage.kt b/uhabits-core-legacy/src/main/js/org/isoron/platform/gui/JsImage.kt deleted file mode 100644 index 66a60f1ef..000000000 --- a/uhabits-core-legacy/src/main/js/org/isoron/platform/gui/JsImage.kt +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.gui - -import org.khronos.webgl.* -import org.w3c.dom.* -import kotlin.browser.* -import kotlin.math.* - -class JsImage(val canvas: JsCanvas, - val imageData: ImageData) : Image { - - override val width: Int - get() = imageData.width - - override val height: Int - get() = imageData.height - - val pixels = imageData.unsafeCast() - - init { - console.log(width, height, imageData.data.length) - } - - override suspend fun export(path: String) { - canvas.ctx.putImageData(imageData, 0.0, 0.0) - val container = document.createElement("div") - container.className = "export" - val title = document.createElement("div") - title.innerHTML = path - document.body?.appendChild(container) - container.appendChild(title) - container.appendChild(canvas.element) - } - - override fun getPixel(x: Int, y: Int): Color { - val offset = 4 * (y * width + x) - return Color(imageData.data[offset + 0] / 255.0, - imageData.data[offset + 1] / 255.0, - imageData.data[offset + 2] / 255.0, - imageData.data[offset + 3] / 255.0) - } - - override fun setPixel(x: Int, y: Int, color: Color) { - val offset = 4 * (y * width + x) - inline fun map(x: Double): Byte { - return (x * 255).roundToInt().unsafeCast() - } - imageData.data.set(offset + 0, map(color.red)) - imageData.data.set(offset + 1, map(color.green)) - imageData.data.set(offset + 2, map(color.blue)) - imageData.data.set(offset + 3, map(color.alpha)) - } - -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/js/org/isoron/platform/io/JsDatabase.kt b/uhabits-core-legacy/src/main/js/org/isoron/platform/io/JsDatabase.kt deleted file mode 100644 index db4c2c992..000000000 --- a/uhabits-core-legacy/src/main/js/org/isoron/platform/io/JsDatabase.kt +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.io - -external fun require(module: String): dynamic - -class JsPreparedStatement(val stmt: dynamic) : PreparedStatement { - - override fun step(): StepResult { - val isRowAvailable = stmt.step() as Boolean - return if(isRowAvailable) StepResult.ROW else StepResult.DONE - } - - override fun finalize() { - stmt.free() - } - - override fun getInt(index: Int): Int { - return (stmt.getNumber(index) as Double).toInt() - } - - override fun getLong(index: Int): Long { - return (stmt.getNumber(index) as Double).toLong() - } - - override fun getText(index: Int): String { - return stmt.getString(index) as String - } - - override fun getReal(index: Int): Double { - return stmt.getNumber(index) as Double - } - - override fun bindInt(index: Int, value: Int) { - stmt.bindNumber(value, index + 1) - } - - override fun bindLong(index: Int, value: Long) { - stmt.bindNumber(value, index + 1) - } - - override fun bindText(index: Int, value: String) { - stmt.bindString(value, index + 1) - } - - override fun bindReal(index: Int, value: Double) { - stmt.bindNumber(value, index + 1) - } - - override fun reset() { - stmt.reset() - } - -} - -class JsDatabase(val db: dynamic) : Database { - override fun prepareStatement(sql: String): PreparedStatement { - return JsPreparedStatement(db.prepare(sql)) - } - - override fun close() { - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/js/org/isoron/platform/io/JsFiles.kt b/uhabits-core-legacy/src/main/js/org/isoron/platform/io/JsFiles.kt deleted file mode 100644 index 7b8257856..000000000 --- a/uhabits-core-legacy/src/main/js/org/isoron/platform/io/JsFiles.kt +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.io - -import kotlinx.coroutines.* -import org.isoron.platform.gui.* -import org.isoron.platform.gui.Image -import org.w3c.dom.* -import org.w3c.xhr.* -import kotlin.browser.* -import kotlin.js.* - -class JsFileStorage { - private val TAG = "JsFileStorage" - private val log = StandardLog() - - private val indexedDB = eval("indexedDB") - private var db: dynamic = null - - private val DB_NAME = "Main" - private val OS_NAME = "Files" - - suspend fun init() { - log.info(TAG, "Initializing") - Promise { resolve, reject -> - val req = indexedDB.open(DB_NAME, 2) - req.onerror = { reject(Exception("could not open IndexedDB")) } - req.onupgradeneeded = { - log.info(TAG, "Creating document store") - req.result.createObjectStore(OS_NAME) - } - req.onsuccess = { - log.info(TAG, "Ready") - db = req.result - resolve(0) - } - }.await() - } - - suspend fun delete(path: String) { - Promise { resolve, reject -> - val transaction = db.transaction(OS_NAME, "readwrite") - val os = transaction.objectStore(OS_NAME) - val req = os.delete(path) - req.onerror = { reject(Exception("could not delete $path")) } - req.onsuccess = { resolve(0) } - }.await() - } - - suspend fun put(path: String, content: String) { - Promise { resolve, reject -> - val transaction = db.transaction(OS_NAME, "readwrite") - val os = transaction.objectStore(OS_NAME) - val req = os.put(content, path) - req.onerror = { reject(Exception("could not put $path")) } - req.onsuccess = { resolve(0) } - }.await() - } - - suspend fun get(path: String): String { - return Promise { resolve, reject -> - val transaction = db.transaction(OS_NAME, "readonly") - val os = transaction.objectStore(OS_NAME) - val req = os.get(path) - req.onerror = { reject(Exception("could not get $path")) } - req.onsuccess = { resolve(req.result) } - }.await() - } - - suspend fun exists(path: String): Boolean { - return Promise { resolve, reject -> - val transaction = db.transaction(OS_NAME, "readonly") - val os = transaction.objectStore(OS_NAME) - val req = os.count(path) - req.onerror = { reject(Exception("could not count $path")) } - req.onsuccess = { resolve(req.result > 0) } - }.await() - } -} - -class JsFileOpener(val fileStorage: JsFileStorage) : FileOpener { - - override fun openUserFile(path: String): UserFile { - return JsUserFile(fileStorage, path) - } - - override fun openResourceFile(path: String): ResourceFile { - return JsResourceFile(path) - } -} - -class JsUserFile(val fs: JsFileStorage, - val filename: String) : UserFile { - override suspend fun lines(): List { - return fs.get(filename).lines() - } - - override suspend fun delete() { - fs.delete(filename) - } - - override suspend fun exists(): Boolean { - return fs.exists(filename) - } -} - -class JsResourceFile(val filename: String) : ResourceFile { - override suspend fun exists(): Boolean { - return Promise { resolve, reject -> - val xhr = XMLHttpRequest() - xhr.open("GET", "/assets/$filename", true) - xhr.onload = { resolve(xhr.status.toInt() != 404) } - xhr.onerror = { reject(Exception()) } - xhr.send() - }.await() - } - - override suspend fun lines(): List { - return Promise> { resolve, reject -> - val xhr = XMLHttpRequest() - xhr.open("GET", "/assets/$filename", true) - xhr.onload = { resolve(xhr.responseText.lines()) } - xhr.onerror = { reject(Exception()) } - xhr.send() - }.await() - } - - override suspend fun copyTo(dest: UserFile) { - val fs = (dest as JsUserFile).fs - fs.put(dest.filename, lines().joinToString("\n")) - } - - override suspend fun toImage(): Image { - return Promise { resolve, reject -> - val img = org.w3c.dom.Image() - img.onload = { - val canvas = JsCanvas(document.createElement("canvas") as HTMLCanvasElement, 1.0) - canvas.element.width = img.naturalWidth - canvas.element.height = img.naturalHeight - canvas.setColor(Color(0xffffff)) - canvas.fillRect(0.0, 0.0, canvas.getWidth(), canvas.getHeight()) - canvas.ctx.drawImage(img, 0.0, 0.0) - resolve(canvas.toImage()) - } - img.src = "/assets/$filename" - }.await() - } -} diff --git a/uhabits-core-legacy/src/main/js/org/isoron/platform/io/JsStrings.kt b/uhabits-core-legacy/src/main/js/org/isoron/platform/io/JsStrings.kt deleted file mode 100644 index 2d583967c..000000000 --- a/uhabits-core-legacy/src/main/js/org/isoron/platform/io/JsStrings.kt +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.io - -actual fun format(format: String, arg: String): String { - return js("vsprintf")(format, arg) as String -} - -actual fun format(format: String, arg: Int): String { - return js("vsprintf")(format, arg) as String -} - -actual fun format(format: String, arg: Double): String { - return js("vsprintf")(format, arg) as String -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/js/org/isoron/platform/time/JsDates.kt b/uhabits-core-legacy/src/main/js/org/isoron/platform/time/JsDates.kt deleted file mode 100644 index 0810d9df2..000000000 --- a/uhabits-core-legacy/src/main/js/org/isoron/platform/time/JsDates.kt +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.time - -import kotlin.js.* - -fun LocalDate.toJsDate(): Date { - return Date(year, month - 1, day) -} - -class JsDateFormatter(private val locale: String) : LocalDateFormatter { - override fun shortWeekdayName(date: LocalDate): String { - val options = dateLocaleOptions { weekday = "short" } - return date.toJsDate().toLocaleString(locale, options) - } - - override fun shortMonthName(date: LocalDate): String { - val options = dateLocaleOptions { month = "short" } - return date.toJsDate().toLocaleString(locale, options) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/jvm/org/isoron/platform/gui/JavaCanvas.kt b/uhabits-core-legacy/src/main/jvm/org/isoron/platform/gui/JavaCanvas.kt deleted file mode 100644 index 04740b3d3..000000000 --- a/uhabits-core-legacy/src/main/jvm/org/isoron/platform/gui/JavaCanvas.kt +++ /dev/null @@ -1,168 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.gui - -import kotlinx.coroutines.* -import org.isoron.platform.io.* -import java.awt.* -import java.awt.RenderingHints.* -import java.awt.font.* -import java.awt.image.* -import kotlin.math.* - - -class JavaCanvas(val image: BufferedImage, - val pixelScale: Double = 2.0) : Canvas { - override fun toImage(): Image { - return JavaImage(image) - } - - private val frc = FontRenderContext(null, true, true) - private var fontSize = 12.0 - private var font = Font.REGULAR - private var textAlign = TextAlign.CENTER - val widthPx = image.width - val heightPx = image.height - val g2d = image.createGraphics() - - private val NOTO_REGULAR_FONT = createFont("fonts/NotoSans-Regular.ttf") - private val NOTO_BOLD_FONT = createFont("fonts/NotoSans-Bold.ttf") - private val FONT_AWESOME_FONT = createFont("fonts/FontAwesome.ttf") - - init { - g2d.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON); - g2d.setRenderingHint(KEY_TEXT_ANTIALIASING, VALUE_TEXT_ANTIALIAS_ON); - g2d.setRenderingHint(KEY_FRACTIONALMETRICS, VALUE_FRACTIONALMETRICS_ON); - updateFont() - } - - private fun toPixel(x: Double): Int { - return (pixelScale * x).toInt() - } - - private fun toDp(x: Int): Double { - return x / pixelScale - } - - override fun setColor(color: Color) { - g2d.color = java.awt.Color(color.red.toFloat(), - color.green.toFloat(), - color.blue.toFloat(), - color.alpha.toFloat()) - } - - override fun drawLine(x1: Double, y1: Double, x2: Double, y2: Double) { - g2d.drawLine(toPixel(x1), toPixel(y1), toPixel(x2), toPixel(y2)) - } - - override fun drawText(text: String, x: Double, y: Double) { - updateFont() - val bounds = g2d.font.getStringBounds(text, frc) - val bWidth = bounds.width.roundToInt() - val bHeight = bounds.height.roundToInt() - val bx = bounds.x.roundToInt() - val by = bounds.y.roundToInt() - - if (textAlign == TextAlign.CENTER) { - g2d.drawString(text, - toPixel(x) - bx - bWidth / 2, - toPixel(y) - by - bHeight / 2) - } else if (textAlign == TextAlign.LEFT) { - g2d.drawString(text, - toPixel(x) - bx, - toPixel(y) - by - bHeight / 2) - } else { - g2d.drawString(text, - toPixel(x) - bx - bWidth, - toPixel(y) - by - bHeight / 2) - } - } - - override fun fillRect(x: Double, y: Double, width: Double, height: Double) { - g2d.fillRect(toPixel(x), toPixel(y), toPixel(width), toPixel(height)) - } - - override fun drawRect(x: Double, y: Double, width: Double, height: Double) { - g2d.drawRect(toPixel(x), toPixel(y), toPixel(width), toPixel(height)) - } - - override fun getHeight(): Double { - return toDp(heightPx) - } - - override fun getWidth(): Double { - return toDp(widthPx) - } - - - override fun setFont(font: Font) { - this.font = font - updateFont() - } - - override fun setFontSize(size: Double) { - fontSize = size - updateFont() - } - - override fun setStrokeWidth(size: Double) { - g2d.stroke = BasicStroke((size * pixelScale).toFloat()) - } - - private fun updateFont() { - val size = (fontSize * pixelScale).toFloat() - g2d.font = when (font) { - Font.REGULAR -> NOTO_REGULAR_FONT.deriveFont(size) - Font.BOLD -> NOTO_BOLD_FONT.deriveFont(size) - Font.FONT_AWESOME -> FONT_AWESOME_FONT.deriveFont(size) - } - } - - override fun fillCircle(centerX: Double, centerY: Double, radius: Double) { - g2d.fillOval(toPixel(centerX - radius), - toPixel(centerY - radius), - toPixel(radius * 2), - toPixel(radius * 2)) - } - - override fun fillArc(centerX: Double, - centerY: Double, - radius: Double, - startAngle: Double, - swipeAngle: Double) { - - g2d.fillArc(toPixel(centerX - radius), - toPixel(centerY - radius), - toPixel(radius * 2), - toPixel(radius * 2), - startAngle.roundToInt(), - swipeAngle.roundToInt()) - } - - override fun setTextAlign(align: TextAlign) { - this.textAlign = align - } - - private fun createFont(path: String) = runBlocking { - val file = JavaFileOpener().openResourceFile(path) as JavaResourceFile - if (!file.exists()) throw RuntimeException("File not found: ${file.path}") - java.awt.Font.createFont(0, file.stream()) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/jvm/org/isoron/platform/gui/JavaImage.kt b/uhabits-core-legacy/src/main/jvm/org/isoron/platform/gui/JavaImage.kt deleted file mode 100644 index db6d5cb5a..000000000 --- a/uhabits-core-legacy/src/main/jvm/org/isoron/platform/gui/JavaImage.kt +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.gui - -import java.awt.image.* -import java.io.* -import javax.imageio.* - -class JavaImage(val bufferedImage: BufferedImage) : Image { - override fun setPixel(x: Int, y: Int, color: Color) { - bufferedImage.setRGB(x, y, java.awt.Color(color.red.toFloat(), - color.green.toFloat(), - color.blue.toFloat()).rgb) - } - - override suspend fun export(path: String) { - val file = File(path) - file.parentFile.mkdirs() - ImageIO.write(bufferedImage, "png", file) - } - - override val width: Int - get() = bufferedImage.width - - override val height: Int - get() = bufferedImage.height - - override fun getPixel(x: Int, y: Int): Color { - return Color(bufferedImage.getRGB(x, y)) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/jvm/org/isoron/platform/io/JavaDatabase.kt b/uhabits-core-legacy/src/main/jvm/org/isoron/platform/io/JavaDatabase.kt deleted file mode 100644 index df99f0693..000000000 --- a/uhabits-core-legacy/src/main/jvm/org/isoron/platform/io/JavaDatabase.kt +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.io - -import java.sql.* -import java.sql.PreparedStatement - -class JavaPreparedStatement(private var stmt: PreparedStatement) : org.isoron.platform.io.PreparedStatement { - private var rs: ResultSet? = null - - private var hasExecuted = false - - override fun step(): StepResult { - if (!hasExecuted) { - hasExecuted = true - val hasResult = stmt.execute() - if (hasResult) rs = stmt.resultSet - } - - if (rs == null || !rs!!.next()) return StepResult.DONE - return StepResult.ROW - } - - override fun finalize() { - stmt.close() - } - - override fun getInt(index: Int): Int { - return rs!!.getInt(index + 1) - } - - override fun getLong(index: Int): Long { - return rs!!.getLong(index + 1) - } - - override fun getText(index: Int): String { - return rs!!.getString(index + 1) - } - - override fun getReal(index: Int): Double { - return rs!!.getDouble(index + 1) - } - - override fun bindInt(index: Int, value: Int) { - stmt.setInt(index + 1, value) - } - - override fun bindLong(index: Int, value: Long) { - stmt.setLong(index + 1, value) - } - - override fun bindText(index: Int, value: String) { - stmt.setString(index + 1, value) - } - - override fun bindReal(index: Int, value: Double) { - stmt.setDouble(index + 1, value) - } - - override fun reset() { - stmt.clearParameters() - hasExecuted = false - } -} - -class JavaDatabase(private var conn: Connection, - private val log: Log) : Database { - - override fun prepareStatement(sql: String): org.isoron.platform.io.PreparedStatement { - return JavaPreparedStatement(conn.prepareStatement(sql)) - } - - override fun close() { - conn.close() - } -} - -class JavaDatabaseOpener(val log: Log) : DatabaseOpener { - override fun open(file: UserFile): Database { - val platformFile = file as JavaUserFile - val conn = DriverManager.getConnection("jdbc:sqlite:${platformFile.path}") - return JavaDatabase(conn, log) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/jvm/org/isoron/platform/io/JavaFiles.kt b/uhabits-core-legacy/src/main/jvm/org/isoron/platform/io/JavaFiles.kt deleted file mode 100644 index 1bb3384e8..000000000 --- a/uhabits-core-legacy/src/main/jvm/org/isoron/platform/io/JavaFiles.kt +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.io - -import org.isoron.platform.gui.* -import java.io.* -import java.nio.file.* -import javax.imageio.* - -class JavaResourceFile(val path: String) : ResourceFile { - private val javaPath: Path - get() { - val mainPath = Paths.get("assets/main/$path") - val testPath = Paths.get("assets/test/$path") - if (Files.exists(mainPath)) return mainPath - else return testPath - } - - override suspend fun exists(): Boolean { - return Files.exists(javaPath) - } - - override suspend fun lines(): List { - return Files.readAllLines(javaPath) - } - - override suspend fun copyTo(dest: UserFile) { - if (dest.exists()) dest.delete() - val destPath = (dest as JavaUserFile).path - destPath.toFile().parentFile?.mkdirs() - Files.copy(javaPath, destPath) - } - - fun stream(): InputStream { - return Files.newInputStream(javaPath) - } - - override suspend fun toImage(): Image { - return JavaImage(ImageIO.read(stream())) - } -} - -class JavaUserFile(val path: Path) : UserFile { - override suspend fun lines(): List { - return Files.readAllLines(path) - } - - override suspend fun exists(): Boolean { - return Files.exists(path) - } - - override suspend fun delete() { - Files.delete(path) - } -} - -class JavaFileOpener : FileOpener { - override fun openUserFile(path: String): UserFile { - val path = Paths.get("/tmp/$path") - return JavaUserFile(path) - } - - override fun openResourceFile(path: String): ResourceFile { - return JavaResourceFile(path) - } -} diff --git a/uhabits-core-legacy/src/main/jvm/org/isoron/platform/io/Strings.kt b/uhabits-core-legacy/src/main/jvm/org/isoron/platform/io/Strings.kt deleted file mode 100644 index edb787583..000000000 --- a/uhabits-core-legacy/src/main/jvm/org/isoron/platform/io/Strings.kt +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.io - -actual fun format(format: String, arg: String): String = - String.format(format, arg) - -actual fun format(format: String, arg: Int): String = - String.format(format, arg) - -actual fun format(format: String, arg: Double): String = - String.format(format, arg) \ No newline at end of file diff --git a/uhabits-core-legacy/src/main/jvm/org/isoron/platform/time/JavaDates.kt b/uhabits-core-legacy/src/main/jvm/org/isoron/platform/time/JavaDates.kt deleted file mode 100644 index ebb0a0862..000000000 --- a/uhabits-core-legacy/src/main/jvm/org/isoron/platform/time/JavaDates.kt +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.time - -import java.util.* -import java.util.Calendar.* - -fun LocalDate.toGregorianCalendar(): GregorianCalendar { - val cal = GregorianCalendar() - cal.timeZone = TimeZone.getTimeZone("GMT") - cal.set(MILLISECOND, 0) - cal.set(SECOND, 0) - cal.set(MINUTE, 0) - cal.set(HOUR_OF_DAY, 0) - cal.set(YEAR, this.year) - cal.set(MONTH, this.month - 1) - cal.set(DAY_OF_MONTH, this.day) - return cal -} - -class JavaLocalDateFormatter(private val locale: Locale) : LocalDateFormatter { - override fun shortMonthName(date: LocalDate): String { - val cal = date.toGregorianCalendar() - val longName = cal.getDisplayName(MONTH, LONG, locale) - val shortName = cal.getDisplayName(MONTH, SHORT, locale) - - // For some locales, such as Japan, SHORT name is exceedingly short - return if (longName.length <= 3) longName else shortName - } - - override fun shortWeekdayName(date: LocalDate): String { - val cal = date.toGregorianCalendar() - return cal.getDisplayName(DAY_OF_WEEK, SHORT, locale); - } -} diff --git a/uhabits-core-legacy/src/test/common/org/isoron/AsyncTests.kt b/uhabits-core-legacy/src/test/common/org/isoron/AsyncTests.kt deleted file mode 100644 index 323e2c234..000000000 --- a/uhabits-core-legacy/src/test/common/org/isoron/AsyncTests.kt +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron - -/** - * Workaround until Kotlin adds support for testing suspend functions - * https://youtrack.jetbrains.com/issue/KT-22228 - */ -expect fun asyncTest(block: suspend () -> Unit) \ No newline at end of file diff --git a/uhabits-core-legacy/src/test/common/org/isoron/DependencyResolver.kt b/uhabits-core-legacy/src/test/common/org/isoron/DependencyResolver.kt deleted file mode 100644 index e7208049c..000000000 --- a/uhabits-core-legacy/src/test/common/org/isoron/DependencyResolver.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron - -import org.isoron.platform.gui.* -import org.isoron.platform.io.* -import org.isoron.platform.time.* - -enum class Locale { - US, JAPAN -} - -expect object DependencyResolver { - val ignoreViewTests: Boolean - suspend fun getFileOpener(): FileOpener - suspend fun getDatabase(): Database - fun getDateFormatter(locale: Locale): LocalDateFormatter - fun createCanvas(width: Int, height: Int): Canvas -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/test/common/org/isoron/platform/concurrency/ObservableTest.kt b/uhabits-core-legacy/src/test/common/org/isoron/platform/concurrency/ObservableTest.kt deleted file mode 100644 index 25fd37659..000000000 --- a/uhabits-core-legacy/src/test/common/org/isoron/platform/concurrency/ObservableTest.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.concurrency - -import kotlin.test.* - -class ObservableTest { - - interface TestListener { - fun onDataChanged(data: Int) - } - - @Test - fun testNotifyListeners() { - var wasCalled = false - - val listener = object : TestListener { - override fun onDataChanged(data: Int) { - assertEquals(42, data) - wasCalled = true - } - } - - val observable = Observable() - observable.addListener(listener) - observable.notifyListeners { it.onDataChanged(42) } - assertTrue(wasCalled) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/test/common/org/isoron/platform/gui/CanvasTest.kt b/uhabits-core-legacy/src/test/common/org/isoron/platform/gui/CanvasTest.kt deleted file mode 100644 index 1c2065cde..000000000 --- a/uhabits-core-legacy/src/test/common/org/isoron/platform/gui/CanvasTest.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.gui - -import org.isoron.* -import org.isoron.uhabits.* -import kotlin.test.* - -class CanvasTest: BaseViewTest() { - @Test - fun run() = asyncTest{ - val canvas = DependencyResolver.createCanvas(500, 400) - - canvas.setColor(Color(0x303030)) - canvas.fillRect(0.0, 0.0, 500.0, 400.0) - - canvas.setColor(Color(0x606060)) - canvas.setStrokeWidth(25.0) - canvas.drawRect(100.0, 100.0, 300.0, 200.0) - - canvas.setColor(Color(0xFFFF00)) - canvas.setStrokeWidth(1.0) - canvas.drawRect(0.0, 0.0, 100.0, 100.0) - canvas.fillCircle(50.0, 50.0, 30.0) - canvas.drawRect(0.0, 100.0, 100.0, 100.0) - canvas.fillArc(50.0, 150.0, 30.0, 90.0, 135.0) - canvas.drawRect(0.0, 200.0, 100.0, 100.0) - canvas.fillArc(50.0, 250.0, 30.0, 90.0, -135.0) - canvas.drawRect(0.0, 300.0, 100.0, 100.0) - canvas.fillArc(50.0, 350.0, 30.0, 45.0, 90.0) - - canvas.setColor(Color(0xFF0000)) - canvas.setStrokeWidth(2.0) - canvas.drawLine(0.0, 0.0, 500.0, 400.0) - canvas.drawLine(500.0, 0.0, 0.0, 400.0) - - canvas.setFont(Font.BOLD) - canvas.setFontSize(50.0) - canvas.setColor(Color(0x00FF00)) - canvas.setTextAlign(TextAlign.CENTER) - canvas.drawText("HELLO", 250.0, 100.0) - - canvas.setTextAlign(TextAlign.RIGHT) - canvas.drawText("HELLO", 250.0, 150.0) - - canvas.setTextAlign(TextAlign.LEFT) - canvas.drawText("HELLO", 250.0, 200.0) - - canvas.setFont(Font.FONT_AWESOME) - canvas.drawText(FontAwesome.CHECK, 250.0, 300.0) - - assertRenders("components/CanvasTest.png", canvas) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/test/common/org/isoron/platform/io/DatabaseTest.kt b/uhabits-core-legacy/src/test/common/org/isoron/platform/io/DatabaseTest.kt deleted file mode 100644 index 8e46e0872..000000000 --- a/uhabits-core-legacy/src/test/common/org/isoron/platform/io/DatabaseTest.kt +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.io - -import org.isoron.* -import kotlin.test.* - -class DatabaseTest { - @Test - fun testUsage() = asyncTest{ - val db = DependencyResolver.getDatabase() - - db.setVersion(0) - assertEquals(0, db.getVersion()) - - db.setVersion(23) - assertEquals(23, db.getVersion()) - - var stmt = db.prepareStatement("drop table if exists demo") - stmt.step() - stmt.finalize() - - stmt = db.prepareStatement("create table if not exists demo(key int, value text)") - stmt.step() - stmt.finalize() - - stmt = db.prepareStatement("insert into demo(key, value) values (?, ?)") - stmt.bindInt(0, 42) - stmt.bindText(1, "Hello World") - stmt.step() - stmt.finalize() - - stmt = db.prepareStatement("select * from demo where key > ?") - stmt.bindInt(0, 10) - - var result = stmt.step() - assertEquals(StepResult.ROW, result) - assertEquals(42, stmt.getInt(0)) - assertEquals("Hello World", stmt.getText(1)) - - result = stmt.step() - assertEquals(StepResult.DONE, result) - - stmt.finalize() - db.close() - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/test/common/org/isoron/platform/io/FilesTest.kt b/uhabits-core-legacy/src/test/common/org/isoron/platform/io/FilesTest.kt deleted file mode 100644 index f039abc93..000000000 --- a/uhabits-core-legacy/src/test/common/org/isoron/platform/io/FilesTest.kt +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.io - -import org.isoron.* -import kotlin.test.* - -class FilesTest() { - @Test - fun testLines() = asyncTest { - val fileOpener = DependencyResolver.getFileOpener() - - assertFalse(fileOpener.openUserFile("non-existing-usr.txt").exists(), - "non-existing-usr.txt shouldn't exist") - - assertFalse(fileOpener.openResourceFile("non-existing-res.txt").exists(), - "non-existing-res.txt shouldn't exist") - - val hello = fileOpener.openResourceFile("hello.txt") - assertTrue(hello.exists(), "hello.txt should exist") - var lines = hello.lines() - assertEquals(2, lines.size) - assertEquals("Hello World!", lines[0]) - assertEquals("This is a resource.", lines[1]) - - val helloCopy = fileOpener.openUserFile("copies/hello.txt") - hello.copyTo(helloCopy) - lines = helloCopy.lines() - assertEquals("Hello World!", lines[0]) - assertEquals("This is a resource.", lines[1]) - - assertTrue(helloCopy.exists(), "helloCopy should exist") - helloCopy.delete() - assertFalse(helloCopy.exists(), "helloCopy shouldn't exist") - - - val migration = fileOpener.openResourceFile("migrations/012.sql") - assertTrue(migration.exists(), "migrations/012.sql should exist") - lines = migration.lines() - assertEquals("delete from Score", lines[0]) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/test/common/org/isoron/platform/io/StringsTest.kt b/uhabits-core-legacy/src/test/common/org/isoron/platform/io/StringsTest.kt deleted file mode 100644 index 1573e620a..000000000 --- a/uhabits-core-legacy/src/test/common/org/isoron/platform/io/StringsTest.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.io - -import kotlin.test.* - -class StringsTest { - @Test - fun testSprintf() { - assertEquals("hello world!", format("hello %s!", "world")) - assertEquals(" 5", format("%3d", 5)) - assertEquals("005", format("%03d", 5)) - assertEquals("005", format("%03d", 5)) - assertEquals(" 45", format("%3d", 45)) - assertEquals("145", format("%3d", 145)) - assertEquals(" 13.42", format("%8.2f", 13.419187263)) - assertEquals("00013.42", format("%08.2f", 13.419187263)) - assertEquals("13.42 ", format("%-8.2f", 13.419187263)) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/test/common/org/isoron/platform/time/DatesTest.kt b/uhabits-core-legacy/src/test/common/org/isoron/platform/time/DatesTest.kt deleted file mode 100644 index cf64f50de..000000000 --- a/uhabits-core-legacy/src/test/common/org/isoron/platform/time/DatesTest.kt +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.platform.time - -import org.isoron.* -import kotlin.test.* - -class DatesTest { - private val d1 = LocalDate(2019, 3, 25) - private val d2 = LocalDate(2019, 4, 4) - private val d3 = LocalDate(2019, 5, 12) - - @Test - fun testPlusMinusDays() { - val today = LocalDate(2019, 3, 25) - assertEquals(today.minus(28), LocalDate(2019, 2, 25)) - assertEquals(today.plus(7), LocalDate(2019, 4, 1)) - assertEquals(today.plus(42), LocalDate(2019, 5, 6)) - } - - @Test - fun testFormatter() { - var fmt = DependencyResolver.getDateFormatter(Locale.US) - assertEquals("Mon", fmt.shortWeekdayName(d1)) - assertEquals("Thu", fmt.shortWeekdayName(d2)) - assertEquals("Sun", fmt.shortWeekdayName(d3)) - assertEquals("Mar", fmt.shortMonthName(d1)) - assertEquals("Apr", fmt.shortMonthName(d2)) - assertEquals("May", fmt.shortMonthName(d3)) - - fmt = DependencyResolver.getDateFormatter(Locale.JAPAN) - assertEquals("月", fmt.shortWeekdayName(d1)) - assertEquals("木", fmt.shortWeekdayName(d2)) - assertEquals("日", fmt.shortWeekdayName(d3)) - assertEquals("3月", fmt.shortMonthName(d1)) - assertEquals("4月", fmt.shortMonthName(d2)) - assertEquals("5月", fmt.shortMonthName(d3)) - } - - @Test - fun testTimestamps() { - val timestamps = listOf(Timestamp(1555977600000), - Timestamp(968716800000), - Timestamp(946684800000)) - val dates = listOf(LocalDate(2019, 4, 23), - LocalDate(2000, 9, 12), - LocalDate(2000, 1, 1)) - assertEquals(timestamps, dates.map { d -> d.timestamp }) - assertEquals(dates, timestamps.map { t -> t.localDate }) - } - - @Test - fun testIsOlderThan() { - val ref = LocalDate(2010, 10, 5) - assertTrue(ref.isOlderThan(LocalDate(2010, 10, 10))) - assertTrue(ref.isOlderThan(LocalDate(2010, 11, 4))) - assertTrue(ref.isOlderThan(LocalDate(2011, 1, 5))) - assertTrue(ref.isOlderThan(LocalDate(2015, 3, 1))) - - assertFalse(ref.isOlderThan(LocalDate(2010, 10, 5))) - assertFalse(ref.isOlderThan(LocalDate(2010, 10, 4))) - assertFalse(ref.isOlderThan(LocalDate(2010, 9, 1))) - assertFalse(ref.isOlderThan(LocalDate(2005, 10, 5))) - } - - @Test - fun testDistanceInDays() { - val d1 = LocalDate(2019, 5, 10) - val d2 = LocalDate(2019, 5, 30) - val d3 = LocalDate(2019, 6, 5) - - assertEquals(0, d1.distanceTo(d1)) - assertEquals(20, d1.distanceTo(d2)) - assertEquals(20, d2.distanceTo(d1)) - assertEquals(26, d1.distanceTo(d3)) - assertEquals(6, d2.distanceTo(d3)) - } - - @Test - fun testGregorianCalendarConversion() { - fun check(daysSince2000: Int, - expectedYear: Int, - expectedMonth: Int, - expectedDay: Int, - expectedWeekday: Int) { - val date = LocalDate(daysSince2000) - assertEquals(expectedYear, date.year) - assertEquals(expectedMonth, date.month) - assertEquals(expectedDay, date.day) - assertEquals(expectedWeekday, date.dayOfWeek.index) - assertEquals(date, date.timestamp.localDate) - } - - check(0, 2000, 1, 1, 6) - check(626, 2001, 9, 18, 2) - check(915, 2002, 7, 4, 4) - check(2759, 2007, 7, 22, 0) - check(2791, 2007, 8, 23, 4) - check(6524, 2017, 11, 11, 6) - check(7517, 2020, 7, 31, 5) - check(10031, 2027, 6, 19, 6) - check(13091, 2035, 11, 4, 0) - check(14849, 2040, 8, 27, 1) - check(17330, 2047, 6, 13, 4) - check(20566, 2056, 4, 22, 6) - check(23617, 2064, 8, 29, 5) - check(27743, 2075, 12, 16, 1) - check(31742, 2086, 11, 27, 3) - check(36659, 2100, 5, 15, 6) - check(39224, 2107, 5, 24, 2) - check(39896, 2109, 3, 26, 2) - check(40819, 2111, 10, 5, 1) - check(43983, 2120, 6, 3, 1) - check(46893, 2128, 5, 22, 6) - check(51013, 2139, 9, 2, 3) - check(55542, 2152, 1, 26, 3) - check(58817, 2161, 1, 13, 2) - check(63769, 2174, 8, 5, 5) - check(64893, 2177, 9, 2, 2) - check(66840, 2183, 1, 1, 3) - check(68011, 2186, 3, 17, 5) - check(70060, 2191, 10, 26, 3) - check(70733, 2193, 8, 29, 4) - } -} diff --git a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/BaseViewTest.kt b/uhabits-core-legacy/src/test/common/org/isoron/uhabits/BaseViewTest.kt deleted file mode 100644 index 1e9b103e6..000000000 --- a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/BaseViewTest.kt +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits - -import org.isoron.* -import org.isoron.platform.gui.* -import org.isoron.uhabits.components.* -import kotlin.test.* - -open class BaseViewTest { - var theme = LightTheme() - suspend fun assertRenders(width: Int, - height: Int, - expectedPath: String, - component: Component) { - if (DependencyResolver.ignoreViewTests) { - println("WARN: Ignoring BaseViewTest assertion") - return - } - val canvas = DependencyResolver.createCanvas(width, height) - component.draw(canvas) - assertRenders(expectedPath, canvas) - } - - suspend fun assertRenders(path: String, - canvas: Canvas) { - if (DependencyResolver.ignoreViewTests) { - println("WARN: Ignoring BaseViewTest assertion") - return - } - val actualImage = canvas.toImage() - val failedActualPath = "/tmp/failed/${path}" - val failedExpectedPath = failedActualPath.replace(".png", - ".expected.png") - val failedDiffPath = failedActualPath.replace(".png", ".diff.png") - val fileOpener = DependencyResolver.getFileOpener() - val expectedFile = fileOpener.openResourceFile(path) - if (expectedFile.exists()) { - val expectedImage = expectedFile.toImage() - val diffImage = expectedFile.toImage() - diffImage.diff(actualImage) - val distance = diffImage.averageLuminosity * 100 - if (distance >= 1.0) { - expectedImage.export(failedExpectedPath) - actualImage.export(failedActualPath) - diffImage.export(failedDiffPath) - fail("Images differ (distance=${distance})") - } - } else { - actualImage.export(failedActualPath) - fail("Expected image file is missing. Actual image: $failedActualPath") - } - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/components/BarChartTest.kt b/uhabits-core-legacy/src/test/common/org/isoron/uhabits/components/BarChartTest.kt deleted file mode 100644 index 9017f41cf..000000000 --- a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/components/BarChartTest.kt +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.components - -import org.isoron.* -import org.isoron.platform.time.* -import org.isoron.uhabits.* -import kotlin.test.* - -class BarChartTest : BaseViewTest() { - val base = "components/BarChart" - val today = LocalDate(2015, 1, 25) - val dailyAxis = (0..100).map { today.minus(it) } - val weeklyAxis = (0..100).map { today.minus(it * 7) } - val monthlyAxis = (0..100).map { today.minus(it * 30) } - val yearlyAxis = (0..100).map { today.minus(it * 365) } - val fmt = DependencyResolver.getDateFormatter(Locale.US) - val component = BarChart(theme, fmt) - - val series1 = listOf(200.0, 80.0, 150.0, 437.0, 50.0, 80.0, 420.0, - 350.0, 100.0, 375.0, 300.0, 50.0, 60.0, 350.0, - 125.0) - - val series2 = listOf(300.0, 500.0, 280.0, 50.0, 425.0, 300.0, 150.0, - 10.0, 50.0, 200.0, 230.0, 20.0, 60.0, 34.0, 100.0) - - init { - component.axis = dailyAxis - component.series.add(series1) - component.colors.add(theme.color(1)) - } - - @Test - fun testDraw() = asyncTest { - assertRenders(400, 200, "$base/base.png", component) - } - - @Test - fun testDrawWeeklyAxis() = asyncTest { - component.axis = weeklyAxis - assertRenders(400, 200, "$base/axis-weekly.png", component) - } - - @Test - fun testDrawMonthlyAxis() = asyncTest { - component.axis = monthlyAxis - assertRenders(400, 200, "$base/axis-monthly.png", component) - } - - @Test - fun testDrawYearlyAxis() = asyncTest { - component.axis = yearlyAxis - assertRenders(400, 200, "$base/axis-yearly.png", component) - } - - @Test - fun testDrawTwoSeries() = asyncTest { - component.series.add(series2) - component.colors.add(theme.color(3)) - assertRenders(400, 200, "$base/2-series.png", component) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/components/CalendarChartTest.kt b/uhabits-core-legacy/src/test/common/org/isoron/uhabits/components/CalendarChartTest.kt deleted file mode 100644 index dee24ccf8..000000000 --- a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/components/CalendarChartTest.kt +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.components - -import org.isoron.* -import org.isoron.platform.time.* -import org.isoron.uhabits.* -import kotlin.test.* - -class CalendarChartTest : BaseViewTest() { - val base = "components/CalendarChart" - - @Test - fun testDraw() = asyncTest { - val fmt = DependencyResolver.getDateFormatter(Locale.US) - val component = CalendarChart(LocalDate(2015, 1, 25), - theme.color(4), - theme, - fmt) - component.series = listOf(1.0, // today - 0.2, 0.5, 0.7, 0.0, 0.3, 0.4, 0.6, - 0.6, 0.0, 0.3, 0.6, 0.5, 0.8, 0.0, - 0.0, 0.0, 0.0, 0.6, 0.5, 0.7, 0.7, - 0.5, 0.5, 0.8, 0.9, 1.0, 1.0, 1.0, - 1.0, 1.0, 1.0, 1.0, 1.0, 0.5, 0.2) - assertRenders(400, 200, "$base/base.png", component) - - component.scrollPosition = 2 - assertRenders(400, 200, "$base/scroll.png", component) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/components/CheckmarkButtonTest.kt b/uhabits-core-legacy/src/test/common/org/isoron/uhabits/components/CheckmarkButtonTest.kt deleted file mode 100644 index 9a325917d..000000000 --- a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/components/CheckmarkButtonTest.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.components - -import org.isoron.* -import org.isoron.uhabits.* -import kotlin.test.* - -class CheckmarkButtonTest : BaseViewTest() { - val base = "components/CheckmarkButton" - - @Test - fun testDrawExplicit() = asyncTest { - val component = CheckmarkButton(2, theme.color(8), theme) - assertRenders(48, 48, "$base/explicit.png", component) - } - - @Test - fun testDrawImplicit() = asyncTest { - val component = CheckmarkButton(1, theme.color(8), theme) - assertRenders(48, 48, "$base/implicit.png", component) - } - - @Test - fun testDrawUnchecked() = asyncTest { - val component = CheckmarkButton(0, theme.color(8), theme) - assertRenders(48, 48, "$base/unchecked.png", component) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/components/HabitListHeaderTest.kt b/uhabits-core-legacy/src/test/common/org/isoron/uhabits/components/HabitListHeaderTest.kt deleted file mode 100644 index 41c4d9e5b..000000000 --- a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/components/HabitListHeaderTest.kt +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.components - -import org.isoron.* -import org.isoron.platform.time.* -import org.isoron.uhabits.* -import kotlin.test.* - -class HabitListHeaderTest : BaseViewTest() { - @Test - fun testDraw() = asyncTest { - val fmt = DependencyResolver.getDateFormatter(Locale.US) - val header = HabitListHeader(LocalDate(2019, 3, 25), 5, theme, fmt) - assertRenders(600, 48, "components/HabitListHeader/light.png", header) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/components/NumberButtonTest.kt b/uhabits-core-legacy/src/test/common/org/isoron/uhabits/components/NumberButtonTest.kt deleted file mode 100644 index 7f65a95ac..000000000 --- a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/components/NumberButtonTest.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.components - -import org.isoron.* -import org.isoron.uhabits.* -import kotlin.test.* - -class NumberButtonTest : BaseViewTest() { - val base = "components/NumberButton" - - @Test - fun testFormatValue() = asyncTest{ - assertEquals("0.12", 0.1235.toShortString()) - assertEquals("0.1", 0.1000.toShortString()) - assertEquals("5", 5.0.toShortString()) - assertEquals("5.25", 5.25.toShortString()) - assertEquals("12.3", 12.3456.toShortString()) - assertEquals("123", 123.123.toShortString()) - assertEquals("321", 321.2.toShortString()) - assertEquals("4.3k", 4321.2.toShortString()) - assertEquals("54.3k", 54321.2.toShortString()) - assertEquals("654k", 654321.2.toShortString()) - assertEquals("7.7M", 7654321.2.toShortString()) - assertEquals("87.7M", 87654321.2.toShortString()) - assertEquals("988M", 987654321.2.toShortString()) - assertEquals("2.0G", 1987654321.2.toShortString()) - } - - @Test - fun testRenderAbove() = asyncTest { - val btn = NumberButton(theme.color(8), 500.0, 100.0, "steps", theme) - assertRenders(48, 48, "$base/render_above.png", btn) - } - - @Test - fun testRenderBelow() = asyncTest { - val btn = NumberButton(theme.color(8), 99.0, 100.0, "steps", theme) - assertRenders(48, 48, "$base/render_below.png", btn) - } -} diff --git a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/components/RingTest.kt b/uhabits-core-legacy/src/test/common/org/isoron/uhabits/components/RingTest.kt deleted file mode 100644 index a91c4a056..000000000 --- a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/components/RingTest.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.components - -import org.isoron.* -import org.isoron.uhabits.* -import kotlin.test.* - -class RingTest : BaseViewTest() { - val base = "components/Ring" - - @Test - fun testDraw() = asyncTest { - val component = Ring(theme.color(8), - percentage = 0.30, - thickness = 5.0, - radius = 30.0, - theme = theme, - label = true) - assertRenders(60, 60, "$base/draw1.png", component) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/models/CheckmarkListTest.kt b/uhabits-core-legacy/src/test/common/org/isoron/uhabits/models/CheckmarkListTest.kt deleted file mode 100644 index b96965066..000000000 --- a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/models/CheckmarkListTest.kt +++ /dev/null @@ -1,184 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models - -import org.isoron.platform.time.* -import org.isoron.uhabits.models.Checkmark.Companion.CHECKED_AUTOMATIC -import org.isoron.uhabits.models.Checkmark.Companion.CHECKED_MANUAL -import org.isoron.uhabits.models.Checkmark.Companion.UNCHECKED -import kotlin.test.* - -class CheckmarkListTest { - - private val today = LocalDate(2019, 1, 30) - - private fun day(offset: Int): LocalDate { - return today.minus(offset) - } - - @Test - fun buildIntervalsWeekly() { - val checks = listOf(Checkmark(day(23), CHECKED_MANUAL), - Checkmark(day(18), CHECKED_MANUAL), - Checkmark(day(8), CHECKED_MANUAL)) - val expected = listOf( - CheckmarkList.Interval(day(23), day(23), day(17)), - CheckmarkList.Interval(day(18), day(18), day(12)), - CheckmarkList.Interval(day(8), day(8), day(2))) - val actual = CheckmarkList.buildIntervals(checks, - Frequency.WEEKLY) - assertEquals(expected, actual) - } - - @Test - fun buildIntervalsDaily() { - val checks = listOf(Checkmark(day(23), CHECKED_MANUAL), - Checkmark(day(18), CHECKED_MANUAL), - Checkmark(day(8), CHECKED_MANUAL)) - val expected = listOf( - CheckmarkList.Interval(day(23), day(23), day(23)), - CheckmarkList.Interval(day(18), day(18), day(18)), - CheckmarkList.Interval(day(8), day(8), day(8))) - val actual = CheckmarkList.buildIntervals(checks, - Frequency.DAILY) - assertEquals(expected, actual) - } - - @Test - fun buildIntervalsTwoPerWeek() { - val checks = listOf(Checkmark(day(23), CHECKED_MANUAL), - Checkmark(day(22), CHECKED_MANUAL), - Checkmark(day(18), CHECKED_MANUAL), - Checkmark(day(15), CHECKED_MANUAL), - Checkmark(day(8), CHECKED_MANUAL)) - val expected = listOf( - CheckmarkList.Interval(day(23), day(22), day(17)), - CheckmarkList.Interval(day(22), day(18), day(16)), - CheckmarkList.Interval(day(18), day(15), day(12))) - val actual = CheckmarkList.buildIntervals(checks, - Frequency.TWO_TIMES_PER_WEEK) - assertEquals(expected, actual) - } - - @Test - fun testSnapIntervalsTogether() { - val original = mutableListOf( - CheckmarkList.Interval(day(40), day(40), day(34)), - CheckmarkList.Interval(day(25), day(25), day(19)), - CheckmarkList.Interval(day(16), day(16), day(10)), - CheckmarkList.Interval(day(8), day(8), day(2))) - val expected = listOf( - CheckmarkList.Interval(day(40), day(40), day(34)), - CheckmarkList.Interval(day(25), day(25), day(19)), - CheckmarkList.Interval(day(18), day(16), day(12)), - CheckmarkList.Interval(day(11), day(8), day(5))) - CheckmarkList.snapIntervalsTogether(original) - assertEquals(expected, original) - } - - @Test - fun testBuildCheckmarksFromIntervals() { - val checks = listOf(Checkmark(day(10), CHECKED_MANUAL), - Checkmark(day(5), CHECKED_MANUAL), - Checkmark(day(2), CHECKED_MANUAL), - Checkmark(day(1), CHECKED_MANUAL)) - val intervals = listOf(CheckmarkList.Interval(day(10), day(8), day(8)), - CheckmarkList.Interval(day(6), day(5), day(4)), - CheckmarkList.Interval(day(2), day(2), day(1))) - val expected = listOf(Checkmark(day(1), CHECKED_MANUAL), - Checkmark(day(2), CHECKED_MANUAL), - Checkmark(day(3), UNCHECKED), - Checkmark(day(4), CHECKED_AUTOMATIC), - Checkmark(day(5), CHECKED_MANUAL), - Checkmark(day(6), CHECKED_AUTOMATIC), - Checkmark(day(7), UNCHECKED), - Checkmark(day(8), CHECKED_AUTOMATIC), - Checkmark(day(9), CHECKED_AUTOMATIC), - Checkmark(day(10), CHECKED_MANUAL)) - val actual = CheckmarkList.buildCheckmarksFromIntervals(checks, intervals) - assertEquals(expected, actual) - } - - @Test - fun testBuildCheckmarksFromIntervals2() { - val reps = listOf(Checkmark(day(0), CHECKED_MANUAL)) - val intervals = listOf(CheckmarkList.Interval(day(5), day(0), day(0))) - val expected = listOf(Checkmark(day(0), CHECKED_MANUAL), - Checkmark(day(1), CHECKED_AUTOMATIC), - Checkmark(day(2), CHECKED_AUTOMATIC), - Checkmark(day(3), CHECKED_AUTOMATIC), - Checkmark(day(4), CHECKED_AUTOMATIC), - Checkmark(day(5), CHECKED_AUTOMATIC)) - val actual = CheckmarkList.buildCheckmarksFromIntervals(reps, intervals) - assertEquals(expected, actual) - } - - @Test - fun computeAutomaticCheckmarks() { - val checks = listOf(Checkmark(day(10), CHECKED_MANUAL), - Checkmark(day(5), CHECKED_MANUAL), - Checkmark(day(2), CHECKED_MANUAL), - Checkmark(day(1), CHECKED_MANUAL)) - val expected = listOf(Checkmark(day(-1), CHECKED_AUTOMATIC), - Checkmark(day(0), CHECKED_AUTOMATIC), - Checkmark(day(1), CHECKED_MANUAL), - Checkmark(day(2), CHECKED_MANUAL), - Checkmark(day(3), CHECKED_AUTOMATIC), - Checkmark(day(4), CHECKED_AUTOMATIC), - Checkmark(day(5), CHECKED_MANUAL), - Checkmark(day(6), CHECKED_AUTOMATIC), - Checkmark(day(7), CHECKED_AUTOMATIC), - Checkmark(day(8), CHECKED_AUTOMATIC), - Checkmark(day(9), CHECKED_AUTOMATIC), - Checkmark(day(10), CHECKED_MANUAL)) - val actual = CheckmarkList.computeCheckmarks(checks, Frequency(1, 3)) - assertEquals(expected, actual) - } - - @Test - fun testGetUntil() { - val list = CheckmarkList(Frequency(1, 2), HabitType.BOOLEAN_HABIT) - list.setManualCheckmarks(listOf(Checkmark(day(4), CHECKED_MANUAL), - Checkmark(day(7), CHECKED_MANUAL))) - val expected = listOf(Checkmark(day(0), UNCHECKED), - Checkmark(day(1), UNCHECKED), - Checkmark(day(2), UNCHECKED), - Checkmark(day(3), CHECKED_AUTOMATIC), - Checkmark(day(4), CHECKED_MANUAL), - Checkmark(day(5), UNCHECKED), - Checkmark(day(6), CHECKED_AUTOMATIC), - Checkmark(day(7), CHECKED_MANUAL)) - assertEquals(expected, list.getUntil(day(0))) - - val expected2 = listOf(Checkmark(day(3), CHECKED_AUTOMATIC), - Checkmark(day(4), CHECKED_MANUAL), - Checkmark(day(5), UNCHECKED), - Checkmark(day(6), CHECKED_AUTOMATIC), - Checkmark(day(7), CHECKED_MANUAL)) - assertEquals(expected2, list.getUntil(day(3))) - } - - @Test - fun testGetValuesUntil2() { - val list = CheckmarkList(Frequency(1, 2), HabitType.BOOLEAN_HABIT) - val expected = listOf() - assertEquals(expected, list.getUntil(day(0))) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/models/CheckmarkRepositoryTest.kt b/uhabits-core-legacy/src/test/common/org/isoron/uhabits/models/CheckmarkRepositoryTest.kt deleted file mode 100644 index f5e933760..000000000 --- a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/models/CheckmarkRepositoryTest.kt +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models - -import org.isoron.* -import org.isoron.platform.io.* -import org.isoron.platform.time.* -import kotlin.test.* - -class CheckmarkRepositoryTest() { - @Test - fun testCRUD() = asyncTest { - val db = DependencyResolver.getDatabase() - - val habitA = 10 - var checkmarksA = listOf(Checkmark(LocalDate(2019, 1, 15), 100), - Checkmark(LocalDate(2019, 1, 7), 500), - Checkmark(LocalDate(2019, 1, 1), 900)) - - val habitB = 35 - val checkmarksB = listOf(Checkmark(LocalDate(2019, 1, 30), 50), - Checkmark(LocalDate(2019, 1, 29), 30), - Checkmark(LocalDate(2019, 1, 27), 900), - Checkmark(LocalDate(2019, 1, 25), 450), - Checkmark(LocalDate(2019, 1, 20), 1000)) - - val repository = CheckmarkRepository(db) - - for (c in checkmarksA) repository.insert(habitA, c) - for (c in checkmarksB) repository.insert(habitB, c) - assertEquals(checkmarksA, repository.findAll(habitA)) - assertEquals(checkmarksB, repository.findAll(habitB)) - assertEquals(listOf(), repository.findAll(999)) - - checkmarksA = listOf(Checkmark(LocalDate(2019, 1, 15), 100), - Checkmark(LocalDate(2019, 1, 1), 900)) - repository.delete(habitA, LocalDate(2019, 1, 7)) - assertEquals(checkmarksA, repository.findAll(habitA)) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/models/HabitRepositoryTest.kt b/uhabits-core-legacy/src/test/common/org/isoron/uhabits/models/HabitRepositoryTest.kt deleted file mode 100644 index faa234d78..000000000 --- a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/models/HabitRepositoryTest.kt +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models - -import org.isoron.* -import org.isoron.platform.gui.* -import kotlin.test.* - -class HabitRepositoryTest() { - @Test - fun testCRUD() = asyncTest{ - val db = DependencyResolver.getDatabase() - val original0 = Habit(id = 0, - name = "Wake up early", - description = "Did you wake up before 6am?", - frequency = Frequency(1, 1), - color = PaletteColor(3), - isArchived = false, - position = 0, - unit = "", - target = 0.0, - type = HabitType.BOOLEAN_HABIT) - - val original1 = Habit(id = 1, - name = "Exercise", - description = "Did you exercise for at least 20 minutes?", - frequency = Frequency(1, 2), - color = PaletteColor(4), - isArchived = false, - position = 1, - unit = "", - target = 0.0, - type = HabitType.BOOLEAN_HABIT) - - val original2 = Habit(id = 2, - name = "Learn Japanese", - description = "Did you study Japanese today?", - frequency = Frequency(1, 1), - color = PaletteColor(3), - isArchived = false, - position = 2, - unit = "", - target = 0.0, - type = HabitType.BOOLEAN_HABIT) - - val repository = HabitRepository(db) - - var habits = repository.findAll() - assertEquals(0, repository.nextId()) - assertEquals(0, habits.size) - - repository.insert(original0) - repository.insert(original1) - repository.insert(original2) - habits = repository.findAll() - assertEquals(3, habits.size) - assertEquals(original0, habits[0]) - assertEquals(original1, habits[1]) - assertEquals(original2, habits[2]) - - assertEquals(3, repository.nextId()) - - original0.description = "New description" - repository.update(original0) - habits = repository.findAll() - assertEquals(original0, habits[0]) - - repository.delete(original0) - habits = repository.findAll() - assertEquals(2, habits.size) - assertEquals(original1, habits[1]) - assertEquals(original2, habits[2]) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/models/PreferencesRepositoryTest.kt b/uhabits-core-legacy/src/test/common/org/isoron/uhabits/models/PreferencesRepositoryTest.kt deleted file mode 100644 index b24b65ecb..000000000 --- a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/models/PreferencesRepositoryTest.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models - -import org.isoron.* -import org.isoron.platform.io.* -import kotlin.test.* - -class PreferencesRepositoryTest() { - @Test - fun testUsage() = asyncTest{ - val db = DependencyResolver.getDatabase() - val prefs = PreferencesRepository(db) - assertEquals("default", prefs.getString("non_existing_key", "default")) - prefs.putString("ringtone_path", "/tmp") - assertEquals("/tmp", prefs.getString("ringtone_path", "none")) - - assertEquals(42, prefs.getLong("non_existing_key", 42)) - prefs.putLong("times_launched", 130) - assertEquals(130, prefs.getLong("times_launched", 0)) - - assertEquals(true, prefs.getBoolean("non_existing_key", true)) - assertEquals(false, prefs.getBoolean("non_existing_key", false)) - prefs.putBoolean("show_archived", true) - assertEquals(true, prefs.getBoolean("show_archived", false)) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/models/ScoreListTest.kt b/uhabits-core-legacy/src/test/common/org/isoron/uhabits/models/ScoreListTest.kt deleted file mode 100644 index c9e86f5c5..000000000 --- a/uhabits-core-legacy/src/test/common/org/isoron/uhabits/models/ScoreListTest.kt +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.models - -import org.isoron.platform.time.* -import org.isoron.uhabits.models.Checkmark.Companion.CHECKED_MANUAL -import org.isoron.uhabits.models.Frequency.Companion.DAILY -import org.isoron.uhabits.models.ScoreList.Companion.compute -import kotlin.test.* - -class ScoreListTest { - val today = LocalDate(2019, 1, 1) - - @Test - fun computeWithDailyHabit() { - val freq = DAILY - var check = 1 - assertEquals(compute(freq, 0.0, check), 0.051922) - assertEquals(compute(freq, 0.5, check), 0.525961) - assertEquals(compute(freq, 0.75, check), 0.762980) - - check = 0 - assertEquals(compute(freq, 0.0, check), 0.0) - assertEquals(compute(freq, 0.5, check), 0.474038) - assertEquals(compute(freq, 0.75, check), 0.711058) - } - - @Test - fun computeWithNonDailyHabit() { - var check = 1 - val freq = Frequency(1, 3) - assertEquals(compute(freq, 0.0, check), 0.017615) - assertEquals(compute(freq, 0.5, check), 0.508807) - assertEquals(compute(freq, 0.75, check), 0.754403) - - check = 0 - assertEquals(compute(freq, 0.0, check), 0.0) - assertEquals(compute(freq, 0.5, check), 0.491192) - assertEquals(compute(freq, 0.75, check), 0.736788) - } - - @Test - fun getValueUntilWithBooleanHabit() { - val checks = CheckmarkList(DAILY, - HabitType.BOOLEAN_HABIT) - checks.setManualCheckmarks((0..19).map { - Checkmark(today.minus(it), CHECKED_MANUAL) - }) - val scoreList = ScoreList(checks) - val actual = scoreList.getUntil(today) - val expected = listOf(Score(today.minus(0), 0.655741), - Score(today.minus(1), 0.636888), - Score(today.minus(2), 0.617002), - Score(today.minus(3), 0.596027), - Score(today.minus(4), 0.573903), - Score(today.minus(5), 0.550568), - Score(today.minus(6), 0.525955), - Score(today.minus(7), 0.499994), - Score(today.minus(8), 0.472611), - Score(today.minus(9), 0.443729), - Score(today.minus(10), 0.413265), - Score(today.minus(11), 0.381132), - Score(today.minus(12), 0.347240), - Score(today.minus(13), 0.311491), - Score(today.minus(14), 0.273785), - Score(today.minus(15), 0.234014), - Score(today.minus(16), 0.192065), - Score(today.minus(17), 0.147818), - Score(today.minus(18), 0.101148), - Score(today.minus(19), 0.051922)) - - assertEquals(expected, actual) - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/test/ios/org/isoron/DependencyResolver.kt b/uhabits-core-legacy/src/test/ios/org/isoron/DependencyResolver.kt deleted file mode 100644 index 4cd3fd7ed..000000000 --- a/uhabits-core-legacy/src/test/ios/org/isoron/DependencyResolver.kt +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron - -import org.isoron.platform.gui.* -import org.isoron.platform.io.* -import org.isoron.platform.time.* -import org.isoron.uhabits.* -import platform.CoreGraphics.* -import platform.UIKit.* - -actual object DependencyResolver { - actual val ignoreViewTests = true - - actual suspend fun getFileOpener(): FileOpener = IosFileOpener() - - actual fun getDateFormatter(locale: Locale): LocalDateFormatter { - return when (locale) { - Locale.US -> IosLocalDateFormatter("en-US") - Locale.JAPAN -> IosLocalDateFormatter("ja-JP") - } - } - - actual fun createCanvas(width: Int, height: Int): Canvas { - val scale = 2.0 - UIGraphicsBeginImageContext(CGSizeMake(width * scale, height * scale)) - return IosCanvas(width * scale, height * scale, scale = scale) - } - - actual suspend fun getDatabase(): Database { - val log = StandardLog() - val fileOpener = IosFileOpener() - val databaseOpener = IosDatabaseOpener() - - val dbFile = fileOpener.openUserFile("test.sqlite3") - if (dbFile.exists()) dbFile.delete() - val db = databaseOpener.open(dbFile) - db.migrateTo(LOOP_DATABASE_VERSION, fileOpener, log) - return db - } -} \ No newline at end of file diff --git a/uhabits-core-legacy/src/test/ios/org/isoron/IosAsyncTests.kt b/uhabits-core-legacy/src/test/ios/org/isoron/IosAsyncTests.kt deleted file mode 100644 index 711209fc3..000000000 --- a/uhabits-core-legacy/src/test/ios/org/isoron/IosAsyncTests.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron - -import kotlinx.coroutines.* - -/** - * Workaround until Kotlin adds support for testing suspend functions - * https://youtrack.jetbrains.com/issue/KT-22228 - */ -actual fun asyncTest(block: suspend () -> Unit) = runBlocking { block() } diff --git a/uhabits-core-legacy/src/test/js/org/isoron/DependencyResolver.kt b/uhabits-core-legacy/src/test/js/org/isoron/DependencyResolver.kt deleted file mode 100644 index 3a28427e4..000000000 --- a/uhabits-core-legacy/src/test/js/org/isoron/DependencyResolver.kt +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron - -import org.isoron.platform.gui.* -import org.isoron.platform.io.* -import org.isoron.platform.time.* -import org.isoron.uhabits.* -import org.w3c.dom.* -import kotlin.browser.* - -actual object DependencyResolver { - actual val ignoreViewTests = false - - var fileOpener: JsFileOpener? = null - - actual suspend fun getFileOpener(): FileOpener { - if (fileOpener == null) { - val fs = JsFileStorage() - fs.init() - fileOpener = JsFileOpener(fs) - } - return fileOpener!! - } - - actual suspend fun getDatabase(): Database { - val nativeDB = eval("new SQL.Database()") - val db = JsDatabase(nativeDB) - db.migrateTo(LOOP_DATABASE_VERSION, getFileOpener(), StandardLog()) - return db - } - - actual fun getDateFormatter(locale: Locale): LocalDateFormatter { - return when (locale) { - Locale.US -> JsDateFormatter("en-US") - Locale.JAPAN -> JsDateFormatter("ja-JP") - } - } - - actual fun createCanvas(width: Int, height: Int): Canvas { - val element = document.createElement("canvas") as HTMLCanvasElement - element.width = 2 * width - element.height = 2 * height - element.style.width = "${2 * width}px" - element.style.height = "${2 * height}px" - val canvas = JsCanvas(element, 2.0) - canvas.setColor(Color(0xffffff)) - canvas.fillRect(0.0, 0.0, width.toDouble(), height.toDouble()) - return canvas - } -} diff --git a/uhabits-core-legacy/src/test/js/org/isoron/JsAsyncTests.kt b/uhabits-core-legacy/src/test/js/org/isoron/JsAsyncTests.kt deleted file mode 100644 index 6281be452..000000000 --- a/uhabits-core-legacy/src/test/js/org/isoron/JsAsyncTests.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron - -import kotlinx.coroutines.* - -/** - * Workaround until Kotlin adds support for testing suspend functions - * https://youtrack.jetbrains.com/issue/KT-22228 - */ -actual fun asyncTest(block: suspend () -> Unit): dynamic = GlobalScope.promise { block() } diff --git a/uhabits-core-legacy/src/test/jvm/org/isoron/DependencyResolver.kt b/uhabits-core-legacy/src/test/jvm/org/isoron/DependencyResolver.kt deleted file mode 100644 index 9f5d1c093..000000000 --- a/uhabits-core-legacy/src/test/jvm/org/isoron/DependencyResolver.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron - -import org.isoron.platform.gui.* -import org.isoron.platform.io.* -import org.isoron.platform.time.* -import org.isoron.uhabits.* -import java.awt.image.* - -actual object DependencyResolver { - actual val ignoreViewTests = false - - actual suspend fun getFileOpener(): FileOpener = JavaFileOpener() - - actual suspend fun getDatabase(): Database { - val log = StandardLog() - val fileOpener = JavaFileOpener() - val databaseOpener = JavaDatabaseOpener(log) - - val dbFile = fileOpener.openUserFile("test.sqlite3") - if (dbFile.exists()) dbFile.delete() - val db = databaseOpener.open(dbFile) - db.migrateTo(LOOP_DATABASE_VERSION, fileOpener, log) - return db - } - - actual fun getDateFormatter(locale: Locale): LocalDateFormatter { - return when (locale) { - Locale.US -> JavaLocalDateFormatter(java.util.Locale.US) - Locale.JAPAN -> JavaLocalDateFormatter(java.util.Locale.JAPAN) - } - } - - actual fun createCanvas(width: Int, height: Int): Canvas { - val widthPx = width * 2 - val heightPx = height * 2 - val image = BufferedImage(widthPx, - heightPx, - BufferedImage.TYPE_INT_ARGB) - return JavaCanvas(image, pixelScale = 2.0) - } -} diff --git a/uhabits-core-legacy/src/test/jvm/org/isoron/JavaAsyncTests.kt b/uhabits-core-legacy/src/test/jvm/org/isoron/JavaAsyncTests.kt deleted file mode 100644 index 711209fc3..000000000 --- a/uhabits-core-legacy/src/test/jvm/org/isoron/JavaAsyncTests.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron - -import kotlinx.coroutines.* - -/** - * Workaround until Kotlin adds support for testing suspend functions - * https://youtrack.jetbrains.com/issue/KT-22228 - */ -actual fun asyncTest(block: suspend () -> Unit) = runBlocking { block() } diff --git a/uhabits-ios/Application/AppDelegate.swift b/uhabits-ios/Application/AppDelegate.swift deleted file mode 100644 index df6fc7c0f..000000000 --- a/uhabits-ios/Application/AppDelegate.swift +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -import UIKit - -@UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate, BackendListener { - - var window: UIWindow? - var nav: UINavigationController? - let log = StandardLog() - var backend: Backend? - - func application(_ application: UIApplication, - didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { - - backend = Backend(databaseName: "uhabits.db", - databaseOpener: IosDatabaseOpener(), - fileOpener: IosFileOpener(), - localeHelper: IosLocaleHelper(log: log), - log: log, - scope: UIDispatcher()) - - backend?.observable.addListener(listener: self) - backend?.doInit() - - window = UIWindow(frame: UIScreen.main.bounds) - nav = UINavigationController() - window?.backgroundColor = UIColor.white - window?.rootViewController = nav - window?.makeKeyAndVisible() - - return true - } - - func onReady() { - nav?.viewControllers = [MainScreenController(withBackend: backend!)] - } -} diff --git a/uhabits-ios/Application/Assets.xcassets/AppIcon.appiconset/Contents.json b/uhabits-ios/Application/Assets.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index 9e5fe95b3..000000000 --- a/uhabits-ios/Application/Assets.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "images" : [ - { - "idiom" : "iphone", - "size" : "20x20", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "20x20", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "29x29", - "scale" : "3x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "iphone", - "size" : "40x40", - "scale" : "3x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "loop-120.png", - "scale" : "2x" - }, - { - "size" : "60x60", - "idiom" : "iphone", - "filename" : "loop-180.png", - "scale" : "3x" - }, - { - "idiom" : "ipad", - "size" : "20x20", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "20x20", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "29x29", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "40x40", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "1x" - }, - { - "idiom" : "ipad", - "size" : "76x76", - "scale" : "2x" - }, - { - "idiom" : "ipad", - "size" : "83.5x83.5", - "scale" : "2x" - }, - { - "idiom" : "ios-marketing", - "size" : "1024x1024", - "scale" : "1x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/uhabits-ios/Application/Assets.xcassets/AppIcon.appiconset/loop-120.png b/uhabits-ios/Application/Assets.xcassets/AppIcon.appiconset/loop-120.png deleted file mode 100644 index 1fde27933..000000000 Binary files a/uhabits-ios/Application/Assets.xcassets/AppIcon.appiconset/loop-120.png and /dev/null differ diff --git a/uhabits-ios/Application/Assets.xcassets/AppIcon.appiconset/loop-180.png b/uhabits-ios/Application/Assets.xcassets/AppIcon.appiconset/loop-180.png deleted file mode 100644 index 99bc3ce9b..000000000 Binary files a/uhabits-ios/Application/Assets.xcassets/AppIcon.appiconset/loop-180.png and /dev/null differ diff --git a/uhabits-ios/Application/Assets.xcassets/Contents.json b/uhabits-ios/Application/Assets.xcassets/Contents.json deleted file mode 100644 index da4a164c9..000000000 --- a/uhabits-ios/Application/Assets.xcassets/Contents.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/uhabits-ios/Application/Assets.xcassets/ic_more.imageset/Contents.json b/uhabits-ios/Application/Assets.xcassets/ic_more.imageset/Contents.json deleted file mode 100644 index 0a782055b..000000000 --- a/uhabits-ios/Application/Assets.xcassets/ic_more.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "filename" : "baseline_more_horiz_black_24pt_1x.png", - "scale" : "1x" - }, - { - "idiom" : "universal", - "filename" : "baseline_more_horiz_black_24pt_2x.png", - "scale" : "2x" - }, - { - "idiom" : "universal", - "filename" : "baseline_more_horiz_black_24pt_3x.png", - "scale" : "3x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/uhabits-ios/Application/Assets.xcassets/ic_more.imageset/baseline_more_horiz_black_24pt_1x.png b/uhabits-ios/Application/Assets.xcassets/ic_more.imageset/baseline_more_horiz_black_24pt_1x.png deleted file mode 100644 index cd5bd1d9a..000000000 Binary files a/uhabits-ios/Application/Assets.xcassets/ic_more.imageset/baseline_more_horiz_black_24pt_1x.png and /dev/null differ diff --git a/uhabits-ios/Application/Assets.xcassets/ic_more.imageset/baseline_more_horiz_black_24pt_2x.png b/uhabits-ios/Application/Assets.xcassets/ic_more.imageset/baseline_more_horiz_black_24pt_2x.png deleted file mode 100644 index a104c327e..000000000 Binary files a/uhabits-ios/Application/Assets.xcassets/ic_more.imageset/baseline_more_horiz_black_24pt_2x.png and /dev/null differ diff --git a/uhabits-ios/Application/Assets.xcassets/ic_more.imageset/baseline_more_horiz_black_24pt_3x.png b/uhabits-ios/Application/Assets.xcassets/ic_more.imageset/baseline_more_horiz_black_24pt_3x.png deleted file mode 100644 index 539e3ebe7..000000000 Binary files a/uhabits-ios/Application/Assets.xcassets/ic_more.imageset/baseline_more_horiz_black_24pt_3x.png and /dev/null differ diff --git a/uhabits-ios/Application/BridgingHeader.h b/uhabits-ios/Application/BridgingHeader.h deleted file mode 100644 index 7032ff4f2..000000000 --- a/uhabits-ios/Application/BridgingHeader.h +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -#import "LoopHabitTracker.h" diff --git a/uhabits-ios/Application/Frontend/AboutScreenController.swift b/uhabits-ios/Application/Frontend/AboutScreenController.swift deleted file mode 100644 index f4cbe355b..000000000 --- a/uhabits-ios/Application/Frontend/AboutScreenController.swift +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -import UIKit - -class AboutScreenController : UITableViewController { -} diff --git a/uhabits-ios/Application/Frontend/DetailScreenController.swift b/uhabits-ios/Application/Frontend/DetailScreenController.swift deleted file mode 100644 index c9473c337..000000000 --- a/uhabits-ios/Application/Frontend/DetailScreenController.swift +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -import UIKit - -class DetailScreenController : UITableViewController { - - let theme: Theme - let habit: Habit - let color: Color - var cells = [UITableViewCell]() - - required init?(coder aDecoder: NSCoder) { - fatalError() - } - - init(habit: Habit, backend: Backend) { - self.theme = backend.theme - self.habit = habit - self.color = theme.color(paletteIndex: self.habit.color.index) - super.init(style: .grouped) - } - - override func viewDidLoad() { - self.title = habit.name - self.navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .edit, - target: self, - action: #selector(self.onEditHabitClicked)) - cells.append(buildBarChartCell()) - cells.append(buildHistoryChartCell()) - } - - func buildBarChartCell() -> UITableViewCell { - let today = LocalDate(year: 2019, month: 3, day: 15) - let axis = (0...365).map { today.minus(days: $0) } - let component = BarChart(theme: theme, - dateFormatter: IosLocalDateFormatter()) - component.axis = axis - let cell = UITableViewCell() - let view = ComponentView(frame: cell.frame, component: component) - for k in 0...0 { - var series = [KotlinDouble]() - for _ in 1...365 { - series.append(KotlinDouble(value: Double.random(in: 0...5000))) - } - component.series.add(series) - let color = (self.habit.color.index + Int32(k * 3)) % 16 - component.colors.add(theme.color(paletteIndex: color)) - } - view.autoresizingMask = [.flexibleWidth, .flexibleHeight] - cell.contentView.addSubview(view) - return cell - } - - func buildHistoryChartCell() -> UITableViewCell { - let component = CalendarChart(today: LocalDate(year: 2019, month: 3, day: 15), - color: color, - theme: theme, - dateFormatter: IosLocalDateFormatter()) - let cell = UITableViewCell() - let view = ComponentView(frame: cell.frame, component: component) - var series = [KotlinDouble]() - for _ in 1...365 { - series.append(KotlinDouble(value: Double.random(in: 0...1))) - } - component.series = series - view.autoresizingMask = [.flexibleWidth, .flexibleHeight] - cell.contentView.addSubview(view) - return cell - } - - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - self.navigationController?.navigationBar.barStyle = .blackOpaque - self.navigationController?.navigationBar.barTintColor = color.uicolor - self.navigationController?.navigationBar.tintColor = .white - self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: UIColor.white] - } - - override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return 1 - } - - override func numberOfSections(in tableView: UITableView) -> Int { - return cells.count - } - - override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - return cells[indexPath.section] - } - - @objc func onEditHabitClicked() { - self.navigationController?.pushViewController(EditHabitController(), animated: true) - } - - override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { - return 200 - } -} diff --git a/uhabits-ios/Application/Frontend/EditHabitController.swift b/uhabits-ios/Application/Frontend/EditHabitController.swift deleted file mode 100644 index 5f7d5fc4e..000000000 --- a/uhabits-ios/Application/Frontend/EditHabitController.swift +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -import UIKit - -class EditHabitTableViewController: NSObject, UITableViewDataSource, UITableViewDelegate { - func disclosure(title: String, subtitle: String) -> UITableViewCell { - let cell = UITableViewCell(style: .value1, reuseIdentifier: nil) - cell.textLabel?.text = title - cell.detailTextLabel?.text = subtitle - cell.accessoryType = .disclosureIndicator - return cell - } - - func input(title: String) -> UITableViewCell { - let cell = UITableViewCell() - let field = UITextField(frame: cell.bounds.insetBy(dx: 20, dy: 0)) - field.placeholder = title - field.autoresizingMask = [UIView.AutoresizingMask.flexibleWidth, - UIView.AutoresizingMask.flexibleHeight] - cell.contentView.addSubview(field) - return cell - } - - var primary = [UITableViewCell]() - var secondary = [UITableViewCell]() - var parentController: EditHabitController - - init(withParentController parentController: EditHabitController) { - self.parentController = parentController - super.init() - primary.append(input(title: "Name")) - primary.append(input(title: "Question (e.g. Did you wake up early today?)")) - secondary.append(disclosure(title: "Color", subtitle: "Blue")) - secondary.append(disclosure(title: "Repeat", subtitle: "Daily")) - secondary.append(disclosure(title: "Reminder", subtitle: "Disabled")) - } - - func numberOfSections(in tableView: UITableView) -> Int { - return 2 - } - - func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return section == 0 ? primary.count : secondary.count - } - - func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - return indexPath.section == 0 ? primary[indexPath.item] : secondary[indexPath.item] - } - -// func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { -// let alert = UIAlertController(title: "Hello", message: "You selected something", preferredStyle: .alert) -// parentController.present(alert, animated: true) -// } -} - -class EditHabitController: UIViewController { - override func viewWillAppear(_ animated: Bool) { - super.viewWillAppear(animated) - let bounds = UIScreen.main.bounds - let tableController = EditHabitTableViewController(withParentController: self) - let table = UITableView(frame: bounds, style: .grouped) - table.dataSource = tableController - table.delegate = tableController - self.view = table - } - - override func viewDidLoad() { - self.title = "Edit Habit" - } -} diff --git a/uhabits-ios/Application/Frontend/MainScreenController.swift b/uhabits-ios/Application/Frontend/MainScreenController.swift deleted file mode 100644 index 7c4d9136d..000000000 --- a/uhabits-ios/Application/Frontend/MainScreenController.swift +++ /dev/null @@ -1,271 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -import UIKit - -class MainScreenCell : UITableViewCell { - var ring = ComponentView(frame: CGRect(), component: nil) - var label = UILabel() - var buttons: [ComponentView] = [] - - override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) { - super.init(style: .default, reuseIdentifier: reuseIdentifier) - } - required init?(coder aDecoder: NSCoder) { - fatalError() - } - - func update(habit: Habit, checkmarks: [Checkmark], score: Score, theme: Theme, nButtons: Int) { - if buttons.count != nButtons { - buttons.removeAll() - for v in contentView.subviews { v.removeFromSuperview() } - - let size = CGFloat(theme.checkmarkButtonSize) - let stack = UIStackView(frame: contentView.frame) - stack.autoresizingMask = [.flexibleWidth, .flexibleHeight] - stack.axis = .horizontal - stack.distribution = .fill - stack.alignment = .center - contentView.addSubview(stack) - - ring.backgroundColor = .white - ring.widthAnchor.constraint(equalToConstant: size * 0.75).isActive = true - ring.heightAnchor.constraint(equalToConstant: size).isActive = true - stack.addArrangedSubview(ring) - - label.backgroundColor = .white - label.heightAnchor.constraint(equalToConstant: size).isActive = true - stack.addArrangedSubview(label) - - for _ in 1...nButtons { - let btn = ComponentView(frame: frame, component: nil) - btn.backgroundColor = .white - btn.widthAnchor.constraint(equalToConstant: size).isActive = true - btn.heightAnchor.constraint(equalToConstant: size).isActive = true - buttons.append(btn) - stack.addArrangedSubview(btn) - } - } - - var color = theme.color(paletteIndex: habit.color.index) - if habit.isArchived { color = theme.mediumContrastTextColor } - label.text = habit.name - label.textColor = color.uicolor - ring.component = Ring(color: color, - percentage: score.value, - thickness: 2.5, - radius: 7, - theme: theme, - label: false) - ring.setNeedsDisplay() - - for i in 0.. Int { - return data?.habits.count ?? 0 - } - - override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! MainScreenCell - let habit = data!.habits[indexPath.row] - cell.update(habit: habit, - checkmarks: data!.checkmarks[habit]!, - score: data!.scores[habit]!, - theme: theme, - nButtons: nButtons) - return cell - } - - override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { - let component = HabitListHeader(today: LocalDate(year: 2019, month: 3, day: 24), - nButtons: Int32(nButtons), - theme: theme, - fmt: IosLocalDateFormatter()) - return ComponentView(frame: CGRect(x: 0, y: 0, width: 100, height: CGFloat(theme.checkmarkButtonSize)), - component: component) - } - - override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { - return CGFloat(theme.checkmarkButtonSize) - } - - override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { - return CGFloat(theme.checkmarkButtonSize) + 3 - } - - override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - let habit = data!.habits[indexPath.row] - self.navigationController?.pushViewController(DetailScreenController(habit: habit, backend: backend), animated: true) - } - - override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) { - computeNumberOfButtons(Double(size.width)) - reload() - } - - @objc func onCreateHabitClicked() { - self.navigationController?.pushViewController(EditHabitController(), animated: true) - } - - @objc func onMoreActionsClicked() { - let alert = UIAlertController(title: nil, message: nil, preferredStyle: .actionSheet) - - if isThereAnyArchivedHabit() { - if preferences.showArchived { - alert.addAction(UIAlertAction(title: strings.hide_archived, style: .default) { - (action: UIAlertAction) -> Void in - self.preferences.showArchived = false - self.dataSource.requestData() - }) - } else { - alert.addAction(UIAlertAction(title: strings.show_archived, style: .default) { - (action: UIAlertAction) -> Void in - self.preferences.showArchived = true - self.dataSource.requestData() - }) - } - } - - if preferences.showCompleted { - alert.addAction(UIAlertAction(title: strings.hide_completed, style: .default) { - (action: UIAlertAction) -> Void in - self.preferences.showCompleted = false - self.dataSource.requestData() - }) - } else { - alert.addAction(UIAlertAction(title: strings.show_completed, style: .default) { - (action: UIAlertAction) -> Void in - self.preferences.showCompleted = true - self.dataSource.requestData() - }) - } - - if preferences.nightMode { - alert.addAction(UIAlertAction(title: strings.day_mode, style: .default) { - (action: UIAlertAction) -> Void in - self.preferences.nightMode = false - }) - } else { - alert.addAction(UIAlertAction(title: strings.night_mode, style: .default) { - (action: UIAlertAction) -> Void in - self.preferences.nightMode = true - }) - } - - alert.addAction(UIAlertAction(title: strings.help, style: .default) { - (action: UIAlertAction) -> Void in - if let link = URL(string: "http://loophabits.org/faq") { - UIApplication.shared.open(link) - } - }) - alert.addAction(UIAlertAction(title: strings.about, style: .default) { - (action: UIAlertAction) -> Void in - self.navigationController?.pushViewController(AboutScreenController(), animated: true) - }) - alert.addAction(UIAlertAction(title: strings.cancel, style: .cancel) { - (action: UIAlertAction) -> Void in - // Do nothing - }) - present(alert, animated: true, completion: nil) - } - - func onDataChanged(newData: MainScreenDataSource.Data) { - data = newData - reload() - } - - func computeNumberOfButtons(_ width: Double) { - nButtons = Int((width - 220) / theme.checkmarkButtonSize) - nButtons = max(nButtons, 3) - nButtons = min(nButtons, Int(dataSource.maxNumberOfButtons)) - } - - func reload() { - let sections = NSIndexSet(indexesIn: NSMakeRange(0, self.tableView.numberOfSections)) - tableView.reloadSections(sections as IndexSet, with: .automatic) - } - - func isThereAnyArchivedHabit() -> Bool { - return data!.habits.filter({ $0.isArchived }).count > 0 - } -} diff --git a/uhabits-ios/Application/Info.plist b/uhabits-ios/Application/Info.plist deleted file mode 100644 index bb68c7e1f..000000000 --- a/uhabits-ios/Application/Info.plist +++ /dev/null @@ -1,49 +0,0 @@ - - - - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleDisplayName - Loop - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - APPL - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - LSRequiresIPhoneOS - - UIAppFonts - - fonts/FontAwesome.ttf - - UILaunchStoryboardName - Launch.storyboard - UIRequiredDeviceCapabilities - - armv7 - - UISupportedInterfaceOrientations - - UIInterfaceOrientationPortrait - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - UISupportedInterfaceOrientations~ipad - - UIInterfaceOrientationPortrait - UIInterfaceOrientationPortraitUpsideDown - UIInterfaceOrientationLandscapeLeft - UIInterfaceOrientationLandscapeRight - - - diff --git a/uhabits-ios/Application/Launch.storyboard b/uhabits-ios/Application/Launch.storyboard deleted file mode 100644 index f9a048edf..000000000 --- a/uhabits-ios/Application/Launch.storyboard +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/uhabits-ios/Application/Platform/ComponentView.swift b/uhabits-ios/Application/Platform/ComponentView.swift deleted file mode 100644 index 8b111651c..000000000 --- a/uhabits-ios/Application/Platform/ComponentView.swift +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2016-2019 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -import UIKit - -class ComponentView : UIView { - var component: Component? - - init(frame: CGRect, component: Component?) { - self.component = component - super.init(frame: frame) - } - - required init?(coder aDecoder: NSCoder) { - fatalError() - } - - override func draw(_ rect: CGRect) { - let canvas = IosCanvas(width: Double(rect.width), - height: Double(rect.height), - scale: 1.0) - component?.draw(canvas: canvas) - } - - override func layoutSubviews() { - setNeedsDisplay() - } -} diff --git a/uhabits-ios/Tests/Info.plist b/uhabits-ios/Tests/Info.plist deleted file mode 100644 index 866537f58..000000000 --- a/uhabits-ios/Tests/Info.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - UIAppFonts - - fonts/FontAwesome.ttf - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - BNDL - CFBundleShortVersionString - 1.0 - CFBundleVersion - 1 - - diff --git a/uhabits-ios/uhabits.xcodeproj/project.pbxproj b/uhabits-ios/uhabits.xcodeproj/project.pbxproj deleted file mode 100644 index 75fc10fc7..000000000 --- a/uhabits-ios/uhabits.xcodeproj/project.pbxproj +++ /dev/null @@ -1,584 +0,0 @@ -// !$*UTF8*$! -{ - archiveVersion = 1; - classes = { - }; - objectVersion = 50; - objects = { - -/* Begin PBXBuildFile section */ - 001592642260AE0F00D2814F /* LoopHabitTracker.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C0C6C92246E543003D8AF0 /* LoopHabitTracker.framework */; }; - 005166D12471C02D00C6CFD6 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00A5B42722009F590024E00C /* AppDelegate.swift */; }; - 006EFE50225432B8008464E0 /* AboutScreenController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 006EFE4F225432B8008464E0 /* AboutScreenController.swift */; }; - 00A5B42822009F590024E00C /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00A5B42722009F590024E00C /* AppDelegate.swift */; }; - 00A5B42A22009F590024E00C /* MainScreenController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00A5B42922009F590024E00C /* MainScreenController.swift */; }; - 00A5B42F22009F5A0024E00C /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 00A5B42E22009F5A0024E00C /* Assets.xcassets */; }; - 00C0C6BD22465F65003D8AF0 /* fonts in Resources */ = {isa = PBXBuildFile; fileRef = 00C0C6BA22465F65003D8AF0 /* fonts */; }; - 00C0C6BE22465F65003D8AF0 /* databases in Resources */ = {isa = PBXBuildFile; fileRef = 00C0C6BB22465F65003D8AF0 /* databases */; }; - 00C0C6BF22465F65003D8AF0 /* migrations in Resources */ = {isa = PBXBuildFile; fileRef = 00C0C6BC22465F65003D8AF0 /* migrations */; }; - 00C0C6CA2246E543003D8AF0 /* LoopHabitTracker.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00C0C6C92246E543003D8AF0 /* LoopHabitTracker.framework */; }; - 00C0C6CC2246E550003D8AF0 /* LoopHabitTracker.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 00C0C6C92246E543003D8AF0 /* LoopHabitTracker.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; - 00C0C6D122470705003D8AF0 /* ComponentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00C0C6D022470705003D8AF0 /* ComponentView.swift */; }; - 00C0C6E0224A3602003D8AF0 /* DetailScreenController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00C0C6DE224A35FC003D8AF0 /* DetailScreenController.swift */; }; - 00D48BD12200A31300CC4527 /* Launch.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 00D48BD02200A31300CC4527 /* Launch.storyboard */; }; - 00D48BD32200AC1600CC4527 /* EditHabitController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 00D48BD22200AC1600CC4527 /* EditHabitController.swift */; }; -/* End PBXBuildFile section */ - -/* Begin PBXContainerItemProxy section */ - 00A5B43922009F5A0024E00C /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = 00A5B41C22009F590024E00C /* Project object */; - proxyType = 1; - remoteGlobalIDString = 00A5B42322009F590024E00C; - remoteInfo = uhabits; - }; -/* End PBXContainerItemProxy section */ - -/* Begin PBXCopyFilesBuildPhase section */ - 00C0C6B522465C47003D8AF0 /* Embed Frameworks */ = { - isa = PBXCopyFilesBuildPhase; - buildActionMask = 2147483647; - dstPath = ""; - dstSubfolderSpec = 10; - files = ( - 00C0C6CC2246E550003D8AF0 /* LoopHabitTracker.framework in Embed Frameworks */, - ); - name = "Embed Frameworks"; - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXCopyFilesBuildPhase section */ - -/* Begin PBXFileReference section */ - 006EFE4F225432B8008464E0 /* AboutScreenController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutScreenController.swift; sourceTree = ""; }; - 00A5B42422009F590024E00C /* uhabits.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = uhabits.app; sourceTree = BUILT_PRODUCTS_DIR; }; - 00A5B42722009F590024E00C /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; - 00A5B42922009F590024E00C /* MainScreenController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MainScreenController.swift; sourceTree = ""; }; - 00A5B42E22009F5A0024E00C /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; - 00A5B43322009F5A0024E00C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 00A5B43822009F5A0024E00C /* uhabitsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = uhabitsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; - 00A5B43E22009F5A0024E00C /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - 00C0C6AE224655D8003D8AF0 /* BridgingHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BridgingHeader.h; sourceTree = ""; }; - 00C0C6BA22465F65003D8AF0 /* fonts */ = {isa = PBXFileReference; lastKnownFileType = folder; path = fonts; sourceTree = ""; }; - 00C0C6BB22465F65003D8AF0 /* databases */ = {isa = PBXFileReference; lastKnownFileType = folder; path = databases; sourceTree = ""; }; - 00C0C6BC22465F65003D8AF0 /* migrations */ = {isa = PBXFileReference; lastKnownFileType = folder; path = migrations; sourceTree = ""; }; - 00C0C6C92246E543003D8AF0 /* LoopHabitTracker.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = LoopHabitTracker.framework; path = "../uhabits-core-legacy/build/bin/ios/debugFramework/LoopHabitTracker.framework"; sourceTree = ""; }; - 00C0C6D022470705003D8AF0 /* ComponentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ComponentView.swift; sourceTree = ""; }; - 00C0C6DE224A35FC003D8AF0 /* DetailScreenController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DetailScreenController.swift; sourceTree = ""; }; - 00D48BD02200A31300CC4527 /* Launch.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Launch.storyboard; sourceTree = ""; }; - 00D48BD22200AC1600CC4527 /* EditHabitController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditHabitController.swift; sourceTree = ""; }; -/* End PBXFileReference section */ - -/* Begin PBXFrameworksBuildPhase section */ - 00A5B42122009F590024E00C /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 00C0C6CA2246E543003D8AF0 /* LoopHabitTracker.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 00A5B43522009F5A0024E00C /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - 001592642260AE0F00D2814F /* LoopHabitTracker.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXFrameworksBuildPhase section */ - -/* Begin PBXGroup section */ - 006EFE49224FF41B008464E0 /* Frontend */ = { - isa = PBXGroup; - children = ( - 006EFE4F225432B8008464E0 /* AboutScreenController.swift */, - 00C0C6DE224A35FC003D8AF0 /* DetailScreenController.swift */, - 00D48BD22200AC1600CC4527 /* EditHabitController.swift */, - 00A5B42922009F590024E00C /* MainScreenController.swift */, - ); - path = Frontend; - sourceTree = ""; - }; - 00A5B41B22009F590024E00C = { - isa = PBXGroup; - children = ( - 00C0C6C022465F80003D8AF0 /* Assets */, - 00A5B42622009F590024E00C /* Application */, - 00A5B43B22009F5A0024E00C /* Tests */, - 00A5B42522009F590024E00C /* Products */, - 00C0C6B0224658CD003D8AF0 /* Frameworks */, - ); - sourceTree = ""; - }; - 00A5B42522009F590024E00C /* Products */ = { - isa = PBXGroup; - children = ( - 00A5B42422009F590024E00C /* uhabits.app */, - 00A5B43822009F5A0024E00C /* uhabitsTests.xctest */, - ); - name = Products; - sourceTree = ""; - }; - 00A5B42622009F590024E00C /* Application */ = { - isa = PBXGroup; - children = ( - 00C0C6AE224655D8003D8AF0 /* BridgingHeader.h */, - 00A5B43322009F5A0024E00C /* Info.plist */, - 00D48BD02200A31300CC4527 /* Launch.storyboard */, - 00A5B42722009F590024E00C /* AppDelegate.swift */, - 00A5B42E22009F5A0024E00C /* Assets.xcassets */, - 006EFE49224FF41B008464E0 /* Frontend */, - 00C0C6D622471BA3003D8AF0 /* Platform */, - ); - path = Application; - sourceTree = ""; - }; - 00A5B43B22009F5A0024E00C /* Tests */ = { - isa = PBXGroup; - children = ( - 00A5B43E22009F5A0024E00C /* Info.plist */, - ); - path = Tests; - sourceTree = ""; - }; - 00C0C6B0224658CD003D8AF0 /* Frameworks */ = { - isa = PBXGroup; - children = ( - 00C0C6C92246E543003D8AF0 /* LoopHabitTracker.framework */, - ); - name = Frameworks; - sourceTree = ""; - }; - 00C0C6C022465F80003D8AF0 /* Assets */ = { - isa = PBXGroup; - children = ( - 00C0C6BB22465F65003D8AF0 /* databases */, - 00C0C6BA22465F65003D8AF0 /* fonts */, - 00C0C6BC22465F65003D8AF0 /* migrations */, - ); - name = Assets; - path = "../uhabits-core-legacy/assets/main"; - sourceTree = ""; - }; - 00C0C6D622471BA3003D8AF0 /* Platform */ = { - isa = PBXGroup; - children = ( - 00C0C6D022470705003D8AF0 /* ComponentView.swift */, - ); - path = Platform; - sourceTree = ""; - }; -/* End PBXGroup section */ - -/* Begin PBXNativeTarget section */ - 00A5B42322009F590024E00C /* uhabits */ = { - isa = PBXNativeTarget; - buildConfigurationList = 00A5B44122009F5A0024E00C /* Build configuration list for PBXNativeTarget "uhabits" */; - buildPhases = ( - 00C0C6D32247134F003D8AF0 /* Build Core Module */, - 00A5B42022009F590024E00C /* Sources */, - 00A5B42122009F590024E00C /* Frameworks */, - 00A5B42222009F590024E00C /* Resources */, - 00C0C6B522465C47003D8AF0 /* Embed Frameworks */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = uhabits; - productName = uhabits; - productReference = 00A5B42422009F590024E00C /* uhabits.app */; - productType = "com.apple.product-type.application"; - }; - 00A5B43722009F5A0024E00C /* uhabitsTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = 00A5B44422009F5A0024E00C /* Build configuration list for PBXNativeTarget "uhabitsTests" */; - buildPhases = ( - 00A5B43422009F5A0024E00C /* Sources */, - 00A5B43522009F5A0024E00C /* Frameworks */, - 00A5B43622009F5A0024E00C /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - 00A5B43A22009F5A0024E00C /* PBXTargetDependency */, - ); - name = uhabitsTests; - productName = uhabitsTests; - productReference = 00A5B43822009F5A0024E00C /* uhabitsTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; -/* End PBXNativeTarget section */ - -/* Begin PBXProject section */ - 00A5B41C22009F590024E00C /* Project object */ = { - isa = PBXProject; - attributes = { - LastSwiftUpdateCheck = 1010; - LastUpgradeCheck = 1010; - ORGANIZATIONNAME = Loop; - TargetAttributes = { - 00A5B42322009F590024E00C = { - CreatedOnToolsVersion = 10.1; - }; - 00A5B43722009F5A0024E00C = { - CreatedOnToolsVersion = 10.1; - TestTargetID = 00A5B42322009F590024E00C; - }; - }; - }; - buildConfigurationList = 00A5B41F22009F590024E00C /* Build configuration list for PBXProject "uhabits" */; - compatibilityVersion = "Xcode 9.3"; - developmentRegion = en; - hasScannedForEncodings = 0; - knownRegions = ( - en, - Base, - ); - mainGroup = 00A5B41B22009F590024E00C; - productRefGroup = 00A5B42522009F590024E00C /* Products */; - projectDirPath = ""; - projectRoot = ""; - targets = ( - 00A5B42322009F590024E00C /* uhabits */, - 00A5B43722009F5A0024E00C /* uhabitsTests */, - ); - }; -/* End PBXProject section */ - -/* Begin PBXResourcesBuildPhase section */ - 00A5B42222009F590024E00C /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 00C0C6BD22465F65003D8AF0 /* fonts in Resources */, - 00C0C6BE22465F65003D8AF0 /* databases in Resources */, - 00C0C6BF22465F65003D8AF0 /* migrations in Resources */, - 00A5B42F22009F5A0024E00C /* Assets.xcassets in Resources */, - 00D48BD12200A31300CC4527 /* Launch.storyboard in Resources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 00A5B43622009F5A0024E00C /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 00C0C6D32247134F003D8AF0 /* Build Core Module */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputFileListPaths = ( - ); - inputPaths = ( - ); - name = "Build Core Module"; - outputFileListPaths = ( - ); - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "cd ../uhabits-core-legacy\n../gradlew linkDebugFrameworkIos\n"; - }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ - 00A5B42022009F590024E00C /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 00C0C6D122470705003D8AF0 /* ComponentView.swift in Sources */, - 00C0C6E0224A3602003D8AF0 /* DetailScreenController.swift in Sources */, - 00A5B42A22009F590024E00C /* MainScreenController.swift in Sources */, - 00A5B42822009F590024E00C /* AppDelegate.swift in Sources */, - 00D48BD32200AC1600CC4527 /* EditHabitController.swift in Sources */, - 006EFE50225432B8008464E0 /* AboutScreenController.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - 00A5B43422009F5A0024E00C /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - 005166D12471C02D00C6CFD6 /* AppDelegate.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; -/* End PBXSourcesBuildPhase section */ - -/* Begin PBXTargetDependency section */ - 00A5B43A22009F5A0024E00C /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = 00A5B42322009F590024E00C /* uhabits */; - targetProxy = 00A5B43922009F5A0024E00C /* PBXContainerItemProxy */; - }; -/* End PBXTargetDependency section */ - -/* Begin XCBuildConfiguration section */ - 00A5B43F22009F5A0024E00C /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = dwarf; - ENABLE_STRICT_OBJC_MSGSEND = YES; - ENABLE_TESTABILITY = YES; - FRAMEWORK_SEARCH_PATHS = ""; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_DYNAMIC_NO_PIC = NO; - GCC_NO_COMMON_BLOCKS = YES; - GCC_OPTIMIZATION_LEVEL = 0; - GCC_PREPROCESSOR_DEFINITIONS = ( - "DEBUG=1", - "$(inherited)", - ); - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ""; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; - MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; - MTL_FAST_MATH = YES; - ONLY_ACTIVE_ARCH = YES; - SDKROOT = iphoneos; - SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - }; - name = Debug; - }; - 00A5B44022009F5A0024E00C /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_SEARCH_USER_PATHS = NO; - CLANG_ANALYZER_NONNULL = YES; - CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; - CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; - CLANG_CXX_LIBRARY = "libc++"; - CLANG_ENABLE_MODULES = YES; - CLANG_ENABLE_OBJC_ARC = YES; - CLANG_ENABLE_OBJC_WEAK = YES; - CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; - CLANG_WARN_BOOL_CONVERSION = YES; - CLANG_WARN_COMMA = YES; - CLANG_WARN_CONSTANT_CONVERSION = YES; - CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; - CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; - CLANG_WARN_DOCUMENTATION_COMMENTS = YES; - CLANG_WARN_EMPTY_BODY = YES; - CLANG_WARN_ENUM_CONVERSION = YES; - CLANG_WARN_INFINITE_RECURSION = YES; - CLANG_WARN_INT_CONVERSION = YES; - CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; - CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; - CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; - CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; - CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; - CLANG_WARN_STRICT_PROTOTYPES = YES; - CLANG_WARN_SUSPICIOUS_MOVE = YES; - CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; - CLANG_WARN_UNREACHABLE_CODE = YES; - CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_IDENTITY = "iPhone Developer"; - COPY_PHASE_STRIP = NO; - DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; - ENABLE_NS_ASSERTIONS = NO; - ENABLE_STRICT_OBJC_MSGSEND = YES; - FRAMEWORK_SEARCH_PATHS = ""; - GCC_C_LANGUAGE_STANDARD = gnu11; - GCC_NO_COMMON_BLOCKS = YES; - GCC_WARN_64_TO_32_BIT_CONVERSION = YES; - GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; - GCC_WARN_UNDECLARED_SELECTOR = YES; - GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; - GCC_WARN_UNUSED_FUNCTION = YES; - GCC_WARN_UNUSED_VARIABLE = YES; - HEADER_SEARCH_PATHS = ""; - IPHONEOS_DEPLOYMENT_TARGET = 12.1; - MTL_ENABLE_DEBUG_INFO = NO; - MTL_FAST_MATH = YES; - SDKROOT = iphoneos; - SWIFT_COMPILATION_MODE = wholemodule; - SWIFT_OPTIMIZATION_LEVEL = "-O"; - VALIDATE_PRODUCT = YES; - }; - name = Release; - }; - 00A5B44222009F5A0024E00C /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = R5YTHGE3PS; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(PROJECT_DIR)/../uhabits-core-legacy/build/bin/ios/debugFramework/", - "$(PROJECT_DIR)", - ); - HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/../uhabits-core-legacy/build/bin/ios/debugFramework/LoopHabitTracker.framework/Headers/"; - INFOPLIST_FILE = Application/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = org.isoron.uhabits; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_OBJC_BRIDGING_HEADER = Application/BridgingHeader.h; - SWIFT_PRECOMPILE_BRIDGING_HEADER = NO; - SWIFT_VERSION = 4.2; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Debug; - }; - 00A5B44322009F5A0024E00C /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = R5YTHGE3PS; - ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(PROJECT_DIR)/../uhabits-core-legacy/build/bin/ios/debugFramework/", - "$(PROJECT_DIR)", - ); - HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/../uhabits-core-legacy/build/bin/ios/debugFramework/LoopHabitTracker.framework/Headers/"; - INFOPLIST_FILE = Application/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = org.isoron.uhabits; - PRODUCT_NAME = "$(TARGET_NAME)"; - PROVISIONING_PROFILE_SPECIFIER = ""; - SWIFT_OBJC_BRIDGING_HEADER = Application/BridgingHeader.h; - SWIFT_PRECOMPILE_BRIDGING_HEADER = NO; - SWIFT_VERSION = 4.2; - TARGETED_DEVICE_FAMILY = "1,2"; - }; - name = Release; - }; - 00A5B44522009F5A0024E00C /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = R5YTHGE3PS; - FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../core/build/bin/ios/mainDebugFramework/"; - HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/../core/build/bin/ios/mainDebugFramework/main.framework/Headers/"; - INFOPLIST_FILE = Tests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = org.isoron.uhabitsTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = ""; - SWIFT_PRECOMPILE_BRIDGING_HEADER = NO; - SWIFT_VERSION = 4.2; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/uhabits.app/uhabits"; - }; - name = Debug; - }; - 00A5B44622009F5A0024E00C /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - BUNDLE_LOADER = "$(TEST_HOST)"; - CODE_SIGN_STYLE = Automatic; - DEVELOPMENT_TEAM = R5YTHGE3PS; - FRAMEWORK_SEARCH_PATHS = "$(PROJECT_DIR)/../core/build/bin/ios/mainDebugFramework/"; - HEADER_SEARCH_PATHS = "$(PROJECT_DIR)/../core/build/bin/ios/mainDebugFramework/main.framework/Headers/"; - INFOPLIST_FILE = Tests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/Frameworks", - "@loader_path/Frameworks", - ); - PRODUCT_BUNDLE_IDENTIFIER = org.isoron.uhabitsTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SWIFT_OBJC_BRIDGING_HEADER = ""; - SWIFT_PRECOMPILE_BRIDGING_HEADER = NO; - SWIFT_VERSION = 4.2; - TARGETED_DEVICE_FAMILY = "1,2"; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/uhabits.app/uhabits"; - }; - name = Release; - }; -/* End XCBuildConfiguration section */ - -/* Begin XCConfigurationList section */ - 00A5B41F22009F590024E00C /* Build configuration list for PBXProject "uhabits" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 00A5B43F22009F5A0024E00C /* Debug */, - 00A5B44022009F5A0024E00C /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 00A5B44122009F5A0024E00C /* Build configuration list for PBXNativeTarget "uhabits" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 00A5B44222009F5A0024E00C /* Debug */, - 00A5B44322009F5A0024E00C /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - 00A5B44422009F5A0024E00C /* Build configuration list for PBXNativeTarget "uhabitsTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - 00A5B44522009F5A0024E00C /* Debug */, - 00A5B44622009F5A0024E00C /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; -/* End XCConfigurationList section */ - }; - rootObject = 00A5B41C22009F590024E00C /* Project object */; -} diff --git a/uhabits-ios/uhabits.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/uhabits-ios/uhabits.xcodeproj/project.xcworkspace/contents.xcworkspacedata deleted file mode 100644 index 156ec4d58..000000000 --- a/uhabits-ios/uhabits.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ /dev/null @@ -1,7 +0,0 @@ - - - - - diff --git a/uhabits-ios/uhabits.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/uhabits-ios/uhabits.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist deleted file mode 100644 index 18d981003..000000000 --- a/uhabits-ios/uhabits.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +++ /dev/null @@ -1,8 +0,0 @@ - - - - - IDEDidComputeMac32BitWarning - - - diff --git a/uhabits-ios/uhabits.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings b/uhabits-ios/uhabits.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings deleted file mode 100644 index 0c67376eb..000000000 --- a/uhabits-ios/uhabits.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/uhabits-server/.gitignore b/uhabits-server/.gitignore deleted file mode 100644 index fae6b746e..000000000 --- a/uhabits-server/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -/.gradle -/.idea -/out -/build -*.iml -*.ipr -*.iws diff --git a/uhabits-server/Dockerfile b/uhabits-server/Dockerfile deleted file mode 100644 index 34d77779a..000000000 --- a/uhabits-server/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM openjdk:8-jre-alpine -RUN mkdir /app -COPY uhabits-server.jar /app/uhabits-server.jar -ENV LOOP_REPO_PATH /data/ -WORKDIR /app -CMD ["java", \ - "-server", \ - "-XX:MaxGCPauseMillis=100", \ - "-XX:+UseStringDeduplication", \ - "-jar", \ - "uhabits-server.jar"] \ No newline at end of file diff --git a/uhabits-server/build.gradle.kts b/uhabits-server/build.gradle.kts deleted file mode 100644 index 9f2fda06a..000000000 --- a/uhabits-server/build.gradle.kts +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar - -plugins { - application - id("kotlin") - id("com.github.johnrengelman.shadow") version "8.1.1" -} - -kotlin { - jvmToolchain(17) -} - - -application { - group = "org.isoron.uhabits" - version = "0.0.1" - mainClass.set("io.ktor.server.netty.EngineMain") -} - -dependencies { - val ktorVersion = "1.6.8" - implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.22") - implementation("io.ktor:ktor-server-netty:$ktorVersion") - implementation("ch.qos.logback:logback-classic:1.4.14") - implementation("io.ktor:ktor-server-core:$ktorVersion") - implementation("io.ktor:ktor-html-builder:$ktorVersion") - implementation("io.ktor:ktor-jackson:$ktorVersion") - implementation("org.jetbrains:kotlin-css-jvm:1.0.0-pre.148-kotlin-1.4.30") - implementation("io.prometheus:simpleclient:0.16.0") - implementation("io.prometheus:simpleclient_httpserver:0.16.0") - implementation("io.prometheus:simpleclient_hotspot:0.16.0") - testImplementation("io.ktor:ktor-server-tests:$ktorVersion") - testImplementation("org.mockito.kotlin:mockito-kotlin:5.2.1") - testImplementation(kotlin("test")) - testImplementation(kotlin("test-junit")) -} - -tasks.withType { - archiveBaseName.set("uhabits-server") - archiveClassifier.set("") - archiveVersion.set("") -} - diff --git a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/SyncData.kt b/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/SyncData.kt deleted file mode 100644 index d60319d6e..000000000 --- a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/SyncData.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.sync - -import com.fasterxml.jackson.databind.* - -data class SyncData( - val version: Long, - val content: String -) - -data class RegisterReponse(val key: String) - -data class GetDataVersionResponse(val version: Long) - -val defaultMapper = ObjectMapper() -fun SyncData.toJson(): String = defaultMapper.writeValueAsString(this) -fun GetDataVersionResponse.toJson(): String = defaultMapper.writeValueAsString(this) \ No newline at end of file diff --git a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/SyncException.kt b/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/SyncException.kt deleted file mode 100644 index 30689ad86..000000000 --- a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/SyncException.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.sync - -open class SyncException: RuntimeException() - -class KeyNotFoundException: SyncException() - -class ServiceUnavailable: SyncException() - -class EditConflictException: SyncException() \ No newline at end of file diff --git a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/app/LinkModule.kt b/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/app/LinkModule.kt deleted file mode 100644 index 32ed88349..000000000 --- a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/app/LinkModule.kt +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.sync.app - -import io.ktor.application.* -import io.ktor.http.* -import io.ktor.request.* -import io.ktor.response.* -import io.ktor.routing.* -import org.isoron.uhabits.sync.* - -data class LinkRegisterRequestData( - val syncKey: String, -) -fun LinkRegisterRequestData.toJson(): String = defaultMapper.writeValueAsString(this) - -fun Routing.links(app: SyncApplication) { - post("/links") { - try { - val data = call.receive() - val link = app.server.registerLink(data.syncKey) - call.respond(HttpStatusCode.OK, link) - } catch (e: ServiceUnavailable) { - call.respond(HttpStatusCode.ServiceUnavailable) - } - } - get("/links/{id}") { - try { - val id = call.parameters["id"]!! - val link = app.server.getLink(id) - call.respond(HttpStatusCode.OK, link) - } catch (e: ServiceUnavailable) { - call.respond(HttpStatusCode.ServiceUnavailable) - } catch (e: KeyNotFoundException) { - call.respond(HttpStatusCode.NotFound) - } - } -} diff --git a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/app/MetricsModule.kt b/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/app/MetricsModule.kt deleted file mode 100644 index f367dd552..000000000 --- a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/app/MetricsModule.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.sync.app - -import io.ktor.application.* -import io.ktor.http.* -import io.ktor.response.* -import io.ktor.routing.* -import io.prometheus.client.* -import io.prometheus.client.exporter.common.* -import io.prometheus.client.hotspot.* -import java.io.* - - -fun Routing.metrics(app: SyncApplication) { - // Register JVM metrics - DefaultExports.initialize() - - get("/metrics") { - val writer = StringWriter() - TextFormat.write004( - writer, - CollectorRegistry.defaultRegistry.filteredMetricFamilySamples(setOf()), - ) - call.respond(HttpStatusCode.OK, writer.toString()) - } -} diff --git a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/app/RegistrationModule.kt b/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/app/RegistrationModule.kt deleted file mode 100644 index 1501b243a..000000000 --- a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/app/RegistrationModule.kt +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.sync.app - -import io.ktor.application.* -import io.ktor.http.* -import io.ktor.response.* -import io.ktor.routing.* -import org.isoron.uhabits.sync.* - -fun Routing.registration(app: SyncApplication) { - post("/register") { - try { - val key = app.server.register() - call.respond(HttpStatusCode.OK, RegisterReponse(key)) - } catch (e: ServiceUnavailable) { - call.respond(HttpStatusCode.ServiceUnavailable) - } - } -} diff --git a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/app/StorageModule.kt b/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/app/StorageModule.kt deleted file mode 100644 index 3e67d359c..000000000 --- a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/app/StorageModule.kt +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.sync.app - -import io.ktor.application.* -import io.ktor.http.* -import io.ktor.request.* -import io.ktor.response.* -import io.ktor.routing.* -import org.isoron.uhabits.sync.* - -fun Routing.storage(app: SyncApplication) { - route("/db/{key}") { - get { - val key = call.parameters["key"]!! - try { - val data = app.server.getData(key) - call.respond(HttpStatusCode.OK, data) - } catch(e: KeyNotFoundException) { - call.respond(HttpStatusCode.NotFound) - } - } - put { - val key = call.parameters["key"]!! - val data = call.receive() - try { - app.server.put(key, data) - call.respond(HttpStatusCode.OK) - } catch (e: KeyNotFoundException) { - call.respond(HttpStatusCode.NotFound) - } catch (e: EditConflictException) { - call.respond(HttpStatusCode.Conflict) - } - } - get("version") { - val key = call.parameters["key"]!! - try { - val version = app.server.getDataVersion(key) - call.respond(HttpStatusCode.OK, GetDataVersionResponse(version)) - } catch(e: KeyNotFoundException) { - call.respond(HttpStatusCode.NotFound) - } - } - } -} \ No newline at end of file diff --git a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/app/SyncApplication.kt b/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/app/SyncApplication.kt deleted file mode 100644 index 71344b16f..000000000 --- a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/app/SyncApplication.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.sync.app - -import io.ktor.application.* -import io.ktor.features.* -import io.ktor.jackson.* -import io.ktor.routing.* -import org.isoron.uhabits.sync.* -import org.isoron.uhabits.sync.repository.* -import org.isoron.uhabits.sync.server.* -import java.nio.file.* - -fun Application.main() = SyncApplication().apply { main() } - -val REPOSITORY_PATH: Path = Paths.get(System.getenv("LOOP_REPO_PATH")!!) - -class SyncApplication( - val server: AbstractSyncServer = RepositorySyncServer( - FileRepository(REPOSITORY_PATH), - ), -) { - fun Application.main() { - install(DefaultHeaders) - install(CallLogging) - install(ContentNegotiation) { - jackson { } - } - routing { - registration(this@SyncApplication) - storage(this@SyncApplication) - links(this@SyncApplication) - metrics(this@SyncApplication) - } - } -} diff --git a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/links/Link.kt b/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/links/Link.kt deleted file mode 100644 index 9adf50614..000000000 --- a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/links/Link.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.sync.links - -import org.isoron.uhabits.sync.defaultMapper - -/** - * A Link maps a public URL (such as https://sync.loophabits.org/links/B752A6) - * to a synchronization key. They are used to transfer sync keys between devices - * without ever exposing the original sync key. Unlike sync keys, links expire - * after a few minutes. - */ -data class Link( - val id: String, - val syncKey: String, - val createdAt: Long, -) - -fun Link.toJson(): String = defaultMapper.writeValueAsString(this) diff --git a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/links/LinkManager.kt b/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/links/LinkManager.kt deleted file mode 100644 index 4b153861c..000000000 --- a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/links/LinkManager.kt +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.sync.links - -import org.isoron.uhabits.sync.* -import org.isoron.uhabits.sync.utils.* - -class LinkManager( - private val timeoutInMillis: Long = 900_000, -) { - private val links = HashMap() - - fun register(syncKey: String): Link { - val link = Link( - id = randomString(64), - syncKey = syncKey, - createdAt = System.currentTimeMillis(), - ) - links[link.id] = link - return link - } - - fun get(id: String): Link { - val link = links[id] ?: throw KeyNotFoundException() - val ageInMillis = System.currentTimeMillis() - link.createdAt - if (ageInMillis > timeoutInMillis) { - links.remove(id) - throw KeyNotFoundException() - } - return link - } -} \ No newline at end of file diff --git a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/repository/FileRepository.kt b/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/repository/FileRepository.kt deleted file mode 100644 index 1faf93fc7..000000000 --- a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/repository/FileRepository.kt +++ /dev/null @@ -1,73 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.sync.repository - -import org.isoron.uhabits.sync.* -import java.io.* -import java.nio.file.* - -class FileRepository( - private val basepath: Path, -) : Repository { - - override suspend fun put(key: String, data: SyncData) { - // Create directory - val dataPath = key.toDataPath() - val dataDir = dataPath.toFile() - dataDir.mkdirs() - - // Create metadata - val metadataFile = dataPath.resolve("version").toFile() - metadataFile.outputStream().use { outputStream -> - PrintWriter(outputStream).use { printWriter -> - printWriter.print(data.version) - } - } - - // Create data file - val dataFile = dataPath.resolve("content").toFile() - dataFile.outputStream().use { outputStream -> - PrintWriter(outputStream).use { printWriter -> - printWriter.print(data.content) - } - } - } - - override suspend fun get(key: String): SyncData { - val dataPath = key.toDataPath() - val contentFile = dataPath.resolve("content").toFile() - val versionFile = dataPath.resolve("version").toFile() - if (!contentFile.exists() || !versionFile.exists()) { - throw KeyNotFoundException() - } - val version = versionFile.readText().trim().toLong() - return SyncData(version, contentFile.readText()) - } - - override suspend fun contains(key: String): Boolean { - val dataPath = key.toDataPath() - val versionFile = dataPath.resolve("version").toFile() - return versionFile.exists() - } - - private fun String.toDataPath(): Path { - return basepath.resolve("${this[0]}/${this[1]}/${this[2]}/${this[3]}/$this") - } -} \ No newline at end of file diff --git a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/repository/Repository.kt b/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/repository/Repository.kt deleted file mode 100644 index 651ca679f..000000000 --- a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/repository/Repository.kt +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.sync.repository - -import org.isoron.uhabits.sync.KeyNotFoundException -import org.isoron.uhabits.sync.SyncData - -/** - * A class that knows how to store and retrieve a large number of [SyncData] items. - */ -interface Repository { - /** - * Stores a data item, under the provided key. The item can be later retrieved with [get]. - * Replaces existing items silently. - */ - suspend fun put(key: String, data: SyncData) - - /** - * Retrieves a data item that was previously stored using [put]. - * @throws KeyNotFoundException If no such key exists. - */ - suspend fun get(key: String): SyncData - - /** - * Returns true if the repository contains a given key. - */ - suspend fun contains(key: String): Boolean -} - diff --git a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/server/AbstractSyncServer.kt b/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/server/AbstractSyncServer.kt deleted file mode 100644 index bd18c7b30..000000000 --- a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/server/AbstractSyncServer.kt +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.sync.server - -import org.isoron.uhabits.sync.* -import org.isoron.uhabits.sync.links.* - -interface AbstractSyncServer { - /** - * Generates and returns a new sync key, which can be used to store and retrive - * data. - * - * @throws ServiceUnavailable If key cannot be generated at this time, for example, - * due to insufficient server resources, temporary server maintenance or network problems. - */ - suspend fun register(): String - - /** - * Replaces data for a given sync key. - * - * @throws KeyNotFoundException If key is not found - * @throws EditConflictException If the version of the data provided is not - * exactly the current data version plus one. - * @throws ServiceUnavailable If data cannot be put at this time, for example, due - * to insufficient server resources or network problems. - */ - suspend fun put(key: String, newData: SyncData) - - /** - * Returns data for a given sync key. - * - * @throws KeyNotFoundException If key is not found - * @throws ServiceUnavailable If data cannot be retrieved at this time, for example, due - * to insufficient server resources or network problems. - */ - suspend fun getData(key: String): SyncData - - /** - * Returns the current data version for the given key - * - * @throws KeyNotFoundException If key is not found - * @throws ServiceUnavailable If data cannot be retrieved at this time, for example, due - * to insufficient server resources or network problems. - */ - suspend fun getDataVersion(key: String): Long - - /** - * Registers a new temporary link (mapping to the given sync key) and returns it. - * - * @throws ServiceUnavailable If the link cannot be generated at this time due to - * insufficient server resources. - */ - suspend fun registerLink(syncKey: String): Link - - /** - * Retrieves the syncKey associated with the given link id. - * - * @throws ServiceUnavailable If the link cannot be resolved at this time due to - * insufficient server resources. - * @throws KeyNotFoundException If the link id cannot be found, or if it has - * expired. - */ - suspend fun getLink(id: String): Link -} diff --git a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/server/RepositorySyncServer.kt b/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/server/RepositorySyncServer.kt deleted file mode 100644 index cdde98d91..000000000 --- a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/server/RepositorySyncServer.kt +++ /dev/null @@ -1,94 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.sync.server - -import io.prometheus.client.* -import org.isoron.uhabits.sync.* -import org.isoron.uhabits.sync.links.* -import org.isoron.uhabits.sync.repository.* -import org.isoron.uhabits.sync.utils.* - -/** - * An AbstractSyncServer that stores all data in a [Repository]. - */ -class RepositorySyncServer( - private val repo: Repository, - private val linkManager: LinkManager = LinkManager(), -) : AbstractSyncServer { - - private val requestsCounter: Counter = Counter.build() - .name("requests_total") - .help("Total number of requests") - .labelNames("method") - .register() - - override suspend fun register(): String { - requestsCounter.labels("register").inc() - val key = generateKey() - repo.put(key, SyncData(0, "")) - return key - } - - override suspend fun put(key: String, newData: SyncData) { - requestsCounter.labels("put").inc() - if (!repo.contains(key)) { - throw KeyNotFoundException() - } - val prevData = repo.get(key) - if (newData.version != prevData.version + 1) { - throw EditConflictException() - } - repo.put(key, newData) - } - - override suspend fun getData(key: String): SyncData { - requestsCounter.labels("getData").inc() - if (!repo.contains(key)) { - throw KeyNotFoundException() - } - return repo.get(key) - } - - override suspend fun getDataVersion(key: String): Long { - requestsCounter.labels("getDataVersion").inc() - if (!repo.contains(key)) { - throw KeyNotFoundException() - } - return repo.get(key).version - } - - override suspend fun registerLink(syncKey: String): Link { - requestsCounter.labels("registerLink").inc() - return linkManager.register(syncKey) - } - - override suspend fun getLink(id: String): Link { - requestsCounter.labels("getLink").inc() - return linkManager.get(id) - } - - private suspend fun generateKey(): String { - while (true) { - val key = randomString(64) - if (!repo.contains(key)) - return key - } - } -} diff --git a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/utils/String.kt b/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/utils/String.kt deleted file mode 100644 index da043764f..000000000 --- a/uhabits-server/src/main/kotlin/org/isoron/uhabits/sync/utils/String.kt +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.sync.utils - -import java.util.* -import kotlin.streams.* - -fun randomString(length: Long): String { - val chars = "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" - return Random().ints(length, 0, chars.length) - .asSequence() - .map(chars::get) - .joinToString("") -} \ No newline at end of file diff --git a/uhabits-server/src/main/resources/application.conf b/uhabits-server/src/main/resources/application.conf deleted file mode 100644 index d5b282277..000000000 --- a/uhabits-server/src/main/resources/application.conf +++ /dev/null @@ -1,9 +0,0 @@ -ktor { - deployment { - port = 8080 - port = ${?PORT} - } - application { - modules = [ org.isoron.uhabits.sync.app.SyncApplicationKt.main ] - } -} diff --git a/uhabits-server/src/main/resources/logback.xml b/uhabits-server/src/main/resources/logback.xml deleted file mode 100644 index 9a9dfca31..000000000 --- a/uhabits-server/src/main/resources/logback.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - %d{YYYY-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n - - - - - - - - diff --git a/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/app/BaseApplicationTest.kt b/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/app/BaseApplicationTest.kt deleted file mode 100644 index 3c1aa33dd..000000000 --- a/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/app/BaseApplicationTest.kt +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.sync.app - -import org.mockito.kotlin.mock -import io.ktor.application.* -import org.isoron.uhabits.sync.server.* - -open class BaseApplicationTest { - - protected val server: AbstractSyncServer = mock() - - protected fun app(): Application.() -> Unit = { - SyncApplication(server).apply { - main() - } - } -} diff --git a/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/app/LinksModuleTest.kt b/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/app/LinksModuleTest.kt deleted file mode 100644 index 7ee49aa14..000000000 --- a/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/app/LinksModuleTest.kt +++ /dev/null @@ -1,91 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.sync.app - -import org.mockito.kotlin.whenever -import io.ktor.http.ContentType -import io.ktor.http.HttpHeaders -import io.ktor.http.HttpMethod -import io.ktor.http.HttpStatusCode -import io.ktor.server.testing.TestApplicationCall -import io.ktor.server.testing.TestApplicationEngine -import io.ktor.server.testing.handleRequest -import io.ktor.server.testing.setBody -import io.ktor.server.testing.withTestApplication -import kotlinx.coroutines.runBlocking -import org.isoron.uhabits.sync.KeyNotFoundException -import org.isoron.uhabits.sync.links.Link -import org.isoron.uhabits.sync.links.toJson -import org.junit.Test -import kotlin.test.assertEquals - -class LinksModuleTest : BaseApplicationTest() { - private val link = Link( - id = "ABC123", - syncKey = "SECRET", - createdAt = System.currentTimeMillis(), - ) - - @Test - fun `when POST is successful should return link`(): Unit = runBlocking { - whenever(server.registerLink("SECRET")).thenReturn(link) - withTestApplication(app()) { - handlePost("/links", LinkRegisterRequestData(syncKey = "SECRET")).apply { - assertEquals(HttpStatusCode.OK, response.status()) - assertEquals(link.toJson(), response.content) - } - } - } - - @Test - fun `when GET is successful should return link`(): Unit = runBlocking { - whenever(server.getLink("ABC123")).thenReturn(link) - withTestApplication(app()) { - handleGet("/links/ABC123").apply { - assertEquals(HttpStatusCode.OK, response.status()) - assertEquals(link.toJson(), response.content) - } - } - } - - @Test - fun `GET with invalid link id should return 404`(): Unit = runBlocking { - whenever(server.getLink("ABC123")).thenThrow(KeyNotFoundException()) - withTestApplication(app()) { - handleGet("/links/ABC123").apply { - assertEquals(HttpStatusCode.NotFound, response.status()) - } - } - } - - private fun TestApplicationEngine.handlePost( - url: String, - data: LinkRegisterRequestData - ): TestApplicationCall { - return handleRequest(HttpMethod.Post, url) { - addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString()) - setBody(data.toJson()) - } - } - - private fun TestApplicationEngine.handleGet(url: String): TestApplicationCall { - return handleRequest(HttpMethod.Get, url) - } -} diff --git a/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/app/RegistrationModuleTest.kt b/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/app/RegistrationModuleTest.kt deleted file mode 100644 index 8b5710743..000000000 --- a/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/app/RegistrationModuleTest.kt +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.sync.app - -import org.mockito.kotlin.whenever -import io.ktor.http.HttpMethod -import io.ktor.http.HttpStatusCode -import io.ktor.server.testing.handleRequest -import io.ktor.server.testing.withTestApplication -import kotlinx.coroutines.runBlocking -import org.isoron.uhabits.sync.ServiceUnavailable -import org.junit.Test -import kotlin.test.assertEquals - -class RegistrationModuleTest : BaseApplicationTest() { - @Test - fun `when register succeeds should return generated key`(): Unit = runBlocking { - whenever(server.register()).thenReturn("ABCDEF") - withTestApplication(app()) { - val call = handleRequest(HttpMethod.Post, "/register") - assertEquals(HttpStatusCode.OK, call.response.status()) - assertEquals("{\"key\":\"ABCDEF\"}", call.response.content) - } - } - - @Test - fun `when registration is unavailable should return 503`(): Unit = runBlocking { - whenever(server.register()).thenThrow(ServiceUnavailable()) - withTestApplication(app()) { - val call = handleRequest(HttpMethod.Post, "/register") - assertEquals(HttpStatusCode.ServiceUnavailable, call.response.status()) - } - } -} diff --git a/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/app/StorageModuleTest.kt b/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/app/StorageModuleTest.kt deleted file mode 100644 index 36872a194..000000000 --- a/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/app/StorageModuleTest.kt +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.sync.app - -import org.mockito.kotlin.verify -import org.mockito.kotlin.whenever -import io.ktor.http.* -import io.ktor.server.testing.* -import kotlinx.coroutines.* -import org.isoron.uhabits.sync.* -import org.junit.Test -import kotlin.test.* - -class StorageModuleTest : BaseApplicationTest() { - private val data1 = SyncData(1, "Hello world") - private val data2 = SyncData(2, "Hello new world") - - @Test - fun `when get succeeds should return data`(): Unit = runBlocking { - whenever(server.getData("k1")).thenReturn(data1) - withTestApplication(app()) { - handleGet("/db/k1").apply { - assertEquals(HttpStatusCode.OK, response.status()) - assertEquals(data1.toJson(), response.content) - } - } - } - - @Test - fun `when get version succeeds should return version`(): Unit = runBlocking { - whenever(server.getDataVersion("k1")).thenReturn(30) - withTestApplication(app()) { - handleGet("/db/k1/version").apply { - assertEquals(HttpStatusCode.OK, response.status()) - assertEquals(GetDataVersionResponse(30).toJson(), response.content) - } - } - } - - @Test - fun `when get with invalid key should return 404`(): Unit = runBlocking { - whenever(server.getData("k1")).thenThrow(KeyNotFoundException()) - withTestApplication(app()) { - handleGet("/db/k1").apply { - assertEquals(HttpStatusCode.NotFound, response.status()) - } - } - } - - - @Test - fun `when put succeeds should return OK`(): Unit = runBlocking { - withTestApplication(app()) { - handlePut("/db/k1", data1).apply { - runBlocking { - assertEquals(HttpStatusCode.OK, response.status()) - verify(server).put("k1", data1) - } - } - } - } - - @Test - fun `when put with invalid key should return 404`(): Unit = runBlocking { - whenever(server.put("k1", data1)).thenThrow(KeyNotFoundException()) - withTestApplication(app()) { - handlePut("/db/k1", data1).apply { - assertEquals(HttpStatusCode.NotFound, response.status()) - } - } - } - - @Test - fun `when put with invalid version should return 409 and current data`(): Unit = runBlocking { - whenever(server.put("k1", data1)).thenThrow(EditConflictException()) - whenever(server.getData("k1")).thenReturn(data2) - withTestApplication(app()) { - handlePut("/db/k1", data1).apply { - assertEquals(HttpStatusCode.Conflict, response.status()) - } - } - } - - private fun TestApplicationEngine.handlePut(url: String, data: SyncData): TestApplicationCall { - return handleRequest(HttpMethod.Put, url) { - addHeader(HttpHeaders.ContentType, ContentType.Application.Json.toString()) - setBody(data.toJson()) - } - } - - private fun TestApplicationEngine.handleGet(url: String): TestApplicationCall { - return handleRequest(HttpMethod.Get, url) - } -} diff --git a/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/links/LinkManagerTest.kt b/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/links/LinkManagerTest.kt deleted file mode 100644 index d1eb88c24..000000000 --- a/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/links/LinkManagerTest.kt +++ /dev/null @@ -1,44 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.sync.links - -import org.isoron.uhabits.sync.* -import org.junit.Test -import kotlin.test.* - -class LinkManagerTest { - - @Test - fun testUsage() { - val manager = LinkManager(timeoutInMillis = 250) - val originalLink = manager.register(syncKey = "SECRET") - val retrievedLink = manager.get(originalLink.id) - assertEquals(originalLink, retrievedLink) - - Thread.sleep(260) // wait until expiration - assertFailsWith { - manager.get(originalLink.id) - } - - assertFailsWith { - manager.get("INVALID") - } - } -} \ No newline at end of file diff --git a/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/repository/FileRepositoryTest.kt b/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/repository/FileRepositoryTest.kt deleted file mode 100644 index 53ce3a8c6..000000000 --- a/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/repository/FileRepositoryTest.kt +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - - -@file:Suppress("BlockingMethodInNonBlockingContext") - -package org.isoron.uhabits.sync.repository - -import kotlinx.coroutines.* -import org.hamcrest.CoreMatchers.* -import org.isoron.uhabits.sync.* -import org.junit.* -import org.junit.Assert.* -import java.nio.file.* - -class FileRepositoryTest { - - @Test - fun testUsage() = runBlocking { - val tempdir = Files.createTempDirectory("db")!! - val repo = FileRepository(tempdir) - - val original = SyncData(10, "Hello world") - repo.put("abcdefg", original) - - val metaPath = tempdir.resolve("a/b/c/d/abcdefg/version") - assertTrue("$metaPath should exist", Files.exists(metaPath)) - assertEquals("10", metaPath.toFile().readText()) - - val dataPath = tempdir.resolve("a/b/c/d/abcdefg/content") - assertTrue("$dataPath should exist", Files.exists(dataPath)) - assertEquals("Hello world", dataPath.toFile().readText()) - - val retrieved = repo.get("abcdefg") - assertThat(retrieved, equalTo(original)) - } -} \ No newline at end of file diff --git a/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/server/RepositorySyncServerTest.kt b/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/server/RepositorySyncServerTest.kt deleted file mode 100644 index ca1576bda..000000000 --- a/uhabits-server/src/test/kotlin/org/isoron/uhabits/sync/server/RepositorySyncServerTest.kt +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright (C) 2016-2021 Álinson Santos Xavier - * - * This file is part of Loop Habit Tracker. - * - * Loop Habit Tracker is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by the - * Free Software Foundation, either version 3 of the License, or (at your - * option) any later version. - * - * Loop Habit Tracker is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY - * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for - * more details. - * - * You should have received a copy of the GNU General Public License along - * with this program. If not, see . - */ - -package org.isoron.uhabits.sync.server - -import kotlinx.coroutines.* -import org.isoron.uhabits.sync.* -import org.isoron.uhabits.sync.repository.* -import org.junit.Test -import java.nio.file.* -import kotlin.test.* - -class RepositorySyncServerTest { - - private val tempdir = Files.createTempDirectory("db") - private val server = RepositorySyncServer(FileRepository(tempdir)) - private val key = runBlocking { server.register() } - - @Test - fun testUsage(): Unit = runBlocking { - val data0 = SyncData(0, "") - assertEquals(server.getData(key), data0) - - val data1 = SyncData(1, "Hello world") - server.put(key, data1) - assertEquals(server.getData(key), data1) - - val data2 = SyncData(2, "Hello new world") - server.put(key, data2) - assertEquals(server.getData(key), data2) - - assertFailsWith { - server.put(key, data2) - } - - assertFailsWith { - server.getData("INVALID") - } - - assertFailsWith { - server.put("INVALID", data0) - } - } -} \ No newline at end of file diff --git a/uhabits-web/.babelrc b/uhabits-web/.babelrc deleted file mode 100644 index e9a907edb..000000000 --- a/uhabits-web/.babelrc +++ /dev/null @@ -1,6 +0,0 @@ -{ - "presets": [ - ["env", { "modules": false }], - "react" - ] -} diff --git a/uhabits-web/Makefile b/uhabits-web/Makefile deleted file mode 100644 index 69e7fb257..000000000 --- a/uhabits-web/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -test_bundle := build/test.js -node_modules := node_modules/.bin/mocha -core_dir := ../uhabits-core-legacy - -all: $(test_bundle) - -$(node_modules): - npm install - -core: - cd $(core_dir); ./gradlew --quiet jsMainClasses jsTestClasses - cp $(core_dir)/build/classes/kotlin/js/*/*.js node_modules/ - mkdir -p build/assets - rsync -a $(core_dir)/assets/main/ build/assets/ - rsync -a $(core_dir)/assets/test/ build/assets/ - -$(test_bundle): src/test/index.js core - mkdir -p build/lib build/test build/css - npx webpack -d --mode development --target web --output $@ $< - cp src/test/*html build/test - cp node_modules/mocha/mocha.css build/lib - cp node_modules/mocha/mocha.js build/lib - cp node_modules/sql.js/js/sql.js build/lib - cp node_modules/sprintf-js/dist/sprintf.min.js build/lib - -serve: - npx serve build/ - -clean: - rm -rf build - -distclean: clean - rm -rf node_modules - -.PHONY: test clean distclean core diff --git a/uhabits-web/package-lock.json b/uhabits-web/package-lock.json deleted file mode 100644 index 1333e8561..000000000 --- a/uhabits-web/package-lock.json +++ /dev/null @@ -1,6080 +0,0 @@ -{ - "name": "loop-habit-tracker", - "version": "2.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "@webassemblyjs/ast": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.8.5.tgz", - "integrity": "sha512-aJMfngIZ65+t71C3y2nBBg5FFG0Okt9m0XEgWZ7Ywgn1oMAT8cNwx00Uv1cQyHtidq0Xn94R4TAywO+LCQ+ZAQ==", - "dev": true, - "requires": { - "@webassemblyjs/helper-module-context": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5" - } - }, - "@webassemblyjs/floating-point-hex-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.8.5.tgz", - "integrity": "sha512-9p+79WHru1oqBh9ewP9zW95E3XAo+90oth7S5Re3eQnECGq59ly1Ri5tsIipKGpiStHsUYmY3zMLqtk3gTcOtQ==", - "dev": true - }, - "@webassemblyjs/helper-api-error": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.8.5.tgz", - "integrity": "sha512-Za/tnzsvnqdaSPOUXHyKJ2XI7PDX64kWtURyGiJJZKVEdFOsdKUCPTNEVFZq3zJ2R0G5wc2PZ5gvdTRFgm81zA==", - "dev": true - }, - "@webassemblyjs/helper-buffer": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.8.5.tgz", - "integrity": "sha512-Ri2R8nOS0U6G49Q86goFIPNgjyl6+oE1abW1pS84BuhP1Qcr5JqMwRFT3Ah3ADDDYGEgGs1iyb1DGX+kAi/c/Q==", - "dev": true - }, - "@webassemblyjs/helper-code-frame": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-code-frame/-/helper-code-frame-1.8.5.tgz", - "integrity": "sha512-VQAadSubZIhNpH46IR3yWO4kZZjMxN1opDrzePLdVKAZ+DFjkGD/rf4v1jap744uPVU6yjL/smZbRIIJTOUnKQ==", - "dev": true, - "requires": { - "@webassemblyjs/wast-printer": "1.8.5" - } - }, - "@webassemblyjs/helper-fsm": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-fsm/-/helper-fsm-1.8.5.tgz", - "integrity": "sha512-kRuX/saORcg8se/ft6Q2UbRpZwP4y7YrWsLXPbbmtepKr22i8Z4O3V5QE9DbZK908dh5Xya4Un57SDIKwB9eow==", - "dev": true - }, - "@webassemblyjs/helper-module-context": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-module-context/-/helper-module-context-1.8.5.tgz", - "integrity": "sha512-/O1B236mN7UNEU4t9X7Pj38i4VoU8CcMHyy3l2cV/kIF4U5KoHXDVqcDuOs1ltkac90IM4vZdHc52t1x8Yfs3g==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "mamacro": "^0.0.3" - } - }, - "@webassemblyjs/helper-wasm-bytecode": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.8.5.tgz", - "integrity": "sha512-Cu4YMYG3Ddl72CbmpjU/wbP6SACcOPVbHN1dI4VJNJVgFwaKf1ppeFJrwydOG3NDHxVGuCfPlLZNyEdIYlQ6QQ==", - "dev": true - }, - "@webassemblyjs/helper-wasm-section": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.8.5.tgz", - "integrity": "sha512-VV083zwR+VTrIWWtgIUpqfvVdK4ff38loRmrdDBgBT8ADXYsEZ5mPQ4Nde90N3UYatHdYoDIFb7oHzMncI02tA==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5" - } - }, - "@webassemblyjs/ieee754": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.8.5.tgz", - "integrity": "sha512-aaCvQYrvKbY/n6wKHb/ylAJr27GglahUO89CcGXMItrOBqRarUMxWLJgxm9PJNuKULwN5n1csT9bYoMeZOGF3g==", - "dev": true, - "requires": { - "@xtuc/ieee754": "^1.2.0" - } - }, - "@webassemblyjs/leb128": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.8.5.tgz", - "integrity": "sha512-plYUuUwleLIziknvlP8VpTgO4kqNaH57Y3JnNa6DLpu/sGcP6hbVdfdX5aHAV716pQBKrfuU26BJK29qY37J7A==", - "dev": true, - "requires": { - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/utf8": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.8.5.tgz", - "integrity": "sha512-U7zgftmQriw37tfD934UNInokz6yTmn29inT2cAetAsaU9YeVCveWEwhKL1Mg4yS7q//NGdzy79nlXh3bT8Kjw==", - "dev": true - }, - "@webassemblyjs/wasm-edit": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.8.5.tgz", - "integrity": "sha512-A41EMy8MWw5yvqj7MQzkDjU29K7UJq1VrX2vWLzfpRHt3ISftOXqrtojn7nlPsZ9Ijhp5NwuODuycSvfAO/26Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/helper-wasm-section": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-opt": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5", - "@webassemblyjs/wast-printer": "1.8.5" - } - }, - "@webassemblyjs/wasm-gen": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.8.5.tgz", - "integrity": "sha512-BCZBT0LURC0CXDzj5FXSc2FPTsxwp3nWcqXQdOZE4U7h7i8FqtFK5Egia6f9raQLpEKT1VL7zr4r3+QX6zArWg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/ieee754": "1.8.5", - "@webassemblyjs/leb128": "1.8.5", - "@webassemblyjs/utf8": "1.8.5" - } - }, - "@webassemblyjs/wasm-opt": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.8.5.tgz", - "integrity": "sha512-HKo2mO/Uh9A6ojzu7cjslGaHaUU14LdLbGEKqTR7PBKwT6LdPtLLh9fPY33rmr5wcOMrsWDbbdCHq4hQUdd37Q==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-buffer": "1.8.5", - "@webassemblyjs/wasm-gen": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5" - } - }, - "@webassemblyjs/wasm-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.8.5.tgz", - "integrity": "sha512-pi0SYE9T6tfcMkthwcgCpL0cM9nRYr6/6fjgDtL6q/ZqKHdMWvxitRi5JcZ7RI4SNJJYnYNaWy5UUrHQy998lw==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-api-error": "1.8.5", - "@webassemblyjs/helper-wasm-bytecode": "1.8.5", - "@webassemblyjs/ieee754": "1.8.5", - "@webassemblyjs/leb128": "1.8.5", - "@webassemblyjs/utf8": "1.8.5" - } - }, - "@webassemblyjs/wast-parser": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-parser/-/wast-parser-1.8.5.tgz", - "integrity": "sha512-daXC1FyKWHF1i11obK086QRlsMsY4+tIOKgBqI1lxAnkp9xe9YMcgOxm9kLe+ttjs5aWV2KKE1TWJCN57/Btsg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/floating-point-hex-parser": "1.8.5", - "@webassemblyjs/helper-api-error": "1.8.5", - "@webassemblyjs/helper-code-frame": "1.8.5", - "@webassemblyjs/helper-fsm": "1.8.5", - "@xtuc/long": "4.2.2" - } - }, - "@webassemblyjs/wast-printer": { - "version": "1.8.5", - "resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.8.5.tgz", - "integrity": "sha512-w0U0pD4EhlnvRyeJzBqaVSJAo9w/ce7/WPogeXLzGkO6hzhr4GnQIZ4W4uUt5b9ooAaXPtnXlj0gzsXEOUNYMg==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/wast-parser": "1.8.5", - "@xtuc/long": "4.2.2" - } - }, - "@xtuc/ieee754": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", - "integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==", - "dev": true - }, - "@xtuc/long": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", - "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==", - "dev": true - }, - "@zeit/schemas": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/@zeit/schemas/-/schemas-2.6.0.tgz", - "integrity": "sha512-uUrgZ8AxS+Lio0fZKAipJjAh415JyrOZowliZAzmnJSsf7piVL5w+G0+gFJ0KSu3QRhvui/7zuvpLz03YjXAhg==", - "dev": true - }, - "accepts": { - "version": "1.3.7", - "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.7.tgz", - "integrity": "sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==", - "dev": true, - "requires": { - "mime-types": "~2.1.24", - "negotiator": "0.6.2" - } - }, - "acorn": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.3.0.tgz", - "integrity": "sha512-/czfa8BwS88b9gWQVhc8eknunSA2DoJpJyTQkhheIf5E48u1N0R4q/YxxsAeqRrmK9TQ/uYfgLDfZo91UlANIA==", - "dev": true - }, - "ajv": { - "version": "6.5.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.5.3.tgz", - "integrity": "sha512-LqZ9wY+fx3UMiiPd741yB2pj3hhil+hQc8taf4o2QGRFpWgZ2V5C8HA165DY9sS3fJwsk7uT7ZlFEyC3Ig3lLg==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - }, - "ajv-errors": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/ajv-errors/-/ajv-errors-1.0.1.tgz", - "integrity": "sha512-DCRfO/4nQ+89p/RK43i8Ezd41EqdGIU4ld7nGF8OQ14oc/we5rEntLCUa7+jrn3nn83BosfwZA0wb4pon2o8iQ==", - "dev": true - }, - "ajv-keywords": { - "version": "3.4.1", - "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.4.1.tgz", - "integrity": "sha512-RO1ibKvd27e6FEShVFfPALuHI3WjSVNeK5FIsmme/LYRNxjKuNj+Dt7bucLa6NdSv3JcVTyMlm9kGR84z1XpaQ==", - "dev": true - }, - "ansi-align": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ansi-align/-/ansi-align-2.0.0.tgz", - "integrity": "sha1-w2rsy6VjuJzrVW82kPCx2eNUf38=", - "dev": true, - "requires": { - "string-width": "^2.0.0" - } - }, - "ansi-colors": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-3.2.3.tgz", - "integrity": "sha512-LEHHyuhlPY3TmuUYMh2oz89lTShfvgbmzaBcxve9t/9Wuy7Dwf4yoAKcND7KFT1HAQfqZ12qtc+DUrBMeKF9nw==", - "dev": true - }, - "ansi-regex": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz", - "integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=" - }, - "ansi-styles": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-2.2.1.tgz", - "integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=" - }, - "anymatch": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", - "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", - "dev": true, - "requires": { - "micromatch": "^3.1.4", - "normalize-path": "^2.1.1" - }, - "dependencies": { - "normalize-path": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", - "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", - "dev": true, - "requires": { - "remove-trailing-separator": "^1.0.1" - } - } - } - }, - "aproba": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/aproba/-/aproba-1.2.0.tgz", - "integrity": "sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==", - "dev": true - }, - "arch": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/arch/-/arch-2.1.1.tgz", - "integrity": "sha512-BLM56aPo9vLLFVa8+/+pJLnrZ7QGGTVHWsCwieAWT9o9K8UeGaQbzZbGoabWLOo2ksBCztoXdqBZBplqLDDCSg==", - "dev": true - }, - "arg": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/arg/-/arg-2.0.0.tgz", - "integrity": "sha512-XxNTUzKnz1ctK3ZIcI2XUPlD96wbHP2nGqkPKpvk/HNRlPveYrXIVSTk9m3LcqOgDPg3B1nMvdV/K8wZd7PG4w==", - "dev": true - }, - "argparse": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", - "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", - "dev": true, - "requires": { - "sprintf-js": "~1.0.2" - }, - "dependencies": { - "sprintf-js": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", - "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", - "dev": true - } - } - }, - "arr-diff": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", - "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", - "dev": true - }, - "arr-flatten": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", - "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", - "dev": true - }, - "arr-union": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", - "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", - "dev": true - }, - "array-unique": { - "version": "0.3.2", - "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", - "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", - "dev": true - }, - "asn1.js": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/asn1.js/-/asn1.js-4.10.1.tgz", - "integrity": "sha512-p32cOF5q0Zqs9uBiONKYLm6BClCoBCM5O9JfeUSlnQLBTxYdTK+pW+nXflm8UkKd2UYlEbYz5qEi0JuZR9ckSw==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "assert": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/assert/-/assert-1.5.0.tgz", - "integrity": "sha512-EDsgawzwoun2CZkCgtxJbv392v4nbk9XDD06zI+kQYoBM/3RBWLlEyJARDOmhAAosBjWACEkKL6S+lIZtcAubA==", - "dev": true, - "requires": { - "object-assign": "^4.1.1", - "util": "0.10.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.1.tgz", - "integrity": "sha1-sX0I0ya0Qj5Wjv9xn5GwscvfafE=", - "dev": true - }, - "util": { - "version": "0.10.3", - "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz", - "integrity": "sha1-evsa/lCAUkZInj23/g7TeTNqwPk=", - "dev": true, - "requires": { - "inherits": "2.0.1" - } - } - } - }, - "assign-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", - "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", - "dev": true - }, - "async-each": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", - "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", - "dev": true - }, - "atob": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", - "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", - "dev": true - }, - "babel-code-frame": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-code-frame/-/babel-code-frame-6.26.0.tgz", - "integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=", - "requires": { - "chalk": "^1.1.3", - "esutils": "^2.0.2", - "js-tokens": "^3.0.2" - } - }, - "babel-core": { - "version": "6.26.3", - "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-6.26.3.tgz", - "integrity": "sha512-6jyFLuDmeidKmUEb3NM+/yawG0M2bDZ9Z1qbZP59cyHLz8kYGKYwpJP0UwUKKUiTRNvxfLesJnTedqczP7cTDA==", - "requires": { - "babel-code-frame": "^6.26.0", - "babel-generator": "^6.26.0", - "babel-helpers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-register": "^6.26.0", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "convert-source-map": "^1.5.1", - "debug": "^2.6.9", - "json5": "^0.5.1", - "lodash": "^4.17.4", - "minimatch": "^3.0.4", - "path-is-absolute": "^1.0.1", - "private": "^0.1.8", - "slash": "^1.0.0", - "source-map": "^0.5.7" - } - }, - "babel-generator": { - "version": "6.26.1", - "resolved": "https://registry.npmjs.org/babel-generator/-/babel-generator-6.26.1.tgz", - "integrity": "sha512-HyfwY6ApZj7BYTcJURpM5tznulaBvyio7/0d4zFOeMPUmfxkCjHocCuoLa2SAGzBI8AREcH3eP3758F672DppA==", - "requires": { - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "detect-indent": "^4.0.0", - "jsesc": "^1.3.0", - "lodash": "^4.17.4", - "source-map": "^0.5.7", - "trim-right": "^1.0.1" - }, - "dependencies": { - "jsesc": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-1.3.0.tgz", - "integrity": "sha1-RsP+yMGJKxKwgz25vHYiF226s0s=" - } - } - }, - "babel-helper-builder-binary-assignment-operator-visitor": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.24.1.tgz", - "integrity": "sha1-zORReto1b0IgvK6KAsKzRvmlZmQ=", - "requires": { - "babel-helper-explode-assignable-expression": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-builder-react-jsx": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.26.0.tgz", - "integrity": "sha1-Of+DE7dci2Xc7/HzHTg+D/KkCKA=", - "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "esutils": "^2.0.2" - } - }, - "babel-helper-call-delegate": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-call-delegate/-/babel-helper-call-delegate-6.24.1.tgz", - "integrity": "sha1-7Oaqzdx25Bw0YfiL/Fdb0Nqi340=", - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-define-map": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-define-map/-/babel-helper-define-map-6.26.0.tgz", - "integrity": "sha1-pfVtq0GiX5fstJjH66ypgZ+Vvl8=", - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-explode-assignable-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.24.1.tgz", - "integrity": "sha1-8luCz33BBDPFX3BZLVdGQArCLKo=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-function-name/-/babel-helper-function-name-6.24.1.tgz", - "integrity": "sha1-00dbjAPtmCQqJbSDUasYOZ01gKk=", - "requires": { - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-get-function-arity": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.24.1.tgz", - "integrity": "sha1-j3eCqpNAfEHTqlCQj4mwMbG2hT0=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-hoist-variables": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.24.1.tgz", - "integrity": "sha1-HssnaJydJVE+rbyZFKc/VAi+enY=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-optimise-call-expression": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.24.1.tgz", - "integrity": "sha1-96E0J7qfc/j0+pk8VKl4gtEkQlc=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-helper-regex": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-helper-regex/-/babel-helper-regex-6.26.0.tgz", - "integrity": "sha1-MlxZ+QL4LyS3T6zu0DY5VPZJXnI=", - "requires": { - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-helper-remap-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.24.1.tgz", - "integrity": "sha1-XsWBgnrXI/7N04HxySg5BnbkVRs=", - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helper-replace-supers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helper-replace-supers/-/babel-helper-replace-supers-6.24.1.tgz", - "integrity": "sha1-v22/5Dk40XNpohPKiov3S2qQqxo=", - "requires": { - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-helpers": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-helpers/-/babel-helpers-6.24.1.tgz", - "integrity": "sha1-NHHenK7DiOXIUOWX5Yom3fN2ArI=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-loader": { - "version": "7.1.5", - "resolved": "https://registry.npmjs.org/babel-loader/-/babel-loader-7.1.5.tgz", - "integrity": "sha512-iCHfbieL5d1LfOQeeVJEUyD9rTwBcP/fcEbRCfempxTDuqrKpu0AZjLAQHEQa3Yqyj9ORKe2iHfoj4rHLf7xpw==", - "dev": true, - "requires": { - "find-cache-dir": "^1.0.0", - "loader-utils": "^1.0.2", - "mkdirp": "^0.5.1" - }, - "dependencies": { - "find-cache-dir": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-1.0.0.tgz", - "integrity": "sha1-kojj6ePMN0hxfTnq3hfPcfww7m8=", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^1.0.0", - "pkg-dir": "^2.0.0" - } - }, - "find-up": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", - "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", - "dev": true, - "requires": { - "locate-path": "^2.0.0" - } - }, - "locate-path": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", - "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", - "dev": true, - "requires": { - "p-locate": "^2.0.0", - "path-exists": "^3.0.0" - } - }, - "make-dir": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-1.3.0.tgz", - "integrity": "sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ==", - "dev": true, - "requires": { - "pify": "^3.0.0" - } - }, - "p-limit": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", - "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", - "dev": true, - "requires": { - "p-try": "^1.0.0" - } - }, - "p-locate": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", - "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", - "dev": true, - "requires": { - "p-limit": "^1.1.0" - } - }, - "p-try": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", - "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", - "dev": true - }, - "pify": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", - "integrity": "sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY=", - "dev": true - }, - "pkg-dir": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", - "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", - "dev": true, - "requires": { - "find-up": "^2.1.0" - } - } - } - }, - "babel-messages": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-messages/-/babel-messages-6.23.0.tgz", - "integrity": "sha1-8830cDhYA1sqKVHG7F7fbGLyYw4=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-check-es2015-constants": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz", - "integrity": "sha1-NRV7EBQm/S/9PaP3XH0ekYNbv4o=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-syntax-async-functions": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz", - "integrity": "sha1-ytnK0RkbWtY0vzCuCHI5HgZHvpU=" - }, - "babel-plugin-syntax-exponentiation-operator": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz", - "integrity": "sha1-nufoM3KQ2pUoggGmpX9BcDF4MN4=" - }, - "babel-plugin-syntax-flow": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz", - "integrity": "sha1-TDqyCiryaqIM0lmVw5jE63AxDI0=" - }, - "babel-plugin-syntax-jsx": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz", - "integrity": "sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY=" - }, - "babel-plugin-syntax-trailing-function-commas": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz", - "integrity": "sha1-ugNgk3+NBuQBgKQ/4NVhb/9TLPM=" - }, - "babel-plugin-transform-async-to-generator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.24.1.tgz", - "integrity": "sha1-ZTbjeK/2yx1VF6wOQOs+n8jQh2E=", - "requires": { - "babel-helper-remap-async-to-generator": "^6.24.1", - "babel-plugin-syntax-async-functions": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-arrow-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz", - "integrity": "sha1-RSaSy3EdX3ncf4XkQM5BufJE0iE=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoped-functions": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz", - "integrity": "sha1-u8UbSflk1wy42OC5ToICRs46YUE=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-block-scoping": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.26.0.tgz", - "integrity": "sha1-1w9SmcEwjQXBL0Y4E7CgnnOxiV8=", - "requires": { - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "lodash": "^4.17.4" - } - }, - "babel-plugin-transform-es2015-classes": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.24.1.tgz", - "integrity": "sha1-WkxYpQyclGHlZLSyo7+ryXolhNs=", - "requires": { - "babel-helper-define-map": "^6.24.1", - "babel-helper-function-name": "^6.24.1", - "babel-helper-optimise-call-expression": "^6.24.1", - "babel-helper-replace-supers": "^6.24.1", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-computed-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.24.1.tgz", - "integrity": "sha1-b+Ko0WiV1WNPTNmZttNICjCBWbM=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-destructuring": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz", - "integrity": "sha1-mXux8auWf2gtKwh2/jWNYOdlxW0=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-duplicate-keys": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.24.1.tgz", - "integrity": "sha1-c+s9MQypaePvnskcU3QabxV2Qj4=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-for-of": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz", - "integrity": "sha1-9HyVsrYT3x0+zC/bdXNiPHUkhpE=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-function-name": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.24.1.tgz", - "integrity": "sha1-g0yJhTvDaxrw86TF26qU/Y6sqos=", - "requires": { - "babel-helper-function-name": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz", - "integrity": "sha1-T1SgLWzWbPkVKAAZox0xklN3yi4=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-modules-amd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.24.1.tgz", - "integrity": "sha1-Oz5UAXI5hC1tGcMBHEvS8AoA0VQ=", - "requires": { - "babel-plugin-transform-es2015-modules-commonjs": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-commonjs": { - "version": "6.26.2", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.26.2.tgz", - "integrity": "sha512-CV9ROOHEdrjcwhIaJNBGMBCodN+1cfkwtM1SbUHmvyy35KGT7fohbpOxkE2uLz1o6odKK2Ck/tz47z+VqQfi9Q==", - "requires": { - "babel-plugin-transform-strict-mode": "^6.24.1", - "babel-runtime": "^6.26.0", - "babel-template": "^6.26.0", - "babel-types": "^6.26.0" - } - }, - "babel-plugin-transform-es2015-modules-systemjs": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.24.1.tgz", - "integrity": "sha1-/4mhQrkRmpBhlfXxBuzzBdlAfSM=", - "requires": { - "babel-helper-hoist-variables": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-modules-umd": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.24.1.tgz", - "integrity": "sha1-rJl+YoXNGO1hdq22B9YCNErThGg=", - "requires": { - "babel-plugin-transform-es2015-modules-amd": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-object-super": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.24.1.tgz", - "integrity": "sha1-JM72muIcuDp/hgPa0CH1cusnj40=", - "requires": { - "babel-helper-replace-supers": "^6.24.1", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-parameters": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.24.1.tgz", - "integrity": "sha1-V6w1GrScrxSpfNE7CfZv3wpiXys=", - "requires": { - "babel-helper-call-delegate": "^6.24.1", - "babel-helper-get-function-arity": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-template": "^6.24.1", - "babel-traverse": "^6.24.1", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-shorthand-properties": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.24.1.tgz", - "integrity": "sha1-JPh11nIch2YbvZmkYi5R8U3jiqA=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-spread": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz", - "integrity": "sha1-1taKmfia7cRTbIGlQujdnxdG+NE=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-sticky-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.24.1.tgz", - "integrity": "sha1-AMHNsaynERLN8M9hJsLta0V8zbw=", - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-plugin-transform-es2015-template-literals": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz", - "integrity": "sha1-qEs0UPfp+PH2g51taH2oS7EjbY0=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-typeof-symbol": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz", - "integrity": "sha1-3sCfHN3/lLUqxz1QXITfWdzOs3I=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-es2015-unicode-regex": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.24.1.tgz", - "integrity": "sha1-04sS9C6nMj9yk4fxinxa4frrNek=", - "requires": { - "babel-helper-regex": "^6.24.1", - "babel-runtime": "^6.22.0", - "regexpu-core": "^2.0.0" - } - }, - "babel-plugin-transform-exponentiation-operator": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.24.1.tgz", - "integrity": "sha1-KrDJx/MJj6SJB3cruBP+QejeOg4=", - "requires": { - "babel-helper-builder-binary-assignment-operator-visitor": "^6.24.1", - "babel-plugin-syntax-exponentiation-operator": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-flow-strip-types": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz", - "integrity": "sha1-hMtnKTXUNxT9wyvOhFaNh0Qc988=", - "requires": { - "babel-plugin-syntax-flow": "^6.18.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-react-display-name": { - "version": "6.25.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.25.0.tgz", - "integrity": "sha1-Z+K/Hx6ck6sI25Z5LgU5K/LMKNE=", - "requires": { - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-react-jsx": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.24.1.tgz", - "integrity": "sha1-hAoCjn30YN/DotKfDA2R9jduZqM=", - "requires": { - "babel-helper-builder-react-jsx": "^6.24.1", - "babel-plugin-syntax-jsx": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-react-jsx-self": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz", - "integrity": "sha1-322AqdomEqEh5t3XVYvL7PBuY24=", - "requires": { - "babel-plugin-syntax-jsx": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-react-jsx-source": { - "version": "6.22.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz", - "integrity": "sha1-ZqwSFT9c0tF7PBkmj0vwGX9E7NY=", - "requires": { - "babel-plugin-syntax-jsx": "^6.8.0", - "babel-runtime": "^6.22.0" - } - }, - "babel-plugin-transform-regenerator": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.26.0.tgz", - "integrity": "sha1-4HA2lvveJ/Cj78rPi03KL3s6jy8=", - "requires": { - "regenerator-transform": "^0.10.0" - } - }, - "babel-plugin-transform-strict-mode": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.24.1.tgz", - "integrity": "sha1-1fr3qleKZbvlkc9e2uBKDGcCB1g=", - "requires": { - "babel-runtime": "^6.22.0", - "babel-types": "^6.24.1" - } - }, - "babel-preset-env": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/babel-preset-env/-/babel-preset-env-1.7.0.tgz", - "integrity": "sha512-9OR2afuKDneX2/q2EurSftUYM0xGu4O2D9adAhVfADDhrYDaxXV0rBbevVYoY9n6nyX1PmQW/0jtpJvUNr9CHg==", - "requires": { - "babel-plugin-check-es2015-constants": "^6.22.0", - "babel-plugin-syntax-trailing-function-commas": "^6.22.0", - "babel-plugin-transform-async-to-generator": "^6.22.0", - "babel-plugin-transform-es2015-arrow-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoped-functions": "^6.22.0", - "babel-plugin-transform-es2015-block-scoping": "^6.23.0", - "babel-plugin-transform-es2015-classes": "^6.23.0", - "babel-plugin-transform-es2015-computed-properties": "^6.22.0", - "babel-plugin-transform-es2015-destructuring": "^6.23.0", - "babel-plugin-transform-es2015-duplicate-keys": "^6.22.0", - "babel-plugin-transform-es2015-for-of": "^6.23.0", - "babel-plugin-transform-es2015-function-name": "^6.22.0", - "babel-plugin-transform-es2015-literals": "^6.22.0", - "babel-plugin-transform-es2015-modules-amd": "^6.22.0", - "babel-plugin-transform-es2015-modules-commonjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-systemjs": "^6.23.0", - "babel-plugin-transform-es2015-modules-umd": "^6.23.0", - "babel-plugin-transform-es2015-object-super": "^6.22.0", - "babel-plugin-transform-es2015-parameters": "^6.23.0", - "babel-plugin-transform-es2015-shorthand-properties": "^6.22.0", - "babel-plugin-transform-es2015-spread": "^6.22.0", - "babel-plugin-transform-es2015-sticky-regex": "^6.22.0", - "babel-plugin-transform-es2015-template-literals": "^6.22.0", - "babel-plugin-transform-es2015-typeof-symbol": "^6.23.0", - "babel-plugin-transform-es2015-unicode-regex": "^6.22.0", - "babel-plugin-transform-exponentiation-operator": "^6.22.0", - "babel-plugin-transform-regenerator": "^6.22.0", - "browserslist": "^3.2.6", - "invariant": "^2.2.2", - "semver": "^5.3.0" - } - }, - "babel-preset-flow": { - "version": "6.23.0", - "resolved": "https://registry.npmjs.org/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz", - "integrity": "sha1-5xIYiHCFrpoktb5Baa/7WZgWxJ0=", - "requires": { - "babel-plugin-transform-flow-strip-types": "^6.22.0" - } - }, - "babel-preset-react": { - "version": "6.24.1", - "resolved": "https://registry.npmjs.org/babel-preset-react/-/babel-preset-react-6.24.1.tgz", - "integrity": "sha1-umnfrqRfw+xjm2pOzqbhdwLJE4A=", - "requires": { - "babel-plugin-syntax-jsx": "^6.3.13", - "babel-plugin-transform-react-display-name": "^6.23.0", - "babel-plugin-transform-react-jsx": "^6.24.1", - "babel-plugin-transform-react-jsx-self": "^6.22.0", - "babel-plugin-transform-react-jsx-source": "^6.22.0", - "babel-preset-flow": "^6.23.0" - } - }, - "babel-register": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-register/-/babel-register-6.26.0.tgz", - "integrity": "sha1-btAhFz4vy0htestFxgCahW9kcHE=", - "requires": { - "babel-core": "^6.26.0", - "babel-runtime": "^6.26.0", - "core-js": "^2.5.0", - "home-or-tmp": "^2.0.0", - "lodash": "^4.17.4", - "mkdirp": "^0.5.1", - "source-map-support": "^0.4.15" - } - }, - "babel-runtime": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz", - "integrity": "sha1-llxwWGaOgrVde/4E/yM3vItWR/4=", - "requires": { - "core-js": "^2.4.0", - "regenerator-runtime": "^0.11.0" - } - }, - "babel-template": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-template/-/babel-template-6.26.0.tgz", - "integrity": "sha1-3gPi0WOWsGn0bdn/+FIfsaDjXgI=", - "requires": { - "babel-runtime": "^6.26.0", - "babel-traverse": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "lodash": "^4.17.4" - } - }, - "babel-traverse": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-traverse/-/babel-traverse-6.26.0.tgz", - "integrity": "sha1-RqnL1+3MYsjlwGTi0tjQ9ANXZu4=", - "requires": { - "babel-code-frame": "^6.26.0", - "babel-messages": "^6.23.0", - "babel-runtime": "^6.26.0", - "babel-types": "^6.26.0", - "babylon": "^6.18.0", - "debug": "^2.6.8", - "globals": "^9.18.0", - "invariant": "^2.2.2", - "lodash": "^4.17.4" - } - }, - "babel-types": { - "version": "6.26.0", - "resolved": "https://registry.npmjs.org/babel-types/-/babel-types-6.26.0.tgz", - "integrity": "sha1-o7Bz+Uq0nrb6Vc1lInozQ4BjJJc=", - "requires": { - "babel-runtime": "^6.26.0", - "esutils": "^2.0.2", - "lodash": "^4.17.4", - "to-fast-properties": "^1.0.3" - } - }, - "babylon": { - "version": "6.18.0", - "resolved": "https://registry.npmjs.org/babylon/-/babylon-6.18.0.tgz", - "integrity": "sha512-q/UEjfGJ2Cm3oKV71DJz9d25TPnq5rhBVL2Q4fA5wcC3jcrdn7+SssEybFIxwAvvP+YCsCYNKughoF33GxgycQ==" - }, - "balanced-match": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", - "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=" - }, - "base": { - "version": "0.11.2", - "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", - "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", - "dev": true, - "requires": { - "cache-base": "^1.0.1", - "class-utils": "^0.3.5", - "component-emitter": "^1.2.1", - "define-property": "^1.0.0", - "isobject": "^3.0.1", - "mixin-deep": "^1.2.0", - "pascalcase": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "base64-js": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz", - "integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==", - "dev": true - }, - "big.js": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", - "integrity": "sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==", - "dev": true - }, - "binary-extensions": { - "version": "1.13.1", - "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", - "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", - "dev": true - }, - "bluebird": { - "version": "3.5.5", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.5.5.tgz", - "integrity": "sha512-5am6HnnfN+urzt4yfg7IgTbotDjIT/u8AJpEt0sIU9FtXfVeezXAPKswrG+xKUCOYAINpSdgZVDU6QFh+cuH3w==", - "dev": true - }, - "bn.js": { - "version": "4.11.8", - "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.11.8.tgz", - "integrity": "sha512-ItfYfPLkWHUjckQCk8xC+LwxgK8NYcXywGigJgSwOP8Y2iyWT4f2vsZnoOXTTbo+o5yXmIUJ4gn5538SO5S3gA==", - "dev": true - }, - "boxen": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", - "integrity": "sha512-TNPjfTr432qx7yOjQyaXm3dSR0MH9vXp7eT1BFSl/C51g+EFnOR9hTg1IreahGBmDNCehscshe45f+C1TBZbLw==", - "dev": true, - "requires": { - "ansi-align": "^2.0.0", - "camelcase": "^4.0.0", - "chalk": "^2.0.1", - "cli-boxes": "^1.0.0", - "string-width": "^2.0.0", - "term-size": "^1.2.0", - "widest-line": "^2.0.0" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "camelcase": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-4.1.0.tgz", - "integrity": "sha1-1UVjW+HjPFQmScaRc+Xeas+uNN0=", - "dev": true - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "brace-expansion": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", - "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "braces": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", - "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", - "dev": true, - "requires": { - "arr-flatten": "^1.1.0", - "array-unique": "^0.3.2", - "extend-shallow": "^2.0.1", - "fill-range": "^4.0.0", - "isobject": "^3.0.1", - "repeat-element": "^1.1.2", - "snapdragon": "^0.8.1", - "snapdragon-node": "^2.0.1", - "split-string": "^3.0.2", - "to-regex": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "brorand": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/brorand/-/brorand-1.1.0.tgz", - "integrity": "sha1-EsJe/kCkXjwyPrhnWgoM5XsiNx8=", - "dev": true - }, - "browser-stdout": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", - "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", - "dev": true - }, - "browserify-aes": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/browserify-aes/-/browserify-aes-1.2.0.tgz", - "integrity": "sha512-+7CHXqGuspUn/Sl5aO7Ea0xWGAtETPXNSAjHo48JfLdPWcMng33Xe4znFvQweqc/uzk5zSOI3H52CYnjCfb5hA==", - "dev": true, - "requires": { - "buffer-xor": "^1.0.3", - "cipher-base": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.3", - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "browserify-cipher": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/browserify-cipher/-/browserify-cipher-1.0.1.tgz", - "integrity": "sha512-sPhkz0ARKbf4rRQt2hTpAHqn47X3llLkUGn+xEJzLjwY8LRs2p0v7ljvI5EyoRO/mexrNunNECisZs+gw2zz1w==", - "dev": true, - "requires": { - "browserify-aes": "^1.0.4", - "browserify-des": "^1.0.0", - "evp_bytestokey": "^1.0.0" - } - }, - "browserify-des": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/browserify-des/-/browserify-des-1.0.2.tgz", - "integrity": "sha512-BioO1xf3hFwz4kc6iBhI3ieDFompMhrMlnDFC4/0/vd5MokpuAc3R+LYbwTA9A5Yc9pq9UYPqffKpW2ObuwX5A==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "des.js": "^1.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "browserify-rsa": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/browserify-rsa/-/browserify-rsa-4.0.1.tgz", - "integrity": "sha1-IeCr+vbyApzy+vsTNWenAdQTVSQ=", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "randombytes": "^2.0.1" - } - }, - "browserify-sign": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/browserify-sign/-/browserify-sign-4.0.4.tgz", - "integrity": "sha1-qk62jl17ZYuqa/alfmMMvXqT0pg=", - "dev": true, - "requires": { - "bn.js": "^4.1.1", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.2", - "elliptic": "^6.0.0", - "inherits": "^2.0.1", - "parse-asn1": "^5.0.0" - } - }, - "browserify-zlib": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/browserify-zlib/-/browserify-zlib-0.2.0.tgz", - "integrity": "sha512-Z942RysHXmJrhqk88FmKBVq/v5tqmSkDz7p54G/MGyjMnCFFnC79XWNbg+Vta8W6Wb2qtSZTSxIGkJrRpCFEiA==", - "dev": true, - "requires": { - "pako": "~1.0.5" - } - }, - "browserslist": { - "version": "3.2.8", - "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-3.2.8.tgz", - "integrity": "sha512-WHVocJYavUwVgVViC0ORikPHQquXwVh939TaelZ4WDqpWgTX/FsGhl/+P4qBUAGcRvtOgDgC+xftNWWp2RUTAQ==", - "requires": { - "caniuse-lite": "^1.0.30000844", - "electron-to-chromium": "^1.3.47" - } - }, - "buffer": { - "version": "4.9.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-4.9.1.tgz", - "integrity": "sha1-bRu2AbB6TvztlwlBMgkwJ8lbwpg=", - "dev": true, - "requires": { - "base64-js": "^1.0.2", - "ieee754": "^1.1.4", - "isarray": "^1.0.0" - } - }, - "buffer-from": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", - "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==", - "dev": true - }, - "buffer-xor": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/buffer-xor/-/buffer-xor-1.0.3.tgz", - "integrity": "sha1-JuYe0UIvtw3ULm42cp7VHYVf6Nk=", - "dev": true - }, - "builtin-status-codes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz", - "integrity": "sha1-hZgoeOIbmOHGZCXgPQF0eI9Wnug=", - "dev": true - }, - "bytes": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz", - "integrity": "sha1-0ygVQE1olpn4Wk6k+odV3ROpYEg=", - "dev": true - }, - "cacache": { - "version": "12.0.2", - "resolved": "https://registry.npmjs.org/cacache/-/cacache-12.0.2.tgz", - "integrity": "sha512-ifKgxH2CKhJEg6tNdAwziu6Q33EvuG26tYcda6PT3WKisZcYDXsnEdnRv67Po3yCzFfaSoMjGZzJyD2c3DT1dg==", - "dev": true, - "requires": { - "bluebird": "^3.5.5", - "chownr": "^1.1.1", - "figgy-pudding": "^3.5.1", - "glob": "^7.1.4", - "graceful-fs": "^4.1.15", - "infer-owner": "^1.0.3", - "lru-cache": "^5.1.1", - "mississippi": "^3.0.0", - "mkdirp": "^0.5.1", - "move-concurrently": "^1.0.1", - "promise-inflight": "^1.0.1", - "rimraf": "^2.6.3", - "ssri": "^6.0.1", - "unique-filename": "^1.1.1", - "y18n": "^4.0.0" - }, - "dependencies": { - "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", - "dev": true, - "requires": { - "yallist": "^3.0.2" - } - }, - "yallist": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.0.3.tgz", - "integrity": "sha512-S+Zk8DEWE6oKpV+vI3qWkaK+jSbIK86pCwe2IF/xwIpQ8jEuxpw9NyaGjmp9+BoJv5FV2piqCDcoCtStppiq2A==", - "dev": true - } - } - }, - "cache-base": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", - "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", - "dev": true, - "requires": { - "collection-visit": "^1.0.0", - "component-emitter": "^1.2.1", - "get-value": "^2.0.6", - "has-value": "^1.0.0", - "isobject": "^3.0.1", - "set-value": "^2.0.0", - "to-object-path": "^0.3.0", - "union-value": "^1.0.0", - "unset-value": "^1.0.0" - } - }, - "camelcase": { - "version": "5.3.1", - "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", - "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", - "dev": true - }, - "caniuse-lite": { - "version": "1.0.30000957", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000957.tgz", - "integrity": "sha512-8wxNrjAzyiHcLXN/iunskqQnJquQQ6VX8JHfW5kLgAPRSiSuKZiNfmIkP5j7jgyXqAQBSoXyJxfnbCFS0ThSiQ==" - }, - "chalk": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-1.1.3.tgz", - "integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=", - "requires": { - "ansi-styles": "^2.2.1", - "escape-string-regexp": "^1.0.2", - "has-ansi": "^2.0.0", - "strip-ansi": "^3.0.0", - "supports-color": "^2.0.0" - } - }, - "chokidar": { - "version": "2.1.6", - "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", - "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", - "dev": true, - "requires": { - "anymatch": "^2.0.0", - "async-each": "^1.0.1", - "braces": "^2.3.2", - "fsevents": "^1.2.7", - "glob-parent": "^3.1.0", - "inherits": "^2.0.3", - "is-binary-path": "^1.0.0", - "is-glob": "^4.0.0", - "normalize-path": "^3.0.0", - "path-is-absolute": "^1.0.0", - "readdirp": "^2.2.1", - "upath": "^1.1.1" - } - }, - "chownr": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.2.tgz", - "integrity": "sha512-GkfeAQh+QNy3wquu9oIZr6SS5x7wGdSgNQvD10X3r+AZr1Oys22HW8kAmDMvNg2+Dm0TeGaEuO8gFwdBXxwO8A==", - "dev": true - }, - "chrome-trace-event": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.2.tgz", - "integrity": "sha512-9e/zx1jw7B4CO+c/RXoCsfg/x1AfUBioy4owYH0bJprEYAx5hRFLRhWBqHAG57D0ZM4H7vxbP7bPe0VwhQRYDQ==", - "dev": true, - "requires": { - "tslib": "^1.9.0" - } - }, - "cipher-base": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/cipher-base/-/cipher-base-1.0.4.tgz", - "integrity": "sha512-Kkht5ye6ZGmwv40uUDZztayT2ThLQGfnj/T71N/XzeZeo3nf8foyW7zGTsPYkEya3m5f3cAypH+qe7YOrM1U2Q==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "class-utils": { - "version": "0.3.6", - "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", - "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "define-property": "^0.2.5", - "isobject": "^3.0.0", - "static-extend": "^0.1.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "cli-boxes": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/cli-boxes/-/cli-boxes-1.0.0.tgz", - "integrity": "sha1-T6kXw+WclKAEzWH47lCdplFocUM=", - "dev": true - }, - "clipboardy": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/clipboardy/-/clipboardy-1.2.3.tgz", - "integrity": "sha512-2WNImOvCRe6r63Gk9pShfkwXsVtKCroMAevIbiae021mS850UkWPbevxsBz3tnvjZIEGvlwaqCPsw+4ulzNgJA==", - "dev": true, - "requires": { - "arch": "^2.1.0", - "execa": "^0.8.0" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.8.0.tgz", - "integrity": "sha1-2NdrvBtVIX7RkP1t1J08d07PyNo=", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - } - } - }, - "cliui": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-4.1.0.tgz", - "integrity": "sha512-4FG+RSG9DL7uEwRUZXZn3SS34DiDPfzP0VOiEwtUWlE+AR2EIg+hSyvrIgUUfhdgR/UkAeW2QHgeP+hWrXs7jQ==", - "dev": true, - "requires": { - "string-width": "^2.1.1", - "strip-ansi": "^4.0.0", - "wrap-ansi": "^2.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "code-point-at": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/code-point-at/-/code-point-at-1.1.0.tgz", - "integrity": "sha1-DQcLTQQ6W+ozovGkDi7bPZpMz3c=", - "dev": true - }, - "collection-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", - "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", - "dev": true, - "requires": { - "map-visit": "^1.0.0", - "object-visit": "^1.0.0" - } - }, - "color-convert": { - "version": "1.9.3", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", - "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", - "dev": true, - "requires": { - "color-name": "1.1.3" - } - }, - "color-name": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", - "dev": true - }, - "commander": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", - "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", - "dev": true - }, - "commondir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/commondir/-/commondir-1.0.1.tgz", - "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", - "dev": true - }, - "component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", - "dev": true - }, - "compressible": { - "version": "2.0.17", - "resolved": "https://registry.npmjs.org/compressible/-/compressible-2.0.17.tgz", - "integrity": "sha512-BGHeLCK1GV7j1bSmQQAi26X+GgWcTjLr/0tzSvMCl3LH1w1IJ4PFSPoV5316b30cneTziC+B1a+3OjoSUcQYmw==", - "dev": true, - "requires": { - "mime-db": ">= 1.40.0 < 2" - } - }, - "compression": { - "version": "1.7.3", - "resolved": "https://registry.npmjs.org/compression/-/compression-1.7.3.tgz", - "integrity": "sha512-HSjyBG5N1Nnz7tF2+O7A9XUhyjru71/fwgNb7oIsEVHR0WShfs2tIS/EySLgiTe98aOK18YDlMXpzjCXY/n9mg==", - "dev": true, - "requires": { - "accepts": "~1.3.5", - "bytes": "3.0.0", - "compressible": "~2.0.14", - "debug": "2.6.9", - "on-headers": "~1.0.1", - "safe-buffer": "5.1.2", - "vary": "~1.1.2" - } - }, - "concat-map": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", - "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=" - }, - "concat-stream": { - "version": "1.6.2", - "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-1.6.2.tgz", - "integrity": "sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^2.2.2", - "typedarray": "^0.0.6" - } - }, - "console-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/console-browserify/-/console-browserify-1.1.0.tgz", - "integrity": "sha1-8CQcRXMKn8YyOyBtvzjtx0HQuxA=", - "dev": true, - "requires": { - "date-now": "^0.1.4" - } - }, - "constants-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/constants-browserify/-/constants-browserify-1.0.0.tgz", - "integrity": "sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U=", - "dev": true - }, - "content-disposition": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.2.tgz", - "integrity": "sha1-DPaLud318r55YcOoUXjLhdunjLQ=", - "dev": true - }, - "convert-source-map": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", - "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", - "requires": { - "safe-buffer": "~5.1.1" - } - }, - "copy-concurrently": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/copy-concurrently/-/copy-concurrently-1.0.5.tgz", - "integrity": "sha512-f2domd9fsVDFtaFcbaRZuYXwtdmnzqbADSwhSWYxYB/Q8zsdUUFMXVRwXGDMWmbEzAn1kdRrtI1T/KTFOL4X2A==", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "fs-write-stream-atomic": "^1.0.8", - "iferr": "^0.1.5", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.0" - } - }, - "copy-descriptor": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", - "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", - "dev": true - }, - "core-js": { - "version": "2.6.5", - "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.5.tgz", - "integrity": "sha512-klh/kDpwX8hryYL14M9w/xei6vrv6sE8gTHDG7/T/+SEovB/G4ejwcfE/CBzO6Edsu+OETZMZ3wcX/EjUkrl5A==" - }, - "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", - "dev": true - }, - "create-ecdh": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/create-ecdh/-/create-ecdh-4.0.3.tgz", - "integrity": "sha512-GbEHQPMOswGpKXM9kCWVrremUcBmjteUaQ01T9rkKCPDXfUHX0IoP9LpHYo2NPFampa4e+/pFDc3jQdxrxQLaw==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "elliptic": "^6.0.0" - } - }, - "create-hash": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/create-hash/-/create-hash-1.2.0.tgz", - "integrity": "sha512-z00bCGNHDG8mHAkP7CtT1qVu+bFQUPjYq/4Iv3C3kWjTFV10zIjfSoeqXo9Asws8gwSHDGj/hl2u4OGIjapeCg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.1", - "inherits": "^2.0.1", - "md5.js": "^1.3.4", - "ripemd160": "^2.0.1", - "sha.js": "^2.4.0" - } - }, - "create-hmac": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/create-hmac/-/create-hmac-1.1.7.tgz", - "integrity": "sha512-MJG9liiZ+ogc4TzUwuvbER1JRdgvUFSB5+VR/g5h82fGaIRWMWddtKBHi7/sVhfjQZ6SehlyhvQYrcYkaUIpLg==", - "dev": true, - "requires": { - "cipher-base": "^1.0.3", - "create-hash": "^1.1.0", - "inherits": "^2.0.1", - "ripemd160": "^2.0.0", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "cross-spawn": { - "version": "6.0.5", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", - "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", - "dev": true, - "requires": { - "nice-try": "^1.0.4", - "path-key": "^2.0.1", - "semver": "^5.5.0", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "crypto-browserify": { - "version": "3.12.0", - "resolved": "https://registry.npmjs.org/crypto-browserify/-/crypto-browserify-3.12.0.tgz", - "integrity": "sha512-fz4spIh+znjO2VjL+IdhEpRJ3YN6sMzITSBijk6FK2UvTqruSQW+/cCZTSNsMiZNvUeq0CqurF+dAbyiGOY6Wg==", - "dev": true, - "requires": { - "browserify-cipher": "^1.0.0", - "browserify-sign": "^4.0.0", - "create-ecdh": "^4.0.0", - "create-hash": "^1.1.0", - "create-hmac": "^1.1.0", - "diffie-hellman": "^5.0.0", - "inherits": "^2.0.1", - "pbkdf2": "^3.0.3", - "public-encrypt": "^4.0.0", - "randombytes": "^2.0.0", - "randomfill": "^1.0.3" - } - }, - "cyclist": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/cyclist/-/cyclist-0.2.2.tgz", - "integrity": "sha1-GzN5LhHpFKL9bW7WRHRkRE5fpkA=", - "dev": true - }, - "date-now": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/date-now/-/date-now-0.1.4.tgz", - "integrity": "sha1-6vQ5/U1ISK105cx9vvIAZyueNFs=", - "dev": true - }, - "debug": { - "version": "2.6.9", - "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", - "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", - "requires": { - "ms": "2.0.0" - } - }, - "decamelize": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", - "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=", - "dev": true - }, - "decode-uri-component": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", - "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", - "dev": true - }, - "deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "dev": true - }, - "define-properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", - "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", - "dev": true, - "requires": { - "object-keys": "^1.0.12" - } - }, - "define-property": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", - "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", - "dev": true, - "requires": { - "is-descriptor": "^1.0.2", - "isobject": "^3.0.1" - }, - "dependencies": { - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "des.js": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/des.js/-/des.js-1.0.0.tgz", - "integrity": "sha1-wHTS4qpqipoH29YfmhXCzYPsjsw=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0" - } - }, - "detect-file": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/detect-file/-/detect-file-1.0.0.tgz", - "integrity": "sha1-8NZtA2cqglyxtzvbP+YjEMjlUrc=", - "dev": true - }, - "detect-indent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/detect-indent/-/detect-indent-4.0.0.tgz", - "integrity": "sha1-920GQ1LN9Docts5hnE7jqUdd4gg=", - "requires": { - "repeating": "^2.0.0" - } - }, - "diff": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz", - "integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==", - "dev": true - }, - "diffie-hellman": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/diffie-hellman/-/diffie-hellman-5.0.3.tgz", - "integrity": "sha512-kqag/Nl+f3GwyK25fhUMYj81BUOrZ9IuJsjIcDE5icNM9FJHAVm3VcUDxdLPoQtTuUylWm6ZIknYJwwaPxsUzg==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "miller-rabin": "^4.0.0", - "randombytes": "^2.0.0" - } - }, - "domain-browser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/domain-browser/-/domain-browser-1.2.0.tgz", - "integrity": "sha512-jnjyiM6eRyZl2H+W8Q/zLMA481hzi0eszAaBUzIVnmYVDBbnLxVNnfu1HgEBvCbL+71FrxMl3E6lpKH7Ge3OXA==", - "dev": true - }, - "duplexify": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", - "integrity": "sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==", - "dev": true, - "requires": { - "end-of-stream": "^1.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.0.0", - "stream-shift": "^1.0.0" - } - }, - "electron-to-chromium": { - "version": "1.3.124", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.124.tgz", - "integrity": "sha512-glecGr/kFdfeXUHOHAWvGcXrxNU+1wSO/t5B23tT1dtlvYB26GY8aHzZSWD7HqhqC800Lr+w/hQul6C5AF542w==" - }, - "elliptic": { - "version": "6.5.0", - "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.0.tgz", - "integrity": "sha512-eFOJTMyCYb7xtE/caJ6JJu+bhi67WCYNbkGSknu20pmM8Ke/bqOfdnZWxyoGN26JgfxTbXrsCkEw4KheCT/KGg==", - "dev": true, - "requires": { - "bn.js": "^4.4.0", - "brorand": "^1.0.1", - "hash.js": "^1.0.0", - "hmac-drbg": "^1.0.0", - "inherits": "^2.0.1", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.0" - } - }, - "emoji-regex": { - "version": "7.0.3", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", - "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", - "dev": true - }, - "emojis-list": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/emojis-list/-/emojis-list-2.1.0.tgz", - "integrity": "sha1-TapNnbAPmBmIDHn6RXrlsJof04k=", - "dev": true - }, - "end-of-stream": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.1.tgz", - "integrity": "sha512-1MkrZNvWTKCaigbn+W15elq2BB/L22nqrSY5DKlo3X6+vclJm8Bb5djXJBmEX6fS3+zCh/F4VBK5Z2KxJt4s2Q==", - "dev": true, - "requires": { - "once": "^1.4.0" - } - }, - "enhanced-resolve": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-4.1.0.tgz", - "integrity": "sha512-F/7vkyTtyc/llOIn8oWclcB25KdRaiPBpZYDgJHgh/UHtpgT2p2eldQgtQnLtUvfMKPKxbRaQM/hHkvLHt1Vng==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "memory-fs": "^0.4.0", - "tapable": "^1.0.0" - } - }, - "errno": { - "version": "0.1.7", - "resolved": "https://registry.npmjs.org/errno/-/errno-0.1.7.tgz", - "integrity": "sha512-MfrRBDWzIWifgq6tJj60gkAwtLNb6sQPlcFrSOflcP1aFmmruKQ2wRnze/8V6kgyz7H3FF8Npzv78mZ7XLLflg==", - "dev": true, - "requires": { - "prr": "~1.0.1" - } - }, - "es-abstract": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", - "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", - "dev": true, - "requires": { - "es-to-primitive": "^1.2.0", - "function-bind": "^1.1.1", - "has": "^1.0.3", - "is-callable": "^1.1.4", - "is-regex": "^1.0.4", - "object-keys": "^1.0.12" - } - }, - "es-to-primitive": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", - "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", - "dev": true, - "requires": { - "is-callable": "^1.1.4", - "is-date-object": "^1.0.1", - "is-symbol": "^1.0.2" - } - }, - "escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=" - }, - "eslint-scope": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", - "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", - "dev": true, - "requires": { - "esrecurse": "^4.1.0", - "estraverse": "^4.1.1" - } - }, - "esprima": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", - "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", - "dev": true - }, - "esrecurse": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", - "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", - "dev": true, - "requires": { - "estraverse": "^4.1.0" - } - }, - "estraverse": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", - "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", - "dev": true - }, - "esutils": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", - "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=" - }, - "events": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/events/-/events-3.0.0.tgz", - "integrity": "sha512-Dc381HFWJzEOhQ+d8pkNon++bk9h6cdAoAj4iE6Q4y6xgTzySWXlKn05/TVNpjnfRqi/X0EpJEJohPjNI3zpVA==", - "dev": true - }, - "evp_bytestokey": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/evp_bytestokey/-/evp_bytestokey-1.0.3.tgz", - "integrity": "sha512-/f2Go4TognH/KvCISP7OUsHn85hT9nUkxxA9BEWxFn+Oj9o8ZNLm/40hdlgSLyuOimsrTKLUMEorQexp/aPQeA==", - "dev": true, - "requires": { - "md5.js": "^1.3.4", - "safe-buffer": "^5.1.1" - } - }, - "execa": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-1.0.0.tgz", - "integrity": "sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==", - "dev": true, - "requires": { - "cross-spawn": "^6.0.0", - "get-stream": "^4.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "expand-brackets": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", - "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", - "dev": true, - "requires": { - "debug": "^2.3.3", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "posix-character-classes": "^0.1.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "expand-tilde": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/expand-tilde/-/expand-tilde-2.0.2.tgz", - "integrity": "sha1-l+gBqgUt8CRU3kawK/YhZCzchQI=", - "dev": true, - "requires": { - "homedir-polyfill": "^1.0.1" - } - }, - "extend-shallow": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", - "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", - "dev": true, - "requires": { - "assign-symbols": "^1.0.0", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "extglob": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", - "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", - "dev": true, - "requires": { - "array-unique": "^0.3.2", - "define-property": "^1.0.0", - "expand-brackets": "^2.1.4", - "extend-shallow": "^2.0.1", - "fragment-cache": "^0.2.1", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "fast-deep-equal": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", - "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", - "dev": true - }, - "fast-json-stable-stringify": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", - "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", - "dev": true - }, - "fast-url-parser": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/fast-url-parser/-/fast-url-parser-1.1.3.tgz", - "integrity": "sha1-9K8+qfNNiicc9YrSs3WfQx8LMY0=", - "dev": true, - "requires": { - "punycode": "^1.3.2" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } - } - }, - "figgy-pudding": { - "version": "3.5.1", - "resolved": "https://registry.npmjs.org/figgy-pudding/-/figgy-pudding-3.5.1.tgz", - "integrity": "sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==", - "dev": true - }, - "fill-range": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", - "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-number": "^3.0.0", - "repeat-string": "^1.6.1", - "to-regex-range": "^2.1.0" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "find-cache-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-2.1.0.tgz", - "integrity": "sha512-Tq6PixE0w/VMFfCgbONnkiQIVol/JJL7nRMi20fqzA4NRs9AfeqMGeRdPi3wIhYkxjeBaWh2rxwapn5Tu3IqOQ==", - "dev": true, - "requires": { - "commondir": "^1.0.1", - "make-dir": "^2.0.0", - "pkg-dir": "^3.0.0" - } - }, - "find-up": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz", - "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==", - "dev": true, - "requires": { - "locate-path": "^3.0.0" - } - }, - "findup-sync": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/findup-sync/-/findup-sync-3.0.0.tgz", - "integrity": "sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==", - "dev": true, - "requires": { - "detect-file": "^1.0.0", - "is-glob": "^4.0.0", - "micromatch": "^3.0.4", - "resolve-dir": "^1.0.1" - } - }, - "flat": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/flat/-/flat-4.1.0.tgz", - "integrity": "sha512-Px/TiLIznH7gEDlPXcUD4KnBusa6kR6ayRUVcnEAbreRIuhkqow/mun59BuRXwoYk7ZQOLW1ZM05ilIvK38hFw==", - "dev": true, - "requires": { - "is-buffer": "~2.0.3" - } - }, - "flush-write-stream": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/flush-write-stream/-/flush-write-stream-1.1.1.tgz", - "integrity": "sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "readable-stream": "^2.3.6" - } - }, - "for-in": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", - "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", - "dev": true - }, - "fragment-cache": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", - "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", - "dev": true, - "requires": { - "map-cache": "^0.2.2" - } - }, - "from2": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/from2/-/from2-2.3.0.tgz", - "integrity": "sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "readable-stream": "^2.0.0" - } - }, - "fs-write-stream-atomic": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/fs-write-stream-atomic/-/fs-write-stream-atomic-1.0.10.tgz", - "integrity": "sha1-tH31NJPvkR33VzHnCp3tAYnbQMk=", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "iferr": "^0.1.5", - "imurmurhash": "^0.1.4", - "readable-stream": "1 || 2" - } - }, - "fs.realpath": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", - "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", - "dev": true - }, - "fsevents": { - "version": "1.2.9", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", - "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", - "dev": true, - "optional": true, - "requires": { - "nan": "^2.12.1", - "node-pre-gyp": "^0.12.0" - }, - "dependencies": { - "abbrev": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "ansi-regex": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "aproba": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - }, - "are-we-there-yet": { - "version": "1.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "delegates": "^1.0.0", - "readable-stream": "^2.0.6" - } - }, - "balanced-match": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "brace-expansion": { - "version": "1.1.11", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "balanced-match": "^1.0.0", - "concat-map": "0.0.1" - } - }, - "chownr": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "code-point-at": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "concat-map": { - "version": "0.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "console-control-strings": { - "version": "1.1.0", - "bundled": true, - "dev": true, - "optional": true - }, - "core-util-is": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "debug": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ms": "^2.1.1" - } - }, - "deep-extend": { - "version": "0.6.0", - "bundled": true, - "dev": true, - "optional": true - }, - "delegates": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "detect-libc": { - "version": "1.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "fs-minipass": { - "version": "1.2.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "fs.realpath": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "gauge": { - "version": "2.7.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "aproba": "^1.0.3", - "console-control-strings": "^1.0.0", - "has-unicode": "^2.0.0", - "object-assign": "^4.1.0", - "signal-exit": "^3.0.0", - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1", - "wide-align": "^1.1.0" - } - }, - "glob": { - "version": "7.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "has-unicode": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "iconv-lite": { - "version": "0.4.24", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safer-buffer": ">= 2.1.2 < 3" - } - }, - "ignore-walk": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimatch": "^3.0.4" - } - }, - "inflight": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.3", - "bundled": true, - "dev": true, - "optional": true - }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, - "is-fullwidth-code-point": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "isarray": { - "version": "1.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "minimatch": { - "version": "3.0.4", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "bundled": true, - "dev": true, - "optional": true - }, - "minipass": { - "version": "2.3.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "^5.1.2", - "yallist": "^3.0.0" - } - }, - "minizlib": { - "version": "1.2.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minipass": "^2.2.1" - } - }, - "mkdirp": { - "version": "0.5.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "minimist": "0.0.8" - } - }, - "ms": { - "version": "2.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "needle": { - "version": "2.3.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "debug": "^4.1.0", - "iconv-lite": "^0.4.4", - "sax": "^1.2.4" - } - }, - "node-pre-gyp": { - "version": "0.12.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "detect-libc": "^1.0.2", - "mkdirp": "^0.5.1", - "needle": "^2.2.1", - "nopt": "^4.0.1", - "npm-packlist": "^1.1.6", - "npmlog": "^4.0.2", - "rc": "^1.2.7", - "rimraf": "^2.6.1", - "semver": "^5.3.0", - "tar": "^4" - } - }, - "nopt": { - "version": "4.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "abbrev": "1", - "osenv": "^0.1.4" - } - }, - "npm-bundled": { - "version": "1.0.6", - "bundled": true, - "dev": true, - "optional": true - }, - "npm-packlist": { - "version": "1.4.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ignore-walk": "^3.0.1", - "npm-bundled": "^1.0.1" - } - }, - "npmlog": { - "version": "4.1.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "are-we-there-yet": "~1.1.2", - "console-control-strings": "~1.1.0", - "gauge": "~2.7.3", - "set-blocking": "~2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "object-assign": { - "version": "4.1.1", - "bundled": true, - "dev": true, - "optional": true - }, - "once": { - "version": "1.4.0", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "wrappy": "1" - } - }, - "os-homedir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "os-tmpdir": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "osenv": { - "version": "0.1.5", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.0" - } - }, - "path-is-absolute": { - "version": "1.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "process-nextick-args": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "rc": { - "version": "1.2.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "rimraf": { - "version": "2.6.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "glob": "^7.1.3" - } - }, - "safe-buffer": { - "version": "5.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "safer-buffer": { - "version": "2.1.2", - "bundled": true, - "dev": true, - "optional": true - }, - "sax": { - "version": "1.2.4", - "bundled": true, - "dev": true, - "optional": true - }, - "semver": { - "version": "5.7.0", - "bundled": true, - "dev": true, - "optional": true - }, - "set-blocking": { - "version": "2.0.0", - "bundled": true, - "dev": true, - "optional": true - }, - "signal-exit": { - "version": "3.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "string-width": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - }, - "string_decoder": { - "version": "1.1.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-json-comments": { - "version": "2.0.1", - "bundled": true, - "dev": true, - "optional": true - }, - "tar": { - "version": "4.4.8", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "chownr": "^1.1.1", - "fs-minipass": "^1.2.5", - "minipass": "^2.3.4", - "minizlib": "^1.1.1", - "mkdirp": "^0.5.0", - "safe-buffer": "^5.1.2", - "yallist": "^3.0.2" - } - }, - "util-deprecate": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "wide-align": { - "version": "1.1.3", - "bundled": true, - "dev": true, - "optional": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "wrappy": { - "version": "1.0.2", - "bundled": true, - "dev": true, - "optional": true - }, - "yallist": { - "version": "3.0.3", - "bundled": true, - "dev": true, - "optional": true - } - } - }, - "function-bind": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", - "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", - "dev": true - }, - "get-caller-file": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", - "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", - "dev": true - }, - "get-stream": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz", - "integrity": "sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==", - "dev": true, - "requires": { - "pump": "^3.0.0" - } - }, - "get-value": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", - "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", - "dev": true - }, - "glob": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", - "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", - "dev": true, - "requires": { - "fs.realpath": "^1.0.0", - "inflight": "^1.0.4", - "inherits": "2", - "minimatch": "^3.0.4", - "once": "^1.3.0", - "path-is-absolute": "^1.0.0" - } - }, - "glob-parent": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", - "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", - "dev": true, - "requires": { - "is-glob": "^3.1.0", - "path-dirname": "^1.0.0" - }, - "dependencies": { - "is-glob": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", - "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", - "dev": true, - "requires": { - "is-extglob": "^2.1.0" - } - } - } - }, - "global-modules": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-2.0.0.tgz", - "integrity": "sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==", - "dev": true, - "requires": { - "global-prefix": "^3.0.0" - }, - "dependencies": { - "global-prefix": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-3.0.0.tgz", - "integrity": "sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==", - "dev": true, - "requires": { - "ini": "^1.3.5", - "kind-of": "^6.0.2", - "which": "^1.3.1" - } - } - } - }, - "global-prefix": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/global-prefix/-/global-prefix-1.0.2.tgz", - "integrity": "sha1-2/dDxsFJklk8ZVVoy2btMsASLr4=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.2", - "homedir-polyfill": "^1.0.1", - "ini": "^1.3.4", - "is-windows": "^1.0.1", - "which": "^1.2.14" - } - }, - "globals": { - "version": "9.18.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-9.18.0.tgz", - "integrity": "sha512-S0nG3CLEQiY/ILxqtztTWH/3iRRdyBLw6KMDxnKMchrtbj2OFmehVh0WUCfW3DUrIgx/qFrJPICrq4Z4sTR9UQ==" - }, - "graceful-fs": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.1.tgz", - "integrity": "sha512-b9usnbDGnD928gJB3LrCmxoibr3VE4U2SMo5PBuBnokWyDADTqDPXg4YpwKF1trpH+UbGp7QLicO3+aWEy0+mw==", - "dev": true - }, - "growl": { - "version": "1.10.5", - "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", - "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", - "dev": true - }, - "has": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", - "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", - "dev": true, - "requires": { - "function-bind": "^1.1.1" - } - }, - "has-ansi": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/has-ansi/-/has-ansi-2.0.0.tgz", - "integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "has-flag": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", - "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", - "dev": true - }, - "has-symbols": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", - "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", - "dev": true - }, - "has-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", - "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", - "dev": true, - "requires": { - "get-value": "^2.0.6", - "has-values": "^1.0.0", - "isobject": "^3.0.0" - } - }, - "has-values": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", - "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "kind-of": "^4.0.0" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "kind-of": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", - "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "hash-base": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/hash-base/-/hash-base-3.0.4.tgz", - "integrity": "sha1-X8hoaEfs1zSZQDMZprCj8/auSRg=", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "hash.js": { - "version": "1.1.7", - "resolved": "https://registry.npmjs.org/hash.js/-/hash.js-1.1.7.tgz", - "integrity": "sha512-taOaskGt4z4SOANNseOviYDvjEJinIkRgmp7LbKP2YTTmVxWBl87s/uzK9r+44BclBSp2X7K1hqeNfz9JbBeXA==", - "dev": true, - "requires": { - "inherits": "^2.0.3", - "minimalistic-assert": "^1.0.1" - } - }, - "he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true - }, - "hmac-drbg": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/hmac-drbg/-/hmac-drbg-1.0.1.tgz", - "integrity": "sha1-0nRXAQJabHdabFRXk+1QL8DGSaE=", - "dev": true, - "requires": { - "hash.js": "^1.0.3", - "minimalistic-assert": "^1.0.0", - "minimalistic-crypto-utils": "^1.0.1" - } - }, - "home-or-tmp": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/home-or-tmp/-/home-or-tmp-2.0.0.tgz", - "integrity": "sha1-42w/LSyufXRqhX440Y1fMqeILbg=", - "requires": { - "os-homedir": "^1.0.0", - "os-tmpdir": "^1.0.1" - } - }, - "homedir-polyfill": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz", - "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", - "dev": true, - "requires": { - "parse-passwd": "^1.0.0" - } - }, - "https-browserify": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", - "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=", - "dev": true - }, - "ieee754": { - "version": "1.1.13", - "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz", - "integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==", - "dev": true - }, - "iferr": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/iferr/-/iferr-0.1.5.tgz", - "integrity": "sha1-xg7taebY/bazEEofy8ocGS3FtQE=", - "dev": true - }, - "import-local": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/import-local/-/import-local-2.0.0.tgz", - "integrity": "sha512-b6s04m3O+s3CGSbqDIyP4R6aAwAeYlVq9+WUWep6iHa8ETRf9yei1U48C5MmfJmV9AiLYYBKPMq/W+/WRpQmCQ==", - "dev": true, - "requires": { - "pkg-dir": "^3.0.0", - "resolve-cwd": "^2.0.0" - } - }, - "imurmurhash": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", - "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", - "dev": true - }, - "infer-owner": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/infer-owner/-/infer-owner-1.0.4.tgz", - "integrity": "sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==", - "dev": true - }, - "inflight": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", - "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", - "dev": true, - "requires": { - "once": "^1.3.0", - "wrappy": "1" - } - }, - "inherits": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", - "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true - }, - "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", - "dev": true - }, - "interpret": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/interpret/-/interpret-1.2.0.tgz", - "integrity": "sha512-mT34yGKMNceBQUoVn7iCDKDntA7SC6gycMAWzGx1z/CMCTV7b2AAtXlo3nRyHZ1FelRkQbQjprHSYGwzLtkVbw==", - "dev": true - }, - "invariant": { - "version": "2.2.4", - "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", - "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", - "requires": { - "loose-envify": "^1.0.0" - } - }, - "invert-kv": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/invert-kv/-/invert-kv-2.0.0.tgz", - "integrity": "sha512-wPVv/y/QQ/Uiirj/vh3oP+1Ww+AWehmi1g5fFWGPF6IpCBCDVrhgHRMvrLfdYcwDh3QJbGXDW4JAuzxElLSqKA==", - "dev": true - }, - "is-accessor-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", - "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-binary-path": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", - "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", - "dev": true, - "requires": { - "binary-extensions": "^1.0.0" - } - }, - "is-buffer": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", - "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==", - "dev": true - }, - "is-callable": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", - "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", - "dev": true - }, - "is-data-descriptor": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", - "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-date-object": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", - "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", - "dev": true - }, - "is-descriptor": { - "version": "0.1.6", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", - "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^0.1.6", - "is-data-descriptor": "^0.1.4", - "kind-of": "^5.0.0" - }, - "dependencies": { - "kind-of": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", - "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", - "dev": true - } - } - }, - "is-extendable": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", - "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", - "dev": true - }, - "is-extglob": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", - "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", - "dev": true - }, - "is-finite": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-finite/-/is-finite-1.0.2.tgz", - "integrity": "sha1-zGZ3aVYCvlUO8R6LSqYwU0K20Ko=", - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "is-fullwidth-code-point": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", - "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", - "dev": true - }, - "is-glob": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", - "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", - "dev": true, - "requires": { - "is-extglob": "^2.1.1" - } - }, - "is-number": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", - "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "is-plain-object": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", - "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "is-regex": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", - "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", - "dev": true, - "requires": { - "has": "^1.0.1" - } - }, - "is-stream": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", - "integrity": "sha1-EtSj3U5o4Lec6428hBc66A2RykQ=", - "dev": true - }, - "is-symbol": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", - "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", - "dev": true, - "requires": { - "has-symbols": "^1.0.0" - } - }, - "is-windows": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", - "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", - "dev": true - }, - "is-wsl": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-1.1.0.tgz", - "integrity": "sha1-HxbkqiKwTRM2tmGIpmrzxgDDpm0=", - "dev": true - }, - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, - "isexe": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", - "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", - "dev": true - }, - "isobject": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", - "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", - "dev": true - }, - "js-tokens": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-3.0.2.tgz", - "integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=" - }, - "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", - "dev": true, - "requires": { - "argparse": "^1.0.7", - "esprima": "^4.0.0" - } - }, - "jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=" - }, - "json-parse-better-errors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", - "integrity": "sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==", - "dev": true - }, - "json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true - }, - "json5": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-0.5.1.tgz", - "integrity": "sha1-Hq3nrMASA0rYTiOWdn6tn6VJWCE=" - }, - "kind-of": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", - "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", - "dev": true - }, - "kotlin": { - "version": "1.3.41", - "resolved": "https://registry.npmjs.org/kotlin/-/kotlin-1.3.41.tgz", - "integrity": "sha512-Lo3++B/8B/Eaht5mV5NFlwSDsRjAOh90haopf9YPP0YJcDWdFpQB9yyEucSfuqBSbioHCHx0+ZjQ4tVJ/mYhug==" - }, - "kotlin-test": { - "version": "1.3.41", - "resolved": "https://registry.npmjs.org/kotlin-test/-/kotlin-test-1.3.41.tgz", - "integrity": "sha512-6y5ANRWCXVXw9O14RXKandwr+PiZl3fGjm/07BfmXwTF5VrD5edJjA8tERUf612T35/dV8BAb6Yr/SJr8Q+X0g==", - "requires": { - "kotlin": "1.3.41" - } - }, - "kotlinx-coroutines-core": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/kotlinx-coroutines-core/-/kotlinx-coroutines-core-1.2.2.tgz", - "integrity": "sha512-03ZIn8jrqY98Ysz5K7JavRW+1KxDnw/P/eISH93SQBhioyKeT5sDxGNpoWcJeShJsY0SWymzbxOgQlKcnDJYWg==" - }, - "lcid": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/lcid/-/lcid-2.0.0.tgz", - "integrity": "sha512-avPEb8P8EGnwXKClwsNUgryVjllcRqtMYa49NTsbQagYuT1DcXnl1915oxWjoyGrXR6zH/Y0Zc96xWsPcoDKeA==", - "dev": true, - "requires": { - "invert-kv": "^2.0.0" - } - }, - "loader-runner": { - "version": "2.4.0", - "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-2.4.0.tgz", - "integrity": "sha512-Jsmr89RcXGIwivFY21FcRrisYZfvLMTWx5kOLc+JTxtpBOG6xML0vzbc6SEQG2FO9/4Fc3wW4LVcB5DmGflaRw==", - "dev": true - }, - "loader-utils": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.2.3.tgz", - "integrity": "sha512-fkpz8ejdnEMG3s37wGL07iSBDg99O9D5yflE9RGNH3hRdx9SOwYfnGYdZOUIZitN8E+E2vkq3MUMYMvPYl5ZZA==", - "dev": true, - "requires": { - "big.js": "^5.2.2", - "emojis-list": "^2.0.0", - "json5": "^1.0.1" - }, - "dependencies": { - "json5": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.1.tgz", - "integrity": "sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==", - "dev": true, - "requires": { - "minimist": "^1.2.0" - } - }, - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "locate-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", - "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==", - "dev": true, - "requires": { - "p-locate": "^3.0.0", - "path-exists": "^3.0.0" - } - }, - "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" - }, - "log-symbols": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-2.2.0.tgz", - "integrity": "sha512-VeIAFslyIerEJLXHziedo2basKbMKtTw3vfn5IzG0XTjhAVEJyNHnL2p7vc+wBDSdQuUpNw3M2u6xb9QsAY5Eg==", - "dev": true, - "requires": { - "chalk": "^2.0.1" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "lru-cache": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", - "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", - "dev": true, - "requires": { - "pseudomap": "^1.0.2", - "yallist": "^2.1.2" - } - }, - "make-dir": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", - "integrity": "sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==", - "dev": true, - "requires": { - "pify": "^4.0.1", - "semver": "^5.6.0" - } - }, - "mamacro": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/mamacro/-/mamacro-0.0.3.tgz", - "integrity": "sha512-qMEwh+UujcQ+kbz3T6V+wAmO2U8veoq2w+3wY8MquqwVA3jChfwY+Tk52GZKDfACEPjuZ7r2oJLejwpt8jtwTA==", - "dev": true - }, - "map-age-cleaner": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/map-age-cleaner/-/map-age-cleaner-0.1.3.tgz", - "integrity": "sha512-bJzx6nMoP6PDLPBFmg7+xRKeFZvFboMrGlxmNj9ClvX53KrmvM5bXFXEWjbz4cz1AFn+jWJ9z/DJSz7hrs0w3w==", - "dev": true, - "requires": { - "p-defer": "^1.0.0" - } - }, - "map-cache": { - "version": "0.2.2", - "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", - "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", - "dev": true - }, - "map-visit": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", - "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", - "dev": true, - "requires": { - "object-visit": "^1.0.0" - } - }, - "md5.js": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", - "integrity": "sha512-xitP+WxNPcTTOgnTJcrhM0xvdPepipPSf3I8EIpGKeFLjt3PlJLIDG3u8EX53ZIubkb+5U2+3rELYpEhHhzdkg==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "mem": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/mem/-/mem-4.3.0.tgz", - "integrity": "sha512-qX2bG48pTqYRVmDB37rn/6PT7LcR8T7oAX3bf99u1Tt1nzxYfxkgqDwUwolPlXweM0XzBOBFzSx4kfp7KP1s/w==", - "dev": true, - "requires": { - "map-age-cleaner": "^0.1.1", - "mimic-fn": "^2.0.0", - "p-is-promise": "^2.0.0" - } - }, - "memory-fs": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/memory-fs/-/memory-fs-0.4.1.tgz", - "integrity": "sha1-OpoguEYlI+RHz7x+i7gO1me/xVI=", - "dev": true, - "requires": { - "errno": "^0.1.3", - "readable-stream": "^2.0.1" - } - }, - "micromatch": { - "version": "3.1.10", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", - "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "braces": "^2.3.1", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "extglob": "^2.0.4", - "fragment-cache": "^0.2.1", - "kind-of": "^6.0.2", - "nanomatch": "^1.2.9", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.2" - } - }, - "miller-rabin": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/miller-rabin/-/miller-rabin-4.0.1.tgz", - "integrity": "sha512-115fLhvZVqWwHPbClyntxEVfVDfl9DLLTuJvq3g2O/Oxi8AiNouAHvDSzHS0viUJc+V5vm3eq91Xwqn9dp4jRA==", - "dev": true, - "requires": { - "bn.js": "^4.0.0", - "brorand": "^1.0.1" - } - }, - "mime-db": { - "version": "1.40.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz", - "integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==", - "dev": true - }, - "mime-types": { - "version": "2.1.24", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz", - "integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==", - "dev": true, - "requires": { - "mime-db": "1.40.0" - } - }, - "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", - "dev": true - }, - "minimalistic-assert": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz", - "integrity": "sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A==", - "dev": true - }, - "minimalistic-crypto-utils": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz", - "integrity": "sha1-9sAMHAsIIkblxNmd+4x8CDsrWCo=", - "dev": true - }, - "minimatch": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", - "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", - "requires": { - "brace-expansion": "^1.1.7" - } - }, - "minimist": { - "version": "0.0.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", - "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=" - }, - "mississippi": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/mississippi/-/mississippi-3.0.0.tgz", - "integrity": "sha512-x471SsVjUtBRtcvd4BzKE9kFC+/2TeWgKCgw0bZcw1b9l2X3QX5vCWgF+KaZaYm87Ss//rHnWryupDrgLvmSkA==", - "dev": true, - "requires": { - "concat-stream": "^1.5.0", - "duplexify": "^3.4.2", - "end-of-stream": "^1.1.0", - "flush-write-stream": "^1.0.0", - "from2": "^2.1.0", - "parallel-transform": "^1.1.0", - "pump": "^3.0.0", - "pumpify": "^1.3.3", - "stream-each": "^1.1.0", - "through2": "^2.0.0" - } - }, - "mixin-deep": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.2.tgz", - "integrity": "sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==", - "dev": true, - "requires": { - "for-in": "^1.0.2", - "is-extendable": "^1.0.1" - }, - "dependencies": { - "is-extendable": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", - "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", - "dev": true, - "requires": { - "is-plain-object": "^2.0.4" - } - } - } - }, - "mkdirp": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", - "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", - "requires": { - "minimist": "0.0.8" - } - }, - "mocha": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/mocha/-/mocha-6.2.0.tgz", - "integrity": "sha512-qwfFgY+7EKAAUAdv7VYMZQknI7YJSGesxHyhn6qD52DV8UcSZs5XwCifcZGMVIE4a5fbmhvbotxC0DLQ0oKohQ==", - "dev": true, - "requires": { - "ansi-colors": "3.2.3", - "browser-stdout": "1.3.1", - "debug": "3.2.6", - "diff": "3.5.0", - "escape-string-regexp": "1.0.5", - "find-up": "3.0.0", - "glob": "7.1.3", - "growl": "1.10.5", - "he": "1.2.0", - "js-yaml": "3.13.1", - "log-symbols": "2.2.0", - "minimatch": "3.0.4", - "mkdirp": "0.5.1", - "ms": "2.1.1", - "node-environment-flags": "1.0.5", - "object.assign": "4.1.0", - "strip-json-comments": "2.0.1", - "supports-color": "6.0.0", - "which": "1.3.1", - "wide-align": "1.1.3", - "yargs": "13.2.2", - "yargs-parser": "13.0.0", - "yargs-unparser": "1.5.0" - }, - "dependencies": { - "debug": { - "version": "3.2.6", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.6.tgz", - "integrity": "sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==", - "dev": true, - "requires": { - "ms": "^2.1.1" - } - }, - "ms": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.1.tgz", - "integrity": "sha512-tgp+dl5cGk28utYktBsrFqA7HKgrhgPsg6Z/EfhWI4gl1Hwq8B/GmY/0oXZ6nF8hDVesS/FpnYaD/kOWhYQvyg==", - "dev": true - }, - "supports-color": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.0.0.tgz", - "integrity": "sha512-on9Kwidc1IUQo+bQdhi8+Tijpo0e1SS6RoGo2guUwn5vdaxw8RXOF9Vb2ws+ihWOmh4JnCJOvaziZWP1VABaLg==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "move-concurrently": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/move-concurrently/-/move-concurrently-1.0.1.tgz", - "integrity": "sha1-viwAX9oy4LKa8fBdfEszIUxwH5I=", - "dev": true, - "requires": { - "aproba": "^1.1.1", - "copy-concurrently": "^1.0.0", - "fs-write-stream-atomic": "^1.0.8", - "mkdirp": "^0.5.1", - "rimraf": "^2.5.4", - "run-queue": "^1.0.3" - } - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", - "dev": true, - "optional": true - }, - "nanomatch": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", - "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", - "dev": true, - "requires": { - "arr-diff": "^4.0.0", - "array-unique": "^0.3.2", - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "fragment-cache": "^0.2.1", - "is-windows": "^1.0.2", - "kind-of": "^6.0.2", - "object.pick": "^1.3.0", - "regex-not": "^1.0.0", - "snapdragon": "^0.8.1", - "to-regex": "^3.0.1" - } - }, - "negotiator": { - "version": "0.6.2", - "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-0.6.2.tgz", - "integrity": "sha512-hZXc7K2e+PgeI1eDBe/10Ard4ekbfrrqG8Ep+8Jmf4JID2bNg7NvCPOZN+kfF574pFQI7mum2AUqDidoKqcTOw==", - "dev": true - }, - "neo-async": { - "version": "2.6.1", - "resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.1.tgz", - "integrity": "sha512-iyam8fBuCUpWeKPGpaNMetEocMt364qkCsfL9JuhjXX6dRnguRVOfk2GZaDpPjcOKiiXCPINZC1GczQ7iTq3Zw==", - "dev": true - }, - "nice-try": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", - "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", - "dev": true - }, - "node-environment-flags": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/node-environment-flags/-/node-environment-flags-1.0.5.tgz", - "integrity": "sha512-VNYPRfGfmZLx0Ye20jWzHUjyTW/c+6Wq+iLhDzUI4XmhrDd9l/FozXV3F2xOaXjvp0co0+v1YSR3CMP6g+VvLQ==", - "dev": true, - "requires": { - "object.getownpropertydescriptors": "^2.0.3", - "semver": "^5.7.0" - } - }, - "node-libs-browser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/node-libs-browser/-/node-libs-browser-2.2.1.tgz", - "integrity": "sha512-h/zcD8H9kaDZ9ALUWwlBUDo6TKF8a7qBSCSEGfjTVIYeqsioSKaAX+BN7NgiMGp6iSIXZ3PxgCu8KS3b71YK5Q==", - "dev": true, - "requires": { - "assert": "^1.1.1", - "browserify-zlib": "^0.2.0", - "buffer": "^4.3.0", - "console-browserify": "^1.1.0", - "constants-browserify": "^1.0.0", - "crypto-browserify": "^3.11.0", - "domain-browser": "^1.1.1", - "events": "^3.0.0", - "https-browserify": "^1.0.0", - "os-browserify": "^0.3.0", - "path-browserify": "0.0.1", - "process": "^0.11.10", - "punycode": "^1.2.4", - "querystring-es3": "^0.2.0", - "readable-stream": "^2.3.3", - "stream-browserify": "^2.0.1", - "stream-http": "^2.7.2", - "string_decoder": "^1.0.0", - "timers-browserify": "^2.0.4", - "tty-browserify": "0.0.0", - "url": "^0.11.0", - "util": "^0.11.0", - "vm-browserify": "^1.0.1" - }, - "dependencies": { - "punycode": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz", - "integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=", - "dev": true - } - } - }, - "normalize-path": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", - "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", - "dev": true - }, - "npm-run-path": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", - "integrity": "sha1-NakjLfo11wZ7TLLd8jV7GHFTbF8=", - "dev": true, - "requires": { - "path-key": "^2.0.0" - } - }, - "number-is-nan": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/number-is-nan/-/number-is-nan-1.0.1.tgz", - "integrity": "sha1-CXtgK1NCKlIsGvuHkDGDNpQaAR0=" - }, - "object-assign": { - "version": "4.1.1", - "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", - "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", - "dev": true - }, - "object-copy": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", - "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", - "dev": true, - "requires": { - "copy-descriptor": "^0.1.0", - "define-property": "^0.2.5", - "kind-of": "^3.0.3" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "object-keys": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", - "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", - "dev": true - }, - "object-visit": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", - "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", - "dev": true, - "requires": { - "isobject": "^3.0.0" - } - }, - "object.assign": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", - "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "function-bind": "^1.1.1", - "has-symbols": "^1.0.0", - "object-keys": "^1.0.11" - } - }, - "object.getownpropertydescriptors": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz", - "integrity": "sha1-h1jIRvW0B62rDyNuCYbxSwUcqhY=", - "dev": true, - "requires": { - "define-properties": "^1.1.2", - "es-abstract": "^1.5.1" - } - }, - "object.pick": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", - "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", - "dev": true, - "requires": { - "isobject": "^3.0.1" - } - }, - "on-headers": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", - "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", - "dev": true - }, - "once": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", - "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", - "dev": true, - "requires": { - "wrappy": "1" - } - }, - "os-browserify": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/os-browserify/-/os-browserify-0.3.0.tgz", - "integrity": "sha1-hUNzx/XCMVkU/Jv8a9gjj92h7Cc=", - "dev": true - }, - "os-homedir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-homedir/-/os-homedir-1.0.2.tgz", - "integrity": "sha1-/7xJiDNuDoM94MFox+8VISGqf7M=" - }, - "os-locale": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/os-locale/-/os-locale-3.1.0.tgz", - "integrity": "sha512-Z8l3R4wYWM40/52Z+S265okfFj8Kt2cC2MKY+xNi3kFs+XGI7WXu/I309QQQYbRW4ijiZ+yxs9pqEhJh0DqW3Q==", - "dev": true, - "requires": { - "execa": "^1.0.0", - "lcid": "^2.0.0", - "mem": "^4.0.0" - } - }, - "os-tmpdir": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", - "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=" - }, - "p-defer": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-defer/-/p-defer-1.0.0.tgz", - "integrity": "sha1-n26xgvbJqozXQwBKfU+WsZaw+ww=", - "dev": true - }, - "p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=", - "dev": true - }, - "p-is-promise": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/p-is-promise/-/p-is-promise-2.1.0.tgz", - "integrity": "sha512-Y3W0wlRPK8ZMRbNq97l4M5otioeA5lm1z7bkNkxCka8HSPjR0xRWmpCmc9utiaLP9Jb1eD8BgeIxTW4AIF45Pg==", - "dev": true - }, - "p-limit": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz", - "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==", - "dev": true, - "requires": { - "p-try": "^2.0.0" - } - }, - "p-locate": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz", - "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==", - "dev": true, - "requires": { - "p-limit": "^2.0.0" - } - }, - "p-try": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", - "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", - "dev": true - }, - "pako": { - "version": "1.0.10", - "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.10.tgz", - "integrity": "sha512-0DTvPVU3ed8+HNXOu5Bs+o//Mbdj9VNQMUOe9oKCwh8l0GNwpTDMKCWbRjgtD291AWnkAgkqA/LOnQS8AmS1tw==", - "dev": true - }, - "parallel-transform": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/parallel-transform/-/parallel-transform-1.1.0.tgz", - "integrity": "sha1-1BDwZbBdojCB/NEPKIVMKb2jOwY=", - "dev": true, - "requires": { - "cyclist": "~0.2.2", - "inherits": "^2.0.3", - "readable-stream": "^2.1.5" - } - }, - "parse-asn1": { - "version": "5.1.4", - "resolved": "https://registry.npmjs.org/parse-asn1/-/parse-asn1-5.1.4.tgz", - "integrity": "sha512-Qs5duJcuvNExRfFZ99HDD3z4mAi3r9Wl/FOjEOijlxwCZs7E7mW2vjTpgQ4J8LpTF8x5v+1Vn5UQFejmWT11aw==", - "dev": true, - "requires": { - "asn1.js": "^4.0.0", - "browserify-aes": "^1.0.0", - "create-hash": "^1.1.0", - "evp_bytestokey": "^1.0.0", - "pbkdf2": "^3.0.3", - "safe-buffer": "^5.1.1" - } - }, - "parse-passwd": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/parse-passwd/-/parse-passwd-1.0.0.tgz", - "integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=", - "dev": true - }, - "pascalcase": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", - "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", - "dev": true - }, - "path-browserify": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/path-browserify/-/path-browserify-0.0.1.tgz", - "integrity": "sha512-BapA40NHICOS+USX9SN4tyhq+A2RrN/Ws5F0Z5aMHDp98Fl86lX8Oti8B7uN93L4Ifv4fHOEA+pQw87gmMO/lQ==", - "dev": true - }, - "path-dirname": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", - "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", - "dev": true - }, - "path-exists": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", - "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", - "dev": true - }, - "path-is-absolute": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", - "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=" - }, - "path-is-inside": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", - "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", - "dev": true - }, - "path-key": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", - "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", - "dev": true - }, - "path-to-regexp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-2.2.1.tgz", - "integrity": "sha512-gu9bD6Ta5bwGrrU8muHzVOBFFREpp2iRkVfhBJahwJ6p6Xw20SjT0MxLnwkjOibQmGSYhiUnf2FLe7k+jcFmGQ==", - "dev": true - }, - "pbkdf2": { - "version": "3.0.17", - "resolved": "https://registry.npmjs.org/pbkdf2/-/pbkdf2-3.0.17.tgz", - "integrity": "sha512-U/il5MsrZp7mGg3mSQfn742na2T+1/vHDCG5/iTI3X9MKUuYUZVLQhyRsg06mCgDBTd57TxzgZt7P+fYfjRLtA==", - "dev": true, - "requires": { - "create-hash": "^1.1.2", - "create-hmac": "^1.1.4", - "ripemd160": "^2.0.1", - "safe-buffer": "^5.0.1", - "sha.js": "^2.4.8" - } - }, - "pify": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/pify/-/pify-4.0.1.tgz", - "integrity": "sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==", - "dev": true - }, - "pkg-dir": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-3.0.0.tgz", - "integrity": "sha512-/E57AYkoeQ25qkxMj5PBOVgF8Kiu/h7cYS30Z5+R7WaiCCBfLq58ZI/dSeaEKb9WVJV5n/03QwrN3IeWIFllvw==", - "dev": true, - "requires": { - "find-up": "^3.0.0" - } - }, - "posix-character-classes": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", - "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", - "dev": true - }, - "private": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", - "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==" - }, - "process": { - "version": "0.11.10", - "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", - "integrity": "sha1-czIwDoQBYb2j5podHZGn1LwW8YI=", - "dev": true - }, - "process-nextick-args": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true - }, - "promise-inflight": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", - "integrity": "sha1-mEcocL8igTL8vdhoEputEsPAKeM=", - "dev": true - }, - "prr": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz", - "integrity": "sha1-0/wRS6BplaRexok/SEzrHXj19HY=", - "dev": true - }, - "pseudomap": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", - "integrity": "sha1-8FKijacOYYkX7wqKw0wa5aaChrM=", - "dev": true - }, - "public-encrypt": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/public-encrypt/-/public-encrypt-4.0.3.tgz", - "integrity": "sha512-zVpa8oKZSz5bTMTFClc1fQOnyyEzpl5ozpi1B5YcvBrdohMjH2rfsBtyXcuNuwjsDIXmBYlF2N5FlJYhR29t8Q==", - "dev": true, - "requires": { - "bn.js": "^4.1.0", - "browserify-rsa": "^4.0.0", - "create-hash": "^1.1.0", - "parse-asn1": "^5.0.0", - "randombytes": "^2.0.1", - "safe-buffer": "^5.1.2" - } - }, - "pump": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", - "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - }, - "pumpify": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-1.5.1.tgz", - "integrity": "sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==", - "dev": true, - "requires": { - "duplexify": "^3.6.0", - "inherits": "^2.0.3", - "pump": "^2.0.0" - }, - "dependencies": { - "pump": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pump/-/pump-2.0.1.tgz", - "integrity": "sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "once": "^1.3.1" - } - } - } - }, - "punycode": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", - "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", - "dev": true - }, - "querystring": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/querystring/-/querystring-0.2.0.tgz", - "integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", - "dev": true - }, - "querystring-es3": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/querystring-es3/-/querystring-es3-0.2.1.tgz", - "integrity": "sha1-nsYfeQSYdXB9aUFFlv2Qek1xHnM=", - "dev": true - }, - "randombytes": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", - "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", - "dev": true, - "requires": { - "safe-buffer": "^5.1.0" - } - }, - "randomfill": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/randomfill/-/randomfill-1.0.4.tgz", - "integrity": "sha512-87lcbR8+MhcWcUiQ+9e+Rwx8MyR2P7qnt15ynUlbm3TU/fjbgz4GsvfSUDTemtCCtVCqb4ZcEFlyPNTh9bBTLw==", - "dev": true, - "requires": { - "randombytes": "^2.0.5", - "safe-buffer": "^5.1.0" - } - }, - "range-parser": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.0.tgz", - "integrity": "sha1-9JvmtIeJTdxA3MlKMi9hEJLgDV4=", - "dev": true - }, - "rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "dev": true, - "requires": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "dependencies": { - "minimist": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", - "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", - "dev": true - } - } - }, - "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "readdirp": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", - "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.11", - "micromatch": "^3.1.10", - "readable-stream": "^2.0.2" - } - }, - "regenerate": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", - "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==" - }, - "regenerator-runtime": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz", - "integrity": "sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==" - }, - "regenerator-transform": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.10.1.tgz", - "integrity": "sha512-PJepbvDbuK1xgIgnau7Y90cwaAmO/LCLMI2mPvaXq2heGMR3aWW5/BQvYrhJ8jgmQjXewXvBjzfqKcVOmhjZ6Q==", - "requires": { - "babel-runtime": "^6.18.0", - "babel-types": "^6.19.0", - "private": "^0.1.6" - } - }, - "regex-not": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", - "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.2", - "safe-regex": "^1.1.0" - } - }, - "regexpu-core": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-2.0.0.tgz", - "integrity": "sha1-SdA4g3uNz4v6W5pCE5k45uoq4kA=", - "requires": { - "regenerate": "^1.2.1", - "regjsgen": "^0.2.0", - "regjsparser": "^0.1.4" - } - }, - "registry-auth-token": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/registry-auth-token/-/registry-auth-token-3.3.2.tgz", - "integrity": "sha512-JL39c60XlzCVgNrO+qq68FoNb56w/m7JYvGR2jT5iR1xBrUA3Mfx5Twk5rqTThPmQKMWydGmq8oFtDlxfrmxnQ==", - "dev": true, - "requires": { - "rc": "^1.1.6", - "safe-buffer": "^5.0.1" - } - }, - "registry-url": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/registry-url/-/registry-url-3.1.0.tgz", - "integrity": "sha1-PU74cPc93h138M+aOBQyRE4XSUI=", - "dev": true, - "requires": { - "rc": "^1.0.1" - } - }, - "regjsgen": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.2.0.tgz", - "integrity": "sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc=" - }, - "regjsparser": { - "version": "0.1.5", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.1.5.tgz", - "integrity": "sha1-fuj4Tcb6eS0/0K4ijSS9lJ6tIFw=", - "requires": { - "jsesc": "~0.5.0" - } - }, - "remove-trailing-separator": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", - "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", - "dev": true - }, - "repeat-element": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", - "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", - "dev": true - }, - "repeat-string": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", - "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", - "dev": true - }, - "repeating": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/repeating/-/repeating-2.0.1.tgz", - "integrity": "sha1-UhTFOpJtNVJwdSf7q0FdvAjQbdo=", - "requires": { - "is-finite": "^1.0.0" - } - }, - "require-directory": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", - "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", - "dev": true - }, - "require-main-filename": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", - "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", - "dev": true - }, - "resolve-cwd": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-2.0.0.tgz", - "integrity": "sha1-AKn3OHVW4nA46uIyyqNypqWbZlo=", - "dev": true, - "requires": { - "resolve-from": "^3.0.0" - } - }, - "resolve-dir": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/resolve-dir/-/resolve-dir-1.0.1.tgz", - "integrity": "sha1-eaQGRMNivoLybv/nOcm7U4IEb0M=", - "dev": true, - "requires": { - "expand-tilde": "^2.0.0", - "global-modules": "^1.0.0" - }, - "dependencies": { - "global-modules": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/global-modules/-/global-modules-1.0.0.tgz", - "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==", - "dev": true, - "requires": { - "global-prefix": "^1.0.1", - "is-windows": "^1.0.1", - "resolve-dir": "^1.0.0" - } - } - } - }, - "resolve-from": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-3.0.0.tgz", - "integrity": "sha1-six699nWiBvItuZTM17rywoYh0g=", - "dev": true - }, - "resolve-url": { - "version": "0.2.1", - "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", - "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", - "dev": true - }, - "ret": { - "version": "0.1.15", - "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", - "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", - "dev": true - }, - "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - }, - "ripemd160": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/ripemd160/-/ripemd160-2.0.2.tgz", - "integrity": "sha512-ii4iagi25WusVoiC4B4lq7pbXfAp3D9v5CwfkY33vffw2+pkDjY1D8GaN7spsxvCSx8dkPqOZCEZyfxcmJG2IA==", - "dev": true, - "requires": { - "hash-base": "^3.0.0", - "inherits": "^2.0.1" - } - }, - "run-queue": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/run-queue/-/run-queue-1.0.3.tgz", - "integrity": "sha1-6Eg5bwV9Ij8kOGkkYY4laUFh7Ec=", - "dev": true, - "requires": { - "aproba": "^1.1.1" - } - }, - "safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" - }, - "safe-regex": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", - "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", - "dev": true, - "requires": { - "ret": "~0.1.10" - } - }, - "schema-utils": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-1.0.0.tgz", - "integrity": "sha512-i27Mic4KovM/lnGsy8whRCHhc7VicJajAjTrYg11K9zfZXnYIt4k5F+kZkwjnrhKzLic/HLU4j11mjsz2G/75g==", - "dev": true, - "requires": { - "ajv": "^6.1.0", - "ajv-errors": "^1.0.0", - "ajv-keywords": "^3.1.0" - } - }, - "semver": { - "version": "5.7.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", - "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==" - }, - "serialize-javascript": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-1.7.0.tgz", - "integrity": "sha512-ke8UG8ulpFOxO8f8gRYabHQe/ZntKlcig2Mp+8+URDP1D8vJZ0KUt7LYo07q25Z/+JVSgpr/cui9PIp5H6/+nA==", - "dev": true - }, - "serve": { - "version": "11.1.0", - "resolved": "https://registry.npmjs.org/serve/-/serve-11.1.0.tgz", - "integrity": "sha512-+4wpDtOSS+4ZLyDWMxThutA3iOTawX2+yDovOI8cjOUOmemyvNlHyFAsezBlSgbZKTYChI3tzA1Mh0z6XZ62qA==", - "dev": true, - "requires": { - "@zeit/schemas": "2.6.0", - "ajv": "6.5.3", - "arg": "2.0.0", - "boxen": "1.3.0", - "chalk": "2.4.1", - "clipboardy": "1.2.3", - "compression": "1.7.3", - "serve-handler": "6.1.0", - "update-check": "1.5.2" - }, - "dependencies": { - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.1.tgz", - "integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - } - }, - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "serve-handler": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/serve-handler/-/serve-handler-6.1.0.tgz", - "integrity": "sha512-63N075Tn3PsFYcu0NVV7tb367UbiW3gnC+/50ohL4oqOhAG6bmbaWqiRcXQgbzqc0ALBjSAzg7VTfa0Qw4E3hA==", - "dev": true, - "requires": { - "bytes": "3.0.0", - "content-disposition": "0.5.2", - "fast-url-parser": "1.1.3", - "mime-types": "2.1.18", - "minimatch": "3.0.4", - "path-is-inside": "1.0.2", - "path-to-regexp": "2.2.1", - "range-parser": "1.2.0" - }, - "dependencies": { - "mime-db": { - "version": "1.33.0", - "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.33.0.tgz", - "integrity": "sha512-BHJ/EKruNIqJf/QahvxwQZXKygOQ256myeN/Ew+THcAa5q+PjyTTMMeNQC4DZw5AwfvelsUrA6B67NKMqXDbzQ==", - "dev": true - }, - "mime-types": { - "version": "2.1.18", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.18.tgz", - "integrity": "sha512-lc/aahn+t4/SWV/qcmumYjymLsWfN3ELhpmVuUFjgsORruuZPVSwAQryq+HHGvO/SI2KVX26bx+En+zhM8g8hQ==", - "dev": true, - "requires": { - "mime-db": "~1.33.0" - } - } - } - }, - "set-blocking": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/set-blocking/-/set-blocking-2.0.0.tgz", - "integrity": "sha1-BF+XgtARrppoA93TgrJDkrPYkPc=", - "dev": true - }, - "set-value": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.1.tgz", - "integrity": "sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==", - "dev": true, - "requires": { - "extend-shallow": "^2.0.1", - "is-extendable": "^0.1.1", - "is-plain-object": "^2.0.3", - "split-string": "^3.0.1" - }, - "dependencies": { - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "setimmediate": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz", - "integrity": "sha1-KQy7Iy4waULX1+qbg3Mqt4VvgoU=", - "dev": true - }, - "sha.js": { - "version": "2.4.11", - "resolved": "https://registry.npmjs.org/sha.js/-/sha.js-2.4.11.tgz", - "integrity": "sha512-QMEp5B7cftE7APOjk5Y6xgrbWu+WkLVQwk8JNjZ8nKRciZaByEW6MubieAiToS7+dwvrjGhH8jRXz3MVd0AYqQ==", - "dev": true, - "requires": { - "inherits": "^2.0.1", - "safe-buffer": "^5.0.1" - } - }, - "shebang-command": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", - "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", - "dev": true, - "requires": { - "shebang-regex": "^1.0.0" - } - }, - "shebang-regex": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", - "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", - "dev": true - }, - "signal-exit": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", - "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", - "dev": true - }, - "slash": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=" - }, - "snapdragon": { - "version": "0.8.2", - "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", - "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", - "dev": true, - "requires": { - "base": "^0.11.1", - "debug": "^2.2.0", - "define-property": "^0.2.5", - "extend-shallow": "^2.0.1", - "map-cache": "^0.2.2", - "source-map": "^0.5.6", - "source-map-resolve": "^0.5.0", - "use": "^3.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - }, - "extend-shallow": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", - "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", - "dev": true, - "requires": { - "is-extendable": "^0.1.0" - } - } - } - }, - "snapdragon-node": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", - "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", - "dev": true, - "requires": { - "define-property": "^1.0.0", - "isobject": "^3.0.0", - "snapdragon-util": "^3.0.1" - }, - "dependencies": { - "define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", - "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", - "dev": true, - "requires": { - "is-descriptor": "^1.0.0" - } - }, - "is-accessor-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", - "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-data-descriptor": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", - "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", - "dev": true, - "requires": { - "kind-of": "^6.0.0" - } - }, - "is-descriptor": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", - "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", - "dev": true, - "requires": { - "is-accessor-descriptor": "^1.0.0", - "is-data-descriptor": "^1.0.0", - "kind-of": "^6.0.2" - } - } - } - }, - "snapdragon-util": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", - "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", - "dev": true, - "requires": { - "kind-of": "^3.2.0" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "source-list-map": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz", - "integrity": "sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw==", - "dev": true - }, - "source-map": { - "version": "0.5.7", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", - "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=" - }, - "source-map-resolve": { - "version": "0.5.2", - "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", - "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", - "dev": true, - "requires": { - "atob": "^2.1.1", - "decode-uri-component": "^0.2.0", - "resolve-url": "^0.2.1", - "source-map-url": "^0.4.0", - "urix": "^0.1.0" - } - }, - "source-map-support": { - "version": "0.4.18", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.4.18.tgz", - "integrity": "sha512-try0/JqxPLF9nOjvSta7tVondkP5dwgyLDjVoyMDlmjugT2lRZ1OfsrYTkCd2hkDnJTKRbO/Rl3orm8vlsUzbA==", - "requires": { - "source-map": "^0.5.6" - } - }, - "source-map-url": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", - "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", - "dev": true - }, - "split-string": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", - "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", - "dev": true, - "requires": { - "extend-shallow": "^3.0.0" - } - }, - "sprintf-js": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.2.tgz", - "integrity": "sha512-VE0SOVEHCk7Qc8ulkWw3ntAzXuqf7S2lvwQaDLRnUeIEaKNQJzV6BwmLKhOqT61aGhfUMrXeaBk+oDGCzvhcug==" - }, - "sql.js": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/sql.js/-/sql.js-0.5.0.tgz", - "integrity": "sha1-+IDeoYKAqEDkHfIgnclnQi36jYE=" - }, - "ssri": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ssri/-/ssri-6.0.1.tgz", - "integrity": "sha512-3Wge10hNcT1Kur4PDFwEieXSCMCJs/7WvSACcrMYrNp+b8kDL1/0wJch5Ni2WrtwEa2IO8OsVfeKIciKCDx/QA==", - "dev": true, - "requires": { - "figgy-pudding": "^3.5.1" - } - }, - "static-extend": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", - "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", - "dev": true, - "requires": { - "define-property": "^0.2.5", - "object-copy": "^0.1.0" - }, - "dependencies": { - "define-property": { - "version": "0.2.5", - "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", - "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", - "dev": true, - "requires": { - "is-descriptor": "^0.1.0" - } - } - } - }, - "stream-browserify": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/stream-browserify/-/stream-browserify-2.0.2.tgz", - "integrity": "sha512-nX6hmklHs/gr2FuxYDltq8fJA1GDlxKQCz8O/IM4atRqBH8OORmBNgfvW5gG10GT/qQ9u0CzIvr2X5Pkt6ntqg==", - "dev": true, - "requires": { - "inherits": "~2.0.1", - "readable-stream": "^2.0.2" - } - }, - "stream-each": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/stream-each/-/stream-each-1.2.3.tgz", - "integrity": "sha512-vlMC2f8I2u/bZGqkdfLQW/13Zihpej/7PmSiMQsbYddxuTsJp8vRe2x2FvVExZg7FaOds43ROAuFJwPR4MTZLw==", - "dev": true, - "requires": { - "end-of-stream": "^1.1.0", - "stream-shift": "^1.0.0" - } - }, - "stream-http": { - "version": "2.8.3", - "resolved": "https://registry.npmjs.org/stream-http/-/stream-http-2.8.3.tgz", - "integrity": "sha512-+TSkfINHDo4J+ZobQLWiMouQYB+UVYFttRA94FpEzzJ7ZdqcL4uUUQ7WkdkI4DSozGmgBUE/a47L+38PenXhUw==", - "dev": true, - "requires": { - "builtin-status-codes": "^3.0.0", - "inherits": "^2.0.1", - "readable-stream": "^2.3.6", - "to-arraybuffer": "^1.0.0", - "xtend": "^4.0.0" - } - }, - "stream-shift": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.0.tgz", - "integrity": "sha1-1cdSgl5TZ+eG944Y5EXqIjoVWVI=", - "dev": true - }, - "string-width": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", - "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", - "dev": true, - "requires": { - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^4.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", - "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", - "dev": true - }, - "strip-ansi": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", - "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", - "dev": true, - "requires": { - "ansi-regex": "^3.0.0" - } - } - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - }, - "strip-ansi": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-3.0.1.tgz", - "integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=", - "requires": { - "ansi-regex": "^2.0.0" - } - }, - "strip-eof": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", - "integrity": "sha1-u0P/VZim6wXYm1n80SnJgzE2Br8=", - "dev": true - }, - "strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", - "dev": true - }, - "supports-color": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-2.0.0.tgz", - "integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=" - }, - "tapable": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", - "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==", - "dev": true - }, - "term-size": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", - "integrity": "sha1-RYuDiH8oj8Vtb/+/rSYuJmOO+mk=", - "dev": true, - "requires": { - "execa": "^0.7.0" - }, - "dependencies": { - "cross-spawn": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", - "integrity": "sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk=", - "dev": true, - "requires": { - "lru-cache": "^4.0.1", - "shebang-command": "^1.2.0", - "which": "^1.2.9" - } - }, - "execa": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", - "integrity": "sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c=", - "dev": true, - "requires": { - "cross-spawn": "^5.0.1", - "get-stream": "^3.0.0", - "is-stream": "^1.1.0", - "npm-run-path": "^2.0.0", - "p-finally": "^1.0.0", - "signal-exit": "^3.0.0", - "strip-eof": "^1.0.0" - } - }, - "get-stream": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", - "integrity": "sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ=", - "dev": true - } - } - }, - "terser": { - "version": "4.1.4", - "resolved": "https://registry.npmjs.org/terser/-/terser-4.1.4.tgz", - "integrity": "sha512-+ZwXJvdSwbd60jG0Illav0F06GDJF0R4ydZ21Q3wGAFKoBGyJGo34F63vzJHgvYxc1ukOtIjvwEvl9MkjzM6Pg==", - "dev": true, - "requires": { - "commander": "^2.20.0", - "source-map": "~0.6.1", - "source-map-support": "~0.5.12" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "source-map-support": { - "version": "0.5.13", - "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.13.tgz", - "integrity": "sha512-SHSKFHadjVA5oR4PPqhtAVdcBWwRYVd6g6cAXnIbRiIwc2EhPrTuKUBdSLvlEKyIP3GCf89fltvcZiP9MMFA1w==", - "dev": true, - "requires": { - "buffer-from": "^1.0.0", - "source-map": "^0.6.0" - } - } - } - }, - "terser-webpack-plugin": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/terser-webpack-plugin/-/terser-webpack-plugin-1.4.1.tgz", - "integrity": "sha512-ZXmmfiwtCLfz8WKZyYUuuHf3dMYEjg8NrjHMb0JqHVHVOSkzp3cW2/XG1fP3tRhqEqSzMwzzRQGtAPbs4Cncxg==", - "dev": true, - "requires": { - "cacache": "^12.0.2", - "find-cache-dir": "^2.1.0", - "is-wsl": "^1.1.0", - "schema-utils": "^1.0.0", - "serialize-javascript": "^1.7.0", - "source-map": "^0.6.1", - "terser": "^4.1.2", - "webpack-sources": "^1.4.0", - "worker-farm": "^1.7.0" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "through2": { - "version": "2.0.5", - "resolved": "https://registry.npmjs.org/through2/-/through2-2.0.5.tgz", - "integrity": "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==", - "dev": true, - "requires": { - "readable-stream": "~2.3.6", - "xtend": "~4.0.1" - } - }, - "timers-browserify": { - "version": "2.0.11", - "resolved": "https://registry.npmjs.org/timers-browserify/-/timers-browserify-2.0.11.tgz", - "integrity": "sha512-60aV6sgJ5YEbzUdn9c8kYGIqOubPoUdqQCul3SBAsRCZ40s6Y5cMcrW4dt3/k/EsbLVJNl9n6Vz3fTc+k2GeKQ==", - "dev": true, - "requires": { - "setimmediate": "^1.0.4" - } - }, - "to-arraybuffer": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz", - "integrity": "sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M=", - "dev": true - }, - "to-fast-properties": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-1.0.3.tgz", - "integrity": "sha1-uDVx+k2MJbguIxsG46MFXeTKGkc=" - }, - "to-object-path": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", - "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", - "dev": true, - "requires": { - "kind-of": "^3.0.2" - }, - "dependencies": { - "is-buffer": { - "version": "1.1.6", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", - "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", - "dev": true - }, - "kind-of": { - "version": "3.2.2", - "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", - "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", - "dev": true, - "requires": { - "is-buffer": "^1.1.5" - } - } - } - }, - "to-regex": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", - "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", - "dev": true, - "requires": { - "define-property": "^2.0.2", - "extend-shallow": "^3.0.2", - "regex-not": "^1.0.2", - "safe-regex": "^1.1.0" - } - }, - "to-regex-range": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", - "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", - "dev": true, - "requires": { - "is-number": "^3.0.0", - "repeat-string": "^1.6.1" - } - }, - "trim-right": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=" - }, - "tslib": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.10.0.tgz", - "integrity": "sha512-qOebF53frne81cf0S9B41ByenJ3/IuH8yJKngAX35CmiZySA0khhkovshKK+jGCaMnVomla7gVlIcc3EvKPbTQ==", - "dev": true - }, - "tty-browserify": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/tty-browserify/-/tty-browserify-0.0.0.tgz", - "integrity": "sha1-oVe6QC2iTpv5V/mqadUk7tQpAaY=", - "dev": true - }, - "typedarray": { - "version": "0.0.6", - "resolved": "https://registry.npmjs.org/typedarray/-/typedarray-0.0.6.tgz", - "integrity": "sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=", - "dev": true - }, - "union-value": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.1.tgz", - "integrity": "sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==", - "dev": true, - "requires": { - "arr-union": "^3.1.0", - "get-value": "^2.0.6", - "is-extendable": "^0.1.1", - "set-value": "^2.0.1" - } - }, - "unique-filename": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/unique-filename/-/unique-filename-1.1.1.tgz", - "integrity": "sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==", - "dev": true, - "requires": { - "unique-slug": "^2.0.0" - } - }, - "unique-slug": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/unique-slug/-/unique-slug-2.0.2.tgz", - "integrity": "sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==", - "dev": true, - "requires": { - "imurmurhash": "^0.1.4" - } - }, - "unset-value": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", - "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", - "dev": true, - "requires": { - "has-value": "^0.3.1", - "isobject": "^3.0.0" - }, - "dependencies": { - "has-value": { - "version": "0.3.1", - "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", - "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", - "dev": true, - "requires": { - "get-value": "^2.0.3", - "has-values": "^0.1.4", - "isobject": "^2.0.0" - }, - "dependencies": { - "isobject": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", - "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", - "dev": true, - "requires": { - "isarray": "1.0.0" - } - } - } - }, - "has-values": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", - "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", - "dev": true - } - } - }, - "upath": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", - "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", - "dev": true - }, - "update-check": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/update-check/-/update-check-1.5.2.tgz", - "integrity": "sha512-1TrmYLuLj/5ZovwUS7fFd1jMH3NnFDN1y1A8dboedIDt7zs/zJMo6TwwlhYKkSeEwzleeiSBV5/3c9ufAQWDaQ==", - "dev": true, - "requires": { - "registry-auth-token": "3.3.2", - "registry-url": "3.1.0" - } - }, - "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", - "dev": true, - "requires": { - "punycode": "^2.1.0" - } - }, - "urix": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", - "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", - "dev": true - }, - "url": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/url/-/url-0.11.0.tgz", - "integrity": "sha1-ODjpfPxgUh63PFJajlW/3Z4uKPE=", - "dev": true, - "requires": { - "punycode": "1.3.2", - "querystring": "0.2.0" - }, - "dependencies": { - "punycode": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/punycode/-/punycode-1.3.2.tgz", - "integrity": "sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=", - "dev": true - } - } - }, - "use": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", - "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", - "dev": true - }, - "util": { - "version": "0.11.1", - "resolved": "https://registry.npmjs.org/util/-/util-0.11.1.tgz", - "integrity": "sha512-HShAsny+zS2TZfaXxD9tYj4HQGlBezXZMZuM/S5PKLLoZkShZiGk9o5CzukI1LVHZvjdvZ2Sj1aW/Ndn2NB/HQ==", - "dev": true, - "requires": { - "inherits": "2.0.3" - }, - "dependencies": { - "inherits": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", - "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", - "dev": true - } - } - }, - "util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", - "dev": true - }, - "v8-compile-cache": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.0.3.tgz", - "integrity": "sha512-CNmdbwQMBjwr9Gsmohvm0pbL954tJrNzf6gWL3K+QMQf00PF7ERGrEiLgjuU3mKreLC2MeGhUsNV9ybTbLgd3w==", - "dev": true - }, - "vary": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", - "integrity": "sha1-IpnwLG3tMNSllhsLn3RSShj2NPw=", - "dev": true - }, - "vm-browserify": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/vm-browserify/-/vm-browserify-1.1.0.tgz", - "integrity": "sha512-iq+S7vZJE60yejDYM0ek6zg308+UZsdtPExWP9VZoCFCz1zkJoXFnAX7aZfd/ZwrkidzdUZL0C/ryW+JwAiIGw==", - "dev": true - }, - "watchpack": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-1.6.0.tgz", - "integrity": "sha512-i6dHe3EyLjMmDlU1/bGQpEw25XSjkJULPuAVKCbNRefQVq48yXKUpwg538F7AZTf9kyr57zj++pQFltUa5H7yA==", - "dev": true, - "requires": { - "chokidar": "^2.0.2", - "graceful-fs": "^4.1.2", - "neo-async": "^2.5.0" - } - }, - "webpack": { - "version": "4.39.1", - "resolved": "https://registry.npmjs.org/webpack/-/webpack-4.39.1.tgz", - "integrity": "sha512-/LAb2TJ2z+eVwisldp3dqTEoNhzp/TLCZlmZm3GGGAlnfIWDgOEE758j/9atklNLfRyhKbZTCOIoPqLJXeBLbQ==", - "dev": true, - "requires": { - "@webassemblyjs/ast": "1.8.5", - "@webassemblyjs/helper-module-context": "1.8.5", - "@webassemblyjs/wasm-edit": "1.8.5", - "@webassemblyjs/wasm-parser": "1.8.5", - "acorn": "^6.2.1", - "ajv": "^6.10.2", - "ajv-keywords": "^3.4.1", - "chrome-trace-event": "^1.0.2", - "enhanced-resolve": "^4.1.0", - "eslint-scope": "^4.0.3", - "json-parse-better-errors": "^1.0.2", - "loader-runner": "^2.4.0", - "loader-utils": "^1.2.3", - "memory-fs": "^0.4.1", - "micromatch": "^3.1.10", - "mkdirp": "^0.5.1", - "neo-async": "^2.6.1", - "node-libs-browser": "^2.2.1", - "schema-utils": "^1.0.0", - "tapable": "^1.1.3", - "terser-webpack-plugin": "^1.4.1", - "watchpack": "^1.6.0", - "webpack-sources": "^1.4.1" - }, - "dependencies": { - "ajv": { - "version": "6.10.2", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", - "integrity": "sha512-TXtUUEYHuaTEbLZWIKUr5pmBuhDLy+8KYtPYdcV8qC+pOZL+NKqYwvWSRrVXHn+ZmRRAu8vJTAznH7Oag6RVRw==", - "dev": true, - "requires": { - "fast-deep-equal": "^2.0.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" - } - } - } - }, - "webpack-cli": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-3.3.6.tgz", - "integrity": "sha512-0vEa83M7kJtxK/jUhlpZ27WHIOndz5mghWL2O53kiDoA9DIxSKnfqB92LoqEn77cT4f3H2cZm1BMEat/6AZz3A==", - "dev": true, - "requires": { - "chalk": "2.4.2", - "cross-spawn": "6.0.5", - "enhanced-resolve": "4.1.0", - "findup-sync": "3.0.0", - "global-modules": "2.0.0", - "import-local": "2.0.0", - "interpret": "1.2.0", - "loader-utils": "1.2.3", - "supports-color": "6.1.0", - "v8-compile-cache": "2.0.3", - "yargs": "13.2.4" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "ansi-styles": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", - "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", - "dev": true, - "requires": { - "color-convert": "^1.9.0" - } - }, - "chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } - }, - "cliui": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz", - "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==", - "dev": true, - "requires": { - "string-width": "^3.1.0", - "strip-ansi": "^5.2.0", - "wrap-ansi": "^5.1.0" - } - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - }, - "supports-color": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", - "integrity": "sha512-qe1jfm1Mg7Nq/NSh6XE24gPXROEVsWHxC1LIx//XNlD9iw7YZQGjZNjYN7xGaEG6iKdA8EtNFW6R0gjnVXp+wQ==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - }, - "wrap-ansi": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz", - "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==", - "dev": true, - "requires": { - "ansi-styles": "^3.2.0", - "string-width": "^3.0.0", - "strip-ansi": "^5.0.0" - } - }, - "yargs": { - "version": "13.2.4", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.4.tgz", - "integrity": "sha512-HG/DWAJa1PAnHT9JAhNa8AbAv3FPaiLzioSjCcmuXXhP8MlpHO5vwls4g4j6n30Z74GVQj8Xa62dWVx1QCGklg==", - "dev": true, - "requires": { - "cliui": "^5.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "os-locale": "^3.1.0", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.1.0" - } - }, - "yargs-parser": { - "version": "13.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz", - "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - }, - "webpack-sources": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-1.4.3.tgz", - "integrity": "sha512-lgTS3Xhv1lCOKo7SA5TjKXMjpSM4sBjNV5+q2bqesbSPs5FjGmU6jjtBSkX9b4qW87vDIsCIlUPOEhbZrMdjeQ==", - "dev": true, - "requires": { - "source-list-map": "^2.0.0", - "source-map": "~0.6.1" - }, - "dependencies": { - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - } - } - }, - "which": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", - "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", - "dev": true, - "requires": { - "isexe": "^2.0.0" - } - }, - "which-module": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/which-module/-/which-module-2.0.0.tgz", - "integrity": "sha1-2e8H3Od7mQK4o6j6SzHD4/fm6Ho=", - "dev": true - }, - "wide-align": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", - "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", - "dev": true, - "requires": { - "string-width": "^1.0.2 || 2" - } - }, - "widest-line": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-2.0.1.tgz", - "integrity": "sha512-Ba5m9/Fa4Xt9eb2ELXt77JxVDV8w7qQrH0zS/TWSJdLyAwQjWoOzpzj5lwVftDz6n/EOu3tNACS84v509qwnJA==", - "dev": true, - "requires": { - "string-width": "^2.1.1" - } - }, - "worker-farm": { - "version": "1.7.0", - "resolved": "https://registry.npmjs.org/worker-farm/-/worker-farm-1.7.0.tgz", - "integrity": "sha512-rvw3QTZc8lAxyVrqcSGVm5yP/IJ2UcB3U0graE3LCFoZ0Yn2x4EoVSqJKdB/T5M+FLcRPjz4TDacRf3OCfNUzw==", - "dev": true, - "requires": { - "errno": "~0.1.7" - } - }, - "wrap-ansi": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-2.1.0.tgz", - "integrity": "sha1-2Pw9KE3QV5T+hJc8rs3Rz4JP3YU=", - "dev": true, - "requires": { - "string-width": "^1.0.1", - "strip-ansi": "^3.0.1" - }, - "dependencies": { - "is-fullwidth-code-point": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz", - "integrity": "sha1-754xOG8DGn8NZDr4L95QxFfvAMs=", - "dev": true, - "requires": { - "number-is-nan": "^1.0.0" - } - }, - "string-width": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-1.0.2.tgz", - "integrity": "sha1-EYvfW4zcUaKn5w0hHgfisLmxB9M=", - "dev": true, - "requires": { - "code-point-at": "^1.0.0", - "is-fullwidth-code-point": "^1.0.0", - "strip-ansi": "^3.0.0" - } - } - } - }, - "wrappy": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", - "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", - "dev": true - }, - "xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "dev": true - }, - "y18n": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz", - "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==", - "dev": true - }, - "yallist": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", - "integrity": "sha1-HBH5IY8HYImkfdUS+TxmmaaoHVI=", - "dev": true - }, - "yargs": { - "version": "13.2.2", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.2.2.tgz", - "integrity": "sha512-WyEoxgyTD3w5XRpAQNYUB9ycVH/PQrToaTXdYXRdOXvEy1l19br+VJsc0vcO8PTGg5ro/l/GY7F/JMEBmI0BxA==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "find-up": "^3.0.0", - "get-caller-file": "^2.0.1", - "os-locale": "^3.1.0", - "require-directory": "^2.1.1", - "require-main-filename": "^2.0.0", - "set-blocking": "^2.0.0", - "string-width": "^3.0.0", - "which-module": "^2.0.0", - "y18n": "^4.0.0", - "yargs-parser": "^13.0.0" - }, - "dependencies": { - "ansi-regex": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", - "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", - "dev": true - }, - "string-width": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", - "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", - "dev": true, - "requires": { - "emoji-regex": "^7.0.1", - "is-fullwidth-code-point": "^2.0.0", - "strip-ansi": "^5.1.0" - } - }, - "strip-ansi": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", - "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", - "dev": true, - "requires": { - "ansi-regex": "^4.1.0" - } - } - } - }, - "yargs-parser": { - "version": "13.0.0", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.0.0.tgz", - "integrity": "sha512-w2LXjoL8oRdRQN+hOyppuXs+V/fVAYtpcrRxZuF7Kt/Oc+Jr2uAcVntaUTNT6w5ihoWfFDpNY8CPx1QskxZ/pw==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - }, - "yargs-unparser": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-1.5.0.tgz", - "integrity": "sha512-HK25qidFTCVuj/D1VfNiEndpLIeJN78aqgR23nL3y4N0U/91cOAzqfHlF8n2BvoNDcZmJKin3ddNSvOxSr8flw==", - "dev": true, - "requires": { - "flat": "^4.1.0", - "lodash": "^4.17.11", - "yargs": "^12.0.5" - }, - "dependencies": { - "get-caller-file": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", - "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", - "dev": true - }, - "require-main-filename": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-1.0.1.tgz", - "integrity": "sha1-l/cXtp1IeE9fUmpsWqj/3aBVpNE=", - "dev": true - }, - "yargs": { - "version": "12.0.5", - "resolved": "https://registry.npmjs.org/yargs/-/yargs-12.0.5.tgz", - "integrity": "sha512-Lhz8TLaYnxq/2ObqHDql8dX8CJi97oHxrjUcYtzKbbykPtVW9WB+poxI+NM2UIzsMgNCZTIf0AQwsjK5yMAqZw==", - "dev": true, - "requires": { - "cliui": "^4.0.0", - "decamelize": "^1.2.0", - "find-up": "^3.0.0", - "get-caller-file": "^1.0.1", - "os-locale": "^3.0.0", - "require-directory": "^2.1.1", - "require-main-filename": "^1.0.1", - "set-blocking": "^2.0.0", - "string-width": "^2.0.0", - "which-module": "^2.0.0", - "y18n": "^3.2.1 || ^4.0.0", - "yargs-parser": "^11.1.1" - } - }, - "yargs-parser": { - "version": "11.1.1", - "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-11.1.1.tgz", - "integrity": "sha512-C6kB/WJDiaxONLJQnF8ccx9SEeoTTLek8RVbaOIsrAUS8VrBEXfmeSnCZxygc+XC2sNMBIwOOnfcxiynjHsVSQ==", - "dev": true, - "requires": { - "camelcase": "^5.0.0", - "decamelize": "^1.2.0" - } - } - } - } - } -} diff --git a/uhabits-web/package.json b/uhabits-web/package.json deleted file mode 100644 index 421742cd3..000000000 --- a/uhabits-web/package.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "loop-habit-tracker", - "version": "2.0.0", - "description": "App for creating and maintaining good habits", - "repository": { - "type": "git", - "url": "git@github.com:iSoron/uhabits.git" - }, - "main": "index.js", - "scripts": { - "compile": "webpack", - "test": "mocha" - }, - "keywords": [], - "author": "", - "license": "GPL-3.0-or-later", - "dependencies": { - "babel-core": "^6.26.3", - "babel-preset-env": "^1.7.0", - "babel-preset-react": "^6.24.1", - "kotlin": "^1.3.41", - "kotlin-test": "^1.3.41", - "kotlinx-coroutines-core": "^1.2.2", - "sprintf-js": "^1.1.2", - "sql.js": "^0.5.0" - }, - "devDependencies": { - "babel-loader": "^7.1.5", - "mocha": "^6.2.0", - "serve": "^11.1.0", - "webpack": "^4.39.1", - "webpack-cli": "^3.3.6" - } -} diff --git a/uhabits-web/src/main/index.js b/uhabits-web/src/main/index.js deleted file mode 100644 index a420803c0..000000000 --- a/uhabits-web/src/main/index.js +++ /dev/null @@ -1 +0,0 @@ -console.log('Hello World!'); diff --git a/uhabits-web/src/test/index.html b/uhabits-web/src/test/index.html deleted file mode 100644 index 5bfeb0601..000000000 --- a/uhabits-web/src/test/index.html +++ /dev/null @@ -1,51 +0,0 @@ - - - - Mocha Tests - - - - - - - - - -   -   -   - -
- - - - - diff --git a/uhabits-web/src/test/index.js b/uhabits-web/src/test/index.js deleted file mode 100644 index c9f32ca2f..000000000 --- a/uhabits-web/src/test/index.js +++ /dev/null @@ -1,3 +0,0 @@ -let assert = require('assert'); -let coreTest = require('uhabits-core-legacy_test'); -document.coreTest = coreTest;