diff --git a/opensrp-gizi/.gitignore b/opensrp-gizi/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/opensrp-gizi/.gitignore @@ -0,0 +1 @@ +/build diff --git a/opensrp-gizi/build.gradle b/opensrp-gizi/build.gradle new file mode 100644 index 0000000..3405233 --- /dev/null +++ b/opensrp-gizi/build.gradle @@ -0,0 +1,138 @@ +buildscript { + repositories { + jcenter() + } + dependencies { + classpath "com.android.tools.build:gradle:1.2.3" + classpath 'org.robolectric:robolectric-gradle-plugin:1.1.0' + classpath 'org.kt3k.gradle.plugin:coveralls-gradle-plugin:2.8.1' + } +} + +allprojects { + repositories { + maven { url 'https://oss.sonatype.org/content/repositories/snapshots/' } + mavenLocal() + } +} + +apply plugin: 'com.android.application' +apply plugin: 'jacoco' +apply plugin: 'com.github.kt3k.coveralls' + +android { + compileSdkVersion 23 + buildToolsVersion "26.0.1" + + defaultConfig { + applicationId "org.ei.opensrp.gizi" + minSdkVersion 18 + targetSdkVersion 21 + versionCode 1 + versionName "1.0" + multiDexEnabled true + buildConfigField "long", "MAX_SERVER_TIME_DIFFERENCE", "1800000l" + buildConfigField "boolean", "TIME_CHECK", "false" + resValue "string", 'opensrp_url', '"http://46.101.51.199:8181/opensrp"' + } + + dexOptions { + incremental true + javaMaxHeapSize "4g" + } + + lintOptions { + lintConfig file("lint.xml") + abortOnError false + } + + buildTypes { + release { + minifyEnabled false + zipAlignEnabled true + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + + debug { + testCoverageEnabled true + } + + } + packagingOptions { + exclude 'META-INF/DEPENDENCIES.txt' + exclude 'META-INF/LICENSE.txt' + exclude 'META-INF/NOTICE.txt' + exclude 'META-INF/NOTICE' + exclude 'META-INF/LICENSE' + exclude 'META-INF/DEPENDENCIES' + exclude 'META-INF/notice.txt' + exclude 'META-INF/license.txt' + exclude 'META-INF/dependencies.txt' + exclude 'META-INF/LGPL2.1' + exclude 'LICENSE.txt' + } + + testOptions { + unitTests.returnDefaultValues = true + } + + dexOptions { + incremental true + javaMaxHeapSize "4g" + } +} + +dependencies { + compile('org.smartregister:opensrp-client-core:1.0.0-SNAPSHOT@aar') { + transitive = true + exclude group: 'com.github.bmelnychuk', module: 'atv' + exclude group: 'com.google.guava', module: 'guava' + } + compile fileTree(dir: 'libs', include: ['*.jar']) + compile 'com.android.support:design:22.2.1' + + compile 'com.jjoe64:graphview:4.0.1' + compile 'com.google.code.gson:gson:2.8.2' + compile 'com.android.support:appcompat-v7:22.2.1' +// compile project(':json2view') + compile 'com.google.guava:guava:20.0' + + androidTestCompile 'junit:junit:4.12' + + testCompile 'junit:junit:4.12' + testCompile 'org.apache.maven:maven-ant-tasks:2.1.3' + testCompile('com.squareup:fest-android:1.0.8') { exclude module: 'support-v4' } + testCompile 'org.robolectric:robolectric:3.4.2' + testCompile "org.robolectric:shadows-multidex:3.4-rc2" + // PowerMock + def powerMockVersion = '1.7.3' + testCompile "org.powermock:powermock-module-junit4:$powerMockVersion" + testCompile "org.powermock:powermock-module-junit4-rule:$powerMockVersion" + testCompile "org.powermock:powermock-api-mockito2:$powerMockVersion" + testCompile("org.powermock:powermock-classloading-xstream:$powerMockVersion") +} + +task jacocoTestReport(type: JacocoReport, dependsOn: ['testDebug']) { + + reports { + xml.enabled = true + html.enabled = true + } + + getReports().getXml().setDestination(file("${buildDir}/reports/jacoco/jacocoRootReport/merged.xml")) + getReports().getHtml().setDestination(file("${buildDir}/reports/jacoco/jacocoRootReport/html")) + + def fileFilter = ['**/R.class', '**/R$*.class', '**/BuildConfig.*', '**/Manifest*.*', '**/*Test*.*', 'android/**/*.*', '**/*$ViewBinder*.*'] + def debugTree = fileTree(dir: "$project.buildDir/intermediates/classes/debug", excludes: fileFilter) + def mainSrc = "$project.projectDir/src/main/java" + + sourceDirectories = files([mainSrc]) + classDirectories = files([debugTree]) + executionData = fileTree(dir: project.buildDir, includes: [ + 'jacoco/testDebug.exec', 'outputs/code-coverage/connected/*coverage.ec' + ]) +} + +coveralls { + jacocoReportPath = "${buildDir}/reports/jacoco/jacocoRootReport/merged.xml" +} diff --git a/opensrp-gizi/libs/FlurryAnalytics-6.0.0.jar b/opensrp-gizi/libs/FlurryAnalytics-6.0.0.jar new file mode 100644 index 0000000..b53d8a5 Binary files /dev/null and b/opensrp-gizi/libs/FlurryAnalytics-6.0.0.jar differ diff --git a/opensrp-gizi/libs/sd-sdk-facial-processing.jar b/opensrp-gizi/libs/sd-sdk-facial-processing.jar new file mode 100755 index 0000000..bf93c53 Binary files /dev/null and b/opensrp-gizi/libs/sd-sdk-facial-processing.jar differ diff --git a/opensrp-gizi/proguard-rules.pro b/opensrp-gizi/proguard-rules.pro new file mode 100644 index 0000000..7c577a1 --- /dev/null +++ b/opensrp-gizi/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /home/soran/Documents/android-sdk-linux/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/opensrp-gizi/src/androidTest/java/org/ei/opensrp/gizi/ApplicationTest.java b/opensrp-gizi/src/androidTest/java/org/ei/opensrp/gizi/ApplicationTest.java new file mode 100644 index 0000000..2f96876 --- /dev/null +++ b/opensrp-gizi/src/androidTest/java/org/ei/opensrp/gizi/ApplicationTest.java @@ -0,0 +1,13 @@ +package org.ei.opensrp.gizi; + +import android.app.Application; +import android.test.ApplicationTestCase; + +/** + * Testing Fundamentals + */ +public class ApplicationTest extends ApplicationTestCase { + public ApplicationTest() { + super(Application.class); + } +} \ No newline at end of file diff --git a/opensrp-gizi/src/main/AndroidManifest.xml b/opensrp-gizi/src/main/AndroidManifest.xml new file mode 100644 index 0000000..78f2bd8 --- /dev/null +++ b/opensrp-gizi/src/main/AndroidManifest.xml @@ -0,0 +1,70 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/app.properties b/opensrp-gizi/src/main/assets/app.properties new file mode 100644 index 0000000..9f60ea5 --- /dev/null +++ b/opensrp-gizi/src/main/assets/app.properties @@ -0,0 +1,4 @@ +DRISHTI_BASE_URL=http://46.101.51.199:8080/oweb +PORT=8080 +SHOULD_VERIFY_CERTIFICATE=false +SYNC_DOWNLOAD_BATCH_SIZE=100 \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/bindtypes.json b/opensrp-gizi/src/main/assets/bindtypes.json new file mode 100644 index 0000000..6cae093 --- /dev/null +++ b/opensrp-gizi/src/main/assets/bindtypes.json @@ -0,0 +1,28 @@ +{ + "bindobjects": [ + { + "name": "bidan", + "columns": [ + {"name":"bidanId"} + ] + }, + { + "name": "kartu_ibu", + "columns": [ + {"name":"namalengkap"},{"name":"isOutOfArea"},{"name":"umur"},{"name":"namaSuami"},{"name":"noIbu"},{"name":"htp"} + ] + }, + { + "name": "ibu", + "columns": [ + {"name":"kartuIbuId"},{"name":"type"},{"name":"ancDate"},{"name":"ancKe"},{"name":"hariKeKF"} + ] + }, + { + "name": "anak", + "columns": [ + {"name":"ibuCaseId"},{"name":"namaBayi"},{"name":"tanggalLahirAnak"} + ] + } + ] +} \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/ec_client_alerts.json b/opensrp-gizi/src/main/assets/ec_client_alerts.json new file mode 100644 index 0000000..f9ebb97 --- /dev/null +++ b/opensrp-gizi/src/main/assets/ec_client_alerts.json @@ -0,0 +1,34 @@ +{ + "name": "alerts", + "columns": [{ + "column_name": "caseID", + "json_mapping": { + "field": "baseEntityId" + } + }, { + "column_name": "scheduleName", + "json_mapping": { + "field": "data.scheduleName" + } + }, { + "column_name": "visitCode", + "json_mapping": { + "field": "data.visitCode" + } + }, { + "column_name": "status", + "json_mapping": { + "field": "data.alertStatus" + } + }, { + "column_name": "startDate", + "json_mapping": { + "field": "data.startDate" + } + }, { + "column_name": "expiryDate", + "json_mapping": { + "field": "data.expiryDate" + } + }] +} \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/ec_client_classification.json b/opensrp-gizi/src/main/assets/ec_client_classification.json new file mode 100644 index 0000000..6bf3ff5 --- /dev/null +++ b/opensrp-gizi/src/main/assets/ec_client_classification.json @@ -0,0 +1,109 @@ +{ + "case_classification_rules": [ + { + "comment": "KARTU IBU: This rule checks whether a given case belongs to Household register", + "rule": { + "type": "event", + "fields": [ + { + "field":"eventType", + "field_value": "Registrasi Vaksinator", + "creates_case":["ec_kartu_ibu"] + }, + { + "field":"eventType", + "field_value": "Registrasi Gizi", + "creates_case":["ec_kartu_ibu"] + }, + { + "field":"eventType", + "field_value": "Identitas Ibu", + "creates_case":["ec_kartu_ibu"] + }, + { + "field":"eventType", + "field_value": "Tambah KB", + "creates_case":["ec_kartu_ibu"] + }, + { + "field":"eventType", + "field_value": "Penutupan Ibu", + "closes_case":["ec_kartu_ibu","ec_ibu","ec_pnc"] + } + ] + } + }, + { + "comment": "ANC: This rule checks whether a given case belongs to ANC register", + "rule": { + "type": "event", + "fields": [ + { + "field":"obs.fieldCode", + "concept": "45AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", + "values": ["703AAAAAAAAAAAAAAAAAAAAAAAAAAAAA"], + "creates_case":["ec_ibu"] + }, + { + "field":"eventType", + "field_value": "Kunjungan ANC", + "creates_case":["ec_ibu"] + }, + { + "field":"eventType", + "field_value": "Penutupan ANC", + "closes_case":["ec_ibu"] + } + ] + } + }, + { + "comment": "ANC: This rule checks whether a given case belongs to PNC register", + "rule": { + "type": "event", + "fields": [ + { + "field":"obs.fieldCode", + "concept": "160085AAAAAAAAAAAAAAAAAAAAAAAAAA", + "values": ["160429AAAAAAAAAAAAAAAAAAAAAAAAAA"], + "creates_case":["ec_ibu"] + }, + { + "field":"eventType", + "field_value": "Kunjungan PNC", + "creates_case":["ec_ibu"] + }, + { + "field":"eventType", + "field_value": "Penutupan PNC", + "closes_case":["ec_ibu"] + } + ] + } + }, + { + "comment": "Anak: This rule checks whether a given case belongs to Child register", + "rule": { + "type": "event", + "fields": [ + { + "field":"obs.fieldCode", + "concept": "159917AAAAAAAAAAAAAAAAAAAAAAAAAA", + "values": ["151849AAAAAAAAAAAAAAAAAAAAAAAAAA"], + "creates_case":["ec_anak"] + }, + { + "field":"eventType", + "field_value": "Child Registration", + "creates_case":["ec_anak"] + }, + { + "field":"eventType", + "field_value": "Penutupan Anak", + "closes_case":["ec_anak"] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/ec_client_fields.json b/opensrp-gizi/src/main/assets/ec_client_fields.json new file mode 100644 index 0000000..703e027 --- /dev/null +++ b/opensrp-gizi/src/main/assets/ec_client_fields.json @@ -0,0 +1,202 @@ +{ + "bindobjects": [ + { + "name": "ec_kartu_ibu", + "columns": [ + { + "column_name": "base_entity_id", + "type": "Client", + "json_mapping": { + "field": "baseEntityId" + } + }, + { + "column_name": "namalengkap", + "type": "Client", + "json_mapping": { + "field": "firstName" + } + }, + { + "column_name": "noIbu", + "type": "Client", + "json_mapping": { + "field": "attributes.NoIbu" + } + }, + { + "column_name": "unique_id", + "type": "Client", + "json_mapping": { + "field": "attributes.UniqueId" + } + }, + { + "column_name": "namaSuami", + "type": "Client", + "json_mapping": { + "field": "lastName" + } + }, + { + "column_name": "tanggalLahir", + "type": "Client", + "json_mapping": { + "field": "birthdate" + } + }, + { + "column_name": "isOutOfArea", + "type": "Client", + "json_mapping": { + "field": "isOutOfArea", + "comment": "doesn't have concept mapping" + } + }, + { + "column_name": "htp", + "type": "Event", + "json_mapping": { + "field": "obs.fieldCode", + "concept": "5596AAAAAAAAAAAAAAAAAAAAAAAAAAAA" + } + }, + { + "column_name": "jenisKontrasepsi", + "type": "Event", + "json_mapping": { + "field": "obs.fieldCode", + "concept": "374AAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + } + }, + { + "column_name": "umur", + "type": "Event", + "json_mapping": { + "field": "obs.fieldCode", + "concept": "1532AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + } + } + ] + }, + { + "name": "ec_ibu", + "columns": [ + { + "column_name": "base_entity_id", + "type": "Client", + "json_mapping": { + "field": "baseEntityId" + } + }, + { + "column_name": "kartuIbuId", + "type": "Client", + "json_mapping": { + "field": "kartuIbuId", + "comment": "doesn't have concept mapping" + } + }, + { + "column_name": "tanggalHPHT", + "type": "Event", + "json_mapping": { + "field": "obs.fieldCode", + "concept": "1427AAAAAAAAAAAAAAAAAAAAAAAAAAAA" + } + }, + + { + "column_name": "referenceDate", + "type": "Event", + "json_mapping": { + "field": "obs.fieldCode", + "concept": "160753AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + } + }, + { + "column_name": "pptest", + "type": "Event", + "json_mapping": { + "field": "obs.fieldCode", + "concept": "45AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + } + }, + { + "column_name": "ancDate", + "type": "Event", + "json_mapping": { + "field": "obs.fieldCode", + "concept": "160753AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + } + }, + { + "column_name": "ancKe", + "type": "Event", + "json_mapping": { + "field": "obs.fieldCode", + "concept": "1425AAAAAAAAAAAAAAAAAAAAAAAAAAAA" + } + }, + + { + "column_name": "type", + "type": "Event", + "json_mapping": { + "field": "type", + "comment": "doesn't have concept mapping" + } + } + ] + }, + { + "name": "ec_anak", + "columns": [ + { + "column_name": "base_entity_id", + "type": "Client", + "json_mapping": { + "field": "baseEntityId" + } + }, + { + "column_name": "relational_id", + "type": "Client", + "json_mapping": { + "field": "relationships.ibuCaseId" + } + }, + { + "column_name": "noBayi", + "type": "Client", + "json_mapping": { + "field": "attributes.noBayi" + } + }, + { + "column_name": "beratLahir", + "type": "Event", + "json_mapping": { + "field": "obs.fieldCode", + "concept": "5916AAAAAAAAAAAAAAAAAAAAAAAAAAAA" + } + }, + { + "column_name": "namaBayi", + "type": "Event", + "json_mapping": { + "field": "obs.fieldCode", + "concept": "1586AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" + } + }, + { + "column_name": "tanggalLahirAnak", + "type": "Client", + "json_mapping": { + "field": "birthdate" + } + } + ] + } + ] +} \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/ec_client_relationships.json b/opensrp-gizi/src/main/assets/ec_client_relationships.json new file mode 100644 index 0000000..a50c972 --- /dev/null +++ b/opensrp-gizi/src/main/assets/ec_client_relationships.json @@ -0,0 +1,12 @@ +[ + { + "client_relationship": "kartuIbuId", + "field": "kartuIbuId", + "comment": "this field is the name as it appears in the field_definition.json file" + }, + { + "client_relationship": "ibuCaseId", + "field": "ibu_entity_id", + "comment": "this field is the name as it appears in the field_definition.json file" + } +] diff --git a/opensrp-gizi/src/main/assets/sync_filters.json b/opensrp-gizi/src/main/assets/sync_filters.json new file mode 100644 index 0000000..c7dddcd --- /dev/null +++ b/opensrp-gizi/src/main/assets/sync_filters.json @@ -0,0 +1,8 @@ +{ + "_id": "_design/cloudantFilter", + "filters": { + "locationId": "function(doc, req){ if(doc.type == \"Client\"){ return true; } if ( doc.locationId != req.query.locationId ){ return false; } return true; }", + "providerId": "function(doc, req){ if(doc.type == \"Client\"){ return true; } if ( doc.providerId == req.query.providerId ){ return true; } return false; }", + "team": "function(doc, req){ if(doc.type == \"Client\"){ return true; } if(req.query.team){ if(req.query.team.split(',').indexOf(doc.providerId) >= 0){ return true; } } return false; }" + } +} \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/close_form/form.json b/opensrp-gizi/src/main/assets/www/form/close_form/form.json new file mode 100644 index 0000000..8a3705f --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/close_form/form.json @@ -0,0 +1 @@ +{"name":"penutupan_anak_mapped","title":"Penutupan Anak","sms_keyword":"penutupan_anak_1_1","default_language":"Bahasa","instance":{"encounter_type":"Penutupan Anak"},"version":"201704100243","id_string":"penutupan_anak_1_1","type":"survey","children":[{"instance":{"openmrs_entity_id":"encounter_start","openmrs_entity":"encounter"},"type":"start","name":"start"},{"instance":{"openmrs_entity_id":"encounter_date","openmrs_entity":"encounter"},"type":"today","name":"today"},{"type":"deviceid","name":"deviceid"},{"type":"simserial","name":"simserial"},{"type":"phonenumber","name":"phonenumber"},{"type":"hidden","name":"Province","hint":{"Bahasa":"Inject from app"}},{"type":"hidden","name":"District","hint":{"Bahasa":"Inject from app"}},{"type":"hidden","name":"Sub-district","hint":{"Bahasa":"Inject from app"}},{"type":"hidden","name":"Village","hint":{"Bahasa":"Inject from app"}},{"type":"hidden","name":"Sub-village"},{"type":"note","name":"generated_note_name_13","label":{"Bahasa":"Desa : ${Village}","English":"Village : ${Village}"}},{"type":"note","name":"generated_note_name_14","label":{"Bahasa":"Dusun : ${Sub-village}","English":"Sub Village : ${Sub-village}"}},{"instance":{"openmrs_entity_id":"birthdate","openmrs_entity":"person"},"type":"hidden","name":"tanggal_lahir","hint":{"English":"inject from app"}},{"instance":{"openmrs_entity_id":"1586AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"Concept"},"type":"hidden","name":"nama_bayi","hint":{"English":"inject from app"}},{"type":"note","name":"generated_note_name_18","label":{"Bahasa":"Nama Bayi : ${nama_bayi}"}},{"type":"note","name":"generated_note_name_19","label":{"Bahasa":"Tanggal Lahir : ${tanggal_lahir}"}},{"name":"close_reason","hint":{"Bahasa":"Pilihlah salah satu alasan yang tersedia","English":"Select one of reasons available"},"bind":{"required":"yes"},"label":{"Bahasa":"Alasan penutupan","English":"Reason for closure?"},"instance":{"openmrs_entity_id":"160417AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"Concept"},"type":"select one","children":[{"instance":{"openmrs_code":"163496AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"child_over5","label":{"Bahasa":"Umur anak >5 tahun","English":"Child's age > 5 years"}},{"instance":{"openmrs_code":"160415AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"permanent_relocation","label":{"Bahasa":"Relokasi (permanen)","English":"Relocation (permanent)"}},{"instance":{"openmrs_code":"162076AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"death_of_child","label":{"Bahasa":"Anak meninggal","English":"Child's death"}},{"instance":{"openmrs_code":"163133AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"wrong_entry","label":{"Bahasa":"Kesalahan entry","English":"Data Entry Error"}},{"instance":{"openmrs_code":"5622AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"others","label":{"Bahasa":"Lainnya","English":"Other"}}]},{"name":"close_reason_other","hint":{"Bahasa":"Sebutkan alasan lainnya jika ada","English":"Write other reason, if available"},"bind":{"relevant":"${close_reason} = 'others'"},"label":{"Bahasa":"Lainnya","English":"Other"},"instance":{"openmrs_entity_parent":"Close_Reason - 160417AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity_id":"160632AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"text"},{"control":{"appearance":"minimal"},"name":"child_death_cause","bind":{"relevant":"${close_reason} = 'death_of_child'"},"label":{"Bahasa":"Penyebab kematian anak","English":"Cause of child's death"},"instance":{"openmrs_entity_id":"159482AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"Concept"},"type":"select one","children":[{"instance":{"openmrs_code":"226AAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"sepsis","label":{"Bahasa":"Sepsis","English":"Sepsis"}},{"instance":{"openmrs_code":"121397AAAAAAAAAA\nAAAAAAAAAAAAAAAA"},"name":"asphyxia","label":{"Bahasa":"Asfiksia","English":"Asphyxia"}},{"instance":{"openmrs_code":"116222AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"lbw","label":{"Bahasa":"berat lahir kurang (< 2.5 kg)","English":"Low birthweight (< 2.5 kg)"}},{"instance":{"openmrs_code":"114100AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"pneumonia","label":{"Bahasa":"Pneumonia","English":"Pneumonia"}},{"instance":{"openmrs_code":"142412AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"diarrhea","label":{"Bahasa":"Diare","English":"Diarrhea"}},{"instance":{"openmrs_code":"134561AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"measles","label":{"Bahasa":"Campak","English":"Measles"}},{"instance":{"openmrs_code":"115122AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"malnutrition","label":{"Bahasa":"Malnutrisi","English":"Malnutrition"}},{"instance":{"openmrs_code":"154983AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"Infeksi_pernafasan_akut","label":{"Bahasa":"Infeksi pernafasan akut","English":"Acute respiratory infection"}},{"instance":{"openmrs_code":"123565AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"infeksi_pernapasan_atas","label":{"Bahasa":"Infeksi Saluran Pernapasan Atas","English":"Upper Respiratory Infection"}},{"instance":{"openmrs_code":"116128AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"malaria","label":{"Bahasa":"Malaria","English":"Malaria"}},{"instance":{"openmrs_code":"124954AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"tetanus_neonatorum","label":{"Bahasa":"Tetanus Neonatorum","English":"Neonatal Tetanus"}},{"instance":{"openmrs_code":"115368AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"ikterus","label":{"Bahasa":"Ikterus","English":"Jaundice"}},{"instance":{"openmrs_code":"142591AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"demam_berdarah","label":{"Bahasa":"Demam Berdarah","English":"Dengue Fever"}},{"instance":{"openmrs_code":"119975AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"congenital_abnormality","label":{"Bahasa":"Kelainan Kongenital","English":"Congenital Abnormality"}},{"instance":{"openmrs_code":"119242AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"kelainan_saluran_cerna","label":{"Bahasa":"Kelainan Saluran Cerna","English":"Gastrointestinal Abnormality"}},{"instance":{"openmrs_code":"160176AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"Kelainan_syaraf","label":{"Bahasa":"Kelainan Syaraf","English":"Neurological Abnormality"}},{"instance":{"openmrs_code":"5622AAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"others","label":{"Bahasa":"Lainnya","English":"Other"}},{"instance":{"openmrs_code":"1067AAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"cause_not_identified","label":{"Bahasa":"Penyebab tidak teridentifikasi","English":"Unidentified cause"}}]},{"name":"child_death_cause_other","hint":{"Bahasa":"Sebutkan alasan lainnya Jika ada","English":"Write other reason, if available"},"bind":{"relevant":"${child_death_cause} = 'others'"},"label":{"Bahasa":"Lainnya","English":"Other"},"instance":{"openmrs_entity":"Concept"},"type":"text"},{"bind":{"required":"yes","jr:constraintMsg":{"Bahasa":"Tanggal kematian anak hari ini atau hari-hari sebelumnya","English":"Date of child's death today or the days before"},"relevant":"${close_reason} = 'death_of_child'","constraint":".<=${today}"},"type":"date","instance":{"openmrs_entity_id":"1543AAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"Concept"},"name":"child_death_date","label":{"Bahasa":"Tanggal kematian anak","English":"Date of child death"}},{"name":"place_of_death","hint":{"Bahasa":"Tempat anak dikatakan meninggal","English":"The Place where children died"},"bind":{"relevant":"${close_reason} = 'death_of_child'"},"label":{"Bahasa":"Tempat Meninggal","English":"Location Died"},"instance":{"openmrs_entity_id":"160632AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"Concept"},"type":"text"},{"name":"referred","hint":{"Bahasa":"Untuk mengetahui apakah bayi/anak tersebut dirujuk ke fasilitas lain","English":"Information whether the baby/child was referred to other facility or not"},"bind":{"relevant":"${close_reason} = 'death_of_child'"},"label":{"Bahasa":"Apakah bayi/anak ini dirujuk?","English":"Was this baby/child referred to other facility?"},"instance":{"openmrs_entity_id":"1648AAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"Concept"},"type":"select one","children":[{"instance":{"openmrs_code":"1065AAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"yes","label":{"Bahasa":"Ya","English":"Yes"}},{"instance":{"openmrs_code":"1066AAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"no","label":{"Bahasa":"Tidak","English":"No"}}]},{"name":"prereferral_management","hint":{"Bahasa":"Tuliskan tindakan perawatan yang diberikan kepada ibu sebelum dirujuk","English":"Describe the care management provided for the mother prior to referral"},"bind":{"relevant":"${referred}='yes'"},"label":{"Bahasa":"Tindakan sebelum dirujuk","English":"Pre-referral management"},"instance":{"openmrs_entity":"Concept"},"type":"text"},{"name":"referral_location","hint":{"Bahasa":"Untuk mengetahui bayi/anak dirujuk ke fasilitas mana","English":"Information related to the location of baby/child's referral"},"bind":{"relevant":"${referred}='yes'"},"label":{"Bahasa":"Bayi/anak dirujuk ke","English":"Location of referral"},"instance":{"openmrs_entity_id":"161562AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"Concept"},"type":"text"},{"name":"confirm_child_close","bind":{"required":"yes"},"label":{"Bahasa":"Konfirmasi penutupan anak","English":"Confirmation of child's closure"},"instance":{"openmrs_entity":"n/a"},"type":"select one","children":[{"instance":{"openmrs_code":"1065AAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"yes","label":{"Bahasa":"Ya","English":"Yes"}}]},{"instance":{"openmrs_entity_id":"encounter_end","openmrs_entity":"encounter"},"type":"end","name":"end"},{"control":{"bodyless":true},"type":"group","children":[{"bind":{"readonly":"true()","calculate":"concat('uuid:', uuid())"},"type":"calculate","name":"instanceID"}],"name":"meta"}]} \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/close_form/form.xml b/opensrp-gizi/src/main/assets/www/form/close_form/form.xml new file mode 100644 index 0000000..458a570 --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/close_form/form.xml @@ -0,0 +1,24 @@ +
+

EC Penutupan Anak

+ + + + + + +
Alasan penutupanReason for closure?*Pilihlah salah satu alasan yang tersediaSelect one of reasons available +
This field is required
+ + + + + +
Apakah bayi/anak ini dirujuk?Was this baby/child referred to other facility?Untuk mengetahui apakah bayi/anak tersebut dirujuk ke fasilitas lainInformation whether the baby/child was referred to other facility or not +
+ + +
Konfirmasi penutupan anakConfirmation of child's closure* +
This field is required
+ +
\ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/close_form/form_definition.json b/opensrp-gizi/src/main/assets/www/form/close_form/form_definition.json new file mode 100644 index 0000000..d4a22f1 --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/close_form/form_definition.json @@ -0,0 +1,83 @@ +{ + "form_data_definition_version": "3", + "form": { + "bind_type":"anak", + "ec_bind_type":"ec_anak", + "default_bind_path": "/model/instance/penutupan_anak_mapped/", + "fields": [ + { + "name": "id", + "shouldLoadValue": true + }, + { + "name": "existing_location", + "bind": "/model/instance/penutupan_anak_mapped/existing_location", + "shouldLoadValue": true + }, + { + "name": "id", + "shouldLoadValue": true + }, + { + "name": "desa_anak", + "bind": "/model/instance/penutupan_anak_mapped/Village", + "shouldLoadValue": true + }, + { + "name": "existing_Sub-village", + "bind": "/model/instance/penutupan_anak_mapped/Sub-village", + "shouldLoadValue": true + }, + { + "name": "tanggalLahirAnak", + "bind": "/model/instance/penutupan_anak_mapped/tanggal_lahir", + "shouldLoadValue": true + }, + { + "name": "namaBayi", + "bind": "/model/instance/penutupan_anak_mapped/nama_bayi", + "shouldLoadValue": true + }, + { + "name": "closeReason", + "bind": "/model/instance/penutupan_anak_mapped/close_reason" + }, + { + "name": "childDeathCause", + "bind": "/model/instance/penutupan_anak_mapped/child_death_cause" + }, + { + "name": "childDeathCauseOther", + "bind": "/model/instance/penutupan_anak_mapped/child_death_cause_other" + }, + { + "name": "placeOfDeath", + "bind": "/model/instance/penutupan_anak_mapped/place_of_death" + }, + { + "name": "prereferralManagement", + "bind": "/model/instance/penutupan_anak_mapped/prereferral_management" + }, + { + "name": "referred", + "bind": "/model/instance/penutupan_anak_mapped/referred" + }, + { + "name": "referralLocation", + "bind": "/model/instance/penutupan_anak_mapped/referral_location" + }, + { + "name": "submissionDate", + "bind": "/model/instance/penutupan_anak_mapped/today" + }, + { + "name": "confirmChildClose", + "bind": "/model/instance/penutupan_anak_mapped/confirm_child_close" + }, + { + "name": "isClosed", + "value": "true" + } + ] + } +} diff --git a/opensrp-gizi/src/main/assets/www/form/close_form/model.xml b/opensrp-gizi/src/main/assets/www/form/close_form/model.xml new file mode 100644 index 0000000..ee070b1 --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/close_form/model.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/edit_kunjungan_gizi/form.xml b/opensrp-gizi/src/main/assets/www/form/edit_kunjungan_gizi/form.xml new file mode 100644 index 0000000..e4e4a22 --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/edit_kunjungan_gizi/form.xml @@ -0,0 +1,161 @@ +
+ + +

Kunjungan Gizi

+ + + + + + + + + + + +
+
+ + Asi Eksklusif + Exclusive Breastfeeding + Pemberian asi ekslusif pada bayi + - + +
+ + +
+
+ Value not allowed +
+
+
+ + Diberikan Vitamin A ? + Vitamin A given + - + - + +
+ + +
+
+ Value not allowed +
+ + +
\ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/edit_kunjungan_gizi/form_definition.json b/opensrp-gizi/src/main/assets/www/form/edit_kunjungan_gizi/form_definition.json new file mode 100644 index 0000000..aebec75 --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/edit_kunjungan_gizi/form_definition.json @@ -0,0 +1,102 @@ +{ + "form_data_definition_version": "1", + "form": { + "bind_type": "anak", + "default_bind_path": "/model/instance/kunjungan_gizi/", + "fields": [ + { + "name": "id", + "shouldLoadValue": true + }, + { + "name": "start", + "bind": "/model/instance/kunjungan_gizi/start" + }, + { + "name": "desa", + "bind": "/model/instance/registrasi_gizi/existing_Village", + "shouldLoadValue": true + }, + { + "name": "provinsi", + "bind": "/model/instance/registrasi_gizi/existing_Province", + "shouldLoadValue": true + }, + { + "name": "kecamatan", + "bind": "/model/instance/registrasi_gizi/existing_Sub-district", + "shouldLoadValue": true + }, + { + "name": "kabupaten", + "bind": "/model/instance/registrasi_gizi/existing_District", + "shouldLoadValue": true + }, + { + "name": "dusun", + "bind": "/model/instance/registrasi_gizi/existing_Sub-village", + "shouldLoadValue": true + }, + { + "name": "underweight", + "bind": "/model/instance/kunjungan_gizi/underweight", + "shouldLoadValue": true + }, + { + "name": "stunting", + "bind": "/model/instance/kunjungan_gizi/stunting", + "shouldLoadValue": true + }, + { + "name": "wasting", + "bind": "/model/instance/kunjungan_gizi/wasting", + "shouldLoadValue": true + }, + + { + "name": "tanggalPenimbangan", + "bind": "/model/instance/kunjungan_gizi/tanggal_preload", + "shouldLoadValue": true + }, + { + "name": "kunjunganSebelumnya", + "bind": "/model/instance/kunjungan_gizi/kunjungan_sebelumnya" + }, + { + "name": "tanggalPenimbangan", + "bind": "/model/instance/kunjungan_gizi/tanggal_penimbangan" + }, + { + "name": "tanggalLahir", + "bind": "/model/instance/kunjungan_gizi/tanggal_lahir", + "shouldLoadValue": true + }, + { + "name": "umur", + "bind": "/model/instance/kunjungan_gizi/umur" + }, + { + "name": "beratBadan", + "bind": "/model/instance/kunjungan_gizi/berat_badan" + }, + + { + "name": "tinggiBadan", + "bind": "/model/instance/kunjungan_gizi/tinggi_badan" + }, + { + "name": "asi", + "bind": "/model/instance/kunjungan_gizi/ae" + }, + { + "name": "vitA", + "bind": "/model/instance/kunjungan_gizi/vitA" + }, + { + "name": "end", + "bind": "/model/instance/kunjungan_gizi/end" + } + + ] + } +} \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/edit_kunjungan_gizi/model.xml b/opensrp-gizi/src/main/assets/www/form/edit_kunjungan_gizi/model.xml new file mode 100644 index 0000000..80e64df --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/edit_kunjungan_gizi/model.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + + 0 + + + + + + + + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/edit_registrasi_gizi/form.json b/opensrp-gizi/src/main/assets/www/form/edit_registrasi_gizi/form.json new file mode 100644 index 0000000..f32fd20 --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/edit_registrasi_gizi/form.json @@ -0,0 +1 @@ +{"name":"Registrasi_Gizi-NewStructure-mapped_O","title":"Registrasi Gizi","sms_keyword":"registrasi_gizi_new","default_language":"Bahasa","instance":{"encounter_type":"Registrasi Gizi"},"version":"201611220216","id_string":"registrasi_gizi_new","type":"survey","children":[{"instance":{"openmrs_entity_id":"encounter_start","openmrs_entity":"encounter"},"type":"start","name":"start"},{"instance":{"openmrs_entity_id":"encounter_date","openmrs_entity":"encounter"},"type":"today","name":"today"},{"type":"deviceid","name":"deviceid"},{"type":"simserial","name":"simserial"},{"type":"phonenumber","name":"phonenumber"},{"type":"hidden","name":"Province"},{"type":"hidden","name":"District","hint":{"Bahasa":"Inject from app"}},{"type":"hidden","name":"Sub-district","hint":{"Bahasa":"Inject from app"}},{"type":"hidden","name":"Village","hint":{"Bahasa":"Inject from app"}},{"type":"hidden","name":"Sub-village","hint":{"Bahasa":"Inject from app"}},{"type":"note","name":"generated_note_name_13","label":{"Bahasa":"Desa : ${Village}"}},{"type":"note","name":"generated_note_name_14","label":{"Bahasa":"Dusun : ${Sub-village}"}},{"bind":{"calculate":"${Village}"},"type":"hidden","name":"existing_location","instance":{"openmrs_entity_id":"location_id","openmrs_entity":"encounter"}},{"bind":{"calculate":"${Province}"},"type":"calculate","name":"provinsi","instance":{"openmrs_entity_parent":"usual_residence","openmrs_entity_id":"stateProvince","openmrs_entity":"person_address"}},{"bind":{"calculate":"${District}"},"type":"calculate","name":"kabupaten","instance":{"openmrs_entity_parent":"usual_residence","openmrs_entity_id":"countyDistrict","openmrs_entity":"person_address"}},{"bind":{"calculate":"${Village}"},"type":"calculate","name":"desa","instance":{"openmrs_entity_parent":"usual_residence","openmrs_entity_id":"cityVillage","openmrs_entity":"person_address"}},{"bind":{"calculate":"${Sub-village}"},"type":"calculate","name":"dusun","instance":{"openmrs_entity_parent":"usual_residence","openmrs_entity_id":"address1","openmrs_entity":"person_address"}},{"bind":{"calculate":"${Sub-district}"},"type":"calculate","name":"kecamatan","instance":{"openmrs_entity_parent":"usual_residence","openmrs_entity_id":"address2","openmrs_entity":"person_address"}},{"label":{"Bahasa":"Nama Posyandu","English":"Health Post"},"type":"text","name":"posyandu","hint":{"Bahasa":"Nama Pos Pelayanan Terpadu","English":"Name of Health Post"}},{"instance":{"openmrs_entity_id":"last_name","openmrs_entity":"person"},"label":{"Bahasa":"Nama Ayah","English":"Fathr's Name"},"type":"text","name":"nama_ayah","hint":{"Bahasa":"Nama Ayah Bayi yang diberikan Imunisasi","English":"Name of Baby's Father Receiving Immunization"}},{"instance":{"openmrs_entity_id":"first_name","openmrs_entity":"person"},"label":{"Bahasa":"Nama Ibu","English":"Mother's Name"},"type":"text","name":"nama_ibu","hint":{"Bahasa":"Nama Ibu Bayi yang diberikan Imunisasi","English":"Name of Baby's Mother Receiving Immunization"}},{"instance":{"openmrs_entity_id":"NoIbu","openmrs_entity":"person_attribute"},"type":"integer","name":"no_ibu","label":{"Bahasa":"No. Ibu","English":"Mother's Number"}},{"instance":{"openmrs_entity_id":"nik","openmrs_entity":"person_identifier"},"label":{"Bahasa":"NIK","English":"National identification number"},"type":"integer","name":"nik","hint":{"Bahasa":"Nomor KTP (Kartu Tanda Penduduk)","English":"Personal identity number"}},{"default":"0","instance":{"openmrs_entity_id":"1532AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"hidden","name":"umur","hint":{"Bahasa":"for sync purpose"}},{"default":"0","instance":{"openmrs_entity_id":"374AAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"hidden","name":"jenis_kontrasepsi","hint":{"Bahasa":"for sync purpose"}},{"instance":{"openmrs_entity_id":"Child Registration","openmrs_entity":"person"},"type":"repeat","children":[{"bind":{"calculate":"${Village}"},"type":"calculate","name":"desa_anak","instance":{"openmrs_entity_parent":"cityVillage","openmrs_entity_id":"160632AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"Concept"}},{"type":"note","name":"generated_note_name_36","label":{"Bahasa":"Desa : ${desa_anak}"}},{"bind":{"calculate":"${Village}"},"type":"hidden","name":"child_existing_location","instance":{"openmrs_entity_id":"location_id","openmrs_entity":"encounter"}},{"name":"nama_bayi","hint":{"Bahasa":"Nama Bayi yang diberikan Imunisasi","English":"Name of Baby Receiving Immunization"},"bind":{"required":"yes"},"label":{"Bahasa":"Nama Bayi","English":"Baby's Name"},"instance":{"openmrs_entity_id":"1586AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"Concept"},"type":"text"},{"name":"jenis_kelamin","hint":{"Bahasa":"Jenis Kelamin Bayi/Balita Yang diberikan Imunisasi","English":"Gender of Baby Receiving Immunization"},"bind":{"required":"yes"},"label":{"Bahasa":"Jenis Kelamin","English":"Gender"},"instance":{"openmrs_entity_id":"gender","openmrs_entity":"person"},"type":"select one","children":[{"instance":{"openmrs_code":"1534AAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"male","label":{"Bahasa":"Laki - laki","English":"Male"}},{"instance":{"openmrs_code":"1535AAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"female","label":{"Bahasa":"Perempuan","English":"Female"}}]},{"name":"tanggal_lahir","hint":{"Bahasa":"Tanggal lahir Bayi","English":"Baby's date of birth"},"bind":{"required":"yes"},"label":{"Bahasa":"Tanggal lahir","English":"DOB"},"instance":{"openmrs_entity_id":"birthdate","openmrs_entity":"person"},"type":"date"},{"instance":{"openmrs_entity_id":"5916AAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"label":{"Bahasa":"Berat badan saat Lahir","English":"Baby's birth weight"},"type":"integer","name":"berat_badan_saat_lahir","hint":{"Bahasa":"Berat badan lahir bayi","English":"Baby's birth weight"}},{"instance":{"openmrs_entity_id":"ibuCaseId","openmrs_entity":"person_relationship"},"type":"hidden","name":"ibu_entity_id"}],"name":"child_registration"},{"control":{"bodyless":true},"type":"group","children":[{"bind":{"readonly":"true()","calculate":"concat('uuid:', uuid())"},"type":"calculate","name":"instanceID"}],"name":"meta"}]} \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/edit_registrasi_gizi/form.xml b/opensrp-gizi/src/main/assets/www/form/edit_registrasi_gizi/form.xml new file mode 100644 index 0000000..bd64f06 --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/edit_registrasi_gizi/form.xml @@ -0,0 +1,23 @@ +
+

Registrasi Gizi New

+ + + + + + + + + + +
Jenis Kelamingender*Jenis kelamin bayi/balitagender of baby/child +
Value not allowedThis field is required
+ +
Apakah anak memiliki Kartu Menuju Sehat (KMS)?Does baby hold the Health Card (KMS)?Apakah anak memiliki Kartu Menuju Sehat (KMS)?Does baby hold the Health Card (KMS)? +
Value not allowed
+ +
\ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/edit_registrasi_gizi/form_definition.json b/opensrp-gizi/src/main/assets/www/form/edit_registrasi_gizi/form_definition.json new file mode 100644 index 0000000..e0c12d3 --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/edit_registrasi_gizi/form_definition.json @@ -0,0 +1,123 @@ +{ + "form_data_definition_version": "2", + "form": { + "bind_type": "anak", + "default_bind_path": "/model/instance/Registrasi_Gizi-NewStructure-map/", + "fields": [ + { + "name": "id", + "shouldLoadValue": true + }, + { + "name": "unique_id", + "bind": "model/instance/Registrasi_Gizi-NewStructure-map/unique_id", + "shouldLoadValue": true + }, + { + "name": "existing_desa", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/existing_Village", + "shouldLoadValue": true + }, + { + "name": "existing_provinsi", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/existing_Province", + "shouldLoadValue": true + }, + { + "name": "existing_kecamatan", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/existing_Sub-district", + "shouldLoadValue": true + }, + { + "name": "existing_kabupaten", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/existing_District", + "shouldLoadValue": true + }, + { + "name": "existing_dusun", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/existing_Sub-village", + "shouldLoadValue": true + }, + { + "name": "provinsi", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/provinsi", + "shouldLoadValue": true + }, + { + "name": "kabupaten", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/kabupaten", + "shouldLoadValue": true + }, + { + "name": "kecamatan", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/kecamatan", + "shouldLoadValue": true + }, + { + "name": "desa", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/desa", + "shouldLoadValue": true + }, + { + "name": "dusun", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/dusun", + "shouldLoadValue": true + }, + { + "name": "posyandu", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/posyandu", + "shouldLoadValue": true + }, + { + "name": "desa_manual", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/existing_Village", + "shouldLoadValue": true + }, + { + "name": "namaBayi", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/nama_anak", + "shouldLoadValue": true + }, + { + "name": "namaAyah", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/nama_ayah", + "shouldLoadValue": true + }, + { + "name": "namaIbu", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/nama_ibu", + "shouldLoadValue": true + }, + { + "name": "tanggalLahir", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/tanggal_lahir", + "shouldLoadValue": true + }, + { + "name": "nik", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/nik", + "shouldLoadValue": true + }, + { + "name": "jenisKelamin", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/jenis_kelamin", + "shouldLoadValue": true + }, + { + "name": "beratLahir", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/birthweight", + "shouldLoadValue": true + }, + { + "name": "kms", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/kms", + "shouldLoadValue": true + }, + { + "name": "registrationDate", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/today", + "shouldLoadValue": true + } + ] + } +} \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/edit_registrasi_gizi/model.xml b/opensrp-gizi/src/main/assets/www/form/edit_registrasi_gizi/model.xml new file mode 100644 index 0000000..db255ab --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/edit_registrasi_gizi/model.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/entity_relationship.json b/opensrp-gizi/src/main/assets/www/form/entity_relationship.json new file mode 100644 index 0000000..dfb5bd6 --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/entity_relationship.json @@ -0,0 +1,26 @@ +[ + { + "parent":"bidan", + "child":"ibu", + "field":"ibu_ibu", + "kind":"one_to_many", + "from":"bidan.id", + "to":"ibu.relationalid" + }, + { + "parent":"kartu_ibu", + "child": "ibu", + "field":"istri", + "kind":"one_to_one", + "from":"kartu_ibu.id", + "to":"ibu.relationalid" + }, + { + "parent":"ibu", + "child":"anak", + "field":"anak_anak", + "kind":"one_to_many", + "from":"ibu.id", + "to":"anak.relationalid" + } +] \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/kohort_anak_tutup/form.json b/opensrp-gizi/src/main/assets/www/form/kohort_anak_tutup/form.json new file mode 100644 index 0000000..1f2ef7e --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/kohort_anak_tutup/form.json @@ -0,0 +1 @@ +{"name":"penutupan_anak_reviewed","title":"Penutupan Anak","sms_keyword":"penutupan_anak","default_language":"Bahasa","instance":{"encounter_type":"Penutupan Anak"},"version":"201610260356","id_string":"penutupan_anak","type":"survey","children":[{"instance":{"openmrs_entity_id":"encounter_start","openmrs_entity":"encounter"},"type":"start","name":"start"},{"instance":{"openmrs_entity_id":"encounter_date","openmrs_entity":"encounter"},"type":"today","name":"today"},{"type":"deviceid","name":"deviceid"},{"type":"simserial","name":"simserial"},{"type":"phonenumber","name":"phonenumber"},{"type":"hidden","name":"Province"},{"type":"hidden","name":"District","hint":{"Bahasa":"Inject from app"}},{"type":"hidden","name":"Sub-district","hint":{"Bahasa":"Inject from app"}},{"type":"hidden","name":"Village","hint":{"Bahasa":"Inject from app"}},{"type":"hidden","name":"Sub-village","hint":{"Bahasa":"Inject from app"}},{"type":"note","name":"generated_note_name_13","label":{"Bahasa":"Desa : ${Village}"}},{"type":"note","name":"generated_note_name_14","label":{"Bahasa":"Dusun : ${Sub-village}"}},{"bind":{"calculate":"${Village}"},"type":"hidden","name":"existing_location","instance":{"openmrs_entity_id":"location_id","openmrs_entity":"encounter"}},{"bind":{"calculate":"${Province}"},"type":"calculate","name":"provinsi","instance":{"openmrs_entity":"person_address","openmrs_entity_id":"stateProvince","openmrs_entity_parent":"usual_residence"}},{"bind":{"calculate":"${District}"},"type":"calculate","name":"kabupaten","instance":{"openmrs_entity":"person_address","openmrs_entity_id":"countyDistrict","openmrs_entity_parent":"usual_residence"}},{"bind":{"calculate":"${Village}"},"type":"calculate","name":"desa","instance":{"openmrs_entity":"person_address","openmrs_entity_id":"cityVillage","openmrs_entity_parent":"usual_residence"}},{"bind":{"calculate":"${Sub-village}"},"type":"calculate","name":"dusun","instance":{"openmrs_entity":"person_address","openmrs_entity_id":"address1","openmrs_entity_parent":"usual_residence"}},{"bind":{"calculate":"${Sub-district}"},"type":"calculate","name":"kecamatan","instance":{"openmrs_entity":"person_address","openmrs_entity_id":"address2","openmrs_entity_parent":"usual_residence"}},{"name":"close_reason","hint":{"Bahasa":"Pilihlah salah satu alasan yang tersedia","English":"Select one of reasons available"},"bind":{"required":"yes"},"label":{"Bahasa":"Alasan penutupan","English":"Reason for closure?"},"instance":{"openmrs_entity_id":"160417AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"Concept"},"type":"select one","children":[{"instance":{"openmrs_code":"163496AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"child_over5","label":{"Bahasa":"Umur anak >5 tahun","English":"Child's age > 5 years"}},{"instance":{"openmrs_code":"160415AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"permanent_relocation","label":{"Bahasa":"Relokasi (permanen)","English":"Relocation (permanent)"}},{"instance":{"openmrs_code":"162076AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"death_of_child","label":{"Bahasa":"Anak meninggal","English":"Child's death"}}]},{"control":{"appearance":"minimal"},"name":"child_death_cause","bind":{"relevant":"${close_reason} = 'death_of_child'"},"label":{"Bahasa":"Penyebab kematian anak","English":"Cause of child's death"},"instance":{"openmrs_entity_id":"159482AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"Concept"},"type":"select one","children":[{"instance":{"openmrs_code":"226AAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"sepsis","label":{"Bahasa":"Sepsis","English":"Sepsis"}},{"instance":{"openmrs_code":"121397AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"asphyxia","label":{"Bahasa":"Asfiksia","English":"Asphyxia"}},{"instance":{"openmrs_code":"116222AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"lbw","label":{"Bahasa":"berat lahir kurang (< 2.5 kg)","English":"Low birthweight (< 2.5 kg)"}},{"instance":{"openmrs_code":"114100AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"pneumonia","label":{"Bahasa":"Pneumonia","English":"Pneumonia"}},{"instance":{"openmrs_code":"142412AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"diarrhea","label":{"Bahasa":"Diare","English":"Diarrhea"}},{"instance":{"openmrs_code":"134561AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"measles","label":{"Bahasa":"Campak","English":"Measles"}},{"instance":{"openmrs_code":"115122AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"malnutrition","label":{"Bahasa":"Malnutrisi","English":"Malnutrition"}},{"instance":{"openmrs_code":"154983AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"Infeksi_pernafasan_akut","label":{"Bahasa":"Infeksi pernafasan akut","English":"Acute respiratory infection"}},{"instance":{"openmrs_code":"123565AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"infeksi_pernapasan_atas","label":{"Bahasa":"Infeksi Saluran Pernapasan Atas","English":"Upper Respiratory Infection"}},{"instance":{"openmrs_code":"116128AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"malaria","label":{"Bahasa":"Malaria","English":"Malaria"}},{"instance":{"openmrs_code":"124954AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"tetanus_neonatorum","label":{"Bahasa":"Tetanus Neonatorum","English":"Neonatal Tetanus"}},{"instance":{"openmrs_code":"115368AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"ikterus","label":{"Bahasa":"Ikterus","English":"Jaundice"}},{"instance":{"openmrs_code":"142591AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"demam_berdarah","label":{"Bahasa":"Demam Berdarah","English":"Dengue Fever"}},{"instance":{"openmrs_code":"119975AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"congenital_abnormality","label":{"Bahasa":"Kelainan Kongenital","English":"Congenital Abnormality"}},{"instance":{"openmrs_code":"119242AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"kelainan_saluran_cerna","label":{"Bahasa":"Kelainan Saluran Cerna","English":"Gastrointestinal Abnormality"}},{"instance":{"openmrs_code":"160176AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"Kelainan_syaraf","label":{"Bahasa":"Kelainan Syaraf","English":"Neurological Abnormality"}},{"instance":{"openmrs_code":"5622AAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"others","label":{"Bahasa":"Lainnya","English":"Other"}},{"instance":{"openmrs_code":"1067AAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"cause_not_identified","label":{"Bahasa":"Penyebab tidak teridentifikasi","English":"Unidentified cause"}}]},{"name":"child_death_cause_other","hint":{"Bahasa":"Sebutkan alasan lainnya Jika ada","English":"Write other reason, if available"},"bind":{"relevant":"${child_death_cause} = 'others'"},"label":{"Bahasa":"Lainnya","English":"Other"},"instance":{"openmrs_entity_id":"160632AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"Concept"},"type":"text"},{"bind":{"required":"yes","jr:constraintMsg":{"Bahasa":"Tanggal kematian anak hari ini atau hari-hari sebelumnya","English":"Date of child's death today or the days before"},"relevant":"${close_reason} = 'death_of_child'","constraint":".<=${today}"},"type":"date","instance":{"openmrs_entity_id":"1543AAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"Concept"},"name":"child_death_date","label":{"Bahasa":"Tanggal kematian anak","English":"Date of child death"}},{"instance":{"openmrs_entity_id":"160632AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"Concept"},"label":{"Bahasa":"Tempat Meninggal","English":"Location Died"},"type":"text","name":"place_of_death","hint":{"Bahasa":"Tempat anak dikatakan meninggal","English":"The Place where children died"}},{"instance":{"openmrs_entity_id":"163104AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"Concept"},"label":{"Bahasa":"Tindakan sebelum dirujuk","English":"Pre-referral management"},"type":"text","name":"prereferral_management","hint":{"Bahasa":"Tuliskan tindakan perawatan yang diberikan kepada ibu sebelum dirujuk","English":"Describe the care management provided for the mother prior to referral"}},{"name":"referred","hint":{"Bahasa":"Untuk mengetahui apakah bayi/anak tersebut dirujuk ke fasilitas lain","English":"Information whether the baby/child was referred to other facility or not"},"label":{"Bahasa":"Apakah bayi/anak ini dirujuk?","English":"Was this baby/child referred to other facility?"},"instance":{"openmrs_entity_id":"1648AAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"Concept"},"type":"select one","children":[{"instance":{"openmrs_code":"1065AAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"yes","label":{"Bahasa":"Ya","English":"Yes"}},{"instance":{"openmrs_code":"1066AAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"no","label":{"Bahasa":"Tidak","English":"No"}}]},{"instance":{"openmrs_entity_id":"161562AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"Concept"},"label":{"Bahasa":"Bayi/anak dirujuk ke","English":"Location of referral"},"type":"text","name":"referral_location","hint":{"Bahasa":"Untuk mengetahui bayi/anak dirujuk ke fasilitas mana","English":"Information related to the location of baby/child's referral"}},{"name":"confirm_child_close","bind":{"required":"yes"},"label":{"Bahasa":"Konfirmasi penutupan anak","English":"Confirmation of child's closure"},"instance":{"openmrs_entity":"n/a"},"type":"select one","children":[{"instance":{"openmrs_code":"1065AAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"yes","label":{"Bahasa":"Ya","English":"Yes"}}]},{"instance":{"openmrs_entity_id":"encounter_end","openmrs_entity":"encounter"},"type":"end","name":"end"},{"control":{"bodyless":true},"type":"group","children":[{"bind":{"readonly":"true()","calculate":"concat('uuid:', uuid())"},"type":"calculate","name":"instanceID"}],"name":"meta"}]} \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/kohort_anak_tutup/form.xml b/opensrp-gizi/src/main/assets/www/form/kohort_anak_tutup/form.xml new file mode 100644 index 0000000..8494be3 --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/kohort_anak_tutup/form.xml @@ -0,0 +1,23 @@ +
+

Penutupan Anak

+ + + + +
Alasan penutupanReason for closure?*Pilihlah salah satu alasan yang tersediaSelect one of reasons available +
+ + + + + +
Apakah bayi/anak ini dirujuk?Was this baby/child referred to other facility?Untuk mengetahui apakah bayi/anak tersebut dirujuk ke fasilitas lainInformation whether the baby/child was referred to other facility or not +
+ +
Konfirmasi penutupan anakConfirmation of child's closure* +
+ +
\ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/kohort_anak_tutup/form_definition.json b/opensrp-gizi/src/main/assets/www/form/kohort_anak_tutup/form_definition.json new file mode 100644 index 0000000..2eb986f --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/kohort_anak_tutup/form_definition.json @@ -0,0 +1,64 @@ +{ + "form_data_definition_version": "3", + "form": { + "bind_type":"anak", + "ec_bind_type":"ec_anak", + "default_bind_path": "/model/instance/penutupan_anak_reviewed/", + "fields": [ + { + "name": "id", + "shouldLoadValue": true + }, + { + "name": "cityVillage", + "bind": "/model/instance/penutupan_anak_reviewed/Village", + "shouldLoadValue": true + }, + { + "name": "existing_location", + "bind": "/model/instance/penutupan_anak_reviewed/existing_location", + "shouldLoadValue": true + }, + { + "name": "closeReason", + "bind": "/model/instance/penutupan_anak_reviewed/close_reason" + }, + { + "name": "childDeathCause", + "bind": "/model/instance/penutupan_anak_reviewed/child_death_cause" + }, + { + "name": "childDeathCauseOther", + "bind": "/model/instance/penutupan_anak_reviewed/child_death_cause_other" + }, + { + "name": "placeOfDeath", + "bind": "/model/instance/penutupan_anak_reviewed/place_of_death" + }, + { + "name": "prereferralManagement", + "bind": "/model/instance/penutupan_anak_reviewed/prereferral_management" + }, + { + "name": "referred", + "bind": "/model/instance/penutupan_anak_reviewed/referred" + }, + { + "name": "referralLocation", + "bind": "/model/instance/penutupan_anak_reviewed/referral_location" + }, + { + "name": "submissionDate", + "bind": "/model/instance/penutupan_anak_reviewed/today" + }, + { + "name": "confirmChildClose", + "bind": "/model/instance/penutupan_anak_reviewed/confirm_child_close" + }, + { + "name": "isClosed", + "value": "true" + } + ] + } +} diff --git a/opensrp-gizi/src/main/assets/www/form/kohort_anak_tutup/model.xml b/opensrp-gizi/src/main/assets/www/form/kohort_anak_tutup/model.xml new file mode 100644 index 0000000..c2d9f58 --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/kohort_anak_tutup/model.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/kunjungan_gizi/form.json b/opensrp-gizi/src/main/assets/www/form/kunjungan_gizi/form.json new file mode 100644 index 0000000..beace51 --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/kunjungan_gizi/form.json @@ -0,0 +1 @@ +{"name":"EC_Kunjungan_Gizi_NewStructure-mapped_O","title":"Kunjungan Gizi","sms_keyword":"kunjungan_gizi_new","default_language":"Bahasa","instance":{"encounter_type":"Kunjungan Gizi"},"version":"201703160833","id_string":"kunjungan_gizi_new","type":"survey","children":[{"instance":{"openmrs_entity_id":"encounter_start","openmrs_entity":"encounter"},"type":"start","name":"start"},{"instance":{"openmrs_entity_id":"encounter_date","openmrs_entity":"encounter"},"type":"today","name":"today"},{"type":"deviceid","name":"deviceid"},{"type":"simserial","name":"simserial"},{"type":"phonenumber","name":"phonenumber"},{"type":"hidden","name":"Province"},{"type":"hidden","name":"District","hint":{"Bahasa":"Inject from app"}},{"type":"hidden","name":"Sub-district","hint":{"Bahasa":"Inject from app"}},{"type":"hidden","name":"Village","hint":{"Bahasa":"Inject from app"}},{"type":"hidden","name":"Sub-village","hint":{"Bahasa":"Inject from app"}},{"type":"note","name":"generated_note_name_13","label":{"Bahasa":"Desa : ${Village}"}},{"type":"note","name":"generated_note_name_14","label":{"Bahasa":"Dusun : ${Sub-village}"}},{"instance":{"openmrs_entity_id":"birthdate","openmrs_entity":"person"},"type":"hidden","name":"tanggal_lahir","hint":{"Bahasa":"inject from app"}},{"instance":{"openmrs_entity_id":"1586AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"Concept"},"type":"hidden","name":"nama_bayi","hint":{"Bahasa":"inject from app"}},{"type":"note","name":"generated_note_name_17","label":{"Bahasa":"Nama Bayi : ${nama_bayi}"}},{"type":"note","name":"generated_note_name_18","label":{"Bahasa":"Tanggal Lahir : ${tanggal_lahir}"}},{"bind":{"calculate":"${Village}"},"type":"hidden","name":"existing_location","instance":{"openmrs_entity_id":"location_id","openmrs_entity":"encounter"}},{"bind":{"calculate":"${Province}"},"type":"calculate","name":"provinsi","instance":{"openmrs_entity_parent":"usual_residence","openmrs_entity_id":"stateProvince","openmrs_entity":"person_address"}},{"bind":{"calculate":"${District}"},"type":"calculate","name":"kabupaten","instance":{"openmrs_entity_parent":"usual_residence","openmrs_entity_id":"countyDistrict","openmrs_entity":"person_address"}},{"bind":{"calculate":"${Village}"},"type":"calculate","name":"desa","instance":{"openmrs_entity_parent":"usual_residence","openmrs_entity_id":"cityVillage","openmrs_entity":"person_address"}},{"bind":{"calculate":"${Sub-village}"},"type":"calculate","name":"dusun","instance":{"openmrs_entity_parent":"usual_residence","openmrs_entity_id":"address1","openmrs_entity":"person_address"}},{"bind":{"calculate":"${Sub-district}"},"type":"calculate","name":"kecamatan","instance":{"openmrs_entity_parent":"usual_residence","openmrs_entity_id":"address2","openmrs_entity":"person_address"}},{"instance":{"openmrs_entity_id":"1854AAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"hidden","name":"underweight","hint":{"Bahasa":"Inject from app"}},{"instance":{"openmrs_entity_id":"164088AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"hidden","name":"stunting","hint":{"Bahasa":"Inject from app"}},{"instance":{"openmrs_entity_id":"163515AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"hidden","name":"wasting","hint":{"Bahasa":"Inject from app"}},{"bind":{"calculate":"${underweight}"},"type":"calculate","name":"weight_for_age_status"},{"bind":{"calculate":"${stunting}"},"type":"calculate","name":"height_for_age_status"},{"bind":{"calculate":"${wasting}"},"type":"calculate","name":"weight_for_length_status"},{"instance":{"openmrs_entity_id":"1854AAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"hidden","name":"nutrition_status"},{"instance":{"openmrs_entity_id":"1854AAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"hidden","name":"bgm"},{"instance":{"openmrs_entity_id":"164136AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"hidden","name":"dua_t"},{"bind":{"calculate":"${nutrition_status}"},"type":"calculate","name":"ntob_status"},{"bind":{"calculate":"${bgm}"},"type":"calculate","name":"bgm_status"},{"bind":{"calculate":"${dua_t}"},"type":"calculate","name":"dua_t_status"},{"type":"note","name":"generated_note_name_42","label":{"Bahasa":"Status Gizi Sebelumnya","English":"Previous Nutrition Status"}},{"type":"note","name":"generated_note_name_43","label":{"Bahasa":"Berat/Umur : ${weight_for_age_status}","English":"Weight for Age Status : ${underweight}"}},{"type":"note","name":"generated_note_name_44","label":{"Bahasa":"Tinggi/Umur : ${height_for_age_status}","English":"Height for Age Status : ${stunting}"}},{"type":"note","name":"generated_note_name_45","label":{"Bahasa":"Berat/Tinggi : ${weight_for_length_status}","English":"Weight for Length Status : ${wasting}"}},{"type":"note","name":"generated_note_name_46","label":{"Bahasa":"Status Gizi (NTOB) : ${ntob_status}","English":"Weight Increasement Status : ${ntob_status}"}},{"type":"note","name":"generated_note_name_47","label":{"Bahasa":"Bawah Garis Merah (BGM) : ${bgm_status}","English":"Under red line (weight for age status based on Growth Chart) : ${bgm_status}"}},{"type":"note","name":"generated_note_name_48","label":{"Bahasa":"2 kali berturut-turut tidak naik (2T) : ${dua_t_status}","English":"Failed to weight gain in two consecutive months : ${dua_t_status}"}},{"bind":{"required":"yes"},"type":"hidden","instance":{"openmrs_entity_id":"gender","openmrs_entity":"person"},"name":"jenis_kelamin","hint":{"Bahasa":"Jenis Kelamin Bayi/Balita Yang diberikan Imunisasi","English":"Gender of Baby Receiving Immunization"}},{"name":"tanggal_penimbangan","hint":{"Bahasa":"Tanggal dilakukan penimbangan","English":"date of weighing"},"bind":{"required":"yes","constraint":".>=${tanggal_lahir}"},"label":{"Bahasa":"Tanggal penimbangan","English":"Date of Weighing"},"instance":{"openmrs_entity_id":"160753AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"date"},{"instance":{"openmrs_entity_parent":"160753AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity_id":"160632AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"hidden","name":"kunjungan_sebelumnya"},{"default":"0","instance":{"openmrs_entity_parent":"1532AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity_id":"160632AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"hidden","name":"preload_umur","hint":{"English":"data pulled from app"}},{"default":"0:0","instance":{"openmrs_entity_parent":"5090AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity_id":"160632AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"hidden","name":"preload_history_tinggi","hint":{"English":"data pulled from app"}},{"bind":{"calculate":"int((${tanggal_penimbangan} - ${tanggal_lahir}))"},"type":"calculate","instance":{"openmrs_entity_id":"1532AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"name":"umur","label":{"Bahasa":"Umur","English":"Age"}},{"bind":{"calculate":"int((${umur}) div 30)"},"type":"calculate","instance":{"openmrs_entity_id":"1532AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"name":"umur_bulan","label":{"Bahasa":"Umur Bulan","English":"Monthage"}},{"label":{"Bahasa":"Umur : ${umur_bulan}","English":"Age (Months) : ${umur_bulan}"},"type":"note","name":"generated_note_name_61","hint":{"Bahasa":"Umur bayi/balita dalam bulan","English":"age of baby/child in month"}},{"default":"0:0","instance":{"openmrs_entity_parent":"5089AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity_id":"160632AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"hidden","name":"berat_preload","hint":{"English":"data pulled from app"}},{"name":"berat_badan","hint":{"Bahasa":"Berat badan bayi/balita (kg)","English":"weight of baby/ child in Kg"},"bind":{"required":"yes","constraint":".>0 and .<50"},"label":{"Bahasa":"Berat Badan","English":"Weight (kg)"},"instance":{"openmrs_entity_id":"5089AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"decimal"},{"bind":{"calculate":"concat(${berat_preload},',',${umur},':',${berat_badan})"},"type":"calculate","name":"history_berat","instance":{"openmrs_entity_parent":"5089AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity_id":"160632AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"}},{"instance":{"openmrs_entity_id":"5090AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"label":{"Bahasa":"Tinggi Badan","English":"Height (cm)"},"type":"decimal","name":"tinggi_badan","hint":{"Bahasa":"Tinggi badan bayi/balita (Cm)","English":"Height of baby/child in cm"}},{"bind":{"calculate":"concat(${preload_history_tinggi},',',${umur},':',${tinggi_badan})"},"type":"calculate","name":"history_tinggi","instance":{"openmrs_entity_parent":"5090AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity_id":"160632AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"}},{"bind":{"calculate":"concat(${preload_umur},',',${umur})"},"type":"calculate","name":"history_umur","instance":{"openmrs_entity_parent":"1532AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity_id":"160632AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"}},{"type":"note","name":"generated_note_name_73","label":{"Bahasa":"${history_berat}"}},{"type":"note","name":"generated_note_name_74","label":{"Bahasa":"${history_umur}"}},{"type":"note","name":"generated_note_name_75","label":{"Bahasa":"${history_tinggi}"}},{"instance":{"openmrs_entity_id":"159854AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"label":{"Bahasa":"Makanan Pendamping Asi","English":"Supplementary food for children under 2/complementary feeding"},"type":"select one","children":[{"instance":{"openmrs_code":"1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"Yes","label":{"Bahasa":"Ya","English":"Yes"}},{"instance":{"openmrs_code":"1066AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"No","label":{"Bahasa":"Tidak","English":"No"}}],"name":"mp_asi"},{"name":"ae","hint":{"Bahasa":"Pemberian asi ekslusif pada bayi"},"label":{"Bahasa":"Asi Eksklusif","English":"Exclusive Breastfeeding"},"instance":{"openmrs_entity_id":"5632AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"select one","children":[{"instance":{"openmrs_code":"1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"Yes","label":{"Bahasa":"Ya","English":"Yes"}},{"instance":{"openmrs_code":"1066AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"No","label":{"Bahasa":"Tidak","English":"No"}}]},{"name":"vitA","hint":{"Bahasa":"Pemberian vitamin A pada bayi"},"label":{"Bahasa":"Pemberian Vitamin A","English":"Administration of Vitamin A"},"instance":{"openmrs_entity_id":"161534AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"select one","children":[{"instance":{"openmrs_code":"1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"Yes","label":{"Bahasa":"Ya","English":"Yes"}},{"instance":{"openmrs_code":"1066AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"No","label":{"Bahasa":"Tidak","English":"No"}}]},{"name":"waktuVitA","hint":{"Bahasa":"Tulis 'Ya' Jika diberikan pada Hari pelaksanaan dan 'Tidak' jika diberikan pada Sweeping Day"},"bind":{"relevant":"${vitA}=\"Yes\""},"label":{"Bahasa":"Kapan vitamin A diberikan?","English":"When the vitamin A given?"},"instance":{"openmrs_entity_id":"160632AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"select one","children":[{"instance":{"openmrs_code":"n/a"},"name":"jadwal_posyandu","label":{"Bahasa":"Pada jadwal posyandu","English":"On the day of posyandu"}},{"instance":{"openmrs_code":"n/a"},"name":"sweeping","label":{"Bahasa":"Saat sweeping","English":"During sweeping day"}}]},{"name":"jenisVitA","bind":{"relevant":"${vitA}=\"Yes\""},"label":{"Bahasa":"Jenis Vitamin A yang diberikan","English":"Type of Vitamin A given"},"instance":{"openmrs_entity":"n/a"},"type":"select one","children":[{"instance":{"openmrs_code":"n/a"},"name":"merah","label":{"Bahasa":"Merah","English":"Red"}},{"instance":{"openmrs_code":"n/a"},"name":"biru","label":{"Bahasa":"Biru","English":"Blue"}}]},{"name":"obatcacing","hint":{"Bahasa":"Apakah anak diberikan obat cacing atau tidak?","English":"Is child given Anthelmintic?"},"label":{"Bahasa":"Apakah anak diberikan obat cacing atau tidak?","English":"Is child given antihelmintic?"},"instance":{"openmrs_entity_id":"164137AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"select one","children":[{"instance":{"openmrs_code":"1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"Yes","label":{"Bahasa":"Ya","English":"Yes"}},{"instance":{"openmrs_code":"1066AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"No","label":{"Bahasa":"Tidak","English":"No"}}]},{"instance":{"openmrs_entity_id":"encounter_end","openmrs_entity":"encounter"},"type":"end","name":"end"},{"control":{"bodyless":true},"type":"group","children":[{"bind":{"readonly":"true()","calculate":"concat('uuid:', uuid())"},"type":"calculate","name":"instanceID"}],"name":"meta"}]} \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/kunjungan_gizi/form.xml b/opensrp-gizi/src/main/assets/www/form/kunjungan_gizi/form.xml new file mode 100644 index 0000000..0832695 --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/kunjungan_gizi/form.xml @@ -0,0 +1,37 @@ +
+

EC Kunjungan Gizi

+ + + + + + + + + + + + + + + + + + + + +
Makanan Pendamping AsiSupplementary food for children under 2/complementary feeding +
+
Asi EksklusifExclusive BreastfeedingPemberian asi ekslusif pada bayi- +
+
Pemberian Vitamin AAdministration of Vitamin APemberian vitamin A pada bayi- +
+
Kapan vitamin A diberikan?When the vitamin A given?Tulis 'Ya' Jika diberikan pada Hari pelaksanaan dan 'Tidak' jika diberikan pada Sweeping Day- +
+
Jenis Vitamin A yang diberikanType of Vitamin A given +
+
Apakah anak diberikan obat cacing atau tidak?Is child given antihelmintic?Apakah anak diberikan obat cacing atau tidak?Is child given Anthelmintic? +
+ + +
\ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/kunjungan_gizi/form_definition.json b/opensrp-gizi/src/main/assets/www/form/kunjungan_gizi/form_definition.json new file mode 100644 index 0000000..e474b29 --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/kunjungan_gizi/form_definition.json @@ -0,0 +1,196 @@ +{ + "form_data_definition_version": "1", + "form": { + "bind_type": "anak", + "ec_bind_type":"ec_anak", + "default_bind_path": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/", + "fields": [ + { + "name": "id", + "shouldLoadValue": true + }, + { + "name": "start", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/start" + }, + { + "name": "gender", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/jenis_kelamin", + "shouldLoadValue": true + }, + { + "name": "existing_location", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/existing_location", + "shouldLoadValue": true + }, + { + "name": "desa_anak", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/Village", + "shouldLoadValue": true + }, + { + "name": "dusun", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/existing_Sub-village", + "shouldLoadValue": true + }, + { + "name": "namaBayi", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/nama_bayi", + "shouldLoadValue": true + }, + { + "name": "underweight", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/underweight", + "shouldLoadValue": true + }, + { + "name": "stunting", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/stunting", + "shouldLoadValue": true + }, + { + "name": "wasting", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/wasting", + "shouldLoadValue": true + }, + { + "name": "weight_for_age_status", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/weight_for_age_status", + "shouldLoadValue": true + }, + { + "name": "height_for_age_status", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/height_for_age_status", + "shouldLoadValue": true + }, + { + "name": "weight_for_length_status", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/weight_for_length_status", + "shouldLoadValue": true + }, + { + "name": "nutrition_status", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/nutrition_status", + "shouldLoadValue": true + }, + { + "name": "bgm", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/bgm", + "shouldLoadValue": true + }, + { + "name": "dua_t", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/dua_t", + "shouldLoadValue": true + }, + { + "name": "ntob_status", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/ntob_status", + "shouldLoadValue": true + }, + { + "name": "bgm_status", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/bgm_status", + "shouldLoadValue": true + }, + { + "name": "dua_t_status", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/dua_t_status", + "shouldLoadValue": true + }, + { + "name": "kunjunganSebelumnya", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/kunjungan_sebelumnya", + "shouldLoadValue": true + }, + { + "name": "tanggalPenimbangan", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/tanggal_penimbangan" + }, + { + "name": "tanggalLahirAnak", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/tanggal_lahir", + "shouldLoadValue": true + }, + { + "name": "umur", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/umur" + }, + { + "name": "preload_umur", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/history_umur", + "shouldLoadValue": true + }, + { + "name": "history_umur", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/history_umur" + }, + { + "name": "beratBadan", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/berat_badan" + }, + { + "name": "history_berat", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/berat_preload", + "shouldLoadValue": true + }, + { + "name": "history_berat", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/history_berat" + }, + + { + "name": "tinggiBadan", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/tinggi_badan" + }, + { + "name": "history_tinggi", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/preload_history_tinggi", + "shouldLoadValue": true + }, + { + "name": "history_tinggi", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/history_tinggi" + }, + { + "name": "asi", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/ae" + }, + { + "name": "mp_asi", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/mp_asi" + }, + { + "name": "vitA", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/vitA" + }, + { + "name": "waktuVitA", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/waktuVitA" + }, + { + "name": "obatcacing", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/obatcacing" + }, + { + "name": "lastVitA", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/lastVitA", + "shouldLoadValue":true + }, + { + "name": "lastAnthelmintic", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/lastAnthelmintic", + "shouldLoadValue":true + }, + { + "name": "end", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/end" + }, + { + "name": "registrationDate", + "bind": "/model/instance/EC_Kunjungan_Gizi_NewStructure-mapped_O/today" + } + + ] + } +} \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/kunjungan_gizi/model.xml b/opensrp-gizi/src/main/assets/www/form/kunjungan_gizi/model.xml new file mode 100644 index 0000000..71ddf7e --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/kunjungan_gizi/model.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0:0 + + + + 0:0 + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/registrasi_gizi/form.json b/opensrp-gizi/src/main/assets/www/form/registrasi_gizi/form.json new file mode 100644 index 0000000..7b4002c --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/registrasi_gizi/form.json @@ -0,0 +1 @@ +{"name":"Registrasi_Gizi-NewStructure-map","title":"Registrasi Gizi","sms_keyword":"registrasi_gizi_new","default_language":"Bahasa","instance":{"encounter_type":"Registrasi Gizi"},"version":"201702131126","id_string":"registrasi_gizi_new","type":"survey","children":[{"instance":{"openmrs_entity_id":"encounter_start","openmrs_entity":"encounter"},"type":"start","name":"start"},{"instance":{"openmrs_entity_id":"encounter_date","openmrs_entity":"encounter"},"type":"today","name":"today"},{"type":"deviceid","name":"deviceid"},{"type":"simserial","name":"simserial"},{"type":"phonenumber","name":"phonenumber"},{"type":"hidden","name":"Province"},{"type":"hidden","name":"District","hint":{"Bahasa":"Inject from app"}},{"type":"hidden","name":"Sub-district","hint":{"Bahasa":"Inject from app"}},{"type":"hidden","name":"Village","hint":{"Bahasa":"Inject from app"}},{"type":"hidden","name":"Sub-village","hint":{"Bahasa":"Inject from app"}},{"instance":{"openmrs_entity_id":"UniqueId","openmrs_entity":"person_attribute"},"type":"hidden","name":"unique_id"},{"type":"note","name":"generated_note_name_14","label":{"Bahasa":"Desa : ${Village}"}},{"type":"note","name":"generated_note_name_15","label":{"Bahasa":"Dusun : ${Sub-village}"}},{"bind":{"calculate":"${Village}"},"type":"hidden","name":"existing_location","instance":{"openmrs_entity_id":"location_id","openmrs_entity":"encounter"}},{"bind":{"calculate":"${Province}"},"type":"calculate","name":"provinsi","instance":{"openmrs_entity_parent":"usual_residence","openmrs_entity_id":"stateProvince","openmrs_entity":"person_address"}},{"bind":{"calculate":"${District}"},"type":"calculate","name":"kabupaten","instance":{"openmrs_entity_parent":"usual_residence","openmrs_entity_id":"countyDistrict","openmrs_entity":"person_address"}},{"bind":{"calculate":"${Village}"},"type":"calculate","name":"desa","instance":{"openmrs_entity_parent":"usual_residence","openmrs_entity_id":"cityVillage","openmrs_entity":"person_address"}},{"bind":{"calculate":"${Sub-village}"},"type":"calculate","name":"dusun","instance":{"openmrs_entity_parent":"usual_residence","openmrs_entity_id":"address1","openmrs_entity":"person_address"}},{"bind":{"calculate":"${Sub-district}"},"type":"calculate","name":"kecamatan","instance":{"openmrs_entity_parent":"usual_residence","openmrs_entity_id":"address2","openmrs_entity":"person_address"}},{"name":"pasien_wilayah","bind":{"required":"yes"},"label":{"Bahasa":"Apakah anak adalah sasaran wilayah Anda?","English":"Is the child living in your catchment area?"},"instance":{"openmrs_entity_id":"160637AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"select one","children":[{"instance":{"openmrs_code":"160635AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"pasien_wilayah_desa","label":{"Bahasa":"Ya","English":"Yes"}},{"instance":{"openmrs_code":"160636AAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"pasien_luar_wilayah","label":{"Bahasa":"Tidak","English":"No"}}]},{"name":"pasien_pindahan","bind":{"required":"yes"},"label":{"Bahasa":"Apakah anak ini pindahan dari desa lain?","English":"Is the child moving in to this village?"},"instance":{"openmrs_entity_id":"160563AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"select one","children":[{"instance":{"openmrs_code":"1065AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"Yes","label":{"Bahasa":"Ya","English":"Yes"}},{"instance":{"openmrs_code":"1066AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"No","label":{"Bahasa":"Tidak","English":"No"}}]},{"name":"tgl_pindah","hint":{"Bahasa":"Tuliskan tanggal anak pindah ke desa ini","English":"Write the date when the mother moved into this village"},"bind":{"relevant":"${pasien_pindahan}='ya'","required":"yes","constraint":".<${today}"},"label":{"Bahasa":"Sejak kapan anak pindah ke sini?","English":"Since when did she move this village?"},"instance":{"openmrs_entity_id":"160534AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"date"},{"label":{"Bahasa":"Nama Posyandu","English":"Health Post"},"type":"text","name":"posyandu","hint":{"Bahasa":"Nama Pos Pelayanan Terpadu","English":"Name of Health Post"}},{"instance":{"openmrs_entity_id":"last_name","openmrs_entity":"person"},"label":{"Bahasa":"Nama Ayah","English":"Fathr's Name"},"type":"text","name":"nama_ayah","hint":{"Bahasa":"Nama Ayah Bayi yang diberikan Imunisasi","English":"Name of Baby's Father Receiving Immunization"}},{"instance":{"openmrs_entity_id":"first_name","openmrs_entity":"person"},"label":{"Bahasa":"Nama Ibu","English":"Mother's Name"},"type":"text","name":"nama_ibu","hint":{"Bahasa":"Nama Ibu Bayi yang diberikan Imunisasi","English":"Name of Baby's Mother Receiving Immunization"}},{"instance":{"openmrs_entity_id":"NoIbu","openmrs_entity":"person_attribute"},"type":"integer","name":"no_ibu","bind":{"required":"yes"},"label":{"Bahasa":"No. Ibu","English":"Mother's Number"}},{"instance":{"openmrs_entity_id":"nik","openmrs_entity":"person_identifier"},"label":{"Bahasa":"NIK","English":"National identification number"},"type":"integer","name":"nik","hint":{"Bahasa":"Nomor KTP (Kartu Tanda Penduduk)","English":"Personal identity number"}},{"default":"0","instance":{"openmrs_entity_id":"1532AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"hidden","name":"umur","hint":{"Bahasa":"for sync purpose"}},{"default":"0","instance":{"openmrs_entity_id":"374AAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"type":"hidden","name":"jenis_kontrasepsi","hint":{"Bahasa":"for sync purpose"}},{"instance":{"openmrs_entity_id":"Child Registration","openmrs_entity":"person"},"type":"repeat","children":[{"bind":{"calculate":"${Village}"},"type":"calculate","name":"desa_anak","instance":{"openmrs_entity_parent":"cityVillage","openmrs_entity_id":"160632AAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"Concept"}},{"type":"note","name":"generated_note_name_39","label":{"Bahasa":"Desa : ${desa_anak}"}},{"type":"note","name":"generated_note_name_40","label":{"Bahasa":"Unique ID: ${unique_id}"}},{"bind":{"calculate":"${Village}"},"type":"hidden","name":"child_existing_location","instance":{"openmrs_entity_id":"location_id","openmrs_entity":"encounter"}},{"name":"nama_bayi","hint":{"Bahasa":"Nama Bayi yang diberikan Imunisasi","English":"Name of Baby Receiving Immunization"},"bind":{"required":"yes"},"label":{"Bahasa":"Nama Bayi","English":"Baby's Name"},"instance":{"openmrs_entity_id":"1586AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"Concept"},"type":"text"},{"name":"jenis_kelamin","hint":{"Bahasa":"Jenis Kelamin Bayi/Balita Yang diberikan Imunisasi","English":"Gender of Baby Receiving Immunization"},"bind":{"required":"yes"},"label":{"Bahasa":"Jenis Kelamin","English":"Gender"},"instance":{"openmrs_entity_id":"gender","openmrs_entity":"person"},"type":"select one","children":[{"instance":{"openmrs_code":"1534AAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"male","label":{"Bahasa":"Laki - laki","English":"Male"}},{"instance":{"openmrs_code":"1535AAAAAAAAAAAAAAAAAAAAAAAAAAAA"},"name":"female","label":{"Bahasa":"Perempuan","English":"Female"}}]},{"name":"tanggal_lahir","hint":{"Bahasa":"Tanggal lahir Bayi","English":"Baby's date of birth"},"bind":{"required":"yes"},"label":{"Bahasa":"Tanggal lahir","English":"DOB"},"instance":{"openmrs_entity_id":"birthdate","openmrs_entity":"person"},"type":"date"},{"instance":{"openmrs_entity_id":"5916AAAAAAAAAAAAAAAAAAAAAAAAAAAA","openmrs_entity":"concept"},"label":{"Bahasa":"Berat badan saat Lahir","English":"Baby's birth weight"},"type":"integer","name":"berat_badan_saat_lahir","hint":{"Bahasa":"Berat badan lahir bayi","English":"Baby's birth weight"}},{"instance":{"openmrs_entity_id":"ibuCaseId","openmrs_entity":"person_relationship"},"type":"hidden","name":"ibu_entity_id"}],"name":"child_registration"},{"control":{"bodyless":true},"type":"group","children":[{"bind":{"readonly":"true()","calculate":"concat('uuid:', uuid())"},"type":"calculate","name":"instanceID"}],"name":"meta"}]} \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/registrasi_gizi/form.xml b/opensrp-gizi/src/main/assets/www/form/registrasi_gizi/form.xml new file mode 100644 index 0000000..012db2f --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/registrasi_gizi/form.xml @@ -0,0 +1,22 @@ +
+

EC Registrasi Gizi

+ + + + +
Apakah anak adalah sasaran wilayah Anda?Is the child living in your catchment area?* +
This field is required
+
Apakah anak ini pindahan dari desa lain?Is the child moving in to this village?* +
This field is required
+ + + + + + +
Jenis KelaminGender*Jenis Kelamin Bayi/Balita Yang diberikan ImunisasiGender of Baby Receiving Immunization +
This field is required
+
+
+ +
\ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/registrasi_gizi/form_definition.json b/opensrp-gizi/src/main/assets/www/form/registrasi_gizi/form_definition.json new file mode 100644 index 0000000..2a87904 --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/registrasi_gizi/form_definition.json @@ -0,0 +1,172 @@ +{ + "form_data_definition_version": "3", + "form": { + "bind_type": "kartu_ibu", + "ec_bind_type": "ec_kartu_ibu", + "default_bind_path": "/model/instance/Registrasi_Gizi-NewStructure-map/", + "fields": [ + { + "name": "id", + "shouldLoadValue": true + }, + { + "name": "pasienWilayah", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/pasien_wilayah", + "shouldLoadValue": true + }, + { + "name": "pasienPindahan", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/pasien_pindahan", + "shouldLoadValue": true + }, + { + "name": "tglPindah", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/tgl_pindah", + "shouldLoadValue": true + }, + { + "name": "noIbu", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/no_ibu" + }, + { + "name": "existing_location", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/existing_location", + "shouldLoadValue": true + }, + { + "name": "existing_Village", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/Village", + "shouldLoadValue": true + }, + { + "name": "existing_Province", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/Province", + "shouldLoadValue": true + }, + { + "name": "existing_Sub-district", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/Sub-district", + "shouldLoadValue": true + }, + { + "name": "existing_District", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/District", + "shouldLoadValue": true + }, + { + "name": "existing_Sub-village", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/Sub-village", + "shouldLoadValue": true + }, + { + "name": "provinsi", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/provinsi", + "shouldLoadValue": true + }, + { + "name": "kabupaten", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/kabupaten", + "shouldLoadValue": true + }, + { + "name": "kecamatan", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/kecamatan", + "shouldLoadValue": true + }, + { + "name": "desa", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/desa", + "shouldLoadValue": true + }, + { + "name": "dusun", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/dusun", + "shouldLoadValue": true + }, + { + "name": "posyandu", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/posyandu" + }, + { + "name": "namaSuami", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/nama_ayah" + }, + { + "name": "namalengkap", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/nama_ibu" + }, + { + "name": "nik", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/nik" + }, + { + "name": "jenisKontrasepsi", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/jenis_kontrasepsi" + }, + { + "name": "isOutOfArea", + "value": "false" + }, + { + "name": "submissionDate", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/today" + } + ], + "sub_forms": [ + { + "name": "child_registration", + "bind_type": "anak", + "ec_bind_type": "ec_anak", + "default_bind_path": "/model/instance/Registrasi_Gizi-NewStructure-map/child_registration/", + "fields": [ + { + "name": "id", + "shouldLoadValue": true + }, + { + "name": "relationalid", + "shouldLoadValue": true + }, + { + "name": "injectedBaseEntityId", + "shouldLoadValue": true + }, + { + "name": "ibu_entity_id", + "source": "kartu_ibu.id", + "shouldLoadValue": true + }, + { + "name": "unique_id", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/unique_id", + "shouldLoadValue": true + }, + { + "name": "namaBayi", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/child_registration/nama_bayi" + }, + { + "name": "jenisKelamin", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/child_registration/jenis_kelamin" + }, + { + "name": "desa_anak", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/child_registration/desa_anak" + }, + { + "name": "child_existing_location", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/child_registration/child_existing_location" + }, + { + "name": "tanggalLahirAnak", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/child_registration/tanggal_lahir" + }, + { + "name": "beratLahir", + "bind": "/model/instance/Registrasi_Gizi-NewStructure-map/child_registration/berat_badan_saat_lahir" + } + ] + } + ] + } +} \ No newline at end of file diff --git a/opensrp-gizi/src/main/assets/www/form/registrasi_gizi/model.xml b/opensrp-gizi/src/main/assets/www/form/registrasi_gizi/model.xml new file mode 100644 index 0000000..a645b82 --- /dev/null +++ b/opensrp-gizi/src/main/assets/www/form/registrasi_gizi/model.xml @@ -0,0 +1,52 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 + 0 + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/GiziHomeActivity.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/GiziHomeActivity.java new file mode 100644 index 0000000..97db8ab --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/GiziHomeActivity.java @@ -0,0 +1,381 @@ +package org.ei.opensrp.gizi; + +import android.content.SharedPreferences; +import android.database.Cursor; +import android.os.StrictMode; +import android.preference.PreferenceManager; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.TextView; +import android.widget.Toast; + +import com.flurry.android.FlurryAgent; + +import org.ei.opensrp.AllConstants; +import org.ei.opensrp.Context; +import org.ei.opensrp.commonregistry.CommonPersonObjectController; +import org.ei.opensrp.cursoradapter.SmartRegisterQueryBuilder; +import org.ei.opensrp.event.Listener; + +import org.ei.opensrp.gizi.face.camera.util.Tools; +import org.ei.opensrp.repository.AllSharedPreferences; +import org.ei.opensrp.service.PendingFormSubmissionService; +import org.ei.opensrp.sync.SyncAfterFetchListener; +import org.ei.opensrp.sync.SyncProgressIndicator; +import org.ei.opensrp.sync.UpdateActionsTask; +import org.ei.opensrp.gizi.gizi.FlurryFacade; +import org.ei.opensrp.view.activity.SecuredActivity; +import org.ei.opensrp.view.contract.HomeContext; +import org.ei.opensrp.view.controller.NativeAfterANMDetailsFetchListener; +import org.ei.opensrp.view.controller.NativeUpdateANMDetailsTask; +import org.ei.opensrp.view.fragment.DisplayFormFragment; +import org.json.JSONObject; +import org.opensrp.api.domain.Location; +import org.opensrp.api.util.EntityUtils; +import org.opensrp.api.util.LocationTree; +import org.opensrp.api.util.TreeNode; + +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import util.formula.Support; + +import static android.widget.Toast.LENGTH_SHORT; +import static java.lang.String.valueOf; +import static org.ei.opensrp.event.Event.ACTION_HANDLED; +import static org.ei.opensrp.event.Event.FORM_SUBMITTED; +import static org.ei.opensrp.event.Event.SYNC_COMPLETED; +import static org.ei.opensrp.event.Event.SYNC_STARTED; + +public class GiziHomeActivity extends SecuredActivity { + SimpleDateFormat timer = new SimpleDateFormat("hh:mm:ss"); + private MenuItem updateMenuItem; + private MenuItem remainingFormsToSyncMenuItem; + private PendingFormSubmissionService pendingFormSubmissionService; + + private Listener onSyncStartListener = new Listener() { + @Override + public void onEvent(Boolean data) { + Support.ONSYNC = true; + AllConstants.SLEEP_TIME = 15000; + if (updateMenuItem != null) { + updateMenuItem.setActionView(R.layout.progress); + } + } + }; + + private Listener onSyncCompleteListener = new Listener() { + @Override + public void onEvent(Boolean data) { + //#TODO: RemainingFormsToSyncCount cannot be updated from a back ground thread!! + Support.ONSYNC = true; + updateRemainingFormsToSyncCount(); + if (updateMenuItem != null) { + updateMenuItem.setActionView(null); + } + updateRegisterCounts(); + + new Tools(context()); +// Tools.download_images(); + Tools.setVectorfromAPI(getApplicationContext()); +// AllConstants.SLEEP_TIME = AllConstants.WAITING_TIME; +// Tools.setVectorsBuffered(); + flagActivator(); + } + }; + + private void flagActivator(){ + new Thread(){ + public void run(){ + try{ + while(AllConstants.SLEEP_TIME>0){ + sleep(1000); + if(AllConstants.IDLE) + AllConstants.SLEEP_TIME-=1000; + } + Support.ONSYNC=false; + }catch (InterruptedException ie){ + + } + } + }.start(); + } + + private Listener onFormSubmittedListener = new Listener() { + @Override + public void onEvent(String instanceId) { + updateRegisterCounts(); + } + }; + + private Listener updateANMDetailsListener = new Listener() { + @Override + public void onEvent(String data) { + updateRegisterCounts(); + } + }; + + private TextView anakRegisterClientCountView; + private TextView ibuRegisterClientCountView; + public static CommonPersonObjectController kicontroller; + public static CommonPersonObjectController childcontroller; + public static int kicount; + + private int childcount; + private int ibucount; + + + @Override + protected void onCreation() { + //home dashboard + setContentView(R.layout.smart_registers_gizi_home); + // FlurryFacade.logEvent("gizi_home_dashboard"); + navigationController = new org.ei.opensrp.gizi.GiziNavigationController(this,anmController,context()); + setupViews(); + initialize(); + DisplayFormFragment.formInputErrorMessage = getResources().getString(R.string.forminputerror); + DisplayFormFragment.okMessage = getResources().getString(R.string.okforminputerror); + + String HomeStart = timer.format(new Date()); + Map Home = new HashMap(); + Home.put("start", HomeStart); + FlurryAgent.logEvent("gizi_home_dashboard",Home, true ); + + // Require for okhttp + int SDK_INT = android.os.Build.VERSION.SDK_INT; + if (SDK_INT > 8) + { + StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder() + .permitAll().build(); + StrictMode.setThreadPolicy(policy); + //your codes here + + } + + } + + private void setupViews() { + findViewById(R.id.btn_gizi_register).setOnClickListener(onRegisterStartListener); + findViewById(R.id.btn_gizi_ibu_register).setOnClickListener(onRegisterStartListener); + // findViewById(R.id.btn_test2_register).setOnClickListener(onRegisterStartListener); + // findViewById(R.id.btn_tt_register).setVisibility(View.INVISIBLE); + + findViewById(R.id.btn_reporting).setOnClickListener(onButtonsClickListener); +// findViewById(R.id.btn_videos).setOnClickListener(onButtonsClickListener); + + anakRegisterClientCountView = (TextView) findViewById(R.id.txt_child_register_client_count); + ibuRegisterClientCountView = (TextView) findViewById(R.id.txt_mother_register_client_count); + + } + + private void initialize() { + pendingFormSubmissionService = context().pendingFormSubmissionService(); + SYNC_STARTED.addListener(onSyncStartListener); + SYNC_COMPLETED.addListener(onSyncCompleteListener); + FORM_SUBMITTED.addListener(onFormSubmittedListener); + ACTION_HANDLED.addListener(updateANMDetailsListener); + getSupportActionBar().setTitle(""); + getSupportActionBar().setIcon(getResources().getDrawable(org.ei.opensrp.gizi.R.mipmap.logo)); + getSupportActionBar().setLogo(org.ei.opensrp.gizi.R.mipmap.logo); + getSupportActionBar().setDisplayUseLogoEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + LoginActivity.setLanguage(); +// getActionBar().setBackgroundDrawable(getReso +// urces().getDrawable(R.color.action_bar_background)); + } + + @Override + protected void onResumption() { + LoginActivity.setLanguage(); + updateRegisterCounts(); + updateSyncIndicator(); + updateRemainingFormsToSyncCount(); + + initFR(); + } + + private void initFR() { + new Tools(context()); + Log.e("TAG", "initFR: "+ Tools.getAppContext() ); + } + + private void updateRegisterCounts() { + NativeUpdateANMDetailsTask task = new NativeUpdateANMDetailsTask(Context.getInstance().anmController()); + task.fetch(new NativeAfterANMDetailsFetchListener() { + @Override + public void afterFetch(HomeContext anmDetails) { + updateRegisterCounts(anmDetails); + } + }); + } + + private void updateRegisterCounts(HomeContext homeContext) { + SmartRegisterQueryBuilder sqb = new SmartRegisterQueryBuilder(); + Cursor childcountcursor = context().commonrepository("anak").RawCustomQueryForAdapter(sqb.queryForCountOnRegisters("ec_anak_search", "ec_anak_search.is_closed=0")); + childcountcursor.moveToFirst(); + childcount = childcountcursor.getInt(0); + childcountcursor.close(); + + anakRegisterClientCountView.setText(valueOf(childcount)); + + Cursor ibucountcursor = context().commonrepository("ec_ibu").RawCustomQueryForAdapter(sqb.queryForCountOnRegisters("ec_ibu", "ec_ibu.is_closed=0 and ec_ibu.pptest ='Positive'")); + ibucountcursor.moveToFirst(); + ibucount = ibucountcursor.getInt(0); + ibucountcursor.close(); + + ibuRegisterClientCountView.setText(valueOf(ibucount)); + + + /* CommonPersonObjectController hhcontroller = new CommonPersonObjectController(context.allCommonsRepositoryobjects("anak"), + context.allBeneficiaries(), context.listCache(), + context.personObjectClientsCache(),"nama_bayi","anak","tanggal_lahir", CommonPersonObjectController.ByColumnAndByDetails.byDetails); + + anakRegisterClientCountView.setText(valueOf(hhcontroller.getClients("form_ditutup","true").size()));*/ + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu_main, menu); + return true; + } + + @Override + public boolean onPrepareOptionsMenu(Menu menu) { + super.onPrepareOptionsMenu(menu); + updateMenuItem = menu.findItem(R.id.updateMenuItem); + remainingFormsToSyncMenuItem = menu.findItem(R.id.remainingFormsToSyncMenuItem); + + updateSyncIndicator(); + updateRemainingFormsToSyncCount(); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.updateMenuItem: + updateFromServer(); + return true; + case R.id.switchLanguageMenuItem: + String newLanguagePreference = LoginActivity.switchLanguagePreference(); + LoginActivity.setLanguage(); + Toast.makeText(this, "Language preference set to " + newLanguagePreference + ". Please restart the application.", LENGTH_SHORT).show(); + this.recreate(); + return true; + case R.id.help: + String anmID; + try { + anmID = new JSONObject(context().anmController().get()).get("anmName").toString(); + }catch (org.json.JSONException e){ + anmID = "undefined"; + } + Toast.makeText(this, String.format("%s current user = %s",context().getStringResource(R.string.app_name),anmID), LENGTH_SHORT).show();return true; + default: + return super.onOptionsItemSelected(item); + } + } + + public void updateFromServer() { + UpdateActionsTask updateActionsTask = new UpdateActionsTask( + this, context().actionService(), context().formSubmissionSyncService(), + new SyncProgressIndicator(), context().allFormVersionSyncService()); + FlurryFacade.logEvent("click_update_from_server"); + updateActionsTask.updateFromServer(new SyncAfterFetchListener()); + String locationjson = context().anmLocationController().get(); + LocationTree locationTree = EntityUtils.fromJson(locationjson, LocationTree.class); + + Map> locationMap = + locationTree.getLocationsHierarchy(); + + if (LoginActivity.generator.uniqueIdController().needToRefillUniqueId(LoginActivity.generator.UNIQUE_ID_LIMIT)) // unique id part + LoginActivity.generator.requestUniqueId(); // unique id part + } + + @Override + protected void onDestroy() { + super.onDestroy(); + + SYNC_STARTED.removeListener(onSyncStartListener); + SYNC_COMPLETED.removeListener(onSyncCompleteListener); + FORM_SUBMITTED.removeListener(onFormSubmittedListener); + ACTION_HANDLED.removeListener(updateANMDetailsListener); + } + + private void updateSyncIndicator() { + if (updateMenuItem != null) { + if (context().allSharedPreferences().fetchIsSyncInProgress()) { + updateMenuItem.setActionView(R.layout.progress); + } else + updateMenuItem.setActionView(null); + } + } + + private void updateRemainingFormsToSyncCount() { + if (remainingFormsToSyncMenuItem == null) { + return; + } + + long size = pendingFormSubmissionService.pendingFormSubmissionCount(); + if (size > 0) { + remainingFormsToSyncMenuItem.setTitle(valueOf(size) + " " + getString(R.string.unsynced_forms_count_message)); + remainingFormsToSyncMenuItem.setVisible(true); + } else { + remainingFormsToSyncMenuItem.setVisible(false); + } + } + + private View.OnClickListener onRegisterStartListener = new View.OnClickListener() { + + @Override + public void onClick(View view) { + switch (view.getId()) { + case R.id.btn_gizi_register: + navigationController.startChildSmartRegistry(); + break; + + case R.id.btn_gizi_ibu_register: + navigationController.startANCSmartRegistry(); + break; +/* + case R.id.btn_pnc_register: +// navigationController.startPNCSmartRegistry(); + break; + + case R.id.btn_child_register: +// navigationController.startChildSmartRegistry(); + break; + + case R.id.btn_fp_register: + // navigationController.startFPSmartRegistry(); + break; */ + + } + String HomeEnd = timer.format(new Date()); + Map Home = new HashMap(); + Home.put("end", HomeEnd); + FlurryAgent.logEvent("gizi_home_dashboard",Home, true); + } + }; + + private View.OnClickListener onButtonsClickListener = new View.OnClickListener() { + + @Override + public void onClick(View view) { + switch (view.getId()) { + case R.id.btn_reporting: + navigationController.startReports(); + break; + + case R.id.btn_videos: +// navigationController.startVideos(); + break; + } + } + }; +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/GiziNavigationController.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/GiziNavigationController.java new file mode 100644 index 0000000..4665f91 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/GiziNavigationController.java @@ -0,0 +1,75 @@ +package org.ei.opensrp.gizi; + +import android.app.Activity; +import android.content.Intent; +import android.content.SharedPreferences; +import android.net.Uri; + + +//import org.ei.opensrp.gizi.test.TestSmartRegisterActivity; +import org.ei.opensrp.gizi.gizi.GiziSmartRegisterActivity; +import org.ei.opensrp.gizi.giziIbu.IbuSmartRegisterActivity; +import org.ei.opensrp.view.activity.ReportsActivity; +import org.ei.opensrp.view.controller.ANMController; +import org.json.JSONObject; + + +import static android.preference.PreferenceManager.getDefaultSharedPreferences; + +public class GiziNavigationController extends org.ei.opensrp.view.controller.NavigationController { + private Activity activity; + private ANMController anmController; + private org.ei.opensrp.Context context; + + public GiziNavigationController(Activity activity, ANMController anmController) { + super(activity,anmController); + this.activity = activity; + this.anmController = anmController; + } + + public GiziNavigationController(Activity activity, ANMController anmController, org.ei.opensrp.Context context) { + this(activity,anmController); + this.context=context; + } + + @Override + public void startECSmartRegistry() { + // activity.startActivity(new Intent(activity, TestSmartRegisterActivity.class)); + /// activity.startActivity(new Intent(activity, HouseHoldSmartRegisterActivity.class)); + SharedPreferences sharedPreferences = getDefaultSharedPreferences(this.activity); + + if(sharedPreferences.getBoolean("firstlauch",true)) { + sharedPreferences.edit().putBoolean("firstlauch",false).commit(); + // activity.startActivity(new Intent(activity, tutorialCircleViewFlow.class)); + } + + } + @Override + public void startFPSmartRegistry() { + // activity.startActivity(new Intent(activity, ElcoSmartRegisterActivity.class)); + } + @Override + public void startANCSmartRegistry() { + activity.startActivity(new Intent(activity, IbuSmartRegisterActivity.class)); + } + + @Override + public void startChildSmartRegistry() { + activity.startActivity(new Intent(activity, GiziSmartRegisterActivity.class)); + } + + @Override + public void startReports() { + String id, pass; + try{ + id = new JSONObject(anmController.get()).get("anmName").toString(); + pass = context.allSettings().fetchANMPassword(); + }catch(org.json.JSONException ex){ + id="noname"; + pass="null"; + } + String uri = "http://"+id+":"+pass+"@"+activity.getApplicationContext().getString(R.string.dho_site).replace("http://",""); + activity.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(uri))); + } + +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/LoginActivity.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/LoginActivity.java new file mode 100644 index 0000000..385a742 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/LoginActivity.java @@ -0,0 +1,420 @@ +package org.ei.opensrp.gizi; + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.ProgressDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.res.Resources; +import android.os.Bundle; +import android.text.InputType; +import android.util.DisplayMetrics; +import android.view.KeyEvent; +import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuItem; +import android.view.View; +import android.view.inputmethod.EditorInfo; +import android.view.inputmethod.InputMethodManager; +import android.widget.EditText; +import android.widget.ImageView; +import android.widget.TextView; + +import com.flurry.android.FlurryAgent; + +import org.ei.opensrp.Context; +import org.ei.opensrp.domain.LoginResponse; +import org.ei.opensrp.domain.Response; +import org.ei.opensrp.domain.ResponseStatus; +import org.ei.opensrp.event.Listener; +import org.ei.opensrp.repository.AllSharedPreferences; +import org.ei.opensrp.sync.DrishtiSyncScheduler; +import org.ei.opensrp.gizi.gizi.ErrorReportingFacade; +import org.ei.opensrp.util.Log; +import org.ei.opensrp.view.BackgroundAction; +import org.ei.opensrp.view.LockingBackgroundTask; +import org.ei.opensrp.view.ProgressIndicator; +import org.ei.opensrp.view.activity.SettingsActivity; + +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Locale; +import java.util.zip.ZipEntry; +import java.util.zip.ZipFile; + +import util.uniqueIdGenerator.Generator; + +import static android.preference.PreferenceManager.getDefaultSharedPreferences; +import static android.view.inputmethod.InputMethodManager.HIDE_NOT_ALWAYS; +import static org.ei.opensrp.domain.LoginResponse.NO_INTERNET_CONNECTIVITY; +import static org.ei.opensrp.domain.LoginResponse.SUCCESS; +import static org.ei.opensrp.domain.LoginResponse.UNAUTHORIZED; +import static org.ei.opensrp.domain.LoginResponse.UNKNOWN_RESPONSE; +import static org.ei.opensrp.util.Log.logError; +import static org.ei.opensrp.util.Log.logVerbose; + +public class LoginActivity extends Activity { + private Context context; + private EditText userNameEditText; + private EditText passwordEditText; + private ProgressDialog progressDialog; + public static final String ENGLISH_LOCALE = "en"; + public static final String KANNADA_LOCALE = "kn"; + public static final String BENGALI_LOCALE = "bn"; + public static final String BAHASA_LOCALE = "in"; + public static final String ENGLISH_LANGUAGE = "English"; + public static final String KANNADA_LANGUAGE = "Kannada"; + public static final String Bengali_LANGUAGE = "Bengali"; + public static final String Bahasa_LANGUAGE = "Bahasa"; + + public static Generator generator; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + logVerbose("Initializing ..."); + try { + AllSharedPreferences allSharedPreferences = new AllSharedPreferences(getDefaultSharedPreferences(this)); + String preferredLocale = allSharedPreferences.fetchLanguagePreference(); + Resources res = Context.getInstance().applicationContext().getResources(); + // Change locale settings in the app. + DisplayMetrics dm = res.getDisplayMetrics(); + android.content.res.Configuration conf = res.getConfiguration(); + conf.locale = new Locale(preferredLocale); + res.updateConfiguration(conf, dm); + } catch (Exception e) { + + } + setContentView(org.ei.opensrp.R.layout.login); + ImageView loginglogo = (ImageView) findViewById(R.id.login_logo); + loginglogo.setImageDrawable(getResources().getDrawable(R.mipmap.gizilogin)); + context = Context.getInstance().updateApplicationContext(this.getApplicationContext()); + initializeLoginFields(); + initializeBuildDetails(); + setDoneActionHandlerOnPasswordField(); + initializeProgressDialog(); + getActionBar().setTitle(""); + getActionBar().setIcon(getResources().getDrawable(org.ei.opensrp.gizi.R.mipmap.logo)); + getActionBar().setBackgroundDrawable(getResources().getDrawable(org.ei.opensrp.gizi.R.color.action_bar_background)); + setLanguage(); + + +// debugApp(); + + } + + private void debugApp(){ + LayoutInflater layoutInflater = getLayoutInflater(); + View view = layoutInflater.inflate(R.layout.login, null); + if (context.userService().hasARegisteredUser()){ +// localLogin(view, "demo_test", "Demo@123"); + localLogin(view, "user28", "1Sampai8"); + } else { +// remoteLogin(view, "demo_test", "Demo@123"); + remoteLogin(view, "user28", "1Sampai8"); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) + { + // Inflate the menu; this adds items to the action bar if it is present. + menu.add("Settings"); + return true; + } + @Override + public boolean onOptionsItemSelected(MenuItem item) { + if(item.getTitle().toString().equalsIgnoreCase("Settings")){ + startActivity(new Intent(this,SettingsActivity.class)); + return true; + } + return super.onOptionsItemSelected(item); + } + + private void initializeBuildDetails() { + TextView buildDetailsTextView = (TextView) findViewById(org.ei.opensrp.R.id.login_build); + try { + buildDetailsTextView.setText("Version " + getVersion() + ", Built on: " + getBuildDate()); + } catch (Exception e) { + logError("Error fetching build details: " + e); + } + } + + @Override + protected void onResume() { + super.onResume(); + + if (!context.IsUserLoggedOut()) { + goToHome(); + } + + fillUserIfExists(); + } + + public void login(final View view) { + hideKeyboard(); + view.setClickable(false); + + final String userName = userNameEditText.getText().toString(); + final String password = passwordEditText.getText().toString(); + + if (context.userService().hasARegisteredUser()) { + localLogin(view, userName, password); + } else { + remoteLogin(view, userName, password); + } + } + + private void initializeLoginFields() { + userNameEditText = ((EditText) findViewById(org.ei.opensrp.R.id.login_userNameText)); + userNameEditText.setRawInputType(InputType.TYPE_CLASS_TEXT); + passwordEditText = ((EditText) findViewById(org.ei.opensrp.R.id.login_passwordText)); + passwordEditText.setRawInputType(InputType.TYPE_CLASS_TEXT); + } + + private void setDoneActionHandlerOnPasswordField() { + passwordEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() { + @Override + public boolean onEditorAction(TextView v, int actionId, KeyEvent event) { + if (actionId == EditorInfo.IME_ACTION_DONE) { + login(findViewById(org.ei.opensrp.R.id.login_loginButton)); + } + return false; + } + }); + } + + private void initializeProgressDialog() { + progressDialog = new ProgressDialog(this); + progressDialog.setCancelable(false); + progressDialog.setTitle(getString(org.ei.opensrp.R.string.loggin_in_dialog_title)); + progressDialog.setMessage(getString(org.ei.opensrp.R.string.loggin_in_dialog_message)); + } + + private void localLogin(View view, String userName, String password) { + if (context.userService().isValidLocalLogin(userName, password)) { + localLoginWith(userName, password); + ErrorReportingFacade.setUsername("", userName); + FlurryAgent.setUserId(userName); + } else { + showErrorDialog(getString(org.ei.opensrp.R.string.login_failed_dialog_message)); + view.setClickable(true); + } + } + + private void remoteLogin(final View view, final String userName, final String password) { + tryRemoteLogin(userName, password, new Listener() { + public void onEvent(LoginResponse loginResponse) { + ErrorReportingFacade.setUsername("", userName); + FlurryAgent.setUserId(userName); + if (loginResponse == SUCCESS) { + remoteLoginWith(userName, password, loginResponse.payload()); + } else { + if (loginResponse == null) { + showErrorDialog("Login failed. Unknown reason. Try Again"); + } else { + if(loginResponse == NO_INTERNET_CONNECTIVITY){ + showErrorDialog(getResources().getString(R.string.no_internet_connectivity)); + }else if (loginResponse == UNKNOWN_RESPONSE){ + showErrorDialog(getResources().getString(R.string.unknown_response)); + }else if (loginResponse == UNAUTHORIZED){ + showErrorDialog(getResources().getString(R.string.unauthorized)); + } +// showErrorDialog(loginResponse.message()); + } + view.setClickable(true); + } + } + }); + +/* tryGetUniqueId(userName, password, new Listener() { + @Override + public void onEvent(ResponseStatus data) { + if (data == ResponseStatus.failure) { + logError("failed to fetch unique id"); + } + goToHome(); + } + });*/ + } + + private void showErrorDialog(String message) { + AlertDialog dialog = new AlertDialog.Builder(this) + .setTitle(getString(R.string.login_failed_dialog_title)) + .setMessage(message) + .setPositiveButton("OK", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialogInterface, int i) { + } + }) + .create(); + dialog.show(); + } + + private void getLocation() { + tryGetLocation(new Listener>() { + @Override + public void onEvent(Response data) { + if (data.status() == ResponseStatus.success) { + context.userService().saveAnmLocation(data.payload()); + } + } + }); + } + + private void tryGetLocation(final Listener> afterGet) { + LockingBackgroundTask task = new LockingBackgroundTask(new ProgressIndicator() { + @Override + public void setVisible() { } + + @Override + public void setInvisible() { Log.logInfo("Successfully get location"); } + }); + + task.doActionInBackground(new BackgroundAction>() { + @Override + public Response actionToDoInBackgroundThread() { + return context.userService().getLocationInformation(); + } + + @Override + public void postExecuteInUIThread(Response result) { + afterGet.onEvent(result); + } + }); + } + + private void tryRemoteLogin(final String userName, final String password, final Listener afterLoginCheck) { + LockingBackgroundTask task = new LockingBackgroundTask(new ProgressIndicator() { + @Override + public void setVisible() { + progressDialog.show(); + } + + @Override + public void setInvisible() { + progressDialog.dismiss(); + } + }); + + task.doActionInBackground(new BackgroundAction() { + public LoginResponse actionToDoInBackgroundThread() { + return context.userService().isValidRemoteLogin(userName, password); + } + + public void postExecuteInUIThread(LoginResponse result) { + afterLoginCheck.onEvent(result); + } + }); + } + + private void fillUserIfExists() { + if (context.userService().hasARegisteredUser()) { + userNameEditText.setText(context.allSharedPreferences().fetchRegisteredANM()); + userNameEditText.setEnabled(false); + } + } + + private void hideKeyboard() { + InputMethodManager inputManager = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE); + inputManager.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), HIDE_NOT_ALWAYS); + } + + private void localLoginWith(String userName, String password) { + context.userService().localLogin(userName, password); + LoginActivity.generator = new Generator(context,userName,password); + goToHome(); + DrishtiSyncScheduler.startOnlyIfConnectedToNetwork(getApplicationContext()); + } + + private void remoteLoginWith(String userName, String password, String userInfo) { + context.userService().remoteLogin(userName, password, userInfo); + LoginActivity.generator = new Generator(context,userName,password); + goToHome(); + DrishtiSyncScheduler.startOnlyIfConnectedToNetwork(getApplicationContext()); + } + + private void goToHome() { + startActivity(new Intent(this, GiziHomeActivity.class)); + finish(); + } + + private String getVersion() throws PackageManager.NameNotFoundException { + PackageInfo packageInfo = getPackageManager().getPackageInfo(getPackageName(), 0); + return packageInfo.versionName; + } + + private String getBuildDate() throws PackageManager.NameNotFoundException, IOException { + ApplicationInfo applicationInfo = getPackageManager().getApplicationInfo(getPackageName(), 0); + ZipFile zf = new ZipFile(applicationInfo.sourceDir); + ZipEntry ze = zf.getEntry("classes.dex"); + return new SimpleDateFormat("dd MMM yyyy", Locale.getDefault()).format(new java.util.Date(ze.getTime())); + } + + public static void setLanguage(){ + AllSharedPreferences allSharedPreferences = new AllSharedPreferences(getDefaultSharedPreferences(Context.getInstance().applicationContext())); + String preferredLocale = allSharedPreferences.fetchLanguagePreference(); + Resources res = Context.getInstance().applicationContext().getResources(); + // Change locale settings in the app. + DisplayMetrics dm = res.getDisplayMetrics(); + android.content.res.Configuration conf = res.getConfiguration(); + conf.locale = new Locale(preferredLocale); + res.updateConfiguration(conf, dm); + + } + public static String switchLanguagePreference() { + AllSharedPreferences allSharedPreferences = new AllSharedPreferences(getDefaultSharedPreferences(Context.getInstance().applicationContext())); + + String preferredLocale = allSharedPreferences.fetchLanguagePreference(); + if (ENGLISH_LOCALE.equals(preferredLocale)) { + allSharedPreferences.saveLanguagePreference(BAHASA_LOCALE); + Resources res = Context.getInstance().applicationContext().getResources(); + // Change locale settings in the app. + DisplayMetrics dm = res.getDisplayMetrics(); + android.content.res.Configuration conf = res.getConfiguration(); + conf.locale = new Locale(BAHASA_LOCALE); + res.updateConfiguration(conf, dm); + return Bahasa_LANGUAGE; + } else { + allSharedPreferences.saveLanguagePreference(ENGLISH_LOCALE); + Resources res = Context.getInstance().applicationContext().getResources(); + // Change locale settings in the app. + DisplayMetrics dm = res.getDisplayMetrics(); + android.content.res.Configuration conf = res.getConfiguration(); + conf.locale = new Locale(ENGLISH_LOCALE); + res.updateConfiguration(conf, dm); + return ENGLISH_LANGUAGE; + } + } + + private void tryGetUniqueId(final String username, final String password, final Listener afterGetUniqueId) { + LockingBackgroundTask task = new LockingBackgroundTask(new ProgressIndicator() { + @Override + public void setVisible() { + progressDialog.show(); + } + @Override + public void setInvisible() { + progressDialog.dismiss(); + } + }); + + task.doActionInBackground(new BackgroundAction() { + @Override + public ResponseStatus actionToDoInBackgroundThread() { + LoginActivity.generator = new Generator(context,username,password); + LoginActivity.generator.uniqueIdService().syncUniqueIdFromServer(username, password); + return (LoginActivity.generator.uniqueIdService().getLastUsedId(username, password)); + } + + @Override + public void postExecuteInUIThread(ResponseStatus result) { + afterGetUniqueId.onEvent(result); + } + }); + } + +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/application/GiziApplication.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/application/GiziApplication.java new file mode 100644 index 0000000..90db926 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/application/GiziApplication.java @@ -0,0 +1,128 @@ +package org.ei.opensrp.gizi.application; + +import android.content.Intent; +import android.content.res.Configuration; + +import org.acra.ACRA; +import org.acra.ReportingInteractionMode; +import org.acra.annotation.ReportsCrashes; +import org.ei.opensrp.Context; +import org.ei.opensrp.commonregistry.CommonFtsObject; +import org.ei.opensrp.gizi.LoginActivity; +import org.ei.opensrp.gizi.gizi.ErrorReportingFacade; +import org.ei.opensrp.gizi.gizi.FlurryFacade; +import org.ei.opensrp.sync.DrishtiSyncScheduler; +import org.ei.opensrp.view.activity.DrishtiApplication; +import org.ei.opensrp.view.receiver.SyncBroadcastReceiver; +import static org.ei.opensrp.util.Log.logInfo; +import org.ei.opensrp.gizi.application.SyncGiziBroadcastReceiver; + +import java.util.Locale; + +/** + * Created by koros on 1/22/16. + */ + +public class GiziApplication extends DrishtiApplication { + + @Override + public void onCreate() { + DrishtiSyncScheduler.setReceiverClass(SyncBroadcastReceiver.class); + super.onCreate(); + // ACRA.init(this); + + DrishtiSyncScheduler.setReceiverClass(SyncBroadcastReceiver.class); + ErrorReportingFacade.initErrorHandler(getApplicationContext()); + /** + * ENABLE THIS AGAIN AFTER FINISH TESTING*/ + FlurryFacade.init(this); + context = Context.getInstance(); + context.updateApplicationContext(getApplicationContext()); + context.updateCommonFtsObject(createCommonFtsObject()); + applyUserLanguagePreference(); + cleanUpSyncState(); + } + + @Override + public void logoutCurrentUser(){ + Intent intent = new Intent(getApplicationContext(), LoginActivity.class); + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + getApplicationContext().startActivity(intent); + context.userService().logoutSession(); + } + + private void cleanUpSyncState() { + DrishtiSyncScheduler.stop(getApplicationContext()); + context.allSharedPreferences().saveIsSyncInProgress(false); + } + + @Override + public void onTerminate() { + super.onTerminate(); + logInfo("Application is terminating. Stopping Dristhi Sync scheduler and resetting isSyncInProgress setting."); + cleanUpSyncState(); + } + + private void applyUserLanguagePreference() { + Configuration config = getBaseContext().getResources().getConfiguration(); + + String lang = context.allSharedPreferences().fetchLanguagePreference(); + if (!"".equals(lang) && !config.locale.getLanguage().equals(lang)) { + locale = new Locale(lang); + updateConfiguration(config); + } + } + + private void updateConfiguration(Configuration config) { + config.locale = locale; + Locale.setDefault(locale); + getBaseContext().getResources().updateConfiguration(config, + getBaseContext().getResources().getDisplayMetrics()); + } + + private String[] getFtsSearchFields(String tableName){ + if(tableName.equals("ec_anak")){ + String[] ftsSearchFields = { "namaBayi","tanggalLahirAnak" }; + return ftsSearchFields; + } else if (tableName.equals("ec_kartu_ibu")){ + String[] ftsSearchFields = { "namalengkap", "namaSuami" }; + return ftsSearchFields; + } + return null; + } + + private String[] getFtsSortFields(String tableName){ + if(tableName.equals("ec_anak")){ + String[] sortFields = { "namaBayi","tanggalLahirAnak"}; + return sortFields; + } else if(tableName.equals("ec_kartu_ibu")){ + String[] sortFields = { "namalengkap", "namaSuami"}; + return sortFields; + } + return null; + } + + private String[] getFtsMainConditions(String tableName){ + if(tableName.equals("ec_anak")){ + String[] mainConditions = {"is_closed", "details" , "namaBayi"}; + return mainConditions; + } else if(tableName.equals("ec_kartu_ibu")){ + String[] mainConditions = { "is_closed", "namalengkap"}; + return mainConditions; + } + return null; + } + private String[] getFtsTables(){ + String[] ftsTables = { "ec_anak", "ec_kartu_ibu" }; + return ftsTables; + } + private CommonFtsObject createCommonFtsObject(){ + CommonFtsObject commonFtsObject = new CommonFtsObject(getFtsTables()); + for(String ftsTable: commonFtsObject.getTables()){ + commonFtsObject.updateSearchFields(ftsTable, getFtsSearchFields(ftsTable)); + commonFtsObject.updateSortFields(ftsTable, getFtsSortFields(ftsTable)); + commonFtsObject.updateMainConditions(ftsTable, getFtsMainConditions(ftsTable)); + } + return commonFtsObject; + } +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/application/SyncGiziBroadcastReceiver.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/application/SyncGiziBroadcastReceiver.java new file mode 100644 index 0000000..423c911 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/application/SyncGiziBroadcastReceiver.java @@ -0,0 +1,31 @@ +package org.ei.opensrp.gizi.application; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +import org.ei.opensrp.sync.SyncAfterFetchListener; +import org.ei.opensrp.sync.SyncProgressIndicator; +import org.ei.opensrp.sync.UpdateActionsTask; + +import static org.ei.opensrp.util.Log.logInfo; + +/** + + * Created by Dimas on 9/17/2015. + + */ +public class SyncGiziBroadcastReceiver extends BroadcastReceiver { + @Override + public void onReceive(Context context, Intent intent) { + logInfo("Sync alarm triggered. Trying to Sync."); + UpdateActionsTask updateActionsTask = new UpdateActionsTask( + context, + org.ei.opensrp.Context.getInstance().actionService(), + org.ei.opensrp.Context.getInstance().formSubmissionSyncService(), + new SyncProgressIndicator(), + org.ei.opensrp.Context.getInstance().allFormVersionSyncService()); + + // updateActionsTask.setAdditionalSyncService(org.ei.opensrp.Context.getInstance().uniqueIdService()); + + updateActionsTask.updateFromServer(new SyncAfterFetchListener()); + } +} \ No newline at end of file diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/CameraPreview.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/CameraPreview.java new file mode 100755 index 0000000..098e3c1 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/CameraPreview.java @@ -0,0 +1,90 @@ +package org.ei.opensrp.gizi.face.camera; + +import android.content.Context; +import android.hardware.Camera; +import android.hardware.Camera.Size; +import android.util.Log; +import android.view.SurfaceHolder; +import android.view.SurfaceView; + +import org.ei.opensrp.gizi.face.camera.util.FaceConstants; + +import java.io.IOException; +import java.util.List; + +public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback{ + + private static final String TAG = CameraPreview.class.getSimpleName(); + private final int mPictureFormat; + SurfaceHolder mHolder; + private Camera mCamera; + Context mContext; + protected List mPictureSizeList; + Camera.Parameters cameraParams; + + @SuppressWarnings("deprecation") + public CameraPreview(Context context, Camera camera) { + + super(context); + mCamera = camera; + mContext = context; + + // Install a SurfaceHolder.Callback so we get notified when the underlying surface is created and destroyed. + mHolder = getHolder(); + mHolder.addCallback(this); + + // deprecated setting, but required on Android versions prior to 3.0 + mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); + + cameraParams = mCamera.getParameters(); + mPictureSizeList = cameraParams.getSupportedPictureSizes(); + mPictureFormat = cameraParams.getPictureFormat(); + } + + @Override + public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {} + + @Override + public void surfaceCreated(SurfaceHolder holder) { + // After created Surface, draw View. + try { + mCamera.setDisplayOrientation(90); + mCamera.setPreviewDisplay(mHolder); + + int index = 0; + + for(int i=0; i < mPictureSizeList.size(); i++) { + + int width = mPictureSizeList.get(i).width; + int height = mPictureSizeList.get(i).height; + int size = width*height*3/2; + int MAX_NUM_BYTES = FaceConstants.MAX_PHOTO_SIZE; + if(size< MAX_NUM_BYTES) { + index = i; + break; + } + } + //int indx = mPictureSizeList.size() - 2; + cameraParams.setPictureSize(mPictureSizeList.get(index).width, mPictureSizeList.get(index).height); + + Log.e(TAG, "FORMAT" + mPictureFormat); + Log.d("CameraSurfaceView", mPictureSizeList.size() + "Picture dimension: " + mPictureSizeList.get(0).width + "x" + mPictureSizeList.get(0).height); + mCamera.setParameters(cameraParams); + mCamera.startPreview(); + + } catch (IOException e) { + + Log.e(TAG, "Error setting camera preview: " + e.getMessage()); + + } + } + + @Override + public void surfaceDestroyed(SurfaceHolder holder) { + mCamera.stopPreview(); + mCamera.release(); + mCamera = null; + } + + +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/ClientsList.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/ClientsList.java new file mode 100644 index 0000000..d345985 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/ClientsList.java @@ -0,0 +1,196 @@ +package org.ei.opensrp.gizi.face.camera; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.AdapterView; +import android.widget.GridView; +import android.widget.Toast; + +import org.ei.opensrp.clientandeventmodel.Client; +import org.ei.opensrp.gizi.R; +import org.ei.opensrp.gizi.face.camera.util.ClientAdapter; +import org.ei.opensrp.gizi.face.camera.util.FaceConstants; +import org.ei.opensrp.gizi.face.camera.util.Tools; + +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map.Entry; + +/** + * Created by wildan on 1/16/17. + */ +public class ClientsList extends Activity{ + private static final String TAG = ClientsList.class.getSimpleName(); + + private GridView gv_clientList; + private String[] names; + private HashMap hash; + + private Tools tools; + + private boolean deleteUser = false; + private boolean updateUser = false; + private byte[] albumBuffer; + + + protected void onCreate(Bundle savedInstanceBundle){ + super.onCreate(savedInstanceBundle); + + setContentView(R.layout.activity_fr_clients); + + final SmartShutterActivity ssa = new SmartShutterActivity(); + final ImageConfirmation im = new ImageConfirmation(); + + hash = SmartShutterActivity.retrieveHash(getApplicationContext()); + + gv_clientList = (GridView) findViewById(R.id.gv_list); + + refreshClients(); + + deleteUser = true; + + gv_clientList.setOnItemClickListener(new AdapterView.OnItemClickListener() { + public void onItemClick(AdapterView parent, View v, int position, long id) { + // Get the username associated with the clicked cell. + final String base_id = (String) parent.getItemAtPosition(position); + + // Delete the user + if (deleteUser && !updateUser) { + new AlertDialog.Builder(ClientsList.this) + .setMessage( + "Are you sure you want to DELETE " + + base_id + " from the album?") + .setCancelable(true) + .setPositiveButton("No", null) + .setNegativeButton("Yes", + new DialogInterface.OnClickListener() { + public void onClick( + DialogInterface dialog, int id) { + String keyValue = hash + .get(base_id); + // Getting the faceId of the registered user and converting it to integer. + int faceId = Integer + .parseInt(keyValue); + SmartShutterActivity.faceProc + .deletePerson(faceId); // Deleting the user from the database + saveAlbum(); + hash.remove(base_id); + + photo_remove(base_id); + + refreshClients(); + + im.saveHash(hash, getApplicationContext()); + Toast.makeText(getApplicationContext(), + base_id + " deleted successfully.", + Toast.LENGTH_LONG).show(); + } + }).show(); + } else if (updateUser && !deleteUser) // Update the user. + { +// Intent intent = new Intent(ClientsList.this, AddPhoto.class); +// intent.putExtra("Username", username); +// intent.putExtra("PersonId", clientList.get(username)); +// intent.putExtra("UpdatePerson", true); +// startActivity(intent); + } + } + }); + } + + public boolean onCreateOptionsMenu(Menu menu){ + + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.client_activity, menu); + + return super.onCreateOptionsMenu(menu); + } + + public boolean onOptionsItemSelected(MenuItem item){ + switch (item.getItemId()){ + case R.id.action_reset: +// SmartShutterActivity ss = new SmartShutterActivity(); + resetAlbum(); +// Tools.alertDialog(ClientsList.this, AppConstant.RESET_OPT); +// Storage + + return true; + default: + return super.onOptionsItemSelected(item); + } + } + + private void photo_remove(String base_id) { + + } + + private void saveAlbum() { + Log.e(TAG, "saveAlbum: "+"saving" ); + albumBuffer = SmartShutterActivity.faceProc.serializeRecogntionAlbum(); + Log.e(TAG, "saveAlbum: "+albumBuffer.toString() ); + SharedPreferences settings = getSharedPreferences(FaceConstants.ALBUM_NAME, 0); + SharedPreferences.Editor editor = settings.edit(); + editor.putString(FaceConstants.ALBUM_ARRAY, Arrays.toString(albumBuffer)); + editor.apply(); + } + + private void refreshClients(){ + names = new String[hash.size()]; + int i = 0; + for (Entry entry : hash.entrySet() + ){ + names[i] = entry.getKey(); + i++; + } + gv_clientList.setAdapter(new ClientAdapter(this, names)); + } + + public void resetAlbum() { + + AlertDialog.Builder builder= new AlertDialog.Builder(this); + + builder.setTitle("Are you Sure?"); + builder.setMessage("All photos and media will lose!"); + builder.setNegativeButton("CANCEL", null); + builder.setPositiveButton("ERASE", doEmpty); + builder.show(); + } + + private DialogInterface.OnClickListener doEmpty = new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + boolean result = SmartShutterActivity.faceProc.resetAlbum(); + +// Log.e(TAG, "onClick: "+result ); +// new Tools().resetAlbum(); + + if (result) { + HashMap hashMap = SmartShutterActivity.retrieveHash(getApplicationContext()); + hashMap.clear(); + + SmartShutterActivity ss = new SmartShutterActivity(); + + // Clear List Clients + ss.saveHash(hashMap, getApplicationContext()); + + saveAlbum(); + + Toast.makeText(getApplicationContext(), + "Album Reset Successful.", + Toast.LENGTH_LONG).show(); + } else { + Toast.makeText( + getApplicationContext(), + "Internal Error. Reset album failed", + Toast.LENGTH_LONG).show(); + } + } + }; +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/ImageConfirmation.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/ImageConfirmation.java new file mode 100755 index 0000000..f202ec7 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/ImageConfirmation.java @@ -0,0 +1,427 @@ +package org.ei.opensrp.gizi.face.camera; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Matrix; +import android.graphics.Rect; +import android.os.Bundle; +import android.os.Parcelable; +import android.util.Base64; +import android.util.Log; +import android.view.Menu; +import android.view.MotionEvent; +import android.view.View; +import android.widget.ImageView; +import android.widget.Toast; + +import com.qualcomm.snapdragon.sdk.face.FaceData; +import com.qualcomm.snapdragon.sdk.face.FacialProcessing; + +import org.ei.opensrp.commonregistry.AllCommonsRepository; +import org.ei.opensrp.commonregistry.CommonPersonObject; +import org.ei.opensrp.commonregistry.CommonPersonObjectClient; +import org.ei.opensrp.gizi.R; + +import org.ei.opensrp.gizi.face.camera.util.FaceConstants; +import org.ei.opensrp.gizi.face.camera.util.Tools; + +import org.ei.opensrp.gizi.fragment.GiziIbuSmartRegisterFragment; +import org.ei.opensrp.gizi.fragment.GiziSmartRegisterFragment; +import org.ei.opensrp.gizi.gizi.GiziDetailActivity; +import org.ei.opensrp.gizi.gizi.GiziSmartRegisterActivity; +import org.ei.opensrp.gizi.giziIbu.IbuSmartRegisterActivity; + +import java.io.ByteArrayOutputStream; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Iterator; + +//import com.google.firebase.database.DatabaseReference; +//import com.google.firebase.database.FirebaseDatabase; + +public class ImageConfirmation extends Activity { + + private static String TAG = ImageConfirmation.class.getSimpleName(); + private Bitmap storedBitmap; + private Bitmap workingBitmap; + private Bitmap mutableBitmap; + ImageView confirmationView; + ImageView confirmButton; + ImageView trashButton; + private String entityId; + private Rect[] rects; + private boolean faceFlag = false; + private boolean identifyPerson = false; + private FacialProcessing objFace; + private FaceData[] faceDatas; + private int arrayPossition; + Tools tools; + HashMap clientList; + private String selectedPersonName = ""; + private Parcelable[] kiclient; + + String str_origin_class; + + byte[] data; + int angle; + boolean switchCamera; + private byte[] faceVector; + private boolean updated = false; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_fr_image_face_confirmation); + + init_gui(); + + init_extras(); + + storedBitmap = BitmapFactory.decodeByteArray(data, 0, data.length, null); + objFace = SmartShutterActivity.faceProc; + + Matrix mat = new Matrix(); + if (!switchCamera) { + mat.postRotate(angle == 90 ? 270 : (angle == 180 ? 180 : 0)); + mat.postScale(-1, 1); + storedBitmap = Bitmap.createBitmap(storedBitmap, 0, 0, storedBitmap.getWidth(), storedBitmap.getHeight(), mat, true); + } else { + mat.postRotate(angle == 90 ? 90 : (angle == 180 ? 180 : 0)); + storedBitmap = Bitmap.createBitmap(storedBitmap, 0, 0, storedBitmap.getWidth(), storedBitmap.getHeight(), mat, true); + } +// TODO : Image from gallery + +// Retrieve data from Local Storage + clientList = SmartShutterActivity.retrieveHash(getApplicationContext()); + + boolean setBitmapResult = objFace.setBitmap(storedBitmap); + faceDatas = objFace.getFaceData(); + + int imageViewSurfaceWidth = storedBitmap.getWidth(); + int imageViewSurfaceHeight = storedBitmap.getHeight(); +// int imageViewSurfaceWidth = confirmationView.getWidth(); +// int imageViewSurfaceHeight = confirmationView.getHeight(); + + // Face Confirmation view purpose + workingBitmap = Bitmap.createScaledBitmap(storedBitmap, + imageViewSurfaceWidth, imageViewSurfaceHeight, false); +// mutableBitmap = workingBitmap.copy(Bitmap.Config.ARGB_8888, true); + + mutableBitmap = storedBitmap.copy(Bitmap.Config.ARGB_8888, true); + + objFace.normalizeCoordinates(imageViewSurfaceWidth, imageViewSurfaceHeight); + + // Set Bitmap Success + if(setBitmapResult){ +// Log.e(TAG, "onCreate: SetBitmap objFace "+"Success" ); + + // Face Data Exist + if(faceDatas != null){ +// Log.e(TAG, "onCreate: faceDatas "+faceDatas.length ); + rects = new Rect[faceDatas.length]; + + for (int i = 0; i < faceDatas.length; i++) { + Rect rect = faceDatas[i].rect; + rects[i] = rect; + + int matchRate = faceDatas[i].getRecognitionConfidence(); + + float pixelDensity = getResources().getDisplayMetrics().density; + +// Identify or new record + if (identifyPerson) { + String selectedPersonId = Integer.toString(faceDatas[i].getPersonId()); + Iterator> iter = clientList.entrySet().iterator(); + // Default name is the person is unknown + selectedPersonName = "Not Identified"; + while (iter.hasNext()) { + Log.e(TAG, "In"); + HashMap.Entry entry = iter.next(); + if (entry.getValue().equals(selectedPersonId)) { + selectedPersonName = entry.getKey(); + } + } + + Toast.makeText(getApplicationContext(), selectedPersonName, Toast.LENGTH_SHORT).show(); + +// Draw Info on Image + Tools.drawInfo(rect, mutableBitmap, pixelDensity, selectedPersonName); + + showDetailUser(selectedPersonName); + + } else { + // Not Identifiying, do new record. +// Draw Info on Image + Tools.drawRectFace(rect, mutableBitmap, pixelDensity); + + Log.e(TAG, "onCreate: PersonId "+faceDatas[i].getPersonId() ); + + // Check Detected existing face + if(faceDatas[i].getPersonId() < 0){ + + arrayPossition = i; + +// TODO : wait Button Response +// buttonJob(); +// int res = objFace.addPerson(arrayPossition); +// clientList.put(entityId, Integer.toString(res)); +// saveHash(clientList, getApplicationContext()); +// saveAlbum(); + + } else { + + showPersonInfo(matchRate); + + } + +// TODO: asign selectedPersonName to search + + // Applied Image that came in to the view. + // Face only +// confirmationView.setImageBitmap(storedBitmap); + // Face and Rect + confirmationView.setImageBitmap(mutableBitmap); + + } // end if-else mode Identify {True or False} + + } // end for count ic_faces + + } else { + + Log.e(TAG, "onCreate: faceDatas "+"Null" ); + Toast.makeText(ImageConfirmation.this, "No Face Detected", Toast.LENGTH_SHORT).show(); + Intent resultIntent = new Intent(); + setResult(RESULT_CANCELED, resultIntent); + ImageConfirmation.this.finish(); + } + + } else { + + Log.e(TAG, "onCreate: SetBitmap objFace"+"Failed" ); + + } + +// confirmationView.setImageBitmap(storedBitmap); // Setting the view with the bitmap image that came in. +// confirmationView.setImageBitmap(mutableBitmap); // Setting the view with the bitmap image that came in. + + buttonJob(); + } + + private void showPersonInfo(int recognitionConfidence) { + Log.e(TAG, "showPersonInfo: Similar face found " + + Integer.toString(recognitionConfidence)); + + AlertDialog.Builder builder= new AlertDialog.Builder(this); + + builder.setTitle("Are you Sure?"); + builder.setMessage("Similar Face Found! : Confidence "+recognitionConfidence); + builder.setNegativeButton("CANCEL", null); + builder.show(); + confirmButton.setVisibility(View.INVISIBLE); + + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.image_confirmation, menu); + return true; + } + + /** + * Method to get Info from previous Intent + */ + private void init_extras() { + Bundle extras = getIntent().getExtras(); + data = getIntent().getByteArrayExtra("org.sid.sidface.ImageConfirmation"); + angle = extras.getInt("org.sid.sidface.ImageConfirmation.orientation"); + switchCamera = extras.getBoolean("org.sid.sidface.ImageConfirmation.switchCamera"); + entityId = extras.getString("org.sid.sidface.ImageConfirmation.id"); + identifyPerson = extras.getBoolean("org.sid.sidface.ImageConfirmation.identify"); + kiclient = extras.getParcelableArray("org.sid.sidface.ImageConfirmation.kiclient"); + str_origin_class = extras.getString("org.sid.sidface.ImageConfirmation.origin"); + updated = extras.getBoolean("org.sid.sidface.ImageConfirmation.updated"); + + } + + + private void init_gui() { + // Display New Photo + confirmationView = (ImageView) findViewById(R.id.iv_confirmationView); + trashButton = (ImageView) findViewById(R.id.iv_cancel); + confirmButton = (ImageView) findViewById(R.id.iv_approve); + } + + public void showDetailUser(String selectedPersonName) { + + AllCommonsRepository ibuRepository = org.ei.opensrp.Context.getInstance().allCommonsRepositoryobjects("ec_kartu_ibu"); + CommonPersonObject kiclient = ibuRepository.findByCaseID(selectedPersonName); + +// Log.e(TAG, "onCreate: IbuRepo "+ibuRepository ); +// Log.e(TAG, "onCreate: Id "+selectedPersonName ); +// Log.e(TAG, "onCreate: KiClient "+kiclient.getCaseId() ); + + Class origin_class = this.getClass(); + + Log.e(TAG, "showDetailUser: "+ origin_class.getSimpleName() ); + Log.e(TAG, "showDetailUser: "+ str_origin_class); + + if(str_origin_class.equals(GiziSmartRegisterFragment.class.getSimpleName())){ + origin_class = GiziSmartRegisterActivity.class; + } else if(str_origin_class.equals(GiziIbuSmartRegisterFragment.class.getSimpleName())){ + origin_class = IbuSmartRegisterActivity.class; + } + + Intent intent = new Intent(ImageConfirmation.this, origin_class); + intent.putExtra("org.ei.opensrp.indonesia.face.face_mode", true); + intent.putExtra("org.ei.opensrp.indonesia.face.base_id", selectedPersonName); + + startActivity(intent); + + } + + /** + * + */ + private void buttonJob() { + // If approved then save the image and close. + confirmButton.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View arg0) { + Log.e(TAG, "onClick: " + identifyPerson); + Log.e(TAG, "onClick: " + entityId); + + if (!identifyPerson) { + +// saveAndClose(entityId); + Tools.saveAndClose(getApplicationContext(), entityId, updated, objFace, arrayPossition, storedBitmap, str_origin_class); + + } else { +// SmartRegisterQueryBuilder sqb = new SmartRegisterQueryBuilder(); +// Cursor cursor = getApplicationContext(). + GiziDetailActivity.childclient = (CommonPersonObjectClient) arg0.getTag(); + Log.e(TAG, "onClick: " + GiziDetailActivity.childclient); +// Intent intent = new Intent(ImageConfirmation.this,KIDetailActivity.class); + Log.e(TAG, "onClick: " + selectedPersonName); +// startActivity(intent); + } + } + + }); + + confirmButton.setOnTouchListener(new View.OnTouchListener() { + + @Override + public boolean onTouch(View arg0, MotionEvent arg1) { + + if (arg1.getAction() == MotionEvent.ACTION_DOWN) { + confirmButton.setImageResource(R.drawable.ic_confirm_highlighted_24dp); + } else if (arg1.getAction() == MotionEvent.ACTION_UP) { + confirmButton.setImageResource(R.drawable.ic_confirm_white_24dp); + } + + return false; + } + }); + + // Trash the image and return back to the camera preview. + trashButton.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View arg0) { + Intent resultIntent = new Intent(); + setResult(RESULT_CANCELED, resultIntent); + ImageConfirmation.this.finish(); + } + + }); + + trashButton.setOnTouchListener(new View.OnTouchListener() { + + @Override + public boolean onTouch(View arg0, MotionEvent arg1) { + + if (arg1.getAction() == MotionEvent.ACTION_DOWN) { + trashButton.setImageResource(R.drawable.ic_trash_delete_green); + } else if (arg1.getAction() == MotionEvent.ACTION_UP) { + trashButton.setImageResource(R.drawable.ic_trash_delete); + } + + return false; + } + }); + + } + + /* + Save File and DB + */ + private void saveAndClose(String entityId) { + + Log.e(TAG, "saveAndClose: updated "+ updated ); + + faceVector = objFace.serializeRecogntionAlbum(); + + Log.e(TAG, "saveAndClose: " + Arrays.toString(faceVector)); + + int result = objFace.addPerson(arrayPossition); + clientList.put(entityId, Integer.toString(result)); + + byte[] albumBuffer = SmartShutterActivity.faceProc.serializeRecogntionAlbum(); + + SmartShutterActivity.faceProc.resetAlbum(); + +// Tools.WritePictureToFile(ImageConfirmation.this, storedBitmap, entityId, albumBuffer, updated); + // TODO : change album buffer to String[] +// Tools.WritePictureToFile(storedBitmap, entityId, albumBuffer, updated); + + ImageConfirmation.this.finish(); + + Intent resultIntent = new Intent(this, GiziDetailActivity.class); + setResult(RESULT_OK, resultIntent); + startActivityForResult(resultIntent, 1); + + Log.e(TAG, "saveAndClose: "+"end" ); + } + + public void saveHash(HashMap hashMap, android.content.Context context) { + SharedPreferences settings = context.getSharedPreferences(FaceConstants.HASH_NAME, 0); + + SharedPreferences.Editor editor = settings.edit(); + editor.clear(); + Log.e(TAG, "Hash Save Size = " + hashMap.size()); + for (String s : hashMap.keySet()) { + editor.putString(s, hashMap.get(s)); + } + editor.apply(); + } + + public void saveAlbum() { + byte[] albumBuffer = SmartShutterActivity.faceProc.serializeRecogntionAlbum(); +// saveCloud(albumBuffer); + Log.e(TAG, "Size of byte Array =" + albumBuffer.length); + SharedPreferences settings = getSharedPreferences(FaceConstants.ALBUM_NAME, 0); + SharedPreferences.Editor editor = settings.edit(); + editor.putString(FaceConstants.ALBUM_ARRAY, Arrays.toString(albumBuffer)); + editor.apply(); + } + + public void encodeBitmapAndSaveToFirebase(Bitmap bitmap) { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos); + String imageEncoded = Base64.encodeToString(baos.toByteArray(), Base64.DEFAULT); +// DatabaseReference ref = FirebaseDatabase.getInstance() +// .getReference(AllConstantsINA.FIREBASE_OPENSRP_INA) +// .child(FirebaseAuth.getInstance().getCurrentUser().getUid()) +// .child(mRestaurant.getPushId()) +// .child("imageUrl"); +// ref.setValue(imageEncoded); + } + + +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/PaintFaceView.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/PaintFaceView.java new file mode 100755 index 0000000..72ba618 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/PaintFaceView.java @@ -0,0 +1,100 @@ +package org.ei.opensrp.gizi.face.camera; + +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Point; +import android.graphics.PorterDuff.Mode; +import android.graphics.Rect; +import android.view.SurfaceView; + +import com.qualcomm.snapdragon.sdk.face.FaceData; + +import org.ei.opensrp.gizi.face.camera.util.FaceConstants; + + +public class PaintFaceView extends SurfaceView { + + public FaceData[]mFaceArray; + boolean existFrame; + private Paint leftEyeBrush = new Paint(); + private Paint rightEyeBrush = new Paint(); + private Paint mouthBrush = new Paint(); + private Paint rectBrush = new Paint(); + public Point leftEye, rightEye, mouth; + Rect mFaceRect; + int mSurfaceWidth; + int mSurfaceHeight; + int cameraPreviewWidth; + int cameraPreviewHeight; + boolean mLandScapeMode; + float scaleX=1.0f; + float scaleY=1.0f; + + public PaintFaceView(Context context, FaceData[] faceArray, boolean inFrame) { + super(context); + setWillNotDraw(false); + mFaceArray = faceArray; + existFrame = inFrame; + } + + + @Override + protected void onDraw(Canvas canvas){ + + // Check exist face in frame. + if(existFrame) { + for (FaceData aMFaceArray : mFaceArray) { + leftEyeBrush.setColor(Color.RED); + canvas.drawCircle(aMFaceArray.leftEye.x, aMFaceArray.leftEye.y, 5f, leftEyeBrush); + + rightEyeBrush.setColor(Color.GREEN); + canvas.drawCircle(aMFaceArray.rightEye.x, aMFaceArray.rightEye.y, 5f, rightEyeBrush); + + mouthBrush.setColor(Color.WHITE); + canvas.drawCircle(aMFaceArray.mouth.x, aMFaceArray.mouth.y, 5f, mouthBrush); + + setRectColor(aMFaceArray, rectBrush); // changing color w.r.t. smile + + rectBrush.setStrokeWidth(2); + rectBrush.setStyle(Paint.Style.STROKE); + canvas.drawRect(aMFaceArray.rect.left, aMFaceArray.rect.top, aMFaceArray.rect.right, aMFaceArray.rect.bottom, rectBrush); + } + + } else { + canvas.drawColor(0, Mode.CLEAR); + } + } + + /* + Method Coloring face by Smile Value + */ + private void setRectColor(FaceData faceData, Paint rectBrush) { + if(faceData.getSmileValue() < 40) { + + rectBrush.setColor(Color.RED); + + } else if(faceData.getSmileValue() < 55) { + + rectBrush.setColor(Color.parseColor(FaceConstants.RED_ORANGE)); + + } else if(faceData.getSmileValue() < 70) { + + rectBrush.setColor(Color.parseColor(FaceConstants.ORANGE_YELLOW)); + + } else if(faceData.getSmileValue() < 85) { + + rectBrush.setColor(Color.parseColor(FaceConstants.YELLOW_GREEN)); + + } else { + + rectBrush.setColor(Color.parseColor(FaceConstants.GREEN)); + } + + } + + + + +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/SmartShutterActivity.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/SmartShutterActivity.java new file mode 100755 index 0000000..6e1b7b2 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/SmartShutterActivity.java @@ -0,0 +1,1081 @@ +package org.ei.opensrp.gizi.face.camera; + +import android.annotation.SuppressLint; +import android.app.Activity; +import android.app.AlertDialog; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.Configuration; +import android.graphics.Bitmap; +import android.graphics.Color; +import android.graphics.drawable.AnimationDrawable; +import android.hardware.Camera; +import android.hardware.Camera.Parameters; +import android.hardware.Camera.PictureCallback; +import android.hardware.Camera.ShutterCallback; +import android.hardware.Camera.Size; +import android.media.MediaScannerConnection; +import android.net.Uri; +import android.os.Bundle; +import android.os.Environment; +import android.os.Parcelable; +import android.util.Log; +import android.view.Display; +import android.view.Menu; +import android.view.MotionEvent; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.Window; +import android.view.WindowManager; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.widget.CheckBox; +import android.widget.FrameLayout; +import android.widget.ImageView; +import android.widget.Toast; + +import com.qualcomm.snapdragon.sdk.face.FaceData; +import com.qualcomm.snapdragon.sdk.face.FacialProcessing; +import com.qualcomm.snapdragon.sdk.face.FacialProcessing.PREVIEW_ROTATION_ANGLE; + +import org.ei.opensrp.commonregistry.CommonPersonObjectClient; +import org.ei.opensrp.gizi.R; +import org.ei.opensrp.gizi.face.camera.util.FaceConstants; +import org.ei.opensrp.gizi.face.camera.util.Tools; +import org.ei.opensrp.gizi.fragment.GiziIbuSmartRegisterFragment; +import org.ei.opensrp.gizi.fragment.GiziSmartRegisterFragment; +import org.ei.opensrp.gizi.gizi.GiziSmartRegisterActivity; +import org.ei.opensrp.gizi.giziIbu.IbuSmartRegisterActivity; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Arrays; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.Map; + +public class SmartShutterActivity extends Activity implements Camera.PreviewCallback { + + private static final String TAG = SmartShutterActivity.class.getSimpleName(); + public static CommonPersonObjectClient kidetail; + + Camera cameraObj; + FrameLayout preview; + CameraPreview mPreview; + public static FacialProcessing faceProc; + PaintFaceView drawView; + FaceData[] faceArray; + private ImageView cameraButton; + private ImageView settingsButton; + private ImageView switchCameraButton; + private ImageView chooseCameraButton; + private ImageView menu; + private ImageView faceEyesMouthBtn; + private ImageView perfectPhotoButton; + private ImageView galleryButton; + private ImageView flashButton; + Display display; + + Animation animationFadeOut; + + AnimationDrawable frameAnimation; + CheckBox smile; + CheckBox gazeAngle; + CheckBox eyeBlink; + + private int FRONT_CAMERA_INDEX = 1; + private int BACK_CAMERA_INDEX = 0; + private boolean isDevCompat; + private static boolean switchCamera = false; + private static boolean settingsButtonPress; + private static boolean faceEyesMouthDetectionPressed; + private static boolean perfectModeButtonPress; + private static boolean cameraButtonPress; + private static boolean animationPress; + private static String flashButtonPress; + private int displayAngle; + private boolean smileFlag; + private boolean blinkFlag; + private boolean horizontalGazeAngleFlag; + private boolean verticalGazeAngleFlag; + private static boolean activityStartedOnce; + private int numFaces; + private static String pathName; + private static String entityId; + private boolean identifyPerson = false; + + private ImageView clientListButton; + HashMap hash; + private String selectedPersonName; + long t_startCamera = 0; + double t_stopCamera = 0; + String str_origin_class; + private boolean updated; + + @Override + protected void onCreate(Bundle savedInstanceState) { + t_startCamera = System.nanoTime(); + super.onCreate(savedInstanceState); + + requestWindowFeature(Window.FEATURE_NO_TITLE); + getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, + WindowManager.LayoutParams.FLAG_FULLSCREEN); + + setContentView(R.layout.activity_fr_main_face); + + Bundle extras = getIntent().getExtras(); + updated = extras.getBoolean("org.sid.sidface.SmartShutterActivity.updated"); + entityId = extras.getString("org.sid.sidface.ImageConfirmation.id"); + identifyPerson = extras.getBoolean("org.sid.sidface.ImageConfirmation.identify"); + kidetail = extras.getParcelable("org.sid.sidface.ImageConfirmation.kidetail"); + str_origin_class = extras.getString("org.sid.sidface.ImageConfirmation.origin"); + + Log.e(TAG, "onCreate: " + kidetail); + + initializeFlags(); + + initializeCheckBoxes(); + + animationFadeOut = AnimationUtils.loadAnimation(SmartShutterActivity.this, R.anim.fadeout); + + initializeImageButtons(); + + hash = SmartShutterActivity.retrieveHash(getApplicationContext()); + + settingsButtonPress = false; + + + chooseCameraActionListener(); +// switchCameraActionListener(); + galleryActionListener(); + cameraActionListener(); + settingsActionListener(); + faceDetectionActionListener(); + perfectPhotoActionListener(); + flashActionListener(); + + clientListActionListener(); + + initCamera(); + + display = ((WindowManager) getSystemService(Context.WINDOW_SERVICE)).getDefaultDisplay(); + + Tools.loadAlbum(getApplicationContext()); + + + } + + @Override + protected void onPause() { + super.onPause(); + stopCamera(); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + } + + @Override + protected void onResume() { + super.onResume(); + if (cameraObj != null) { + stopCamera(); + } + initCamera(); + } + + @Override + public void onPreviewFrame(byte[] data, Camera camera) { + + setFlagsTrue(); + int dRotation = display.getRotation(); + PREVIEW_ROTATION_ANGLE angleEnum = PREVIEW_ROTATION_ANGLE.ROT_0; + + switch (dRotation) { + case 0: // Device is not rotated + displayAngle = 90; + angleEnum = PREVIEW_ROTATION_ANGLE.ROT_90; + break; + + case 1: // Landscape left + displayAngle = 0; + angleEnum = PREVIEW_ROTATION_ANGLE.ROT_0; + break; + + case 2: // Device upside down + displayAngle = 270; + angleEnum = PREVIEW_ROTATION_ANGLE.ROT_270; + break; + + case 3: // Landscape right + displayAngle = 180; + angleEnum = PREVIEW_ROTATION_ANGLE.ROT_180; + break; + } + + cameraObj.setDisplayOrientation(displayAngle); + + if (isDevCompat) { + +// loadAlbum(); + if (faceProc == null) { + faceProc = FacialProcessing.getInstance(); + } +// byte[] dataFace = faceProc.serializeRecogntionAlbum(); + +// Log.e(TAG, "onCreate: "+ dataFace.length ); + +// faceProc.setProcessingMode(FacialProcessing.FP_MODES.FP_MODE_STILL); // Static Image + faceProc.setProcessingMode(FacialProcessing.FP_MODES.FP_MODE_VIDEO); + + Parameters params = cameraObj.getParameters(); + Size previewSize = params.getPreviewSize(); +// params.set("iso", 400); + +// Log purpose only +// int previewWidth = params.getPreviewSize().width; +// int previewHeight = params.getPreviewSize().height; +// Log.e(TAG, "Preview Size = " + previewWidth + " x " + previewHeight); + + // View Mode : Landscape - Portrait + // Landscape mode camera : Front , Back + if (this.getResources().getConfiguration().orientation == + Configuration.ORIENTATION_LANDSCAPE && !switchCamera) { + faceProc.setFrame(data, previewSize.width, previewSize.height, true, angleEnum); + } else if (this.getResources().getConfiguration().orientation == + Configuration.ORIENTATION_LANDSCAPE && switchCamera) { + faceProc.setFrame(data, previewSize.width, previewSize.height, false, angleEnum); + } + + // Portrait mode camera : Front + else if (this.getResources().getConfiguration().orientation == + Configuration.ORIENTATION_PORTRAIT && !switchCamera) { + faceProc.setFrame(data, previewSize.width, previewSize.height, true, angleEnum); + } else { + faceProc.setFrame(data, previewSize.width, previewSize.height, false, angleEnum); + } + + // Number of Face in the frame. + numFaces = faceProc.getNumFaces(); + + if (numFaces == 0) { +// Log.e(TAG, "No Face Detected"); + smile.setChecked(false); + eyeBlink.setChecked(false); + gazeAngle.setChecked(false); + + if (drawView != null) { + preview.removeView(drawView); + drawView = new PaintFaceView(this, null, false); + preview.addView(drawView); + } + + } else { +// Log.e(TAG, "Face Detected"); + faceArray = faceProc.getFaceData(); + + if (faceArray == null) { + + Log.e(TAG, "onPreviewFrame: "+ "No Face value" ); + + } else { + int surfaceWidth = mPreview.getWidth(); + int surfaceHeight = mPreview.getHeight(); + + faceProc.normalizeCoordinates(surfaceWidth, surfaceHeight); + + Log.e(TAG, "onPreviewFrame: personId" + faceArray[0].getPersonId()); + + if (identifyPerson && faceArray[0].getPersonId() != -111) { + String selectedPersonId = Integer.toString(faceArray[0].getPersonId()); + Iterator> iter = hash.entrySet().iterator(); + // Default name is the person is unknown + selectedPersonName = "Not Identified"; + while (iter.hasNext()) { + Log.e(TAG, "onPreviewFrame: "+"check Hash" ); + HashMap.Entry entry = iter.next(); + if (entry.getValue().equals(selectedPersonId)) { + selectedPersonName = entry.getKey(); + t_stopCamera = (System.nanoTime() - t_startCamera) / 1000000000.0D; + } + } + +// Log.e(TAG, "onPreviewFrame: t_start"+t_startCamera ); + + Class origin_class = this.getClass(); + + Log.e(TAG, "onPreviewFrame: init" + origin_class.getSimpleName()); + Log.e(TAG, "onPreviewFrame: origin" + str_origin_class); + + if (str_origin_class.equals(GiziSmartRegisterFragment.class.getSimpleName())) { + origin_class = GiziSmartRegisterActivity.class; + } else if (str_origin_class.equals(GiziIbuSmartRegisterFragment.class.getSimpleName())) { + origin_class = IbuSmartRegisterActivity.class; + } + + Log.e(TAG, "onPreviewFrame: " + origin_class.getSimpleName()); + Intent intent = new Intent(SmartShutterActivity.this, origin_class); + intent.putExtra("org.ei.opensrp.indonesia.face.face_mode", true); + intent.putExtra("org.ei.opensrp.indonesia.face.base_id", selectedPersonName); + intent.putExtra("org.ei.opensrp.indonesia.face.proc_time", t_stopCamera); + + startActivity(intent); + + } + +// Options + if (faceEyesMouthDetectionPressed) { + // Remove the previously created view to avoid unnecessary stacking of Views. + preview.removeView(drawView); + drawView = new PaintFaceView(this, faceArray, true); + Log.e(TAG, "onPreviewFrame: " + faceArray[0].getPersonId()); + preview.addView(drawView); + + } else { + + preview.removeView(drawView); + drawView = new PaintFaceView(this, null, false); + preview.addView(drawView); + + } + + if (perfectModeButtonPress) { + for (int i = 0; i < numFaces; i++) { + if (faceArray[i].getSmileValue() < 75) { + smileFlag = false; + smile.setChecked(false); + } else { + smile.setChecked(true); + } + + if (faceArray[i].getLeftEyeBlink() > 50 && faceArray[i].getRightEyeBlink() > 50) { + blinkFlag = false; + eyeBlink.setChecked(false); + } else { + eyeBlink.setChecked(true); + } + + if (faceArray[i].getEyeHorizontalGazeAngle() < -8 || faceArray[i].getEyeHorizontalGazeAngle() > 8) { + horizontalGazeAngleFlag = false; + gazeAngle.setChecked(false); + } else if (faceArray[i].getEyeVerticalGazeAngle() < -8 || faceArray[i].getEyeVerticalGazeAngle() > 8) { + verticalGazeAngleFlag = false; + gazeAngle.setChecked(false); + } else { + gazeAngle.setChecked(true); + } + + } + if (smileFlag && blinkFlag && horizontalGazeAngleFlag && verticalGazeAngleFlag && cameraButtonPress) { + try { + cameraObj.takePicture(shutterCallback, rawCallback, jpegCallback); + } catch (Exception e) { + + } + + frameAnimation.stop(); + cameraButton.setBackgroundResource(R.drawable.ic_camera_alt_white_24dp); + cameraButton.invalidate(); + cameraButtonPress = false; + animationPress = false; + smile.setVisibility(View.INVISIBLE); + gazeAngle.setVisibility(View.INVISIBLE); + eyeBlink.setVisibility(View.INVISIBLE); + smile.setChecked(false); + eyeBlink.setChecked(false); + gazeAngle.setChecked(false); + } + } + } + } + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.main, menu); + return true; + } + + /** + * @param requestCode + * @param resultCode + * @param data + */ + @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + switch (requestCode) { + case 0: + if (resultCode == RESULT_OK) { + if (requestCode == 0) { + Uri selectedImageUri = data.getData(); + Intent intent = new Intent(); + intent.setType("image/*"); + intent.setAction(Intent.ACTION_VIEW); + intent.setData(selectedImageUri); + startActivity(intent); + } + } + break; + // For the rest don't do anything. + } + } + + /** + * + */ + ShutterCallback shutterCallback = new ShutterCallback() { + public void onShutter() { + Log.d(TAG, "onShutter'd"); + } + }; + + /** + * + */ + PictureCallback rawCallback = new PictureCallback() { + public void onPictureTaken(byte[] data, Camera camera) { + Log.d(TAG, "onPictureTaken - raw"); + } + }; + + /** + * + */ + PictureCallback jpegCallback = new PictureCallback() { + public void onPictureTaken(byte[] data, Camera camera) { + savePicture(data); + } + + }; + + /** + * + */ + private void initializeFlags() { + isDevCompat = false; + settingsButtonPress = false; + faceEyesMouthDetectionPressed = false; + perfectModeButtonPress = false; + cameraButtonPress = false; + animationPress = false; + flashButtonPress = "FLASH_MODE_OFF"; + smileFlag = true; + blinkFlag = true; + horizontalGazeAngleFlag = true; + verticalGazeAngleFlag = true; + activityStartedOnce = false; + } + + // Stop the camera preview. release the camera. Release the FacialActivity Processing object. Make the objects null. + private void stopCamera() { + + if (cameraObj != null) { + cameraObj.stopPreview(); + cameraObj.setPreviewCallback(null); + preview.removeView(mPreview); + cameraObj.release(); +// if (isDevCompat) { +// faceProc.release(); +// faceProc = null; +// } + } + cameraObj = null; + } + + // Start with the camera preview. Open the Camera. See if the feature is supported. Initialize the facial processing instance. + + /** + * + */ + private void initCamera() { + + // Check to see if the FacialProc feature is supported in the device or no. + isDevCompat = FacialProcessing.isFeatureSupported(FacialProcessing.FEATURE_LIST.FEATURE_FACIAL_PROCESSING); + + if (isDevCompat && faceProc == null) { + Log.e(TAG, "Feature is supported"); + // Calling the FacialActivity Processing Constructor. + faceProc = FacialProcessing.getInstance(); + faceProc.setRecognitionConfidence(Tools.CONFIDENCE_VALUE); + +// Tools tools = new Tools(); +// Tools.loadAlbum(getApplicationContext()); + + } else if (!isDevCompat && !activityStartedOnce) { + Log.e(TAG, "Feature is NOT supported"); + AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(SmartShutterActivity.this); + + // set title + alertDialogBuilder.setTitle("Not Supported"); + + // set dialog message + alertDialogBuilder + .setMessage("Your device does not support Qualcomm's FacialActivity Processing Feature. Continue with the normal camera.") + .setCancelable(false) + .setPositiveButton("OK", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + + } + }); + + // create alert dialog + AlertDialog alertDialog = alertDialogBuilder.create(); + + // show it + alertDialog.show(); + activityStartedOnce = true; + } + + if (!switchCamera) { + // Open the Front camera + cameraObj = Camera.open(FRONT_CAMERA_INDEX); + } else { + // Open the back camera + cameraObj = Camera.open(BACK_CAMERA_INDEX); + } + + // Create a new surface on which Camera will be displayed. + mPreview = new CameraPreview(SmartShutterActivity.this, cameraObj); + preview = (FrameLayout) findViewById(R.id.cameraPreview); + preview.addView(mPreview); + cameraObj.setPreviewCallback(SmartShutterActivity.this); + + } + + /* + * Function to Initialize all the image buttons that are there in the view and sets its visibility and image resources here. + */ + private void initializeImageButtons() { + cameraButton = (ImageView) findViewById(R.id.cameraButton); // Camera Shutter Button + + galleryButton = (ImageView) findViewById(R.id.gallery); + galleryButton.setImageResource(R.drawable.ic_collections_white_24dp); + galleryButton.setVisibility(View.INVISIBLE); + + settingsButton = (ImageView) findViewById(R.id.settings); + settingsButton.setVisibility(View.INVISIBLE); + + chooseCameraButton = (ImageView) findViewById(R.id.chooseCamera); + chooseCameraButton.setImageResource(R.drawable.ic_camera_rear_white_24dp); + chooseCameraButton.setVisibility(View.VISIBLE); + +// Settings Option Menu + + menu = (ImageView) findViewById(R.id.menu); + menu.setVisibility(View.INVISIBLE); // Initially make menu invisible. Make it visible only when the settings button is pressed. + + switchCameraButton = (ImageView) findViewById(R.id.switchCamera); + switchCameraButton.setImageResource(R.drawable.ic_camera_front_white_24dp); + switchCameraButton.setVisibility(View.INVISIBLE); // Initially make switchCamera invisible. Make it visible only when the settings button is pressed. + + perfectPhotoButton = (ImageView) findViewById(R.id.perfectMode); + perfectPhotoButton.setVisibility(View.INVISIBLE); // Initially make perfectMode invisible. Make it visible only when the settings button is pressed. + perfectPhotoButton.setImageResource(R.drawable.ic_perfect_mode_off); + + flashButton = (ImageView) findViewById(R.id.flash); + flashButton.setVisibility(View.INVISIBLE); // Initially make flashButton invisible. Make it visible only when the settings button is pressed. + + clientListButton = (ImageView) findViewById(R.id.clientList); + clientListButton.setVisibility(View.INVISIBLE); + clientListButton.setImageResource(R.drawable.ic_faces); + + // Change the flash image depending on the button that is being pressed. + if (flashButtonPress == "FLASH_MODE_OFF") { + flashButton.setImageResource(R.drawable.ic_flash_off); + } else { + flashButton.setImageResource(R.drawable.ic_flash_green); + } + + // Detect Eyes and Mouth. + if (!faceEyesMouthDetectionPressed) { + faceEyesMouthBtn = (ImageView) findViewById(R.id.faceDetection); + faceEyesMouthBtn.setImageResource(R.drawable.fr_face_detection); + } else { + faceEyesMouthBtn = (ImageView) findViewById(R.id.faceDetection); + faceEyesMouthBtn.setImageResource(R.drawable.fr_face_detection_on); + } + faceEyesMouthBtn.setVisibility(View.INVISIBLE); + } + + /* + * Initialize the Check Box Buttons. Initially it will be invisible. Will be visible only when the photo is to be taken. + */ + private void initializeCheckBoxes() { + smile = (CheckBox) findViewById(R.id.smileCheckBox); + smile.setVisibility(View.GONE); + smile.setTextColor(Color.YELLOW); + gazeAngle = (CheckBox) findViewById(R.id.gazeAngleCheckBox); + gazeAngle.setVisibility(View.GONE); + gazeAngle.setTextColor(Color.YELLOW); + eyeBlink = (CheckBox) findViewById(R.id.blinkCheckBox); + eyeBlink.setVisibility(View.GONE); + eyeBlink.setTextColor(Color.YELLOW); + } + + private void clientListActionListener() { + clientListButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(SmartShutterActivity.this, ClientsList.class); + + startActivity(intent); + } + }); + + } + + private void chooseCameraActionListener() { + chooseCameraButton.setOnClickListener(new OnClickListener() { + @Override + public void onClick(View v) { + + if (!switchCamera) { + stopCamera(); + chooseCameraButton.setImageResource(R.drawable.ic_camera_front_white_24dp); + switchCamera = true; + initCamera(); + } else { + stopCamera(); + chooseCameraButton.setImageResource(R.drawable.ic_camera_rear_white_24dp); + switchCamera = false; + initCamera(); + } + } + }); + } + + /* + * Function to detect the on click listener for the switch camera button. + */ + private void switchCameraActionListener() { + switchCameraButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View arg0) { + + if (!switchCamera) // Flag to check if the camera is switched to front or back. + { + switchCameraButton.setImageResource(R.drawable.ic_camera_rear_white_24dp); + stopCamera(); + switchCamera = true; + settingsButtonPress = false; + initCamera(); + fadeOutAnimation(); + } else { + switchCameraButton.setImageResource(R.drawable.ic_camera_front_white_24dp); + stopCamera(); + switchCamera = false; + settingsButtonPress = false; + initCamera(); + fadeOutAnimation(); + } + } + }); + } + + /* + * Function to detect the on click listener for the GALLERY button. + */ + private void galleryActionListener() { + galleryButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View arg0) { + Intent intent = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI); + intent.setType("image/*"); + intent.setAction(Intent.ACTION_GET_CONTENT); + startActivityForResult(Intent.createChooser(intent, "Select Picture"), 0); + } + }); + } + + /* + * Function to detect the on click listener for the camera shutter button. + */ + private void cameraActionListener() { + cameraButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View arg0) { + + if (numFaces != 0) { + if (!perfectModeButtonPress) { + cameraObj.autoFocus(new Camera.AutoFocusCallback() { + @Override + public void onAutoFocus(boolean success, Camera camera) { + + cameraObj.takePicture(shutterCallback, rawCallback, jpegCallback); + + } + }); + + } else { + // Play animation + cameraButton.setBackgroundResource(R.drawable.fr_spin_animation); + frameAnimation = (AnimationDrawable) cameraButton.getBackground(); + + checkBoxVisiblity(true); // As soon as the shutter button is pressed, make the check boxes visible. + + // Start the animation (looped playback by default). + if (!animationPress) { + frameAnimation.start(); + animationPress = true; + cameraButtonPress = true; + } else { + // If the shutter button is stopped then make the check boxes invisible + checkBoxVisiblity(false); + // and un-check them. + textBoxChecked(false); + frameAnimation.stop(); + cameraButton.setBackgroundResource(R.drawable.ic_camera_alt_white_24dp); + animationPress = false; + cameraButtonPress = false; + } + } + } + } + }); + } + + /* + * Function to detect the on click listener for the switch camera button. + */ + private void settingsActionListener() { + settingsButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View arg0) { + if (!settingsButtonPress) { + // Disable the buttons if the facial processing feature is not supported. + if (isDevCompat) { + faceEyesMouthBtn.setVisibility(View.VISIBLE); + perfectPhotoButton.setVisibility(View.VISIBLE); + clientListButton.setVisibility(View.VISIBLE); + + } + menu.setVisibility(View.VISIBLE); + switchCameraButton.setVisibility(View.VISIBLE); + if (switchCamera)// If facing back camera then only make it visible or else dont. + flashButton.setVisibility(View.VISIBLE); + settingsButtonPress = true; + } else { + faceEyesMouthBtn.setVisibility(View.INVISIBLE); + menu.setVisibility(View.INVISIBLE); + switchCameraButton.setVisibility(View.INVISIBLE); + perfectPhotoButton.setVisibility(View.INVISIBLE); + flashButton.setVisibility(View.INVISIBLE); + settingsButtonPress = false; + clientListButton.setVisibility(View.INVISIBLE); + } + } + + }); + + // On touch listener for the settings button to make it highlighted when pressed + settingsButton.setOnTouchListener(new View.OnTouchListener() { + + @Override + public boolean onTouch(View arg0, MotionEvent arg1) { + + if (arg1.getAction() == MotionEvent.ACTION_DOWN) { + settingsButton.setImageResource(R.drawable.ic_settings_green_24dp); + } else if (arg1.getAction() == MotionEvent.ACTION_UP) { + settingsButton.setImageResource(R.drawable.ic_settings_white_24dp); + } + return false; + } + }); + } + + /* + * Interactive Draw of Eyes and Mouth position. + */ + private void faceDetectionActionListener() { + faceEyesMouthBtn.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View arg0) { + if (!faceEyesMouthDetectionPressed) { + faceEyesMouthBtn.setImageResource(R.drawable.fr_face_detection_on); + fadeOutAnimation(); + faceEyesMouthDetectionPressed = true; + settingsButtonPress = false; + } else { + faceEyesMouthBtn.setImageResource(R.drawable.fr_face_detection); + fadeOutAnimation(); + faceEyesMouthDetectionPressed = false; + settingsButtonPress = false; + } + } + }); + + } + + /* + Control Flash Mode + */ + private void flashActionListener() { + flashButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View arg0) { + Parameters params = cameraObj.getParameters(); + String flashMode = params.getFlashMode(); + if (flashMode == null) + return; + else { + // On-Off Flash + if (flashButtonPress == "FLASH_MODE_OFF") { + params.setFlashMode(Parameters.FLASH_MODE_ON); + flashButton.setImageResource(R.drawable.ic_flash_green); + cameraObj.setParameters(params); + fadeOutAnimation(); + flashButtonPress = "FLASH_MODE_ON"; + settingsButtonPress = false; + return; + } else { + params.setFlashMode(Parameters.FLASH_MODE_OFF); + flashButton.setImageResource(R.drawable.ic_flash_off); + cameraObj.setParameters(params); + fadeOutAnimation(); + flashButtonPress = "FLASH_MODE_OFF"; + settingsButtonPress = false; + return; + } + } + } + }); + + } + + /* + * Function to detect the on click listener for the perfect photo mode button. + */ + private void perfectPhotoActionListener() { + perfectPhotoButton.setOnClickListener(new OnClickListener() { + + @Override + public void onClick(View arg0) { + if (perfectModeButtonPress) { + perfectPhotoButton.setImageResource(R.drawable.ic_perfect_mode_off); + fadeOutAnimation(); + settingsButtonPress = false; + perfectModeButtonPress = false; + } else { + perfectPhotoButton.setImageResource(R.drawable.ic_perfect_mode_on); + fadeOutAnimation(); + settingsButtonPress = false; + perfectModeButtonPress = true; + } + } + }); + } + + /* Animation menu display + * + */ + private void fadeOutAnimation() { + + // Activated features only Supported Device + if (isDevCompat) { + faceEyesMouthBtn.startAnimation(animationFadeOut); + perfectPhotoButton.startAnimation(animationFadeOut); + } + menu.startAnimation(animationFadeOut); + switchCameraButton.startAnimation(animationFadeOut); + clientListButton.startAnimation(animationFadeOut); + + if (switchCamera) { + flashButton.startAnimation(animationFadeOut); + } + faceEyesMouthBtn.setVisibility(View.GONE); + menu.setVisibility(View.GONE); + switchCameraButton.setVisibility(View.GONE); + perfectPhotoButton.setVisibility(View.GONE); + flashButton.setVisibility(View.GONE); + + } + + /* + * Function to write an image to the file system for future viewing. + */ + public static boolean WritePictureToFile(Context context, Bitmap bitmap) { + File pictureFile = getOutputMediaFile(); + if (pictureFile == null) { + Log.e(TAG, "Error creating media file, check storage permissions "); + return false; + } + + try { + FileOutputStream fos = new FileOutputStream(pictureFile); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos); + fos.close(); + Log.e(TAG, "Wrote image to " + pictureFile); + + MediaScannerConnection.scanFile(context, new String[]{pictureFile.toString()}, null, new MediaScannerConnection.OnScanCompletedListener() { + public void onScanCompleted(String path, Uri uri) { + Log.i("ExternalStorage", "Scanned " + path + ":"); + Log.i("ExternalStorage", "-> uri=" + uri); + } + }); + pathName = pictureFile.toString(); + Log.e(TAG, "Path Name = " + pathName); + return true; + + } catch (FileNotFoundException e) { + Log.d(TAG, "File not found: " + e.getMessage()); + } catch (IOException e) { + Log.d(TAG, "Error accessing file: " + e.getMessage()); + } + return false; + } + + /** + * Create a File for saving an image or video + */ + @SuppressLint("SimpleDateFormat") + private static File getOutputMediaFile() { + // To be safe, you should check that the SDCard is mounted + // using Environment.getExternalStorageState() before doing this. + + File mediaStorageDir = new File( + Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), "OPENSRP_SID"); + + // This location works best if you want the created images to be shared + // between applications and persist after your app has been uninstalled. + + // Create the storage directory if it does not exist + if (!mediaStorageDir.exists()) { + Log.e(TAG, "failed to find directory " + mediaStorageDir.getAbsolutePath()); + if (!mediaStorageDir.mkdirs()) { + Log.e(TAG, "failed to create directory " + mediaStorageDir.getAbsolutePath()); + return null; + } + } + + // Create a media file name + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); +// String filename = entity); + File mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + entityId + ".jpg"); + return mediaFile; + } + + /* + * Function to take the raw YUV byte array and do the necessary conversions to save it. + */ + private void savePicture(byte[] data) { + Intent intent = new Intent(this, ImageConfirmation.class); + // This is when smart shutter feature is not ON. Take the photo generally. + if (data != null) { + intent.putExtra("org.sid.sidface.ImageConfirmation", data); + } + intent.putExtra("org.sid.sidface.ImageConfirmation.switchCamera", switchCamera); + intent.putExtra("org.sid.sidface.ImageConfirmation.orientation", displayAngle); + intent.putExtra("org.sid.sidface.ImageConfirmation.id", entityId); + intent.putExtra("org.sid.sidface.ImageConfirmation.identify", identifyPerson); + intent.putExtra("org.sid.sidface.ImageConfirmation.kidetail", (Parcelable) kidetail); + intent.putExtra("org.sid.sidface.ImageConfirmation.origin", str_origin_class); + intent.putExtra("org.sid.sidface.ImageConfirmation.updated", updated); + + startActivityForResult(intent, 1); + } + + private void setFlagsTrue() { + smileFlag = true; + blinkFlag = true; + horizontalGazeAngleFlag = true; + verticalGazeAngleFlag = true; + } + + /* + * A helper function to handle the visibility of the check boxes. + */ + private void checkBoxVisiblity(boolean visible) { + + if (visible) { + smile.setVisibility(View.VISIBLE); + gazeAngle.setVisibility(View.VISIBLE); + eyeBlink.setVisibility(View.VISIBLE); + } else { + smile.setVisibility(View.INVISIBLE); + gazeAngle.setVisibility(View.INVISIBLE); + eyeBlink.setVisibility(View.INVISIBLE); + } + + } + + /* + * A helper function to handle the CHECK-MARK of the Check-Text Boxes. + */ + private void textBoxChecked(boolean check) { + if (check) { + smile.setChecked(true); + eyeBlink.setChecked(true); + gazeAngle.setChecked(true); + } else { + smile.setChecked(false); + eyeBlink.setChecked(false); + gazeAngle.setChecked(false); + } + + } + + public void loadAlbum() { +// Toast.makeText(this, "Load FacialActivity Album", Toast.LENGTH_SHORT).show(); + Log.e(TAG, "loadAlbum: start"); + SharedPreferences settings = getSharedPreferences(FaceConstants.ALBUM_NAME, 0); + String arrayOfString = settings.getString(FaceConstants.ALBUM_ARRAY, null); + + Log.e(TAG, "loadAlbum: " + arrayOfString); + byte[] albumArray; + if (arrayOfString != null) { + String[] splitStringArray = arrayOfString.substring(1, + arrayOfString.length() - 1).split(", "); + + albumArray = new byte[splitStringArray.length]; + for (int i = 0; i < splitStringArray.length; i++) { + albumArray[i] = Byte.parseByte(splitStringArray[i]); + } + // Boolean + SmartShutterActivity.faceProc.deserializeRecognitionAlbum(albumArray); + Log.e(TAG, "De-Serialized Album Success! " + albumArray.toString()); + } + } + + + /** + * Get Client List + * @param context + * @return + */ + public static HashMap retrieveHash(Context context) { + SharedPreferences settings = context.getSharedPreferences(FaceConstants.HASH_NAME, 0); + HashMap hash = new HashMap<>(); + hash.putAll((Map) settings.getAll()); + return hash; + } + + + protected void saveHash(HashMap hashMap, Context context) { + SharedPreferences settings = context.getSharedPreferences(FaceConstants.HASH_NAME, 0); + + SharedPreferences.Editor editor = settings.edit(); + editor.clear(); + Log.e(TAG, "Hash Save Size Clients List= " + hashMap.size()); + for (String s : hashMap.keySet()) { + editor.putString(s, hashMap.get(s)); + } + editor.apply(); + } + + +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/ClientAdapter.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/ClientAdapter.java new file mode 100644 index 0000000..9320e07 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/ClientAdapter.java @@ -0,0 +1,77 @@ +package org.ei.opensrp.gizi.face.camera.util; + +import android.app.Activity; +import android.app.AlertDialog; +import android.content.Context; +import android.graphics.Color; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.BaseAdapter; +import android.widget.ImageView; +import android.widget.TextView; + +import org.ei.opensrp.gizi.R; + +/** + * Created by wildan on 1/16/17. + */ +public class ClientAdapter extends BaseAdapter { + private static final String TAG = ClientAdapter.class.getCanonicalName(); + private Context mContext; + String[] mNames; + private Activity context; + + public ClientAdapter(Context context, String[] names) { + mContext = context; + mNames = names; + } + + @Override + public int getCount() { + return mNames.length; + } + + @Override + public Object getItem(int position) { + return mNames[position]; + } + + @Override + public long getItemId(int position) { + return 0; + } + + @Override + public View getView(int position, View convertView, ViewGroup parent) { + View gridview; + LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + + if (convertView == null){ + gridview = new View(mContext); + gridview = inflater.inflate(R.layout.fr_base_id_clients, null); + } else{ + gridview = convertView; + } + + TextView tv = (TextView) gridview.findViewById(R.id.tv_baseid); + tv.setBackgroundColor(Color.BLACK); + tv.setText(" " + (position + 1) + ". " + mNames[position]); + + ImageView delete = (ImageView) gridview.findViewById(R.id.delete); + delete.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Log.e(TAG, "onClick: " ); + AlertDialog.Builder builder = new AlertDialog.Builder(context); + builder.setMessage("Do you want to remove?"); + builder.setCancelable(false); + AlertDialog alertDialog = builder.create(); + alertDialog.show(); + } + }); + + return gridview; + } +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/DebugApp.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/DebugApp.java new file mode 100644 index 0000000..eecd6e4 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/DebugApp.java @@ -0,0 +1,60 @@ +package org.ei.opensrp.gizi.face.camera.util; + +import android.annotation.TargetApi; +import android.os.Build; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; + +import org.ei.opensrp.Context; +import org.ei.opensrp.gizi.LoginActivity; +import org.ei.opensrp.gizi.R; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +/** + * Created by sid on 2/2/17. + */ +public class DebugApp { + + private static final String TAG = DebugApp.class.getSimpleName(); + + @TargetApi(Build.VERSION_CODES.KITKAT) + public static void debugApp(LayoutInflater layoutInflater, Context context){ + View view = layoutInflater.inflate(R.layout.login, null); + + Log.e(TAG, "debugApp: "+context ); + LoginActivity l = new LoginActivity(); + Class[] aArg = new Class[1]; + String[] value = {"ec_bidan", "Satu2345"}; + Method mLocal = null, mRemote = null; + +// ProgressDialog pd = new ProgressDialog(l); + try { + Field p = LoginActivity.class.getDeclaredField("progressDialog"); + Field f = LoginActivity.class.getDeclaredField("context"); + mLocal = LoginActivity.class.getDeclaredMethod("localLogin", View.class, String.class, String.class); + mRemote = LoginActivity.class.getDeclaredMethod("remoteLogin", View.class, String.class, String.class); + mLocal.setAccessible(true); + mRemote.setAccessible(true); + f.setAccessible(true); + p.setAccessible(true); + + if (context.userService().hasARegisteredUser()){ + Log.e(TAG, "debugApp: " + "mLocal"); + f.set(l, context); +// p.set(l, pd); + mLocal.invoke(l, view, "ec_bidan", "Satu2345"); + } else { + f.set(l, context); +// p.set(l, pd); + Log.e(TAG, "debugApp: "+"mRemote" ); + mRemote.invoke(l, view, "ec_bidan", "Satu2345"); + } + } catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException | NoSuchFieldException e) { + e.printStackTrace(); + } + } +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/FaceConstants.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/FaceConstants.java new file mode 100644 index 0000000..7e4de1c --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/FaceConstants.java @@ -0,0 +1,19 @@ +package org.ei.opensrp.gizi.face.camera.util; + +/** + * Created by wildan on 1/4/17. + */ +public class FaceConstants { + public static final int THUMBSIZE = 128; + public static final String ALBUM_NAME = "serialize_deserialize"; + public static final String HASH_NAME = "HashMap"; + public static final int MAX_PHOTO_SIZE = 1572864; // 1.5 MB per photo + public static final String ALBUM_ARRAY = "mByteArray"; + + // COLOR + public static final String RED_ORANGE = "#FE642E"; + public static final String ORANGE_YELLOW = "#D7DF01"; + public static final String YELLOW_GREEN = "#86B404"; + public static final String GREEN = "#5FB404"; + +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/FaceRepository.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/FaceRepository.java new file mode 100644 index 0000000..39cf3ae --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/FaceRepository.java @@ -0,0 +1,86 @@ +package org.ei.opensrp.gizi.face.camera.util; + +import android.content.ContentValues; +import android.database.Cursor; +import android.util.Log; + +import net.sqlcipher.database.SQLiteDatabase; + +import org.ei.opensrp.domain.ProfileImage; +import org.ei.opensrp.gizi.face.camera.ImageConfirmation; +import org.ei.opensrp.repository.DrishtiRepository; +import org.ei.opensrp.repository.ImageRepository; +import org.ei.opensrp.repository.Repository; + +import java.util.List; + +/** + * Created by sid on 2/23/17. + */ +public class FaceRepository extends ImageRepository { + + private static String TAG = FaceRepository.class.getSimpleName(); + static FaceRepository faceRepository; + + public DrishtiRepository faceRepository() { + Log.e(TAG, "faceRepository: "+faceRepository ); + if (faceRepository == null) { + faceRepository = new FaceRepository(); + } + Log.e(TAG, "faceRepository: "+faceRepository ); + return faceRepository; + } + + public List allVectorImages() { + Log.e(TAG, "allVectorImages: "+masterRepository); + SQLiteDatabase database = masterRepository.getReadableDatabase(); + Cursor cursor = database.query(Image_TABLE_NAME, Image_TABLE_COLUMNS, null, null, null, null, null, null); + return readAll(cursor); + } + + + public ProfileImage findVectorByEntityId(String entityId) { + SQLiteDatabase database = masterRepository.getReadableDatabase(); + Cursor cursor = database.query(Image_TABLE_NAME, Vector_TABLE_COLUMNS, entityID_COLUMN + " = ?", new String[]{entityId}, null, null, null, null); + List allcursor = readAll(cursor); + return (!allcursor.isEmpty()) ? allcursor.get(0) : null; + } + + public List findVectorAllUnSynced() { + SQLiteDatabase database = masterRepository.getReadableDatabase(); + Cursor cursor = database.query(Image_TABLE_NAME, Image_TABLE_COLUMNS, filevector_COLUMN + " = ?", null , null, null, null, null); + return readAll(cursor); + } + + public void vector_close(String caseId) { + ContentValues values = new ContentValues(); + values.put(syncStatus_COLUMN, TYPE_Synced); + masterRepository.getWritableDatabase().update(Vector_TABLE_NAME, values, ID_COLUMN + " = ?", new String[]{caseId}); + } + + + public void updateByEntityId(String entityId, String faceVector) { +// SQLiteDatabase database = masterRepository.getReadableDatabase(); +// Cursor cursor = database.query(Image_TABLE_NAME, Image_TABLE_COLUMNS, entityID_COLUMN + " = ?", new String[]{entityId}, null, null, null, null); +// List allcursor = readAll(cursor); +// return (!allcursor.isEmpty()) ? allcursor.get(0) : null; + + ContentValues values = new ContentValues(); + values.put(filevector_COLUMN, faceVector); + Log.e(TAG, "updateByEntityId: "+values ); + masterRepository.getWritableDatabase().update(Image_TABLE_NAME, values, "entityID" + " = ?", new String[]{entityId}); + close(entityId); + } + + public void updateByEntityIdNull(String entityId, String faceVector) { + ContentValues values = new ContentValues(); + values.put(filevector_COLUMN, faceVector); + Log.e(TAG, "updateByEntityIdNull: "+values ); + Log.e(TAG, "updateByEntityIdNull: "+masterRepository ); +// masterRepository.getWritableDatabase().update(Image_TABLE_NAME, values, "entityID" + " = ? && faceVector == null ", new String[]{entityId}); +// close(entityId); + + } + + +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/FaceVector.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/FaceVector.java new file mode 100644 index 0000000..615945b --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/FaceVector.java @@ -0,0 +1,10 @@ +package org.ei.opensrp.gizi.face.camera.util; + +/** + * Created by sid on 2/22/17. + */ +public class FaceVector { + + String baseEntityID; + String faceVector; +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/FaceVectorRepository.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/FaceVectorRepository.java new file mode 100644 index 0000000..8854cf7 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/FaceVectorRepository.java @@ -0,0 +1,104 @@ +package org.ei.opensrp.gizi.face.camera.util; + +import android.content.ContentValues; +import android.database.Cursor; +import android.util.Log; + +import net.sqlcipher.database.SQLiteDatabase; + +import org.ei.opensrp.domain.ProfileImage; +import org.ei.opensrp.repository.DrishtiRepository; + +import java.util.ArrayList; +import java.util.List; + +/** + * Created by sid on 2/21/17. + */ +public class FaceVectorRepository extends DrishtiRepository { + private static final String TAG = FaceVectorRepository.class.getCanonicalName(); + public static final String Image_TABLE_NAME = "ImageList"; + public static final String ID_COLUMN = "imageid"; + public static final String anm_ID_COLUMN = "anmId"; + public static final String entityID_COLUMN = "entityID"; + private static final String contenttype_COLUMN = "contenttype"; + public static final String filepath_COLUMN = "filepath"; + public static final String syncStatus_COLUMN = "syncStatus"; + public static final String filecategory_COLUMN = "filecategory"; + + public static final String filevector_COLUMN = "filevector"; + public static final String[] Image_TABLE_COLUMNS = {ID_COLUMN, anm_ID_COLUMN, entityID_COLUMN, contenttype_COLUMN, filepath_COLUMN, syncStatus_COLUMN,filecategory_COLUMN, filevector_COLUMN}; + public static final String Vector_TABLE_NAME = "VectorList"; + public static final String VID_COLUMN = "vectorID"; + private static final String Vector_SQL = "CREATE TABLE VectorList("+VID_COLUMN+" VARCHAR PRIMARY KEY, "+entityID_COLUMN+" VARCHAR, syncStatus VARCHAR )"; + public static final String[] Vector_TABLE_COLUMNS = { + VID_COLUMN, + entityID_COLUMN, + syncStatus_COLUMN + }; + + public static String TYPE_Unsynced = "Unsynced"; + public static String TYPE_Synced = "Synced"; + + + @Override + protected void onCreate(SQLiteDatabase database) { + + } + + private List readAll(Cursor cursor) { + List profileImages = new ArrayList<>(); + + try { + if (cursor != null && cursor.getCount()>0 && cursor.moveToFirst()) { + while (cursor.getCount() > 0 && !cursor.isAfterLast()) { + + profileImages.add(new ProfileImage( + cursor.getString(0), + cursor.getString(1), + cursor.getString(2), + cursor.getString(3), + cursor.getString(4), + cursor.getString(5), + cursor.getString(6), + cursor.getString(7) + ) + ); + + cursor.moveToNext(); + } + } + + } catch (Exception e) { + Log.e(TAG,e.getMessage()); + } finally { + assert cursor != null; + cursor.close(); + } + return profileImages; + } + + + public ProfileImage findVectorByEntityId(String entityId) { + SQLiteDatabase database = masterRepository.getReadableDatabase(); + Cursor cursor = database.query(Vector_TABLE_NAME, + Vector_TABLE_COLUMNS, + entityID_COLUMN + " = ?", + new String[]{entityId}, null, null, null, null); + List allcursor = readAll(cursor); + return (!allcursor.isEmpty()) ? allcursor.get(0) : null; + } + + public List findVectorAllUnSynced() { + SQLiteDatabase database = masterRepository.getReadableDatabase(); + Cursor cursor = database.query(Vector_TABLE_NAME, Vector_TABLE_COLUMNS, syncStatus_COLUMN + " = ?", new String[]{TYPE_Unsynced}, null, null, null, null); + return readAll(cursor); + } + + public void vector_close(String caseId) { + ContentValues values = new ContentValues(); + values.put(syncStatus_COLUMN, TYPE_Synced); + masterRepository.getWritableDatabase().update(Vector_TABLE_NAME, values, ID_COLUMN + " = ?", new String[]{caseId}); + } + +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/HttpHandler.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/HttpHandler.java new file mode 100644 index 0000000..6354431 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/HttpHandler.java @@ -0,0 +1,70 @@ +package org.ei.opensrp.gizi.face.camera.util; + +import android.util.Log; + +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.net.HttpURLConnection; +import java.net.MalformedURLException; +import java.net.ProtocolException; +import java.net.URL; + +/** + * Created by sid on 2/22/17. + */ +public class HttpHandler { + + private static final String TAG = HttpHandler.class.getSimpleName(); + + public HttpHandler() { + } + + public String makeServiceCall(String reqUrl) { +// Log.e(TAG, "makeServiceCall: "+reqUrl ); + String response = null; + try { + URL url = new URL(reqUrl); + HttpURLConnection conn = (HttpURLConnection) url.openConnection(); + Log.e(TAG, "makeServiceCall: "+conn.getResponseCode() ); + conn.setRequestMethod("GET"); + // read the response + Log.e(TAG, "makeServiceCall: "+conn.getInputStream() ); +// InputStream in = new BufferedInputStream(conn.getInputStream()); +// Log.e(TAG, "makeServiceCall: "+url+ " "+convertStreamToString(in) ); +// response = convertStreamToString(in); + } catch (MalformedURLException e) { + Log.e(TAG, "MalformedURLException: " + e.getMessage()); +// } catch (ProtocolException e) { +// Log.e(TAG, "ProtocolException: " + e.getMessage()); + } catch (IOException e) { + Log.e(TAG, "IOException: " + e.getMessage()); + } catch (Exception e) { + Log.e(TAG, "Exception: " + e.getMessage()); + } + return response; + } + + private String convertStreamToString(InputStream is) { + BufferedReader reader = new BufferedReader(new InputStreamReader(is)); + StringBuilder sb = new StringBuilder(); + + String line; + try { + while ((line = reader.readLine()) != null) { + sb.append(line).append('\n'); + } + } catch (IOException e) { + e.printStackTrace(); + } finally { + try { + is.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + return sb.toString(); + } +} \ No newline at end of file diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/MultimediaProcessor.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/MultimediaProcessor.java new file mode 100644 index 0000000..7159c44 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/MultimediaProcessor.java @@ -0,0 +1,170 @@ +package org.ei.opensrp.gizi.face.camera.util; + +import android.content.ContentValues; +import android.content.Context; +import android.content.SharedPreferences; +import android.preference.PreferenceManager; +import android.util.Log; + +import org.ei.opensrp.commonregistry.CommonRepositoryInformationHolder; +import org.ei.opensrp.repository.AllSharedPreferences; +import org.ei.opensrp.sync.ClientProcessor; +import org.ei.opensrp.sync.CloudantDataHandler; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Arrays; +import java.util.Date; +import java.util.List; + +/** + * Created by sid on 2/22/17. + */ +public class MultimediaProcessor extends ClientProcessor { + + private static final String TAG = MultimediaProcessor.class.getSimpleName(); + private static MultimediaProcessor instance; + + public MultimediaProcessor(Context context) { + super(context); + } + + public static MultimediaProcessor getInstance(Context context) { + if (instance == null) { + instance = new MultimediaProcessor(context); + } + return instance; + } + + public synchronized void processMultimediaClient() throws Exception { + CloudantDataHandler handler = CloudantDataHandler.getInstance(mContext); + + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(mContext); + AllSharedPreferences allSharedPreferences = new AllSharedPreferences(preferences); + long lastSyncTimeStamp = allSharedPreferences.fetchLastSyncDate(0); + Date lastSyncDate = new Date(lastSyncTimeStamp); + String multimediaClassificationStr = getFileContents("ec_client_fields.json"); + + List multimedias = handler.getUpdatedEventsAndAlerts(lastSyncDate); + + fetchData("ec_multimedia"); + + if (!multimedias.isEmpty()) { + Log.e(TAG, "processMultimediaClient: "+"exist" ); + for (JSONObject multimedia : multimedias) { + String type = multimedia.has("type") ? multimedia.getString("type") : null; + + if (type != null && type.equals("Multimedia")) { + JSONObject clientClassificationJson = new JSONObject(multimediaClassificationStr); + if(isNullOrEmptyJSONObject(clientClassificationJson)){ + continue; + } + //iterate through the events + processMultimedia(multimedia, clientClassificationJson); + } +// else if (type.equals("Action")) { +// JSONObject clientAlertClassificationJson = new JSONObject(clientAlertsStr); +// if(isNullOrEmptyJSONObject(clientAlertClassificationJson)){ +// continue; +// } +// +// processAlert(eventOrAlert, clientAlertClassificationJson); +// } + } + } + + allSharedPreferences.saveLastSyncDate(lastSyncDate.getTime()); + } + + private JSONObject fetchData(String tableName) throws JSONException { + Log.e(TAG, "fetchData: "+"start" ); + String multimediaClassificationStr = getFileContents("ec_client_fields.json"); + + JSONObject jsonObject = new JSONObject(multimediaClassificationStr); + JSONArray bindtypeObjects = jsonObject.getJSONArray("bindobjects"); + + for(int i = 0 ; i < bindtypeObjects.length(); i++){ + JSONObject bo = bindtypeObjects.getJSONObject(i); + if (bo.getString("name").equals(tableName)){ + + JSONArray columnsJsonArray = bo.getJSONArray("columns"); + String [] columnNames = new String[columnsJsonArray.length()]; + for(int j = 0 ; j < columnNames.length; j++){ + JSONObject columnObject = columnsJsonArray.getJSONObject(j); + columnNames[j] = columnObject.getString("column_name"); + } + Log.e(TAG, "processMultimediaClient: "+ Arrays.toString(columnNames)); + } + + } + + return null; + } + + + public Boolean processMultimedia(JSONObject multimedia, JSONObject multimediaClassificationJson) throws Exception { + + try { + + if(multimedia == null || multimedia.length() == 0){ + return false; + } + + if (multimediaClassificationJson == null || multimediaClassificationJson.length() == 0) { + return false; + } + + JSONArray columns = multimediaClassificationJson.getJSONArray("columns"); + + ContentValues contentValues = new ContentValues(); + + for (int i = 0; i < columns.length(); i++) { + JSONObject colObject = columns.getJSONObject(i); + String columnName = colObject.getString("column_name"); + JSONObject jsonMapping = colObject.getJSONObject("json_mapping"); + String dataSegment = null; + String fieldName = jsonMapping.getString("field"); + if (fieldName != null && fieldName.contains(".")) { + String fieldNameArray[] = fieldName.split("\\."); + dataSegment = fieldNameArray[0]; + fieldName = fieldNameArray[1]; + } + + Object jsonDocSegment; + + if (dataSegment != null) { + //pick data from a specific section of the doc + jsonDocSegment = multimedia.get(dataSegment); + + } else { + //else the use the main doc as the doc segment + jsonDocSegment = multimedia; + + } + + //e.g client attributes section + String columnValue; + JSONObject jsonDocSegmentObject = (JSONObject) jsonDocSegment; + columnValue = jsonDocSegmentObject.has(fieldName) ? jsonDocSegmentObject.getString(fieldName) : ""; + // after successfully retrieving the column name and value store it in Content value + if (columnValue != null) { + columnValue = getHumanReadableConceptResponse(columnValue, jsonDocSegmentObject); + contentValues.put(columnName, columnValue); + } + } + + // save the values to db + if(contentValues.size() > 0) { + executeInsertAlert(contentValues); + } + return true; + + } catch (Exception e) { + Log.e(TAG, e.toString(), e); + return null; + } + } + + +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/Tools.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/Tools.java new file mode 100644 index 0000000..0785592 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/Tools.java @@ -0,0 +1,734 @@ +package org.ei.opensrp.gizi.face.camera.util; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.SharedPreferences; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.graphics.Rect; +import android.graphics.Typeface; +import android.media.ThumbnailUtils; +import android.support.annotation.Nullable; +import android.util.Log; +import android.widget.ImageView; +import android.widget.Toast; + +import com.loopj.android.http.AsyncHttpClient; +import com.loopj.android.http.AsyncHttpResponseHandler; +import com.qualcomm.snapdragon.sdk.face.FaceData; +import com.qualcomm.snapdragon.sdk.face.FacialProcessing; + +import org.apache.commons.lang3.ArrayUtils; +import org.ei.opensrp.Context; +import org.ei.opensrp.domain.ProfileImage; +import org.ei.opensrp.gizi.R; +import org.ei.opensrp.gizi.face.camera.ClientsList; +import org.ei.opensrp.gizi.face.camera.ImageConfirmation; +import org.ei.opensrp.gizi.face.camera.SmartShutterActivity; +import org.ei.opensrp.gizi.gizi.GiziDetailActivity; +import org.ei.opensrp.repository.ImageRepository; +import org.ei.opensrp.util.OpenSRPImageLoader; +import org.ei.opensrp.view.activity.DrishtiApplication; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.File; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import cz.msebera.android.httpclient.Header; +import util.formula.Support; + + +/** + * Created by wildan on 1/4/17. + */ +public class Tools { + + private static final String TAG = Tools.class.getSimpleName(); + public static final int CONFIDENCE_VALUE = 58; + public static org.ei.opensrp.Context appContext; + public static android.content.Context androContext; + private static String[] splitStringArray; + private static Bitmap dummyImage = null; + private static byte[] headerOfVector; + private static byte[] bodyOfVector; + private static byte[] lastContentOfVector; + // private static String headerOne; + private static byte[] albumVectors; + private Bitmap helperImage = null; + private Canvas canvas = null; + SmartShutterActivity ss = new SmartShutterActivity(); + ClientsList cl = new ClientsList(); + private static HashMap hash; + private String albumBuffer; + private List list; + private static String anmId = Context.getInstance().allSharedPreferences().fetchRegisteredANM(); + private static ProfileImage profileImage = new ProfileImage(); + private static ImageRepository imageRepo = (ImageRepository) org.ei.opensrp.Context.imageRepository(); + + static String emptyAlbum = "[32, 0, 0, 0, 76, 65, -68, -20, 77, 116, 46, 83, 105, 110, 97, 105, 6, 0, 0, 0, -24, 3, 0, 0, 10, 0, 0, 0, 0, 0, 0, 0]"; + private static String headerOne = emptyAlbum; + static String singleHeader = "[76, 1, 0, 0, 76, 65, -68, -20, 77, 116, 46, 83, 105, 110, 97, 105, 6, 0, 0, 0, -24, 3, 0, 0, 10, 0, 0, 0, 1, 0, 0, 0]"; + + public Tools() { + Log.e(TAG, "Tools: 1"); + imageRepo = (ImageRepository) org.ei.opensrp.Context.imageRepository(); +// hash = retrieveHash(appContext.applicationContext()); + } + + public Tools(org.ei.opensrp.Context appContext) { + imageRepo = (ImageRepository) org.ei.opensrp.Context.imageRepository(); + Tools.appContext = appContext; +// helperImage = BitmapFactory.decodeResource( appContext.applicationContext().getResources(), R.drawable.h8);//ok +// hash = retrieveHash(appContext.applicationContext()); + } + + /** + * Method to Stored Bitmap as File and Buffer + * + * @param bitmap Photo bitmap + * @param entityId Base user id + * @param faceVector Vector from face + * @param updated capture mode + * @return Boolean + */ +// public static boolean WritePictureToFile(android.content.Context context, Bitmap bitmap, String entityId, byte[] faceVector, boolean updated) { + public static boolean WritePictureToFile(Bitmap bitmap, String entityId, String[] faceVector, boolean updated) { + + File pictureFile = getOutputMediaFile(0, entityId); + File thumbs_photo = getOutputMediaFile(1, entityId); + + if (pictureFile == null || thumbs_photo == null) { + Log.e(TAG, "Error creating media file, check storage permissions!"); + return false; + } + + try { + FileOutputStream fos = new FileOutputStream(pictureFile); + bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos); + fos.close(); + Log.e(TAG, "Wrote image to " + pictureFile); + +// MediaScannerConnection.scanFile(context, new String[]{ +// pictureFile.toString()}, null, +// new MediaScannerConnection.OnScanCompletedListener() { +// public void onScanCompleted(String path, Uri uri) { +// Log.i("ExternalStorage", "Scanned " + path + ":"); +// Log.i("ExternalStorage", "-> uri=" + uri); +// } +// }); + String photoPath = pictureFile.toString(); + Log.e(TAG, "Photo Path = " + photoPath); + +// Create Thumbs + FileOutputStream tfos = new FileOutputStream(thumbs_photo); + final int THUMBSIZE = FaceConstants.THUMBSIZE; + + Bitmap ThumbImage = ThumbnailUtils.extractThumbnail(BitmapFactory.decodeFile(photoPath), + THUMBSIZE, THUMBSIZE); + ThumbImage.compress(Bitmap.CompressFormat.PNG, 100, tfos); + tfos.close(); + Log.e(TAG, "Wrote Thumbs image to " + thumbs_photo); + +// FIXME File & Database Stored +// saveStaticImageToDisk(entityId, ThumbImage, Arrays.toString(faceVector), updated); + + saveToDb(entityId, thumbs_photo.toString(), Arrays.toString(faceVector), updated); + + return true; + + } catch (FileNotFoundException e) { + Log.d(TAG, "File not found: " + e.getMessage()); + } catch (IOException e) { + Log.d(TAG, "Error accessing file: " + e.getMessage()); + } + return false; + } + + private static void saveToDb(String entityId, String absoluteFileName, String faceVector, boolean updated) { + + Log.e(TAG, "saveToDb: " + "start"); + // insert into the db local + if (!updated) { + profileImage.setImageid(UUID.randomUUID().toString()); + profileImage.setAnmId(anmId); + profileImage.setEntityID(entityId); + profileImage.setContenttype("jpeg"); + profileImage.setFilepath(absoluteFileName); + profileImage.setFilecategory("profilepic"); + profileImage.setFilevector(faceVector); + profileImage.setSyncStatus(ImageRepository.TYPE_Unsynced); + + imageRepo.add(profileImage, entityId); + } else { + imageRepo.updateByEntityId(entityId, faceVector); + } + Log.e(TAG, "saveToDb: " + "done"); + + } + + /** + * Method create new file + * + * @param mode capture mode. + * @param entityId Base user id. + * @return File + */ + @Nullable + private static File getOutputMediaFile(Integer mode, String entityId) { + // Mode 0 = Original + // Mode 1 = Thumbs + + // Location use app_dir + String imgFolder = (mode == 0) ? DrishtiApplication.getAppDir() : + DrishtiApplication.getAppDir() + File.separator + ".thumbs"; +// String imgFolder = (mode == 0) ? "OPENSRP_SID":"OPENSRP_SID"+File.separator+".thumbs"; +// File mediaStorageDir = new File( +// Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM), imgFolder); + File mediaStorageDir = new File(imgFolder); + + // Create the storage directory if it does not exist + if (!mediaStorageDir.exists()) { + Log.e(TAG, "failed to find directory " + mediaStorageDir.getAbsolutePath()); + if (!mediaStorageDir.mkdirs()) { + Log.e(TAG, "Created new directory " + mediaStorageDir.getAbsolutePath()); + return null; + } + } + + // Create a media file name + return new File(String.format("%s%s%s.JPEG", mediaStorageDir.getPath(), File.separator, entityId)); + } + + /** + * Methof for Draw Information of existing Person + * + * @param rect Rectangular + * @param mutableBitmap Bitmap + * @param pixelDensity Pixel group area + * @param personName name + */ + public static void drawInfo(Rect rect, Bitmap mutableBitmap, float pixelDensity, String personName) { +// Log.e(TAG, "drawInfo: rect " + rect); +// Log.e(TAG, "drawInfo: bitmap" + mutableBitmap); + + // Extra padding around the faceRects + rect.set(rect.left -= 20, rect.top -= 20, rect.right += 20, rect.bottom += 20); + Canvas canvas = new Canvas(mutableBitmap); + Paint paintForRectFill = new Paint(); + + // Draw rect fill + paintForRectFill.setStyle(Paint.Style.FILL); + paintForRectFill.setColor(Color.WHITE); + paintForRectFill.setAlpha(80); + + // Draw rectangular strokes + Paint paintForRectStroke = new Paint(); + paintForRectStroke.setStyle(Paint.Style.STROKE); + paintForRectStroke.setColor(Color.GREEN); + paintForRectStroke.setStrokeWidth(5); + canvas.drawRect(rect, paintForRectFill); + canvas.drawRect(rect, paintForRectStroke); + +// float pixelDensity = getResources().getDisplayMetrics().density; + int textSize = (int) (rect.width() / 25 * pixelDensity); + + Paint paintForText = new Paint(); + Paint paintForTextBackground = new Paint(); + Typeface tp = Typeface.SERIF; + Rect backgroundRect = new Rect(rect.left, rect.bottom, rect.right, (rect.bottom + textSize)); + + paintForText.setColor(Color.WHITE); + paintForText.setTextSize(textSize); + paintForTextBackground.setStyle(Paint.Style.FILL); + paintForTextBackground.setColor(Color.BLACK); + paintForText.setTypeface(tp); + paintForTextBackground.setAlpha(80); + + if (personName != null) { + canvas.drawRect(backgroundRect, paintForTextBackground); + canvas.drawText(personName, rect.left, rect.bottom + (textSize), paintForText); + } else { + canvas.drawRect(backgroundRect, paintForTextBackground); + canvas.drawText("Not identified", rect.left, rect.bottom + (textSize), paintForText); + } + +// confirmationView.setImageBitmap(mutableBitmap); + + } + + /** + * Draw Area that detected as Face + * + * @param rect Rectangular + * @param mutableBitmap Modified Bitmap + * @param pixelDensity Pixel area density + */ + public static void drawRectFace(Rect rect, Bitmap mutableBitmap, float pixelDensity) { + + Log.e(TAG, "drawRectFace: rect " + rect); + Log.e(TAG, "drawRectFace: bitmap " + mutableBitmap); + Log.e(TAG, "drawRectFace: pixelDensity " + pixelDensity); + + // Extra padding around the faceRects + rect.set(rect.left -= 20, rect.top -= 20, rect.right += 20, rect.bottom += 20); + Canvas canvas = new Canvas(mutableBitmap); + + // Draw rect fill + Paint paintForRectFill = new Paint(); + paintForRectFill.setStyle(Paint.Style.FILL); + paintForRectFill.setColor(Color.WHITE); + paintForRectFill.setAlpha(80); + + // Draw rect strokes + Paint paintForRectStroke = new Paint(); + paintForRectStroke.setStyle(Paint.Style.STROKE); + paintForRectStroke.setColor(Color.GREEN); + paintForRectStroke.setStrokeWidth(5); + + // Draw Face detected Area + canvas.drawRect(rect, paintForRectFill); + canvas.drawRect(rect, paintForRectStroke); + + } + + /** + * Stored list detected Base entity ID to Shared Preference for buffered + * + * @param hashMap HashMap + * @param context context + */ + public static void saveHash(HashMap hashMap, android.content.Context context) { + SharedPreferences settings = context.getSharedPreferences(FaceConstants.HASH_NAME, 0); + + SharedPreferences.Editor editor = settings.edit(); + editor.clear(); +// Log.e(TAG, "Hash Save Size = " + hashMap.size()); + for (String s : hashMap.keySet()) { +// Log.e(TAG, "saveHash: " + s); + editor.putString(s, hashMap.get(s)); + } + editor.apply(); + } + + /** + * Get Existing Hash + * + * @param context Context + * @return hash + */ + public static HashMap retrieveHash(android.content.Context context) { + SharedPreferences settings = context.getSharedPreferences(FaceConstants.HASH_NAME, 0); + HashMap hash = new HashMap<>(); + hash.putAll((Map) settings.getAll()); + return hash; + } + + /** + * Save Vector array to xml + */ + public static void saveAlbum(String albumBuffer, android.content.Context context) { + SharedPreferences settings = context.getSharedPreferences(FaceConstants.ALBUM_NAME, 0); + SharedPreferences.Editor editor = settings.edit(); + editor.putString(FaceConstants.ALBUM_ARRAY, albumBuffer); + editor.apply(); + } + + public static void loadAlbum(android.content.Context context) { + + SharedPreferences settings = context.getSharedPreferences(FaceConstants.ALBUM_NAME, 0); + String arrayOfString = settings.getString(FaceConstants.ALBUM_ARRAY, null); + byte[] albumArray; + + if (arrayOfString != null) { + + splitStringArray = arrayOfString.substring(1, arrayOfString.length() - 1).split(", "); + + albumArray = new byte[splitStringArray.length]; + + + for (int i = 0; i < splitStringArray.length; i++) { + albumArray[i] = Byte.parseByte(splitStringArray[i]); + } + + boolean result = SmartShutterActivity.faceProc.deserializeRecognitionAlbum(albumArray); + + if (result) Log.e(TAG, "loadAlbum: "+"Succes" ); + + } else { + Log.e(TAG, "loadAlbum: " + "is it your first record ? if no, there is problem happen."); + } + } + + public static void alertDialog(android.content.Context context, int opt) { + final AlertDialog.Builder alertDialog = new AlertDialog.Builder(context); + Tools tools = new Tools(); +// alertDialog.setMessage(message); + String message = ""; + switch (opt) { + case 0: + message = "Are you sure to empty The Album?"; +// doEmpty; + break; + case 1: + message = "Are you sure to delete item"; + break; + default: + break; + } + alertDialog.setMessage(message); +// alertDialog.setButton("OK", do); + alertDialog.setPositiveButton("ERASE", tools.doEmpty); + alertDialog.show(); + } + + private DialogInterface.OnClickListener doEmpty = new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int id) { + boolean result = SmartShutterActivity.faceProc.resetAlbum(); + if (result) { +// HashMap hashMap = SmartShutterActivity.retrieveHash(getApplicationContext()); +// HashMap hashMap = retrieveHash(getApplicationContext()); +// HashMap hashMap = retrieveHash(); +// hashMap.clear(); +// SmartShutterActivity ss = new SmartShutterActivity(); +// saveHash(hashMap, getApplicationContext()); +// saveAlbum(); +// Toast.makeText(getApplicationContext(), +// "Album Reset Successful.", +// Toast.LENGTH_LONG).show(); + } else { +// Toast.makeText( +// getApplicationContext(), +// "Internal Error. Reset album failed", +// Toast.LENGTH_LONG).show(); + } + } + }; + + public void resetAlbum() { + + Log.e(TAG, "resetAlbum: " + "start"); + boolean result = SmartShutterActivity.faceProc.resetAlbum(); + + if (result) { + // Clear data + // TODO: Null getApplication COntext +// HashMap hashMap = SmartShutterActivity.retrieveHash(new ClientsList().getApplicationContext()); + HashMap hashMap = SmartShutterActivity.retrieveHash(appContext.applicationContext().getApplicationContext()); + hashMap.clear(); +// saveHash(hashMap, cl.getApplicationContext()); + saveHash(hashMap, appContext.applicationContext().getApplicationContext()); +// saveAlbum(); + +// Toast.makeText(cl.getApplicationContext(), "Reset Succesfully done!", Toast.LENGTH_LONG).show(); + Toast.makeText(appContext.applicationContext().getApplicationContext(), "Reset Succesfully done!", Toast.LENGTH_LONG).show(); + } else { + Toast.makeText(appContext.applicationContext().getApplicationContext(), "Reset Failed!", Toast.LENGTH_LONG).show(); + + } + Log.e(TAG, "resetAlbum: " + "finish"); + } + + /** + * Fetch data from API (json + */ + public static void setVectorfromAPI(final android.content.Context context) { +// AllSharedPreferences allSharedPreferences; + Support.ONSYNC = true; + String DRISTHI_BASE_URL = appContext.configuration().dristhiBaseURL(); + String user = appContext.allSharedPreferences().fetchRegisteredANM(); + String location = appContext.allSharedPreferences().getPreference("locationId"); + String pwd = appContext.allSettings().fetchANMPassword(); + //TODO : cange to based locationId +// String api_url = DRISTHI_BASE_URL + "/multimedia-file?anm-id=" + user; + final String api_url = DRISTHI_BASE_URL + "/multimedia-file?locationid=" + location; +// +// AsyncHttpClient client = new AsyncHttpClient(); +// +// client.setBasicAuth(user, pwd); +// +//// client.get(api_url, new JsonHttpResponseHandler(){ +//// }); +// +// client.get(api_url, new AsyncHttpResponseHandler() { +// @Override +// public void onSuccess(int statusCode, Header[] headers, byte[] responseBody) { +// Log.e(TAG, "onSuccess: " + statusCode); +// insertOrUpdate(responseBody); +// } +// +// @Override +// public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) { +// Log.e(TAG, "onFailure: " + api_url); +// } +// }); + + try { + WebUtils.fetch(api_url, user, pwd); + } catch (Exception e) { + e.printStackTrace(); + } + + + } + + static void insertOrUpdate(byte[] responseBody) { + + try { + JSONArray response = new JSONArray(new String(responseBody)); + + for (int i = 0; i < response.length(); i++) { + JSONObject data = response.getJSONObject(i); + + String uid = data.getString("caseId"); + String anmId = data.getString("providerId"); +// String uid = data.getString("caseId"); + + // To AlbumArray + String faceVector = data.getJSONObject("attributes").getString("faceVector"); + + // Update Table ImageList on existing record based on entityId where faceVector== null + ProfileImage profileImage = new ProfileImage(); +// profileImage.setImageid(UUID.randomUUID().toString()); + // TODO : get anmID from ? + profileImage.setAnmId(anmId); + profileImage.setEntityID(uid); +// profileImage.setFilepath(null); +// profileImage.setFilecategory("profilepic"); +// profileImage.setSyncStatus(ImageRepository.TYPE_Synced); + + // TODO : fetch vector from imagebitmap + profileImage.setFilevector(faceVector); + + imageRepo.createOrUpdate(profileImage, uid); + + } + download_images(); + setVectorsBuffered(); + } catch (JSONException e) { + e.printStackTrace(); + } + + } + + /** + * Method to Parse String + * + * @param arrayOfString + * @return + */ + private String[] parseArray(String arrayOfString) { + + return arrayOfString.substring(1, + arrayOfString.length() - 1).split(", "); + } + + /** + * Save to Buffer from Local DB + * + * @param context + */ + + public static void saveAndClose(android.content.Context context, String entityId, boolean updated, + FacialProcessing objFace, int arrayPossition, + Bitmap storedBitmap, String className) { + + byte[] faceVector; + + if (!updated) { + +// Log.e(TAG, "saveAndClose: "+ "updated : false" ); + Log.e(TAG, "saveAndClose: "+ objFace ); + int result = objFace.addPerson(arrayPossition); + faceVector = objFace.serializeRecogntionAlbum(); + +// Log.e(TAG, "saveAndClose: length "+ faceVector.length ); // 32 +// +// Log.e(TAG, "saveAndClose: " + result); + + hash = retrieveHash(context); + + hash.put(entityId, Integer.toString(result)); +// + // Save Hash + saveHash(hash, context); + +// byte[] albumBuffer = SmartShutterActivity.faceProc.serializeRecogntionAlbum(); + + Log.e(TAG, "saveAndClose: " + faceVector.length); + + saveAlbum(Arrays.toString(faceVector), context); + + String albumBufferArr = Arrays.toString(faceVector); + + String[] faceVectorContent = albumBufferArr.substring(1, albumBufferArr.length() - 1).split(", "); + + // Get Face Vector Contnt Only by removing Header + faceVectorContent = Arrays.copyOfRange(faceVectorContent, faceVector.length - 300, faceVector.length); + + WritePictureToFile(storedBitmap, entityId, faceVectorContent, updated); + + // Reset Album to get Single Face Vector +// SmartShutterActivity.faceProc.resetAlbum(); + + } else { + + int update_result = objFace.updatePerson(Integer.parseInt(hash.get(entityId)), 0); + + if (update_result == 0) { + + Log.e(TAG, "saveAndClose: " + "success"); + + } else { + + Log.e(TAG, "saveAndClose: " + "Maximum Reached Limit for Face"); + + } + + faceVector = objFace.serializeRecogntionAlbum(); + + // TODO : update only face vector + saveAlbum(Arrays.toString(faceVector), context); + } + + new ImageConfirmation().finish(); + + Class origin_class = null; + + if(className.equals(GiziDetailActivity.class.getSimpleName())){ + origin_class = GiziDetailActivity.class; + } + + Intent resultIntent = new Intent(appContext.applicationContext(), origin_class); +// setResult(RESULT_OK, resultIntent); + resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + + appContext.applicationContext().startActivity(resultIntent); + + Log.e(TAG, "saveAndClose: " + "end"); + } + + public static void setVectorsBuffered() { + + List vectorList = imageRepo.getAllVectorImages(); + + if (vectorList.size() != 0) { + + hash = retrieveHash(appContext.applicationContext().getApplicationContext()); +// Log.e(TAG, "setVectorsBuffered: hash size " + hash.size()); + + String[] albumBuffered = new String[0]; + + int i = 0; + for (ProfileImage profileImage : vectorList) { + String[] vectorFace = new String[]{}; + if (profileImage.getFilevector() != null) { + + vectorFace = profileImage.getFilevector().substring(1, profileImage.getFilevector().length() - 1).split(", "); + vectorFace[0] = String.valueOf(i); + +// vectorFace[0] = String.valueOf((i%128) % 256 - 128); + + + albumBuffered = ArrayUtils.addAll(albumBuffered, vectorFace); + hash.put(profileImage.getEntityID(), String.valueOf(i)); + + } else { + Log.e(TAG, "setVectorsBuffered: Profile Image Null"); + } +// Log.e(TAG, "setVectorsBuffered: "+ i +" - "+ vectorFace.length); + i++; + if(i>127) + i=-128; + } + + albumBuffered = ArrayUtils.addAll(getHeaderBaseUserCount(vectorList.size()), albumBuffered); + +// Log.e(TAG, "setVectorsBuffered: hash size" + hash.size() + " album size "+ albumBuffered.length); + saveAlbum(Arrays.toString(albumBuffered), appContext.applicationContext()); + saveHash(hash, appContext.applicationContext()); + + } else { + Log.e(TAG, "setVectorsBuffered: "+ "Multimedia Table Not ready" ); + } + } + + private static String[] getHeaderBaseUserCount(int i) { +// String headerNew = imageRepo.findByUserCount(i); +// return headerNew.substring(1, headerNew.length() -1).split(", "); + Log.e(TAG, "getHeaderBaseUserCount: Number User"+ i ); + +// Init value + int n = i-1; + int n0 = 76; + int max = 128; + int min = -128; + int range = max - min; + int idx0,idx1, idx2,idx3,idx4; + + idx0 = (((n0 + max) + (n * 44)) % range) + min; + idx1 = (1+n)+(((n0) + (n * 44)) / range); + idx2 = (idx1+128) % 256 - 128; + idx3 = n / 218; + idx4 = (1+n+128) % 256 - 128; + // end formula + + String[] newHeader = singleHeader.substring(1, singleHeader.length() - 1).split(", "); + + newHeader[0] = String.valueOf(idx0); + newHeader[1] = String.valueOf(idx2); + newHeader[2] = String.valueOf(idx3); + newHeader[28] = String.valueOf(idx4); + + return newHeader; + } + + public static void download_images() { + Log.e(TAG, "download_images: START" ); + try { + List images = imageRepo.findAllUnDownloaded(); + for (String uid : images){ + ImageView iv = new ImageView(appContext.applicationContext()); + // TODO setTag+"The key must be an application-specific resource id" + iv.setTag(R.id.entity_id, uid); + DrishtiApplication.getCachedImageLoaderInstance().getImageByClientId(uid, OpenSRPImageLoader.getStaticImageListener(iv, 0, 0)); + Log.e(TAG, "download_images: done "+ uid ); + + } + } catch (Exception e){ + Log.e(TAG, "download_images: "+ e.getMessage() ); + } + Log.e(TAG, "download_images: FINISHED" ); + } + + public static void setAppContext(Context context) { + Tools.appContext = context; + } + + public static Context getAppContext(){ + return Tools.appContext; + } + + public void setAlbumBuffer(String albumBuffer) { + this.albumBuffer = albumBuffer; + } + + public String getAlbumBuffer() { + + return albumBuffer; + } + +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/WebUtils.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/WebUtils.java new file mode 100644 index 0000000..6d77e4f --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/face/camera/util/WebUtils.java @@ -0,0 +1,62 @@ +package org.ei.opensrp.gizi.face.camera.util; + +import java.io.IOException; + +import okhttp3.Authenticator; +import okhttp3.Credentials; +import okhttp3.OkHttpClient; +import okhttp3.Request; +import okhttp3.Response; +import okhttp3.Route; + +/** + * Created by sid on 7/24/17. + */ + + +public class WebUtils { + + public static Response fetch(String url, String username, String password) throws Exception { + + OkHttpClient httpClient = createAuthenticatedClient(username, password); + // execute request + + return doRequest(httpClient, url); + + } + + private static OkHttpClient createAuthenticatedClient(final String username, + final String password) { + // build client with authentication information. + OkHttpClient httpClient = new OkHttpClient.Builder().authenticator(new Authenticator() { + public Request authenticate(Route route, Response response) throws IOException { + String credential = Credentials.basic(username, password); + if (responseCount(response) >= 3) { + return null; + } + return response.request().newBuilder().header("Authorization", credential).build(); + } + }).build(); + return httpClient; + } + + private static Response doRequest(OkHttpClient httpClient, String anyURL) throws Exception { + Request request = new Request.Builder().url(anyURL).build(); + Response response = httpClient.newCall(request).execute(); + if (!response.isSuccessful()) { + throw new IOException("Unexpected code " + response); + } +// System.out.println(response.body().string()); + Tools.insertOrUpdate(response.body().bytes()); + + return response; + } + + private static int responseCount(Response response) { + int result = 1; + while ((response = response.priorResponse()) != null) { + result++; + } + return result; + } +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/fragment/GiziIbuSmartRegisterFragment.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/fragment/GiziIbuSmartRegisterFragment.java new file mode 100644 index 0000000..dfebd9c --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/fragment/GiziIbuSmartRegisterFragment.java @@ -0,0 +1,633 @@ +package org.ei.opensrp.gizi.fragment; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Parcelable; +import android.text.Editable; +import android.text.TextWatcher; +import android.util.Log; +import android.view.View; +import android.widget.EditText; + +import com.flurry.android.FlurryAgent; + +import org.ei.opensrp.Context; +import org.ei.opensrp.commonregistry.CommonPersonObjectClient; +import org.ei.opensrp.commonregistry.CommonPersonObjectController; +import org.ei.opensrp.commonregistry.CommonRepository; +import org.ei.opensrp.cursoradapter.CursorCommonObjectFilterOption; +import org.ei.opensrp.cursoradapter.CursorCommonObjectSort; +import org.ei.opensrp.cursoradapter.SecuredNativeSmartRegisterCursorAdapterFragment; +import org.ei.opensrp.cursoradapter.SmartRegisterPaginatedCursorAdapter; +import org.ei.opensrp.cursoradapter.SmartRegisterQueryBuilder; +import org.ei.opensrp.gizi.LoginActivity; +import org.ei.opensrp.gizi.R; +import org.ei.opensrp.gizi.face.camera.SmartShutterActivity; +import org.ei.opensrp.gizi.gizi.FlurryFacade; +import org.ei.opensrp.gizi.giziIbu.IbuServiceModeOption; +import org.ei.opensrp.gizi.gizi.GiziSmartRegisterActivity; +import org.ei.opensrp.gizi.gizi.KICommonObjectFilterOption; +import org.ei.opensrp.gizi.giziIbu.IbuSmartClientsProvider; +import org.ei.opensrp.gizi.giziIbu.IbuSmartRegisterActivity; +import org.ei.opensrp.provider.SmartRegisterClientsProvider; +import org.ei.opensrp.sync.ClientProcessor; +import org.ei.opensrp.util.StringUtil; +import org.ei.opensrp.view.activity.SecuredNativeSmartRegisterActivity; +import org.ei.opensrp.view.contract.ECClient; +import org.ei.opensrp.view.contract.SmartRegisterClient; +import org.ei.opensrp.view.contract.SmartRegisterClients; +import org.ei.opensrp.view.controller.VillageController; +import org.ei.opensrp.view.dialog.AllClientsFilter; +import org.ei.opensrp.view.dialog.DialogOption; +import org.ei.opensrp.view.dialog.DialogOptionMapper; +import org.ei.opensrp.view.dialog.DialogOptionModel; +import org.ei.opensrp.view.dialog.EditOption; +import org.ei.opensrp.view.dialog.FilterOption; +import org.ei.opensrp.view.dialog.NameSort; +import org.ei.opensrp.view.dialog.ServiceModeOption; +import org.ei.opensrp.view.dialog.SortOption; +import org.opensrp.api.domain.Location; +import org.opensrp.api.util.EntityUtils; +import org.opensrp.api.util.LocationTree; +import org.opensrp.api.util.TreeNode; + +import java.util.ArrayList; +import java.util.Map; + +import util.AsyncTask; + +import static android.view.View.INVISIBLE; +import static android.view.View.VISIBLE; +import static org.apache.commons.lang3.StringUtils.isEmpty; + +/** + * Created by koros on 10/12/15. + */ +public class GiziIbuSmartRegisterFragment extends SecuredNativeSmartRegisterCursorAdapterFragment { + + private static final String TAG = GiziIbuSmartRegisterFragment.class.getSimpleName(); + + private SmartRegisterClientsProvider clientProvider = null; + private CommonPersonObjectController controller; + private VillageController villageController; + private DialogOptionMapper dialogOptionMapper; + private ClientProcessor clientProcessor; + private final ClientActionHandler clientActionHandler = new ClientActionHandler(); + private String locationDialogTAG = "locationDialogTAG"; + + public static String criteria; + + @Override + protected void onCreation() { + // + } + +// @Override +// protected SmartRegisterPaginatedAdapter adapter() { +// return new SmartRegisterPaginatedAdapter(clientsProvider()); +// } + + @Override + protected SecuredNativeSmartRegisterActivity.DefaultOptionsProvider getDefaultOptionsProvider() { + return new SecuredNativeSmartRegisterActivity.DefaultOptionsProvider() { + + @Override + public ServiceModeOption serviceMode() { + return new IbuServiceModeOption(clientsProvider()); + } + + @Override + public FilterOption villageFilter() { + return new AllClientsFilter(); + } + + @Override + public SortOption sortOption() { + return new NameSort(); + + } + + @Override + public String nameInShortFormForTitle() { + return Context.getInstance().getStringResource(R.string.gizi_ibu); + } + }; + } + + @Override + protected SecuredNativeSmartRegisterActivity.NavBarOptionsProvider getNavBarOptionsProvider() { + return new SecuredNativeSmartRegisterActivity.NavBarOptionsProvider() { + + @Override + public DialogOption[] filterOptions() { + FlurryFacade.logEvent("click_filter_option_on_kohort_ibu_dashboard"); + ArrayList dialogOptionslist = new ArrayList(); + + dialogOptionslist.add(new CursorCommonObjectFilterOption(getString(R.string.filter_by_all_label),filterStringForAll())); + // dialogOptionslist.add(new CursorCommonObjectFilterOption(getString(R.string.hh_no_mwra),filterStringForNoElco())); + // dialogOptionslist.add(new CursorCommonObjectFilterOption(getString(R.string.hh_has_mwra),filterStringForOneOrMoreElco())); + + String locationjson = context().anmLocationController().get(); + LocationTree locationTree = EntityUtils.fromJson(locationjson, LocationTree.class); + + Map> locationMap = + locationTree.getLocationsHierarchy(); + addChildToList(dialogOptionslist,locationMap); + DialogOption[] dialogOptions = new DialogOption[dialogOptionslist.size()]; + for (int i = 0;i < dialogOptionslist.size();i++){ + dialogOptions[i] = dialogOptionslist.get(i); + } + + return dialogOptions; + } + + @Override + public DialogOption[] serviceModeOptions() { + return new DialogOption[]{}; + } + + @Override + public DialogOption[] sortingOptions() { + // FlurryFacade.logEvent("click_sorting_option_on_kohort_ibu_dashboard"); + return new DialogOption[]{ +// new HouseholdCensusDueDateSort(), + + + new CursorCommonObjectSort(getResources().getString(R.string.sort_by_name_label),KiSortByNameAZ()), + new CursorCommonObjectSort(getResources().getString(R.string.sort_by_name_label_reverse),KiSortByNameZA()), + }; + } + + @Override + public String searchHint() { + return getResources().getString(R.string.hh_search_hint); + } + }; + } + + + + @Override + protected SmartRegisterClientsProvider clientsProvider() { +// if (clientProvider == null) { +// clientProvider = new HouseHoldSmartClientsProvider( +// getActivity(),clientActionHandler , context().alertService()); +// } + return null; + } + + private DialogOption[] getEditOptions() { + return ((GiziSmartRegisterActivity)getActivity()).getEditOptions(); + } + + @Override + protected void onInitialization() { + // context().formSubmissionRouter().getHandlerMap().put("census_enrollment_form", new CensusEnrollmentHandler()); + } + + @Override + public void setupViews(View view) { + getDefaultOptionsProvider(); + + super.setupViews(view); + view.findViewById(R.id.btn_report_month).setVisibility(INVISIBLE); + view.findViewById(R.id.service_mode_selection).setVisibility(View.GONE); + clientsView.setVisibility(View.VISIBLE); + clientsProgressView.setVisibility(View.INVISIBLE); +// list.setBackgroundColor(Color.RED); + initializeQueries(getCriteria()); + } + private String filterStringForAll(){ + return ""; + } + private String sortByAlertmethod() { + return " CASE WHEN alerts.status = 'urgent' THEN '1'" + + + "WHEN alerts.status = 'upcoming' THEN '2'\n" + + "WHEN alerts.status = 'normal' THEN '3'\n" + + "WHEN alerts.status = 'expired' THEN '4'\n" + + "WHEN alerts.status is Null THEN '5'\n" + + "Else alerts.status END ASC"; + } + + public void initializeQueries(String s){ + try { + IbuSmartClientsProvider kiscp = new IbuSmartClientsProvider(getActivity(),clientActionHandler,context().alertService()); + clientAdapter = new SmartRegisterPaginatedCursorAdapter(getActivity(), null, kiscp, new CommonRepository("ec_ibu",new String []{"ec_ibu.is_closed", "ec_kartu_ibu.namalengkap", "ec_kartu_ibu.namaSuami"})); + clientsView.setAdapter(clientAdapter); + + setTablename("ec_ibu"); + SmartRegisterQueryBuilder countqueryBUilder = new SmartRegisterQueryBuilder(); + countqueryBUilder.SelectInitiateMainTableCounts("ec_ibu"); + countqueryBUilder.customJoin("LEFT JOIN ec_kartu_ibu on ec_kartu_ibu.id = ec_ibu.id"); + + if (s == null || s.equals("!")) { + Log.e(TAG, "initializeQueries: "+"Not Initialized" ); + mainCondition = "ec_ibu.is_closed = 0 AND pptest ='Positive' "; + } else { + Log.e(TAG, "initializeQueries: " + s); + mainCondition = "ec_ibu.is_closed = 0 AND pptest ='Positive' AND ec_ibu.id LIKE '%" + s + "%'"; + } + + joinTable = ""; + countSelect = countqueryBUilder.mainCondition(mainCondition); + super.CountExecute(); + + SmartRegisterQueryBuilder queryBUilder = new SmartRegisterQueryBuilder(); + queryBUilder.SelectInitiateMainTable("ec_ibu", new String[]{"ec_ibu.relationalid","ec_ibu.is_closed", "ec_ibu.details", "ec_kartu_ibu.namalengkap","ec_kartu_ibu.namaSuami"}); + queryBUilder.customJoin("LEFT JOIN ec_kartu_ibu on ec_kartu_ibu.id = ec_ibu.id"); + mainSelect = queryBUilder.mainCondition(mainCondition); + Sortqueries = KiSortByNameAZ(); + + currentlimit = 20; + currentoffset = 0; + + super.filterandSortInInitializeQueries(); + + updateSearchView(); + refresh(); + } catch (Exception e){ + e.printStackTrace(); + } + finally { + } + + } + + + @Override + public void startRegistration() { +// FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction(); +// Fragment prev = getActivity().getFragmentManager().findFragmentByTag(locationDialogTAG); +// if (prev != null) { +// ft.remove(prev); +// } +// ft.addToBackStack(null); +// LocationSelectorDialogFragment +// .newInstance((GiziSmartRegisterActivity) getActivity(), new EditDialogOptionModel(), context().anmLocationController().get(), "registrasi_jurim") +// .show(ft, locationDialogTAG); + } + + private class ClientActionHandler implements View.OnClickListener { + public void onClick(View view) { + switch (view.getId()) { +// case R.id.profile_info_layout: +// CharSequence selections[] = new CharSequence[] {"Detail View", "Charts"}; +// GiziDetailActivity.childclient = (CommonPersonObjectClient) view.getTag(); +// GiziGrowthChartActivity.client = (CommonPersonObjectClient)view.getTag(); +// final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); +// builder.setTitle(""); +// builder.setItems(selections, new DialogInterface.OnClickListener() { +// @Override +// public void onClick(DialogInterface dialog, int which) { +// // the user clicked on colors[which] +// if(which == 0) +// { +// Intent intent = new Intent(getActivity(),GiziDetailActivity.class); +// startActivity(intent); +// getActivity().finish(); +// } +// else if(which == 1){ +// Intent intent = new Intent(getActivity(),GiziGrowthChartActivity.class); +// startActivity(intent); +// getActivity().finish(); +// } +// } +// }); +// builder.show(); +// // FlurryFacade.logEvent("click_detail_picture_vaksinator"); +// +// break; + //untuk follow up button + case R.id.btn_edit: + // FlurryFacade.logEvent("click_button_edit_vaksinator"); + showFragmentDialog(new EditDialogOptionModel(), view.getTag()); + break; + } + } + + private void showProfileView(ECClient client) { + navigationController.startEC(client.entityId()); + } + } + + + + private String KiSortByNameAZ() { + return "namalengkap ASC"; + } + private String KiSortByNameZA() { + return "namalengkap DESC"; + } + + private String KiSortByAge() { + return "umur DESC"; + } + private String KiSortByNoIbu() { + return "noIbu ASC"; + } + + private String KiSortByEdd() { + return "htp IS NULL, htp"; + } + + + private class EditDialogOptionModel implements DialogOptionModel { + @Override + public DialogOption[] getDialogOptions() { + return getEditOptions(); + } + @Override + public void onDialogOptionSelection(DialogOption option, Object tag) { + + + /*if(option.name().equalsIgnoreCase(getString(R.string.str_register_anc_form)) ) { + CommonPersonObjectClient pc = KIDetailActivity.kiclient; + if(pc.getDetails().get("ibu.type")!= null) { + if (pc.getDetails().get("ibu.type").equals("anc") || pc.getDetails().get("ibu.type").equals("pnc")) { + Toast.makeText(getActivity().getApplicationContext(), getString(R.string.mother_already_registered), Toast.LENGTH_SHORT).show(); + return; + } + } + }*/ + onEditSelection((EditOption) option, (SmartRegisterClient) tag); + } + } + + @Override + protected void onResumption() { +// super.onResumption(); + getDefaultOptionsProvider(); + if(isPausedOrRefreshList()) { + initializeQueries("!"); + } + // updateSearchView(); +// + try{ + LoginActivity.setLanguage(); + }catch (Exception e){ + + } + + } +// @Override +// public void setupSearchView(View view) { +// searchView = (EditText) view.findViewById(org.ei.opensrp.R.id.edt_search); +// searchView.setHint(getNavBarOptionsProvider().searchHint()); +// searchView.addTextChangedListener(new TextWatcher() { +// @Override +// public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { +// } +// +// @Override +// public void onTextChanged(final CharSequence cs, int start, int before, int count) { +// +// (new AsyncTask() { +// SmartRegisterClients filteredClients; +// +// @Override +// protected Object doInBackground(Object[] params) { +//// currentSearchFilter = +//// setCurrentSearchFilter(new HHSearchOption(cs.toString())); +//// filteredClients = getClientsAdapter().getListItemProvider() +//// .updateClients(getCurrentVillageFilter(), getCurrentServiceModeOption(), +//// getCurrentSearchFilter(), getCurrentSortOption()); +//// +// filters = cs.toString(); +// joinTable = ""; +// mainCondition = " namaBayi !='' "; +// return null; +// } +// +// @Override +// protected void onPostExecute(Object o) { +//// clientsAdapter +//// .refreshList(currentVillageFilter, currentServiceModeOption, +//// currentSearchFilter, currentSortOption); +//// getClientsAdapter().refreshClients(filteredClients); +//// getClientsAdapter().notifyDataSetChanged(); +// getSearchCancelView().setVisibility(isEmpty(cs) ? INVISIBLE : VISIBLE); +// CountExecute(); +// filterandSortExecute(); +// super.onPostExecute(o); +// } +// }).execute(); +// } +// +// @Override +// public void afterTextChanged(Editable editable) { +// } +// }); +// searchCancelView = view.findViewById(org.ei.opensrp.R.id.btn_search_cancel); +// searchCancelView.setOnClickListener(searchCancelHandler); +// } +// + public void updateSearchView(){ + getSearchView().addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { + } + + @Override + public void onTextChanged(final CharSequence cs, int start, int before, int count) { + (new AsyncTask() { + SmartRegisterClients filteredClients; + + @Override + protected Object doInBackground(Object[] params) { +// currentSearchFilter = +// setCurrentSearchFilter(new HHSearchOption(cs.toString())); +// filteredClients = getClientsAdapter().getListItemProvider() +// .updateClients(getCurrentVillageFilter(), getCurrentServiceModeOption(), +// getCurrentSearchFilter(), getCurrentSortOption()); +// + + filters = cs.toString(); + joinTable = ""; + mainCondition = " namaBayi !='' "; + return null; + } + + @Override + protected void onPostExecute(Object o) { +// clientsAdapter +// .refreshList(currentVillageFilter, currentServiceModeOption, +// currentSearchFilter, currentSortOption); +// getClientsAdapter().refreshClients(filteredClients); +// getClientsAdapter().notifyDataSetChanged(); + getSearchCancelView().setVisibility(isEmpty(cs) ? INVISIBLE : VISIBLE); + filterandSortExecute(); + super.onPostExecute(o); + } + }).execute(); +// currentSearchFilter = new HHSearchOption(cs.toString()); +// clientsAdapter +// .refreshList(currentVillageFilter, currentServiceModeOption, +// currentSearchFilter, currentSortOption); +// +// searchCancelView.setVisibility(isEmpty(cs) ? INVISIBLE : VISIBLE); + + + } + + @Override + public void afterTextChanged(Editable editable) { + + } + }); + } + public void addChildToList(ArrayList dialogOptionslist,Map> locationMap){ + for(Map.Entry> entry : locationMap.entrySet()) { + + if(entry.getValue().getChildren() != null) { + addChildToList(dialogOptionslist,entry.getValue().getChildren()); + + }else{ + StringUtil.humanize(entry.getValue().getLabel()); + String name = StringUtil.humanize(entry.getValue().getLabel()); + dialogOptionslist.add(new KICommonObjectFilterOption(name,"desa", name)); + + } + } + } + + // WD + public void setCriteria(String criteria) { + this.criteria = criteria; + } + + public static String getCriteria() { + return criteria; + } + + // WD + @Override + public void setupSearchView(final View view) { + searchView = (EditText) view.findViewById(org.ei.opensrp.R.id.edt_search); + searchView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + CharSequence selections[] = new CharSequence[]{"Name", "Photo"}; + final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle("Please Choose one, Search by"); + builder.setItems(selections, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int opt) { + if (opt == 0) searchTextChangeListener(""); + else getFacialRecord(view); + } + }); + builder.show(); + } + }); + + searchCancelView = view.findViewById(org.ei.opensrp.R.id.btn_search_cancel); + searchCancelView.setOnClickListener(searchCancelHandler); + } + + public void getFacialRecord(View view) { + FlurryAgent.logEvent(TAG+" search_by_face", true); + Log.e(TAG, "getFacialRecord: "); + SmartShutterActivity.kidetail = (CommonPersonObjectClient) view.getTag(); + FlurryAgent.logEvent(TAG + " search_by_face", true); + + Intent intent = new Intent(getActivity(), SmartShutterActivity.class); + intent.putExtra("org.sid.sidface.ImageConfirmation.origin", GiziIbuSmartRegisterFragment.class.getSimpleName()); + intent.putExtra("org.sid.sidface.ImageConfirmation.identify", true); + intent.putExtra("org.sid.sidface.ImageConfirmation.kidetail", (Parcelable) SmartShutterActivity.kidetail); + startActivityForResult(intent, 2); + } + + public void searchTextChangeListener(String s) { + Log.e(TAG, "searchTextChangeListener: " + s); + if (s != null) { + filters = s; + } else { + searchView.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { + } + + @Override + public void onTextChanged(final CharSequence cs, int start, int before, int count) { + + Log.e(TAG, "onTextChanged: " + searchView.getText()); + (new AsyncTask() { +// SmartRegisterClients filteredClients; + + @Override + protected Object doInBackground(Object[] params) { +// currentSearchFilter = +// setCurrentSearchFilter(new HHSearchOption(cs.toString())); +// filteredClients = getClientsAdapter().getListItemProvider() +// .updateClients(getCurrentVillageFilter(), getCurrentServiceModeOption(), +// getCurrentSearchFilter(), getCurrentSortOption()); +// + + filters = cs.toString(); + joinTable = ""; + mainCondition = "nama_bayi !=''"; + Log.e(TAG, "doInBackground: " + filters); + return null; + } +// +// @Override +// protected void onPostExecute(Object o) { +//// clientsAdapter +//// .refreshList(currentVillageFilter, currentServiceModeOption, +//// currentSearchFilter, currentSortOption); +//// getClientsAdapter().refreshClients(filteredClients); +//// getClientsAdapter().notifyDataSetChanged(); +// getSearchCancelView().setVisibility(isEmpty(cs) ? INVISIBLE : VISIBLE); +// CountExecute(); +// filterandSortExecute(); +// super.onPostExecute(o); +// } + }).execute(); + } + + @Override + public void afterTextChanged(Editable editable) { + } + }); + } + } + +// @Override +// public void onActivityResult(int requestCode, int resultCode, Intent data){ +// super.onActivityResult(requestCode, resultCode, data); +// +// Intent myIntent = new Intent(getActivity(), IbuSmartRegisterActivity.class); +// if (data != null) { +// myIntent.putExtra("org.ei.opensrp.indonesia.face.face_mode", true); +// myIntent.putExtra("org.ei.opensrp.indonesia.face.base_id", data.getStringExtra("org.ei.opensrp.indonesia.face.base_id")); +// } +// getActivity().startActivity(myIntent); +// +// } + + + @Override + + public void onActivityResult(int requestCode, int resultCode, Intent data){ + super.onActivityResult(requestCode, resultCode, data); + + if (requestCode == 2 ) { + if (resultCode != 0) { + Intent myIntent = new Intent(getActivity(), IbuSmartRegisterActivity.class); + if (data != null) { + myIntent.putExtra("org.ei.opensrp.indonesia.face.face_mode", true); + myIntent.putExtra("org.ei.opensrp.indonesia.face.base_id", data.getStringExtra("org.ei.opensrp.indonesia.face.base_id")); + } + getActivity().startActivity(myIntent); + } else { + Log.e(TAG, "onActivityResult: "+ resultCode ); + } + } + +} + + + +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/fragment/GiziLocationSelectorDialogFragment.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/fragment/GiziLocationSelectorDialogFragment.java new file mode 100644 index 0000000..a90f9eb --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/fragment/GiziLocationSelectorDialogFragment.java @@ -0,0 +1,176 @@ +package org.ei.opensrp.gizi.fragment; + +import android.app.DialogFragment; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; + +import com.google.common.base.Strings; + +import org.ei.opensrp.domain.form.FieldOverrides; +import org.ei.opensrp.view.activity.SecuredNativeSmartRegisterActivity; +import org.ei.opensrp.view.dialog.DialogOption; +import org.ei.opensrp.view.dialog.DialogOptionModel; +import org.json.JSONObject; +import org.opensrp.api.domain.Location; +import org.opensrp.api.util.EntityUtils; +import org.opensrp.api.util.LocationTree; + +import java.util.Map; + +import atv.holder.SelectableItemHolder; +import atv.model.TreeNode; +import atv.view.AndroidTreeView; + +import static org.ei.opensrp.util.StringUtil.humanize; + +/** + * Created by koros on 2/25/16. + */ +public class GiziLocationSelectorDialogFragment extends DialogFragment { + + private final SecuredNativeSmartRegisterActivity parentActivity; + private final DialogOption[] options; + private final DialogOptionModel dialogOptionModel; + private final String locationJSONString; + public static String savestate ; + AndroidTreeView tView; + public String formname; + // private final Object tag; + + private GiziLocationSelectorDialogFragment(SecuredNativeSmartRegisterActivity activity, + DialogOptionModel dialogOptionModel, + String locationJSONString + , String formname) { + this.formname = formname; + this.parentActivity = activity; + this.options = dialogOptionModel.getDialogOptions(); + this.dialogOptionModel = dialogOptionModel; + this.locationJSONString = locationJSONString; + // this.tag = tag; + } + + public static GiziLocationSelectorDialogFragment newInstance( + SecuredNativeSmartRegisterActivity activity, + DialogOptionModel dialogOptionModel, + String locationJSONString,String formname) { + return new GiziLocationSelectorDialogFragment(activity, dialogOptionModel, locationJSONString,formname); + } + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setStyle(DialogFragment.STYLE_NO_TITLE, android.R.style.Theme_Holo_Light_Dialog); + } + + @Override + public View onCreateView(final LayoutInflater inflater, final ViewGroup container, + Bundle savedInstanceState) { + ViewGroup dialogView = new LinearLayout(getActivity()); + TreeNode root = TreeNode.root(); + + LocationTree locationTree = EntityUtils.fromJson(locationJSONString, LocationTree.class); + + Map> locationMap = + locationTree.getLocationsHierarchy(); + + // creating the tree + locationTreeToTreNode(root, locationMap); + + tView = new AndroidTreeView(getActivity(), root); + tView.setDefaultContainerStyle(org.ei.opensrp.R.style.TreeNodeStyle); + tView.setSelectionModeEnabled(false); + + if(savestate != null){ + tView.restoreState(savestate); + } + + // tView.getSelected().get(1). + dialogView.addView(tView.getView()); + return dialogView; + } + + public TreeNode createNode(String locationlevel, String locationname){ + TreeNode node = new TreeNode(locationname,locationlevel).setViewHolder(new SelectableItemHolder(getActivity(),locationlevel+": ")); + node.setSelectable(false); + addselectlistener(node, ""); + return node; + } + + public void addChildToParentNode(TreeNode parent,TreeNode [] nodes){ + for (int i = 0;i> location) { + + for(Map.Entry> entry : location.entrySet()) { + String locationTag = entry.getValue().getNode().getTags().iterator().next(); + TreeNode tree = createNode( + Strings.isNullOrEmpty(locationTag)?"-":humanize(locationTag), + humanize(entry.getValue().getLabel())); + node.addChild(tree); + addselectlistener(tree, entry.getValue().getId()); + if(entry.getValue().getChildren() != null) { + locationTreeToTreNode(tree, entry.getValue().getChildren()); + } + } + } + +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/fragment/GiziSmartRegisterFragment.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/fragment/GiziSmartRegisterFragment.java new file mode 100644 index 0000000..34180f9 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/fragment/GiziSmartRegisterFragment.java @@ -0,0 +1,642 @@ +package org.ei.opensrp.gizi.fragment; + +import android.app.AlertDialog; +import android.app.Fragment; +import android.app.FragmentTransaction; +import android.content.DialogInterface; +import android.content.Intent; +import android.os.Parcelable; +import android.text.Editable; +import android.text.TextWatcher; +import android.util.Log; +import android.view.View; +import android.widget.EditText; +import android.widget.Toast; + +import com.flurry.android.FlurryAgent; + +import org.ei.opensrp.Context; +import org.ei.opensrp.commonregistry.CommonPersonObjectClient; +import org.ei.opensrp.commonregistry.CommonPersonObjectController; +import org.ei.opensrp.commonregistry.CommonRepository; +import org.ei.opensrp.cursoradapter.CursorCommonObjectFilterOption; +import org.ei.opensrp.cursoradapter.CursorCommonObjectSort; +import org.ei.opensrp.cursoradapter.SecuredNativeSmartRegisterCursorAdapterFragment; +import org.ei.opensrp.cursoradapter.SmartRegisterPaginatedCursorAdapter; +import org.ei.opensrp.cursoradapter.SmartRegisterQueryBuilder; +import org.ei.opensrp.gizi.LoginActivity; +import org.ei.opensrp.gizi.face.camera.SmartShutterActivity; +import org.ei.opensrp.gizi.gizi.GiziDetailActivity; +import org.ei.opensrp.gizi.gizi.GiziGrowthChartActivity; +import org.ei.opensrp.gizi.gizi.GiziServiceModeOption; +import org.ei.opensrp.gizi.gizi.GiziSmartClientsProvider; +import org.ei.opensrp.gizi.gizi.GiziSmartRegisterActivity; +import org.ei.opensrp.gizi.gizi.KICommonObjectFilterOption; +import org.ei.opensrp.provider.SmartRegisterClientsProvider; +import org.ei.opensrp.gizi.R; + +import org.ei.opensrp.sync.ClientProcessor; +import org.ei.opensrp.util.StringUtil; +import org.ei.opensrp.view.activity.SecuredNativeSmartRegisterActivity; +import org.ei.opensrp.view.contract.ECClient; +import org.ei.opensrp.view.contract.SmartRegisterClient; +import org.ei.opensrp.view.contract.SmartRegisterClients; +import org.ei.opensrp.view.controller.VillageController; +import org.ei.opensrp.view.dialog.AllClientsFilter; +import org.ei.opensrp.view.dialog.DialogOption; +import org.ei.opensrp.view.dialog.DialogOptionMapper; +import org.ei.opensrp.view.dialog.DialogOptionModel; +import org.ei.opensrp.view.dialog.EditOption; +import org.ei.opensrp.view.dialog.FilterOption; +import org.ei.opensrp.view.dialog.LocationSelectorDialogFragment; +import org.ei.opensrp.view.dialog.NameSort; +import org.ei.opensrp.view.dialog.ServiceModeOption; +import org.ei.opensrp.view.dialog.SortOption; +import org.opensrp.api.domain.Location; +import org.opensrp.api.util.EntityUtils; +import org.opensrp.api.util.LocationTree; +import org.opensrp.api.util.TreeNode; + +import java.util.ArrayList; +import java.util.Map; + +import util.AsyncTask; +import util.formula.Support; + +import static android.view.View.INVISIBLE; +import static android.view.View.VISIBLE; +import static org.apache.commons.lang3.StringUtils.isEmpty; + +/** + * Created by koros on 10/12/15. + */ +public class GiziSmartRegisterFragment extends SecuredNativeSmartRegisterCursorAdapterFragment { + + private static final String TAG = GiziSmartRegisterFragment.class.getSimpleName(); + + private SmartRegisterClientsProvider clientProvider = null; + private CommonPersonObjectController controller; + private VillageController villageController; + private DialogOptionMapper dialogOptionMapper; + private ClientProcessor clientProcessor; + private final ClientActionHandler clientActionHandler = new ClientActionHandler(); + private String locationDialogTAG = "locationDialogTAG"; + + public static String criteria; + + @Override + protected void onCreation() { + // + } + +// @Override +// protected SmartRegisterPaginatedAdapter adapter() { +// return new SmartRegisterPaginatedAdapter(clientsProvider()); +// } + + @Override + protected SecuredNativeSmartRegisterActivity.DefaultOptionsProvider getDefaultOptionsProvider() { + return new SecuredNativeSmartRegisterActivity.DefaultOptionsProvider() { + + @Override + public ServiceModeOption serviceMode() { + return new GiziServiceModeOption(clientsProvider()); + } + + @Override + public FilterOption villageFilter() { + return new AllClientsFilter(); + } + + @Override + public SortOption sortOption() { + return new NameSort(); + + } + + @Override + public String nameInShortFormForTitle() { + return Context.getInstance().getStringResource(R.string.gizi); + } + }; + } + + @Override + protected SecuredNativeSmartRegisterActivity.NavBarOptionsProvider getNavBarOptionsProvider() { + return new SecuredNativeSmartRegisterActivity.NavBarOptionsProvider() { + + @Override + public DialogOption[] filterOptions() { + FlurryAgent.logEvent("click_filter_option_on_kohort_ibu_dashboard"); + ArrayList dialogOptionslist = new ArrayList(); + + dialogOptionslist.add(new CursorCommonObjectFilterOption(getString(R.string.filter_by_all_label),filterStringForAll())); + // dialogOptionslist.add(new CursorCommonObjectFilterOption(getString(R.string.hh_no_mwra),filterStringForNoElco())); + // dialogOptionslist.add(new CursorCommonObjectFilterOption(getString(R.string.hh_has_mwra),filterStringForOneOrMoreElco())); + + String locationjson = context().anmLocationController().get(); + LocationTree locationTree = EntityUtils.fromJson(locationjson, LocationTree.class); + + Map> locationMap = + locationTree.getLocationsHierarchy(); + addChildToList(dialogOptionslist,locationMap); + DialogOption[] dialogOptions = new DialogOption[dialogOptionslist.size()]; + for (int i = 0;i < dialogOptionslist.size();i++){ + dialogOptions[i] = dialogOptionslist.get(i); + } + + return dialogOptions; + } + + @Override + public DialogOption[] serviceModeOptions() { + return new DialogOption[]{}; + } + + @Override + public DialogOption[] sortingOptions() { + // FlurryFacade.logEvent("click_sorting_option_on_kohort_ibu_dashboard"); + return new DialogOption[]{ +// new HouseholdCensusDueDateSort(), + + + new CursorCommonObjectSort(getResources().getString(R.string.sort_by_name_label),KiSortByNameAZ()), + new CursorCommonObjectSort(getResources().getString(R.string.sort_by_name_label_reverse),KiSortByNameZA()), + new CursorCommonObjectSort(getResources().getString(R.string.sort_by_age),KiSortByAgeASC()), + new CursorCommonObjectSort(getResources().getString(R.string.sort_by_age_reverse),KiSortByAgeDESC()), + }; + } + + @Override + public String searchHint() { + return getResources().getString(R.string.hh_search_hint); + } + }; + } + + + + @Override + protected SmartRegisterClientsProvider clientsProvider() { +// if (clientProvider == null) { +// clientProvider = new HouseHoldSmartClientsProvider( +// getActivity(),clientActionHandler , context().alertService()); +// } + return null; + } + + private DialogOption[] getEditOptions() { + return ((GiziSmartRegisterActivity)getActivity()).getEditOptions(); + } + + @Override + protected void onInitialization() { + // context().formSubmissionRouter().getHandlerMap().put("census_enrollment_form", new CensusEnrollmentHandler()); + } + + @Override + public void setupViews(View view) { + getDefaultOptionsProvider(); + + super.setupViews(view); + view.findViewById(R.id.btn_report_month).setVisibility(INVISIBLE); + view.findViewById(R.id.service_mode_selection).setVisibility(View.GONE); + clientsView.setVisibility(View.VISIBLE); + clientsProgressView.setVisibility(View.INVISIBLE); +// list.setBackgroundColor(Color.RED); + initializeQueries(getCriteria()); + } + + private String filterStringForAll(){ + return ""; + } + + private String sortByAlertmethod() { + return " CASE WHEN alerts.status = 'urgent' THEN '1'" + + + "WHEN alerts.status = 'upcoming' THEN '2'\n" + + "WHEN alerts.status = 'normal' THEN '3'\n" + + "WHEN alerts.status = 'expired' THEN '4'\n" + + "WHEN alerts.status is Null THEN '5'\n" + + "Else alerts.status END ASC"; + } + public void initializeQueries(String s){ + GiziSmartClientsProvider kiscp = new GiziSmartClientsProvider(getActivity(),clientActionHandler,context().alertService()); + clientAdapter = new SmartRegisterPaginatedCursorAdapter(getActivity(), null, kiscp, new CommonRepository("ec_anak",new String []{"tanggalLahirAnak","namaBayi"})); + clientsView.setAdapter(clientAdapter); + + setTablename("ec_anak"); + SmartRegisterQueryBuilder countqueryBUilder = new SmartRegisterQueryBuilder(); + countqueryBUilder.SelectInitiateMainTableCounts("ec_anak"); + + if (s == null || s.equals("!") || s.equals("")) { + Log.e(TAG, "initializeQueries: "+"Not Initialized" ); + mainCondition = "is_closed = 0 "; + } else { + Log.e(TAG, "initializeQueries: " + s); + mainCondition = "is_closed = 0 AND object_id LIKE '%" + s + "%'"; + } + + countSelect = countqueryBUilder.mainCondition("is_closed = 0 "); + // mainCondition = " isClosed !='true' "; + super.CountExecute(); + + SmartRegisterQueryBuilder queryBUilder = new SmartRegisterQueryBuilder(); + queryBUilder.SelectInitiateMainTable("ec_anak", new String[]{"ec_anak.relationalid","ec_anak.is_closed","ec_anak.details","tanggalLahirAnak","namaBayi"}); + mainSelect = queryBUilder.mainCondition("is_closed = 0 "); + // Sortqueries = KiSortByNameAZ(); + + currentlimit = 20; + currentoffset = 0; + + super.filterandSortInInitializeQueries(); + +// setServiceModeViewDrawableRight(null); + updateSearchView(); + refresh(); + + + } + + + @Override + public void startRegistration() { + if(Support.ONSYNC) { + Toast.makeText(getActivity(), "Data still Synchronizing, please wait", Toast.LENGTH_SHORT).show(); + return; + } + + FragmentTransaction ft = getActivity().getFragmentManager().beginTransaction(); + Fragment prev = getActivity().getFragmentManager().findFragmentByTag(locationDialogTAG); + if (prev != null) { + ft.remove(prev); + } + + String uniqueIdJson = LoginActivity.generator.uniqueIdController().getUniqueIdJson(); + if(uniqueIdJson == null || uniqueIdJson.isEmpty()){ + Toast.makeText(getActivity(),"No unique id",Toast.LENGTH_LONG).show(); + return; + } + + ft.addToBackStack(null); + LocationSelectorDialogFragment + .newInstance((GiziSmartRegisterActivity) getActivity(), new EditDialogOptionModel(), context().anmLocationController().get(), "registrasi_gizi") + .show(ft, locationDialogTAG); + } + + private class ClientActionHandler implements View.OnClickListener { + public void onClick(View view) { + switch (view.getId()) { + case R.id.profile_info_layout: + CharSequence selections[] = new CharSequence[] {"Detail View", "Charts"}; + GiziDetailActivity.childclient = (CommonPersonObjectClient) view.getTag(); + GiziGrowthChartActivity.client = (CommonPersonObjectClient)view.getTag(); + final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle(""); + builder.setItems(selections, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // the user clicked on colors[which] + if(which == 0) + { + Intent intent = new Intent(getActivity(),GiziDetailActivity.class); + startActivity(intent); + getActivity().finish(); + } + else if(which == 1){ + Intent intent = new Intent(getActivity(),GiziGrowthChartActivity.class); + startActivity(intent); + getActivity().finish(); + } + } + }); + builder.show(); + // FlurryFacade.logEvent("click_detail_picture_vaksinator"); + + break; + //untuk follow up button + case R.id.btn_edit: + // FlurryFacade.logEvent("click_button_edit_vaksinator"); + showFragmentDialog(new EditDialogOptionModel(), view.getTag()); + break; + } + } + + private void showProfileView(ECClient client) { + navigationController.startEC(client.entityId()); + } + } + + + + private String KiSortByNameAZ() { + return " namaBayi ASC"; + } + private String KiSortByNameZA() { + return " namaBayi DESC"; + } + private String KiSortByAgeASC() { + return " tanggalLahirAnak DESC"; + } + private String KiSortByAgeDESC() { + return " tanggalLahirAnak ASC"; + } + + private String KiSortByAge() { + return " umur DESC"; + } + private String KiSortByNoIbu() { + return " noIbu ASC"; + } + + private String KiSortByEdd() { + return " htp IS NULL, htp"; + } + + + private class EditDialogOptionModel implements DialogOptionModel { + @Override + public DialogOption[] getDialogOptions() { + return getEditOptions(); + } + @Override + public void onDialogOptionSelection(DialogOption option, Object tag) { + + + /*if(option.name().equalsIgnoreCase(getString(R.string.str_register_anc_form)) ) { + CommonPersonObjectClient pc = KIDetailActivity.kiclient; + if(pc.getDetails().get("ibu.type")!= null) { + if (pc.getDetails().get("ibu.type").equals("anc") || pc.getDetails().get("ibu.type").equals("pnc")) { + Toast.makeText(getActivity().getApplicationContext(), getString(R.string.mother_already_registered), Toast.LENGTH_SHORT).show(); + return; + } + } + }*/ + onEditSelection((EditOption) option, (SmartRegisterClient) tag); + } + } + + @Override + protected void onResumption() { +// super.onResumption(); + getDefaultOptionsProvider(); + if(isPausedOrRefreshList()) { + initializeQueries("!"); + } + // updateSearchView(); +// + try{ + LoginActivity.setLanguage(); + }catch (Exception e){ + + } + + } +// @Override +// public void setupSearchView(View view) { +// searchView = (EditText) view.findViewById(org.ei.opensrp.R.id.edt_search); +// searchView.setHint(getNavBarOptionsProvider().searchHint()); +// searchView.addTextChangedListener(new TextWatcher() { +// @Override +// public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { +// } +// +// @Override +// public void onTextChanged(final CharSequence cs, int start, int before, int count) { +// +// (new AsyncTask() { +// SmartRegisterClients filteredClients; +// +// @Override +// protected Object doInBackground(Object[] params) { +//// currentSearchFilter = +//// setCurrentSearchFilter(new HHSearchOption(cs.toString())); +//// filteredClients = getClientsAdapter().getListItemProvider() +//// .updateClients(getCurrentVillageFilter(), getCurrentServiceModeOption(), +//// getCurrentSearchFilter(), getCurrentSortOption()); +//// +// filters = cs.toString(); +// joinTable = ""; +// mainCondition = " is_closed = 0 AND namaBayi !='' "; +// return null; +// } +// +// @Override +// protected void onPostExecute(Object o) { +//// clientsAdapter +//// .refreshList(currentVillageFilter, currentServiceModeOption, +//// currentSearchFilter, currentSortOption); +//// getClientsAdapter().refreshClients(filteredClients); +//// getClientsAdapter().notifyDataSetChanged(); +// getSearchCancelView().setVisibility(isEmpty(cs) ? INVISIBLE : VISIBLE); +// CountExecute(); +// filterandSortExecute(); +// super.onPostExecute(o); +// } +// }).execute(); +// } +// +// @Override +// public void afterTextChanged(Editable editable) { +// } +// }); +// searchCancelView = view.findViewById(org.ei.opensrp.R.id.btn_search_cancel); +// searchCancelView.setOnClickListener(searchCancelHandler); +// } +// + public void updateSearchView(){ + getSearchView().addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { + } + + @Override + public void onTextChanged(final CharSequence cs, int start, int before, int count) { + (new AsyncTask() { + SmartRegisterClients filteredClients; + + @Override + protected Object doInBackground(Object[] params) { +// currentSearchFilter = +// setCurrentSearchFilter(new HHSearchOption(cs.toString())); +// filteredClients = getClientsAdapter().getListItemProvider() +// .updateClients(getCurrentVillageFilter(), getCurrentServiceModeOption(), +// getCurrentSearchFilter(), getCurrentSortOption()); +// + + filters = cs.toString(); + joinTable = ""; + mainCondition = " is_closed = 0 AND namaBayi !='' "; + return null; + } + + @Override + protected void onPostExecute(Object o) { +// clientsAdapter +// .refreshList(currentVillageFilter, currentServiceModeOption, +// currentSearchFilter, currentSortOption); +// getClientsAdapter().refreshClients(filteredClients); +// getClientsAdapter().notifyDataSetChanged(); + getSearchCancelView().setVisibility(isEmpty(cs) ? INVISIBLE : VISIBLE); + filterandSortExecute(); + super.onPostExecute(o); + } + }).execute(); +// currentSearchFilter = new HHSearchOption(cs.toString()); +// clientsAdapter +// .refreshList(currentVillageFilter, currentServiceModeOption, +// currentSearchFilter, currentSortOption); +// +// searchCancelView.setVisibility(isEmpty(cs) ? INVISIBLE : VISIBLE); + + + } + + @Override + public void afterTextChanged(Editable editable) { + + } + }); + } + public void addChildToList(ArrayList dialogOptionslist,Map> locationMap){ + for(Map.Entry> entry : locationMap.entrySet()) { + + if(entry.getValue().getChildren() != null) { + addChildToList(dialogOptionslist,entry.getValue().getChildren()); + + }else{ + StringUtil.humanize(entry.getValue().getLabel()); + String name = StringUtil.humanize(entry.getValue().getLabel()); + dialogOptionslist.add(new KICommonObjectFilterOption(name,"desa", name)); + + } + } + } + + + + // WD + public void setCriteria(String criteria) { + this.criteria = criteria; + } + + public static String getCriteria() { + return criteria; + } + + // WD + @Override + public void setupSearchView(final View view) { + searchView = (EditText) view.findViewById(org.ei.opensrp.R.id.edt_search); + searchView.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + CharSequence selections[] = new CharSequence[]{"Name", "Photo"}; + final AlertDialog.Builder builder = new AlertDialog.Builder(getActivity()); + builder.setTitle("Please Choose one, Search by"); + builder.setItems(selections, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int opt) { + if (opt == 0) searchTextChangeListener(""); + else getFacialRecord(view); + } + }); + builder.show(); + } + }); + + searchCancelView = view.findViewById(org.ei.opensrp.R.id.btn_search_cancel); + searchCancelView.setOnClickListener(searchCancelHandler); + } + + public void getFacialRecord(View view) { + FlurryAgent.logEvent(TAG+" search_by_face", true); + Log.e(TAG, "getFacialRecord: start "); + SmartShutterActivity.kidetail = (CommonPersonObjectClient) view.getTag(); + FlurryAgent.logEvent(TAG + " search_by_face", true); + + Intent intent = new Intent(getActivity(), SmartShutterActivity.class); + intent.putExtra("org.sid.sidface.ImageConfirmation.origin", GiziSmartRegisterFragment.class.getSimpleName()); + intent.putExtra("org.sid.sidface.ImageConfirmation.identify", true); + intent.putExtra("org.sid.sidface.ImageConfirmation.kidetail", (Parcelable) SmartShutterActivity.kidetail); + startActivityForResult(intent, 2); + + + } + + public void searchTextChangeListener(String s) { + Log.e(TAG, "searchTextChangeListener: " + s); + if (s != null) { + filters = s; + } else { + searchView.addTextChangedListener(new TextWatcher() { + @Override + public void beforeTextChanged(CharSequence charSequence, int i, int i2, int i3) { + } + + @Override + public void onTextChanged(final CharSequence cs, int start, int before, int count) { + + (new AsyncTask() { +// SmartRegisterClients filteredClients; + + @Override + protected Object doInBackground(Object[] params) { +// currentSearchFilter = +// setCurrentSearchFilter(new HHSearchOption(cs.toString())); +// filteredClients = getClientsAdapter().getListItemProvider() +// .updateClients(getCurrentVillageFilter(), getCurrentServiceModeOption(), +// getCurrentSearchFilter(), getCurrentSortOption()); +// + + filters = cs.toString(); + joinTable = ""; + mainCondition = "nama_bayi !=''"; + Log.e(TAG, "doInBackground: " + filters); + return null; + } +// +// @Override +// protected void onPostExecute(Object o) { +//// clientsAdapter +//// .refreshList(currentVillageFilter, currentServiceModeOption, +//// currentSearchFilter, currentSortOption); +//// getClientsAdapter().refreshClients(filteredClients); +//// getClientsAdapter().notifyDataSetChanged(); +// getSearchCancelView().setVisibility(isEmpty(cs) ? INVISIBLE : VISIBLE); +// CountExecute(); +// filterandSortExecute(); +// super.onPostExecute(o); +// } + }).execute(); + } + + @Override + public void afterTextChanged(Editable editable) { + } + }); + } + } + + @Override + public void onActivityResult(int requestCode, int resultCode, Intent data){ + super.onActivityResult(requestCode, resultCode, data); + + if (requestCode == 2 ) { + + if (resultCode != 0) { + Intent myIntent = new Intent(getActivity(), GiziSmartRegisterActivity.class); + if (data != null) { + myIntent.putExtra("org.ei.opensrp.indonesia.face.face_mode", true); + myIntent.putExtra("org.ei.opensrp.indonesia.face.base_id", data.getStringExtra("org.ei.opensrp.indonesia.face.base_id")); + } + getActivity().startActivity(myIntent); + } else { + Log.e(TAG, "onActivityResult: "+ resultCode ); + } + } + + } + + +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/CommonObjectFilterOption.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/CommonObjectFilterOption.java new file mode 100644 index 0000000..c940698 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/CommonObjectFilterOption.java @@ -0,0 +1,42 @@ +package org.ei.opensrp.gizi.gizi; + +import org.ei.opensrp.commonregistry.CommonPersonObjectClient; +import org.ei.opensrp.cursoradapter.CursorFilterOption; +import org.ei.opensrp.view.contract.SmartRegisterClient; +import org.ei.opensrp.view.dialog.FilterOption; + +import static org.ei.opensrp.util.StringUtil.humanize; + +public class CommonObjectFilterOption implements FilterOption { + private final String criteria; + public final String fieldname; + private final String filterOptionName; + ByColumnAndByDetails byColumnAndByDetails; + + public enum ByColumnAndByDetails{ + byColumn,byDetails; + } + + public CommonObjectFilterOption(String criteria, String fieldname, ByColumnAndByDetails byColumnAndByDetails, String filteroptionname) { + this.criteria = criteria; + this.fieldname = fieldname; + this.byColumnAndByDetails= byColumnAndByDetails; + this.filterOptionName = filteroptionname; + } + + @Override + public String name() { + return filterOptionName; + } + + @Override + public boolean filter(SmartRegisterClient client) { + switch (byColumnAndByDetails){ + case byColumn: + return ((CommonPersonObjectClient)client).getColumnmaps().get(fieldname).contains(criteria); + case byDetails: + return (humanize((((CommonPersonObjectClient)client).getDetails().get(fieldname)!=null?((CommonPersonObjectClient)client).getDetails().get(fieldname):"").replace("+","_"))).toLowerCase().contains(criteria.toLowerCase()); + } + return false; + } +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/ErrorReportingFacade.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/ErrorReportingFacade.java new file mode 100644 index 0000000..ddd3cdb --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/ErrorReportingFacade.java @@ -0,0 +1,20 @@ +package org.ei.opensrp.gizi.gizi; + +import android.content.Context; +import com.crashlytics.android.Crashlytics; +import io.fabric.sdk.android.Fabric; + +/** + * Created by Dimas on 9/22/2015. + */ +public class ErrorReportingFacade { + + public static void initErrorHandler(Context context) { + Fabric.with(context, new Crashlytics()); + } + public static void setUsername(String fullName, String userName) { + Crashlytics.setUserIdentifier(userName); + Crashlytics.setUserName(userName); + } + +} \ No newline at end of file diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/FlurryFacade.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/FlurryFacade.java new file mode 100644 index 0000000..c3969c1 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/FlurryFacade.java @@ -0,0 +1,48 @@ +package org.ei.opensrp.gizi.gizi; + + +import android.content.Context; +import android.util.Log; + +import com.flurry.android.FlurryAgent; + +import java.util.Map; + +/** + * Created by Null on 2016-09-19. + */ + +public class FlurryFacade { + +// private static final String flurry_key = "3VPFC3PXZQ43PND539DR"; + + //flurry key gizi 2.1 + // private static final String flurry_key = "HTV5HBKKNCNCCBWT338M"; + + //flurry key Gizi EC prototype 1 + private static final String flurry_key = "SQD6SRG84PZ94DM3BM38"; + + public static void logEvent(String event) { + FlurryAgent.logEvent(event); + } + + public static void logEvent(String event, Map map) { + FlurryAgent.logEvent(event, map); + } + + public static void setUserId(String userId) { + FlurryAgent.setUserId(userId); + } + + public static void init(Context context) { +// Configure Flurry + FlurryAgent.setLogEnabled(true); + FlurryAgent.setLogEvents(true); + FlurryAgent.setLogLevel(Log.VERBOSE); + +// init Flurry + FlurryAgent.init(context, flurry_key); + } + + + } \ No newline at end of file diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziDateSort.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziDateSort.java new file mode 100644 index 0000000..31bd7e9 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziDateSort.java @@ -0,0 +1,72 @@ +package org.ei.opensrp.gizi.gizi; + +import org.ei.opensrp.commonregistry.CommonPersonObjectClient; +import org.ei.opensrp.view.contract.SmartRegisterClient; +import org.ei.opensrp.view.contract.SmartRegisterClients; +import org.ei.opensrp.view.dialog.SortOption; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; + +/** + * Created by Iq on 30/03/16. + */ +public class GiziDateSort implements SortOption { + String field; + ByColumnAndByDetails byColumnAndByDetails; + + public enum ByColumnAndByDetails{ + byColumn,byDetails; + } + + public GiziDateSort() { + + } + + @Override + public String name() { + return "Due Status"; + } + + @Override + public SmartRegisterClients sort(SmartRegisterClients allClients) { + Collections.sort(allClients, commoncomparator); + return allClients; + } + + Comparator commoncomparator = new Comparator() { + @Override + public int compare(SmartRegisterClient oneClient, SmartRegisterClient anotherClient2) { + CommonPersonObjectClient commonPersonObjectClient = (CommonPersonObjectClient)oneClient; + CommonPersonObjectClient commonPersonObjectClient2 = (CommonPersonObjectClient)anotherClient2; + switch (byColumnAndByDetails){ + case byColumn: + try { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + Date date1 = dateFormat.parse(commonPersonObjectClient.getColumnmaps().get(field)); + Date date2 = dateFormat.parse(commonPersonObjectClient2.getColumnmaps().get(field)); + + return date1.compareTo(date2); + }catch (Exception e){ + break; + } + + + case byDetails: + try { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + Date date1 = dateFormat.parse(commonPersonObjectClient.getDetails().get(field)); + Date date2 = dateFormat.parse(commonPersonObjectClient2.getDetails().get(field)); + return date1.compareTo(date2); + }catch (Exception e){ + break; + } + + } + return 0; + } + }; +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziDetailActivity.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziDetailActivity.java new file mode 100644 index 0000000..7fc22b2 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziDetailActivity.java @@ -0,0 +1,395 @@ +package org.ei.opensrp.gizi.gizi; + +import android.app.Activity; +import android.content.Intent; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.net.Uri; +import android.os.Bundle; +import android.os.Environment; +import android.view.View; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.TextView; + +import com.flurry.android.FlurryAgent; +import com.jjoe64.graphview.DefaultLabelFormatter; +import com.jjoe64.graphview.GraphView; + +import org.ei.opensrp.Context; +import org.ei.opensrp.commonregistry.AllCommonsRepository; +import org.ei.opensrp.commonregistry.CommonPersonObject; +import org.ei.opensrp.commonregistry.CommonPersonObjectClient; +import org.ei.opensrp.gizi.R; +import org.ei.opensrp.gizi.face.camera.SmartShutterActivity; +import org.ei.opensrp.gizi.face.camera.util.Tools; +import org.ei.opensrp.repository.DetailsRepository; +import org.ei.opensrp.util.Log; +import org.ei.opensrp.util.OpenSRPImageLoader; +import org.ei.opensrp.view.activity.DrishtiApplication; + +import java.io.File; +import java.io.IOException; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.util.HashMap; +import java.util.Map; + +import util.ImageCache; +import util.ImageFetcher; +import util.KMS.KmsCalc; +import util.KMS.KmsPerson; +import util.formula.Support; +import util.growthChart.GrowthChartGenerator; + +/** + * Created by Iq on 26/04/16. + */ +public class GiziDetailActivity extends Activity { + public static CommonPersonObjectClient kiclient; + + SimpleDateFormat timer = new SimpleDateFormat("hh:mm:ss"); + //image retrieving + private static final String TAG = GiziDetailActivity.class.getSimpleName(); + private static final String IMAGE_CACHE_DIR = "thumbs"; + // private static KmsCalc kmsCalc; + private static int mImageThumbSize; + private static int mImageThumbSpacing; + private static String showbgm; + private static ImageFetcher mImageFetcher; + + //image retrieving + + public static CommonPersonObjectClient childclient; + + + private static HashMap hash; + private boolean updateMode = false; + private String mode; + + private String photo_path; + private File tb_photo; + private String fileName; + + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + Context context = Context.getInstance(); + setContentView(R.layout.gizi_detail_activity); + String DetailStart = timer.format(new Date()); + Map Detail = new HashMap(); + Detail.put("start", DetailStart); + FlurryAgent.logEvent("gizi_detail_view",Detail, true ); + + final ImageView childview = (ImageView)findViewById(R.id.detail_profilepic); + //header + TextView header_name = (TextView) findViewById(R.id.header_name); + //sub header + TextView subheader = (TextView) findViewById(R.id.txt_title_label); + //profile + TextView uniqueId = (TextView) findViewById(R.id.txt_profile_unique_id); + TextView nama = (TextView) findViewById(R.id.txt_profile_child_name); + TextView father_name = (TextView) findViewById(R.id.txt_profile_father_name); + TextView mother_name = (TextView) findViewById(R.id.txt_profile_mother_name); + TextView posyandu = (TextView) findViewById(R.id.txt_profile_posyandu); + TextView village_name = (TextView) findViewById(R.id.txt_profile_village_name); + TextView birth_date = (TextView) findViewById(R.id.txt_profile_birth_date); + TextView gender = (TextView) findViewById(R.id.txt_profile_child_gender); + TextView birthWeight = (TextView) findViewById(R.id.txt_profile_birth_weight); + TextView weight = (TextView) findViewById(R.id.txt_profile_last_weight); + TextView height = (TextView) findViewById(R.id.txt_profile_last_height); + //child growth + TextView nutrition_status = (TextView) findViewById(R.id.txt_profile_nutrition_status); + TextView bgm = (TextView) findViewById(R.id.txt_profile_bgm); + TextView dua_t = (TextView) findViewById(R.id.txt_profile_2t); + TextView under_yellow_line = (TextView) findViewById(R.id.txt_profile_under_yellow_line); + TextView breast_feeding = (TextView) findViewById(R.id.txt_profile_breastfeeding); + TextView mpasi = (TextView) findViewById(R.id.txt_profile_mp_asi); + TextView vitA = (TextView) findViewById(R.id.txt_vitA); + TextView obatCacing = (TextView) findViewById(R.id.txt_anthelmintic); + TextView lastVitA = (TextView) findViewById(R.id.txt_profile_last_vitA); + TextView lastAnthelmintic = (TextView) findViewById(R.id.txt_profile_last_anthelmintic); + + ImageButton back = (ImageButton) findViewById(org.ei.opensrp.R.id.btn_back_to_home); + + back.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + startActivity(new Intent(GiziDetailActivity.this, GiziSmartRegisterActivity.class)); + overridePendingTransition(0, 0); + + String DetailEnd = timer.format(new Date()); + Map Detail = new HashMap(); + Detail.put("end", DetailEnd); + FlurryAgent.logEvent("gizi_detail_view", Detail, true); + } + }); + DetailsRepository detailsRepository = org.ei.opensrp.Context.getInstance().detailsRepository(); + detailsRepository.updateDetails(childclient); + + System.out.println("columnmaps: " + childclient.getColumnmaps().toString()); + System.out.println("details: "+childclient.getDetails().toString()); + + childview.setTag(R.id.entity_id, childclient.getCaseId());//required when saving file to disk + + if (childclient.getDetails().get("gender") != null) { + System.out.println(childclient.getDetails().toString()); + util.formula.Support.setImagetoHolderFromUri( this , + DrishtiApplication.getAppDir() + File.separator + childclient.getDetails().get("base_entity_id") + ".JPEG", + childview, childclient.getDetails().get("gender").equals("female") ? R.drawable.child_girl_infant : R.drawable.child_boy_infant); + } else { + android.util.Log.e(TAG, "getView: Gender is NOT SET"); + } + + header_name.setText(R.string.child_profile); + subheader.setText(R.string.child_profile); + uniqueId.setText(String.format("%s %s",getString(R.string.unique_id),Support.getDetails(childclient,"UniqueId"))); + nama.setText(String.format("%s %s",getString(R.string.child_name) , Support.getDetails(childclient,"namaBayi"))); + + AllCommonsRepository childRepository = org.ei.opensrp.Context.getInstance().allCommonsRepositoryobjects("ec_anak"); + CommonPersonObject childobject = childRepository.findByCaseID(childclient.entityId()); + + AllCommonsRepository kirep = org.ei.opensrp.Context.getInstance().allCommonsRepositoryobjects("ec_kartu_ibu"); + final CommonPersonObject kiparent = kirep.findByCaseID(childobject.getColumnmaps().get("relational_id")); + + if(kiparent != null) { + detailsRepository.updateDetails(kiparent); + String namaayah = Support.getDetails(kiparent,"namaSuami"); + String namaibu = Support.getColumnmaps(kiparent, "namalengkap"); + + father_name.setText(getString(R.string.father_name)+" " + namaayah); + mother_name.setText(getString(R.string.mother_name) +" " +namaibu); + village_name.setText(String.format("%s %s",getString(R.string.village),(Support.getDetails(kiparent,"cityVillage")))); + posyandu.setText(String.format("%s %s",getString(R.string.posyandu),(Support.getDetails(kiparent,"address1")))); + + } + + String dateOfBirth = Support.getDetails(childclient, "tanggalLahirAnak").substring(0,10); + birth_date.setText(String.format("%s %s",getString(R.string.birth_date) ,(dateOfBirth.contains("T") ? dateOfBirth.substring(0, 10) : dateOfBirth))); + gender.setText(String.format("%s %s",getString(R.string.gender), (Support.getDetails(childclient, "gender").toLowerCase().contains("em")? getString(R.string.child_female) : getString(R.string.child_male)))); + birthWeight.setText(String.format("%s %s",getString(R.string.birth_weight), (Support.getDetails(childclient, "beratLahir") + " gr"))); + weight.setText(String.format("%s %s",getString(R.string.weight),(Support.getDetails(childclient, "beratBadan")) + " Kg")); + height.setText(String.format("%s %s",getString(R.string.height),(Support.getDetails(childclient, "tinggiBadan") + " Cm"))); + vitA.setText(String.format("%s : %s",getString(R.string.vitamin_a),(inTheSameRegion(Support.getDetails(childclient, "lastVitA")) ? getString(R.string.yes) : getString(R.string.no)))); + mpasi.setText(String.format("%s %s",getString(R.string.mpasi),(yesNo(Support.getDetails(childclient, "mp_asi"))))); + obatCacing.setText(String.format("%s %s",getString(R.string.obatcacing),(inTheSameRegionAnth(Support.getDetails(childclient, "lastAnthelmintic")) ? getString(R.string.yes) : getString(R.string.no)))); + lastVitA.setText(String.format("%s %s",getString(R.string.lastVitA),(Support.getDetails(childclient, "lastVitA")))); + lastAnthelmintic.setText(String.format("%s %s",getString(R.string.lastAnthelmintic),(Support.getDetails(childclient, "lastAnthelmintic")))); + + String[]history = Support.split(Support.fixHistory(Support.getDetails(childclient,"history_berat"))); + String[]historyUmur = history[0].split(","); + String[]historyBerat = history[1].split(","); + + KmsPerson anak = new KmsPerson(childclient); + KmsCalc kalkulator = new KmsCalc(); + +// System.out.println("age "+anak.getAge()); +// System.out.println("dob "+anak.getDateOfBirth()); +// System.out.println("weight "+anak.getWeight()); +// System.out.println("prev weight "+anak.getPreviousWeight()); +// System.out.println("2nd last weight "+anak.getSecondLastWeight()); +// System.out.println("last visit "+anak.getLastVisitDate()); +// System.out.println("2nd last visit "+anak.getSecondLastVisitDate()); +// System.out.println("3rd last visit "+anak.getThirdLastVisitDate()); + + dua_t.setText(String.format("%s %s", getString(R.string.dua_t), (yesNo(kalkulator.cek2T(anak))))); + bgm.setText(String.format("%s %s",getString(R.string.bgm), (yesNo(kalkulator.cekBGM(anak))))); + under_yellow_line.setText(String.format("%s %s",getString(R.string.under_yellow_line),(yesNo(kalkulator.cekBawahKuning(anak))))); + breast_feeding.setText(String.format("%s %s",getString(R.string.asi),(yesNo(Support.getDetails(childclient, "asi"))))); + nutrition_status.setText(String.format("%s %s",getString(R.string.nutrition_status),weightStatus(kalkulator.cekWeightStatus(anak)))); + + //set value + String[]data = split(Support.fixHistory(Support.getDetails(childclient, "history_berat"))); + String[] history_umur = data[0].split(","); + String umurs=arrayToString(history_umur,","); + + generateGrowthChart(umurs,data[1]); + hash = Tools.retrieveHash(context.applicationContext()); + childview.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + + bindobject = "anak"; + entityid = childclient.entityId(); + + if (hash.containsValue(entityid)) { + android.util.Log.e(TAG, "onClick: " + entityid + " updated"); + mode = "updated"; + updateMode = true; + + } + + Intent takePictureIntent = new Intent(GiziDetailActivity.this, SmartShutterActivity.class); + takePictureIntent.putExtra("IdentifyPerson", false); + takePictureIntent.putExtra("org.sid.sidface.ImageConfirmation.id", entityid); + takePictureIntent.putExtra("org.sid.sidface.ImageConfirmation.origin", TAG); // send Class Name + startActivityForResult(takePictureIntent, 2); + + + } + }); + } + + // english: fEMale, bahasa: perEMpuan, both have EM; since en: male, bhs: laki, both no EM + private String gender(String value){ + if (value.toLowerCase().contains("em")) + return getString(R.string.child_female); + else + return getString(R.string.child_male); + } + + private void generateGrowthChart(String xAxis, String yAxis){ + Log.logInfo("Berat :" +yAxis); + Log.logInfo("umurs :" +xAxis); + GraphView graph = (GraphView) findViewById(R.id.graph); + new GrowthChartGenerator(graph,childclient.getDetails().get("gender"), + Support.getDetails(childclient, "tanggalLahirAnak").substring(0, Support.getDetails(childclient, "tanggalLahirAnak").indexOf("T")) + ,xAxis,yAxis); + + graph.getGridLabelRenderer().setLabelFormatter(new DefaultLabelFormatter() { + @Override + public String formatLabel(double value, boolean isValueX) { + if (isValueX) { + // show normal x values + return super.formatLabel(value, isValueX )+ " Month"; + } else { + // show currency for y values + return super.formatLabel(value, isValueX) + " Kg"; + } + } + }); + } + + private String yesNo(String value){ + if(value==null) + return "-"; + else if(value.toLowerCase().contains("yes") || value.toLowerCase().contains("ya")) + return getString(R.string.yes); + else + return getString(R.string.no); + } + + private String weightStatus(String value){ + if(value.toLowerCase().contains("gain") || value.toLowerCase().contains("idak")) + return getString(R.string.weight_not_increase); + else if(value.toLowerCase().contains("ncrea")) + return getString(R.string.weight_increase); + else if(value.toLowerCase().contains("atten")) + return getString(R.string.weight_not_attend); + else + return getString(R.string.weight_new); + } + + String mCurrentPhotoPath; + + private File createImageFile() throws IOException { + // Create an image file name + String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); + String imageFileName = "JPEG_" + timeStamp + "_"; + File storageDir = Environment.getExternalStoragePublicDirectory( + Environment.DIRECTORY_PICTURES); + File image = File.createTempFile( + imageFileName, /* prefix */ + ".jpg", /* suffix */ + storageDir /* directory */ + ); + + // Save a file: path for use with ACTION_VIEW intents + mCurrentPhotoPath = "file:" + image.getAbsolutePath(); + return image; + } + static final int REQUEST_TAKE_PHOTO = 1; + static ImageView mImageView; + static File currentfile; + static String bindobject; + static String entityid; + + public static void setImagetoHolder(Activity activity, String file, ImageView view, int placeholder){ + mImageThumbSize = 300; + mImageThumbSpacing = Context.getInstance().applicationContext().getResources().getDimensionPixelSize(R.dimen.image_thumbnail_spacing); + + + ImageCache.ImageCacheParams cacheParams = + new ImageCache.ImageCacheParams(activity, IMAGE_CACHE_DIR); + cacheParams.setMemCacheSizePercent(0.50f); // Set memory cache to 25% of app memory + mImageFetcher = new ImageFetcher(activity, mImageThumbSize); + mImageFetcher.setLoadingImage(placeholder); + mImageFetcher.addImageCache(activity.getFragmentManager(), cacheParams); + mImageFetcher.loadImage("file:///"+file,view); + } + + public String arrayToString(String[]data,String separator){ + String umurs=""; + for(int i=0;i=8; + boolean date2 = visitDate < 2 || visitDate >=8; + + int indicator = currentDate == 1 ? 2:1; + + return (!((!date1 && date2) || (date1 && !date2)) && ((currentYear-visitYear) Detail = new HashMap(); + Detail.put("end", DetailEnd); + FlurryAgent.logEvent("gizi_detail_view", Detail, true); + } + }); + + navBarDetails.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + GiziDetailActivity.childclient = client; + startActivity(new Intent(GiziGrowthChartActivity.this, GiziDetailActivity.class)); + overridePendingTransition(0, 0); + } + }); + + navBarZScore.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + GiziZScoreChartActivity.client = client; + startActivity(new Intent(GiziGrowthChartActivity.this, GiziZScoreChartActivity.class)); + overridePendingTransition(0, 0); + } + }); + + layoutName.setText(context.getStringResource(R.string.chart_title)); + lfaChartLabel.setText(context.getStringResource(R.string.lfa_string)); + hfaChartLabel.setText(context.getStringResource(R.string.hfa_string)); + + String []series=initiateSeries(); + + System.out.println("gender : "+client.getDetails().get("gender")); + System.out.println("DOB : "+client.getDetails().get("tanggalLahir")); + + new GrowthChartGenerator(lfaGraph, GraphConstant.LFA_CHART,client.getDetails().get("gender"),client.getDetails().get("tanggalLahir"),series[0],series[1]); + lfaGraph.getGridLabelRenderer().setLabelFormatter(new DefaultLabelFormatter() { + @Override + public String formatLabel(double value, boolean isValueX) { + if (isValueX) + return super.formatLabel(value, isValueX) + " " + context.getStringResource(R.string.x_axis_label); + else + return super.formatLabel(value, isValueX) + " " + context.getStringResource(R.string.length_unit); + } + }); + + new GrowthChartGenerator(hfaGraph,GraphConstant.HFA_CHART,client.getDetails().get("gender"),client.getDetails().get("tanggalLahir"),series[2],series[3]); + hfaGraph.getGridLabelRenderer().setLabelFormatter(new DefaultLabelFormatter() { + @Override + public String formatLabel(double value, boolean isValueX) { + if (isValueX) + return super.formatLabel(value, isValueX) + " " + context.getStringResource(R.string.x_axis_label); + else + return super.formatLabel(value, isValueX) + " " + context.getStringResource(R.string.length_unit); + } + }); + } + + private String []initiateSeries(){ + String series[]=new String[4]; + String result = createSeries(); + String []data = result.split("#"); + if(!result.contains(";")){ + if(Integer.parseInt(data[0].split(",")[0]) < 24){ + series[0] = data[0]; + series[1] = data[1]; + series[2] = series[3] = ""; + } + else{ + series[2] = data[0]; + series[3] = data[1]; + series[0] = series[1] = ""; + } + }else{ + series[0] = data[0].split(";")[0]; + series[1] = data[1].split(";")[0]; + series[2] = data[0].split(";")[1]; + series[3] = data[1].split(";")[1]; + } + return series; + } + + private String createSeries(){ + if(client.getDetails().get("history_tinggi")==null) { + return "0#0"; + } + else if(client.getDetails().get("history_tinggi").length()<3) { + return "0#0"; + } + String ageSeries=""; + String lengthSeries=""; + String dateOfBirth = client.getDetails().get("tanggalLahirAnak").substring(0,10); + String data = Support.fixHistory(client.getDetails().get("history_tinggi")); + String []array = data.substring(4,data.length()).split(","); + String [][]array2 = new String[array.length][]; + int []age = new int[array.length]; + for(int i=0;i0){ + if(age[i]>=24 && age[i-1]<24){ + ageSeries=ageSeries + ";" +Integer.toString(age[i]); + lengthSeries = lengthSeries + ";" + array2[i][1]; + } + } + } + if (ageSeries.length()+lengthSeries.length()<2) + return "0#0"; + return ageSeries.substring(1,ageSeries.length())+"#"+lengthSeries.substring(1,lengthSeries.length()); + } + + private int monthAge(String dateFrom, String dateTo){ + if(dateFrom==null || dateTo==null) + return 0; + else if(dateFrom.length()<6 || dateTo.equals("") || dateTo.equals(" ")) + return 0; + else if(dateTo.length()>0 && dateTo.length()<3) + return Integer.parseInt(dateTo); + return ((Integer.parseInt(dateTo.substring(0,4))-Integer.parseInt(dateFrom.substring(0,4)))*12) + + (Integer.parseInt(dateTo.substring(5,7))-Integer.parseInt(dateFrom.substring(5,7))); + } +} \ No newline at end of file diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziSearchOption.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziSearchOption.java new file mode 100644 index 0000000..99704cc --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziSearchOption.java @@ -0,0 +1,57 @@ +package org.ei.opensrp.gizi.gizi; + +import org.ei.opensrp.Context; +import org.ei.opensrp.commonregistry.CommonPersonObjectClient; +import org.ei.opensrp.gizi.R; +import org.ei.opensrp.view.contract.SmartRegisterClient; +import org.ei.opensrp.view.dialog.FilterOption; + +public class GiziSearchOption implements FilterOption { + private final String criteria; + + public GiziSearchOption(String criteria) { + this.criteria = criteria; + } + + @Override + public String name() { + return Context.getInstance().applicationContext().getResources().getString(R.string.hh_search_hint); + } + + @Override + public boolean filter(SmartRegisterClient client) { + boolean result = false; + CommonPersonObjectClient currentclient = (CommonPersonObjectClient) client; +// AllCommonsRepository allElcoRepository = new AllCommonsRepository("elco"); + if(!result) { + if(currentclient.getDetails().get("namaBayi") != null) { + if (currentclient.getDetails().get("namaBayi").toLowerCase().contains(criteria.toLowerCase())) { + result = true; + } + } + } + if(!result) { + if(currentclient.getDetails().get("namaIbu") != null) { + if (currentclient.getDetails().get("namaIbu").toLowerCase().contains(criteria.toLowerCase())) { + result = true; + } + } + } + if(!result) { + if(currentclient.getDetails().get("namaOrtu") != null) { + if (currentclient.getDetails().get("namaOrtu").toLowerCase().contains(criteria.toLowerCase())) { + result = true; + } + } + } + if(!result) { + if(currentclient.getDetails().get("dusun") != null) { + if (currentclient.getDetails().get("dusun").toLowerCase().contains(criteria.toLowerCase())) { + result = true; + } + } + } + + return result; + } +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziServiceModeOption.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziServiceModeOption.java new file mode 100755 index 0000000..c6ab5c2 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziServiceModeOption.java @@ -0,0 +1,81 @@ +package org.ei.opensrp.gizi.gizi; + +import android.view.View; + +import org.ei.opensrp.Context; +import org.ei.opensrp.provider.SmartRegisterClientsProvider; +import org.ei.opensrp.gizi.R; +import org.ei.opensrp.view.contract.ANCSmartRegisterClient; +import org.ei.opensrp.view.contract.ChildSmartRegisterClient; +import org.ei.opensrp.view.contract.FPSmartRegisterClient; +import org.ei.opensrp.view.contract.pnc.PNCSmartRegisterClient; +import org.ei.opensrp.view.dialog.ServiceModeOption; +import org.ei.opensrp.view.viewHolder.NativeANCSmartRegisterViewHolder; +import org.ei.opensrp.view.viewHolder.NativeChildSmartRegisterViewHolder; +import org.ei.opensrp.view.viewHolder.NativeFPSmartRegisterViewHolder; +import org.ei.opensrp.view.viewHolder.NativePNCSmartRegisterViewHolder; + +import static org.ei.opensrp.view.activity.SecuredNativeSmartRegisterActivity.ClientsHeaderProvider; + +public class GiziServiceModeOption extends ServiceModeOption { + + public GiziServiceModeOption(SmartRegisterClientsProvider provider) { + super(provider); + } + + @Override + public String name() { + return Context.getInstance().getStringResource(R.string.test_register); + } + + @Override + public ClientsHeaderProvider getHeaderProvider() { + return new ClientsHeaderProvider() { + @Override + public int count() { + return 5; + } + + @Override + public int weightSum() { + return 100; + } + + @Override + public int[] weights() { + return new int[]{30,25,23,15,7}; + } + + @Override + public int[] headerTextResourceIds() { + return new int[]{ + R.string.child_profile,R.string.anthopometri,R.string.status,R.string.visitSchedule,R.string.header_edit + }; + } + }; + } + + @Override + public void setupListView(ChildSmartRegisterClient client, + NativeChildSmartRegisterViewHolder viewHolder, + View.OnClickListener clientSectionClickListener) { + + } + + @Override + public void setupListView(ANCSmartRegisterClient client, NativeANCSmartRegisterViewHolder viewHolder, View.OnClickListener clientSectionClickListener) { + + } + + @Override + public void setupListView(FPSmartRegisterClient client, NativeFPSmartRegisterViewHolder viewHolder, View.OnClickListener clientSectionClickListener) { + + } + + @Override + public void setupListView(PNCSmartRegisterClient client, NativePNCSmartRegisterViewHolder viewHolder, View.OnClickListener clientSectionClickListener) { + + } + + +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziSmartClientsProvider.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziSmartClientsProvider.java new file mode 100755 index 0000000..cf7755e --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziSmartClientsProvider.java @@ -0,0 +1,463 @@ +package org.ei.opensrp.gizi.gizi; + +import android.app.Activity; +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.AbsListView; +import android.widget.Button; +import android.widget.FrameLayout; +import android.widget.ImageButton; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.ei.opensrp.commonregistry.AllCommonsRepository; +import org.ei.opensrp.commonregistry.CommonPersonObject; +import org.ei.opensrp.commonregistry.CommonPersonObjectClient; +import org.ei.opensrp.commonregistry.CommonPersonObjectController; +import org.ei.opensrp.cursoradapter.SmartRegisterCLientsProviderForCursorAdapter; +import org.ei.opensrp.repository.DetailsRepository; +import org.ei.opensrp.service.AlertService; +import org.ei.opensrp.gizi.R; +import org.ei.opensrp.view.activity.DrishtiApplication; +import org.ei.opensrp.view.contract.SmartRegisterClient; +import org.ei.opensrp.view.contract.SmartRegisterClients; +import org.ei.opensrp.view.dialog.FilterOption; +import org.ei.opensrp.view.dialog.ServiceModeOption; +import org.ei.opensrp.view.dialog.SortOption; +import org.ei.opensrp.view.viewHolder.OnClickFormLauncher; + +import java.io.File; +import java.text.SimpleDateFormat; + +import util.formula.Support; + +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; + +/** + * Created by user on 2/12/15. + */ +public class GiziSmartClientsProvider implements SmartRegisterCLientsProviderForCursorAdapter { + private static final String TAG = GiziSmartClientsProvider.class.getSimpleName(); + private final LayoutInflater inflater; + private final Context context; + private final View.OnClickListener onClickListener; + private Drawable iconPencilDrawable; + private final int txtColorBlack; + private final AbsListView.LayoutParams clientViewLayoutParams; + + protected CommonPersonObjectController controller; + + AlertService alertService; + public GiziSmartClientsProvider(Context context, + View.OnClickListener onClickListener, + AlertService alertService) { + this.onClickListener = onClickListener; +// this.controller = controller; + this.context = context; + this.alertService = alertService; + this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + + clientViewLayoutParams = new AbsListView.LayoutParams(MATCH_PARENT, + (int) context.getResources().getDimension(org.ei.opensrp.R.dimen.list_item_height)); + txtColorBlack = context.getResources().getColor(org.ei.opensrp.R.color.text_black); + + } + + @Override + public void getView(SmartRegisterClient smartRegisterClient, View convertView) { + ViewHolder viewHolder; + + if(convertView.getTag() == null || !(convertView.getTag() instanceof ViewHolder)){ + viewHolder = new ViewHolder(); + viewHolder.profilelayout = (LinearLayout)convertView.findViewById(R.id.profile_info_layout); + viewHolder.name = (TextView)convertView.findViewById(R.id.txt_child_name); + viewHolder.fatherName = (TextView) convertView.findViewById(R.id.ParentName); + viewHolder.subVillage = (TextView) convertView.findViewById(R.id.txt_child_subVillage); + viewHolder.age = (TextView)convertView.findViewById(R.id.txt_child_age); + viewHolder.dateOfBirth = (TextView) convertView.findViewById(R.id.txt_child_date_of_birth); + viewHolder.gender = (TextView)convertView.findViewById(R.id.txt_child_gender); + viewHolder.visitDate = (TextView)convertView.findViewById(R.id.txt_child_visit_date); + viewHolder.height = (TextView)convertView.findViewById(R.id.txt_child_height); + viewHolder.weight = (TextView)convertView.findViewById(R.id.txt_child_weight); + viewHolder.underweight = (TextView)convertView.findViewById(R.id.txt_child_underweight); + viewHolder.stunting_status = (TextView)convertView.findViewById(R.id.txt_child_stunting); + viewHolder.wasting_status = (TextView)convertView.findViewById(R.id.txt_child_wasting); + + viewHolder.absentAlert = (TextView)convertView.findViewById(R.id.absen); + viewHolder.weightText = (TextView)convertView.findViewById(R.id.weightSchedule); + viewHolder.weightLogo = (ImageView)convertView.findViewById(R.id.weightSymbol); + viewHolder.heightText = (TextView)convertView.findViewById(R.id.heightSchedule); + viewHolder.heightLogo = (ImageView)convertView.findViewById(R.id.heightSymbol); + viewHolder.vitALogo = (ImageView)convertView.findViewById(R.id.vitASymbol); + viewHolder.vitAText = (TextView)convertView.findViewById(R.id.vitASchedule); + viewHolder.antihelminticLogo = (ImageView)convertView.findViewById(R.id.antihelminticSymbol); + viewHolder.antihelminticText = (TextView)convertView.findViewById(R.id.antihelminticText); + + viewHolder.profilepic =(ImageView)convertView.findViewById(R.id.profilepic); + viewHolder.follow_up = (ImageButton)convertView.findViewById(R.id.btn_edit); + convertView.setTag(viewHolder); + } else { + viewHolder = (ViewHolder) convertView.getTag(); + } + + viewHolder.follow_up.setOnClickListener(onClickListener); + viewHolder.follow_up.setTag(smartRegisterClient); + viewHolder.profilelayout.setOnClickListener(onClickListener); + viewHolder.profilelayout.setTag(smartRegisterClient); + + CommonPersonObjectClient pc = (CommonPersonObjectClient) smartRegisterClient; + + if (iconPencilDrawable == null) { + iconPencilDrawable = context.getResources().getDrawable(R.drawable.ic_pencil); + } + viewHolder.follow_up.setImageDrawable(iconPencilDrawable); + viewHolder.follow_up.setOnClickListener(onClickListener); + + DetailsRepository detailsRepository = org.ei.opensrp.Context.getInstance().detailsRepository(); + detailsRepository.updateDetails(pc); + + //start profile image +// viewHolder.profilepic.setTag(R.id.entity_id, pc.getCaseId());//required when saving file to disk + viewHolder.profilepic.setTag(R.id.entity_id, pc.getColumnmaps().get("_id"));//required when saving file to disk + + if (pc.getDetails().get("gender") != null) { + util.formula.Support.setImagetoHolderFromUri((Activity) context, + DrishtiApplication.getAppDir() + File.separator + pc.getDetails().get("base_entity_id") + ".JPEG", + viewHolder.profilepic, pc.getDetails().get("gender").equals("female") ? R.drawable.child_girl_infant : R.drawable.child_boy_infant); + } else { + Log.e(TAG, "getView: Gender is NOT SET"); + } + + viewHolder.name.setText(Support.getDetails(pc,"namaBayi")); + String ages = pc.getColumnmaps().get("tanggalLahirAnak").substring(0, pc.getColumnmaps().get("tanggalLahirAnak").indexOf("T")); + viewHolder.age.setVisibility(View.INVISIBLE);//.setText(pc.getDetails().get("tanggalLahirAnak")!= null ? Integer.toString(monthRangeToToday(ages))+" bln" : ""); + + AllCommonsRepository childRepository = org.ei.opensrp.Context.getInstance().allCommonsRepositoryobjects("ec_anak"); + CommonPersonObject childobject = childRepository.findByCaseID(pc.entityId()); + + AllCommonsRepository kirep = org.ei.opensrp.Context.getInstance().allCommonsRepositoryobjects("ec_kartu_ibu"); + final CommonPersonObject kiparent = kirep.findByCaseID(Support.getColumnmaps(childobject,"relational_id")); + + if(kiparent != null) { + detailsRepository.updateDetails(kiparent); + String namaayah = kiparent.getDetails().get("namaSuami") != null ? kiparent.getDetails().get("namaSuami") : ""; + String namaibu = kiparent.getColumnmaps().get("namalengkap") != null ? kiparent.getColumnmaps().get("namalengkap") : ""; + + viewHolder.fatherName.setText(String.format("%s,%s", namaibu, namaayah)); + viewHolder.subVillage.setText(kiparent.getDetails().get("address1") != null ? kiparent.getDetails().get("address1") : ""); + } + + + String Tgl = pc.getDetails().get("tanggalLahirAnak"); + + if (Tgl != null && Tgl.contains("T")) + Tgl = Tgl.substring(0, Tgl.indexOf("T")); + + viewHolder.setAntihelminticVisibility( + dayRangeBetween(Tgl.split("-") + ,new SimpleDateFormat("yyyy-MM-dd").format(new java.util.Date()).split("-") + ) >= 365 ? View.VISIBLE : View.INVISIBLE + ); + viewHolder.dateOfBirth.setText(pc.getDetails().get("tanggalLahirAnak")!=null?Tgl:""); + +// viewHolder.gender.setText( pc.getDetails().get("gender") != null ? setGender(pc.getDetails().get("gender")):"-"); + int age = monthRangeToToday(ages); + viewHolder.gender.setText(pc.getDetails().get("tanggalLahirAnak") != null + ? age/12 + " " + context.getString(R.string.years_unit)+" "+age%12+" "+context.getString(R.string.month_unit) : "-"); + +/** collect history data and clean latest history data which contains no specific date or value, + */ + if(!Support.getDetails(pc,"umur").toLowerCase().equals("nan")) { + String[] history1 = pc.getDetails().get("history_berat") != null ? Support.insertionSort(pc.getDetails().get("history_berat")) : new String[]{"0:0"}; + if (history1[history1.length - 1].charAt(history1[history1.length - 1].length() - 1) == ':') + history1[history1.length - 1] = history1[history1.length - 1] + "-"; + String[] history2 = pc.getDetails().get("history_tinggi") != null ? Support.insertionSort(pc.getDetails().get("history_tinggi")) : new String[]{"0:0"}; + if (history2[history2.length - 1].charAt(history2[history2.length - 1].length() - 1) == ':') + history2[history2.length - 1] = history2[history2.length - 1] + "-"; + String newestDateonHistory = history1.length > 1 + ? findDate(Tgl, Support.getAge(history1[history1.length - 1])) + : pc.getDetails().get("tanggalPenimbangan") != null + ? pc.getDetails().get("tanggalPenimbangan") + : Tgl; + + System.out.println("history1 : " + history1[history1.length - 1]); + System.out.println("history2 : " + history2[history2.length - 1]); + System.out.println("newest : " + newestDateonHistory); +/** + */ + + if (newestDateonHistory.equals(pc.getDetails().get("tanggalPenimbangan") != null ? pc.getDetails().get("tanggalPenimbangan") : "-")) { + System.out.println("history = tglPenimbangan"); + viewHolder.visitDate.setText(context.getString(R.string.tanggal) + " " + (pc.getDetails().get("tanggalPenimbangan") != null ? pc.getDetails().get("tanggalPenimbangan") : "-")); + viewHolder.height.setText(context.getString(R.string.height) + " " + (pc.getDetails().get("tinggiBadan") != null ? pc.getDetails().get("tinggiBadan") : "-") + " Cm"); + viewHolder.weight.setText(context.getString(R.string.weight) + " " + (pc.getDetails().get("beratBadan") != null ? pc.getDetails().get("beratBadan") : "-") + " Kg"); + viewHolder.weightText.setText(context.getString(R.string.label_weight)); + viewHolder.heightText.setText(context.getString(R.string.label_height)); + viewHolder.antihelminticText.setText(R.string.anthelmintic); + } else { + System.out.println("history != tglPenimbangan"); + viewHolder.visitDate.setText(context.getString(R.string.tanggal) + " " + (history1.length > 1 ? newestDateonHistory : "-")); + viewHolder.height.setText(context.getString(R.string.height) + " " + + (pc.getDetails().get("tinggiBadan") != null + ? !pc.getDetails().get("tinggiBadan").equals(history2[history2.length - 1]) + ? history2[history2.length - 1].split(":")[1] + : pc.getDetails().get("tinggiBadan") + : "-") + + " Cm"); + viewHolder.weight.setText(context.getString(R.string.weight) + " " + + (pc.getDetails().get("beratBadan") != null + ? !pc.getDetails().get("beratBadan").equals(history1[history1.length - 1]) + ? history1[history1.length - 1].split(":")[1] + : pc.getDetails().get("beratBadan") + : "-") + + " Kg"); + viewHolder.weightText.setText(context.getString(R.string.label_weight)); + viewHolder.heightText.setText(context.getString(R.string.label_height)); + viewHolder.antihelminticText.setText(R.string.anthelmintic); + } + +//------VISIBLE AND INVISIBLE COMPONENT + viewHolder.absentAlert.setVisibility(pc.getDetails().get("tanggalPenimbangan") != null + ? isLate(pc.getDetails().get("tanggalPenimbangan"), 1) + ? View.VISIBLE + : View.INVISIBLE + : View.INVISIBLE + ); + viewHolder.setVitAVisibility(); + + +//------CHILD DATA HAS BEEN SUBMITTED OR NOT + System.out.println("latest date = " + returnLatestDate(pc.getDetails().get("tanggalPenimbangan"), newestDateonHistory)); + + viewHolder.weightLogo.setImageDrawable(context.getResources().getDrawable(isLate(returnLatestDate(pc.getDetails().get("tanggalPenimbangan"), newestDateonHistory), 0) ? R.drawable.ic_remove : R.drawable.ic_yes_large)); + viewHolder.heightLogo.setImageDrawable(context.getResources().getDrawable(!isLate(returnLatestDate(pc.getDetails().get("tanggalPenimbangan"), newestDateonHistory), 0) && !Support.getDetails(pc, "tinggiBadan").equals("-") ? R.drawable.ic_yes_large : R.drawable.ic_remove)); + viewHolder.vitALogo.setImageDrawable(context.getResources().getDrawable(inTheSameRegion(pc.getDetails().get("lastVitA")) ? R.drawable.ic_yes_large : R.drawable.ic_remove)); + viewHolder.antihelminticLogo.setImageDrawable(context.getResources().getDrawable(isGiven(pc, "obatcacing") ? R.drawable.ic_yes_large : R.drawable.ic_remove)); + + if (pc.getDetails().get("tanggalPenimbangan") != null) { + viewHolder.stunting_status.setText(String.format("%s %s", context.getString(R.string.stunting), hasValue(pc.getDetails().get("stunting")) ? setStatus(pc.getDetails().get("stunting")) : "-")); + viewHolder.underweight.setText(String.format("%s %s", context.getString(R.string.wfa), hasValue(pc.getDetails().get("underweight")) ? setStatus(pc.getDetails().get("underweight")) : "-")); + viewHolder.wasting_status.setText(String.format("%s %s", context.getString(R.string.wasting), hasValue(pc.getDetails().get("wasting")) ? setStatus(pc.getDetails().get("wasting")) : "-")); + } else { + viewHolder.underweight.setText(String.format("%s ", context.getString(R.string.wfa))); + viewHolder.stunting_status.setText(String.format("%s ", context.getString(R.string.stunting))); + viewHolder.wasting_status.setText(String.format("%s ", context.getString(R.string.wasting))); + } + //================ END OF Z-SCORE==============================// + } + convertView.setLayoutParams(clientViewLayoutParams); + // return convertView; + } + CommonPersonObjectController householdelcocontroller; + + private String setStatus(String status){ + switch (status.toLowerCase()){ + case "underweight" : + return context.getString(R.string.underweight); + case "severely underweight" : + return context.getString(R.string.s_underweight); + case "normal": + return context.getString(R.string.normal); + case "overweight": + return context.getString(R.string.overweight); + case "severely stunted" : + return context.getString(R.string.s_stunted); + case "stunted" : + return context.getString(R.string.stunted); + case "tall" : + return context.getString(R.string.tall); + case "severely wasted" : + return context.getString(R.string.s_wasted); + case "wasted" : + return context.getString(R.string.wasted); + default: + return ""; + } + } + + private String setGender(String gender){ + return gender.toLowerCase().contains("em") ? context.getString(R.string.child_female) : context.getString(R.string.child_male); + } + + private String returnLatestDate(String date1, String date2){ + if(date1 == null || date2 == null){ + return date1==null && date2==null + ? null + : date1==null + ? date2 + : date1 + ; + } + return dayRangeBetween(date1.split("-"),date2.split("-"))>0 ? date2 : date1; + } + + private boolean isLate(String lastVisitDate,int threshold){ + if (lastVisitDate==null || lastVisitDate.length()<6) + return true; + return monthRangeToToday(lastVisitDate) > threshold; + } + +// private boolean isDue(String lastVisitDate){ +// if(lastVisitDate==null || lastVisitDate.length()<6) +// return true; +// +// return dayRangeBetween(lastVisitDate.split("-"),new SimpleDateFormat("yyyy-MM-dd").format(new java.util.Date()).split("-")) <= 30; +// } + + private boolean isGiven(CommonPersonObjectClient pc, String details){ + if(pc.getDetails().get(details) != null) + return pc.getDetails().get(details).equalsIgnoreCase("ya") || pc.getDetails().get(details).equalsIgnoreCase("yes"); + return false; + } + + private boolean hasValue(String data){ + if(data == null) + return false; + return data.length() > 2; + } + + private int monthRangeToToday(String lastVisitDate){ + String currentDate[] = new SimpleDateFormat("yyyy-MM").format(new java.util.Date()).substring(0,7).split("-"); + return ((Integer.parseInt(currentDate[0]) - Integer.parseInt(lastVisitDate.substring(0,4)))*12 + + (Integer.parseInt(currentDate[1]) - Integer.parseInt(lastVisitDate.substring(5,7)))); + } + + /** + * The part of method that using to check is the last visit date was in the same region as the + * current vitamin A period + **/ + private boolean inTheSameRegion(String date){ + if(date==null || date.length()<6) + return false; + int currentDate = Integer.parseInt(new SimpleDateFormat("MM").format(new java.util.Date())); + int visitDate = Integer.parseInt(date.substring(5, 7)); + + int currentYear = Integer.parseInt(new SimpleDateFormat("yyyy").format(new java.util.Date())); + int visitYear = Integer.parseInt(date.substring(0, 4)); + + boolean date1 = currentDate < 2 || currentDate >=8; + boolean date2 = visitDate < 2 || visitDate >=8; + + int indicator = currentDate == 1 ? 2:1; + + return (!((!date1 && date2) || (date1 && !date2)) && ((currentYear-visitYear)dayLength[startMonth-1]){ + dayAge = dayAge - dayLength[startMonth-1]; + startMonth++; + if(startMonth>12){ + startYear++; + startMonth = 1; + dayLength[1] = startYear % 4 == 0 ? 29 : 28; + } + } + startDay+=dayAge; + if(startDay > dayLength[startMonth-1]) { + startDay=startDay - dayLength[startMonth-1]; + startMonth++; + } + if(startMonth>12) { + startYear++; + startMonth = 1; + } + + String m = "" + (startMonth<10 ? "0"+startMonth : Integer.toString(startMonth)); + String d = "" + (startDay<10 ? "0"+startDay : Integer.toString(startDay)); + return Integer.toString(startYear)+"-"+m+"-"+d; + } + + +} + diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziSmartRegisterActivity.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziSmartRegisterActivity.java new file mode 100755 index 0000000..ca5c1f3 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziSmartRegisterActivity.java @@ -0,0 +1,460 @@ +package org.ei.opensrp.gizi.gizi; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.database.Cursor; +import android.os.Bundle; +import android.support.v4.app.FragmentPagerAdapter; +import android.support.v4.view.ViewPager; +import android.util.Log; +import android.widget.Toast; + +import com.flurry.android.FlurryAgent; + +import org.ei.opensrp.Context; +import org.ei.opensrp.commonregistry.AllCommonsRepository; +import org.ei.opensrp.commonregistry.CommonPersonObject; +import org.ei.opensrp.commonregistry.CommonPersonObjectClient; +import org.ei.opensrp.cursoradapter.SmartRegisterQueryBuilder; +import org.ei.opensrp.domain.Alert; +import org.ei.opensrp.domain.form.FieldOverrides; +import org.ei.opensrp.domain.form.FormSubmission; +import org.ei.opensrp.gizi.LoginActivity; +import org.ei.opensrp.gizi.fragment.GiziSmartRegisterFragment; +import org.ei.opensrp.gizi.pageradapter.BaseRegisterActivityPagerAdapter; +import org.ei.opensrp.provider.SmartRegisterClientsProvider; +import org.ei.opensrp.service.ZiggyService; +import org.ei.opensrp.gizi.LoginActivity; +import org.ei.opensrp.gizi.R; +import org.ei.opensrp.gizi.fragment.GiziSmartRegisterFragment; +import org.ei.opensrp.gizi.pageradapter.BaseRegisterActivityPagerAdapter; +import org.ei.opensrp.sync.ClientProcessor; +import org.ei.opensrp.util.FormUtils; +import org.ei.opensrp.view.activity.SecuredNativeSmartRegisterActivity; +import org.ei.opensrp.view.dialog.DialogOption; +import org.ei.opensrp.view.dialog.LocationSelectorDialogFragment; +import org.ei.opensrp.view.dialog.OpenFormOption; +import org.ei.opensrp.view.fragment.DisplayFormFragment; +import org.ei.opensrp.view.fragment.SecuredNativeSmartRegisterFragment; +import org.ei.opensrp.view.viewpager.OpenSRPViewPager; +import org.json.JSONException; +import org.json.JSONObject; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +import butterknife.Bind; +import butterknife.ButterKnife; +import util.ZScore.ZScoreSystemCalculation; +import util.formula.Support; + +public class GiziSmartRegisterActivity extends SecuredNativeSmartRegisterActivity implements + LocationSelectorDialogFragment.OnLocationSelectedListener{ + + SimpleDateFormat timer = new SimpleDateFormat("hh:mm:ss"); + + public static final String TAG = GiziSmartRegisterActivity.class.getSimpleName(); + @Bind(R.id.view_pager) + OpenSRPViewPager mPager; + private FragmentPagerAdapter mPagerAdapter; + private int currentPage; + private String[] formNames = new String[]{}; + private android.support.v4.app.Fragment mBaseFragment = null; + + ZiggyService ziggyService; + + GiziSmartRegisterFragment nf = new GiziSmartRegisterFragment(); + + Map FS = new HashMap<>(); + + Bundle extras; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + ButterKnife.bind(this); + + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + String GiziStart = timer.format(new Date()); + Map Gizi = new HashMap<>(); + Gizi.put("start", GiziStart); + + formNames = this.buildFormNameList(); + + extras = getIntent().getExtras(); + + if (extras != null) { + boolean mode_face = extras.getBoolean("org.ei.opensrp.indonesia.face.face_mode"); + String base_id = extras.getString("org.ei.opensrp.indonesia.face.base_id"); + double proc_time = extras.getDouble("org.ei.opensrp.indonesia.face.proc_time"); + + if (mode_face) { + nf.setCriteria(base_id); + mBaseFragment = new GiziSmartRegisterFragment(); + + Log.e(TAG, "onCreate: id " + base_id); + + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("Is it Right Person ?"); + + // TODO : get name by base_id + builder.setNegativeButton("CANCEL", listener ); + builder.setPositiveButton("YES", listener ); + builder.show(); + } + + } else { + mBaseFragment = new GiziSmartRegisterFragment(); + } + + mPagerAdapter = new BaseRegisterActivityPagerAdapter(getSupportFragmentManager(), formNames, mBaseFragment); + mPager.setOffscreenPageLimit(formNames.length); + mPager.setAdapter(mPagerAdapter); + mPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { + @Override + public void onPageSelected(int position) { + currentPage = position; + onPageChanged(position); + } + }); + + if(LoginActivity.generator.uniqueIdController().needToRefillUniqueId(LoginActivity.generator.UNIQUE_ID_LIMIT)) { + String toastMessage = String.format("need to refill unique id, its only %s remaining", + LoginActivity.generator.uniqueIdController().countRemainingUniqueId()); + Toast.makeText(context().applicationContext(), toastMessage, Toast.LENGTH_LONG).show(); + } + ziggyService = context().ziggyService(); + } + public void onPageChanged(int page){ + setRequestedOrientation(page == 0 + ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE + : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + LoginActivity.setLanguage(); + } + + @Override + protected DefaultOptionsProvider getDefaultOptionsProvider() {return null;} + + @Override + protected void setupViews() { + } + + @Override + protected void onResumption(){} + + @Override + protected NavBarOptionsProvider getNavBarOptionsProvider() {return null;} + + @Override + protected SmartRegisterClientsProvider clientsProvider() {return null;} + + @Override + protected void onInitialization() { + context().formSubmissionRouter().getHandlerMap().put("kunjungan_gizi", new KmsHandler()); + } + + @Override + public void startRegistration() { + } + + public DialogOption[] getEditOptions() { + return new DialogOption[]{ + new OpenFormOption("Kunjungan Per Bulan ", "kunjungan_gizi", formController), + new OpenFormOption("Close Form","close_form",formController) + }; + } + + + @Override + public void saveFormSubmission(String formSubmission, String id, String formName, JSONObject fieldOverrides){ + Log.v("fieldoverride", fieldOverrides.toString()); + // save the form + try{ + FormUtils formUtils = FormUtils.getInstance(getApplicationContext()); + FormSubmission submission = formUtils.generateFormSubmisionFromXMLString(id, formSubmission, formName, fieldOverrides); + + ClientProcessor.getInstance(getApplicationContext()).processClient(); + + context().formSubmissionService().updateFTSsearch(submission); + context().formSubmissionRouter().handleSubmission(submission, formName); + switchToBaseFragment(formSubmission); // Unnecessary!! passing on data + + if(formName.equals("registrasi_gizi")) { + saveuniqueid(); + } + //end capture flurry log for FS + String end = timer.format(new Date()); + Map FS = new HashMap(); + FS.put("end", end); + FlurryAgent.logEvent(formName, FS, true); + }catch (Exception e){ + // TODO: show error dialog on the formfragment if the submission fails + DisplayFormFragment displayFormFragment = getDisplayFormFragmentAtIndex(currentPage); + if (displayFormFragment != null) { + displayFormFragment.hideTranslucentProgressDialog(); + } + e.printStackTrace(); + } + + } + + @Override + public void OnLocationSelected(String locationJSONString) { + JSONObject combined = null; + + try { + JSONObject locationJSON = new JSONObject(locationJSONString); + JSONObject uniqueId = new JSONObject(LoginActivity.generator.uniqueIdController().getUniqueIdJson()); + + combined = locationJSON; + Iterator iter = uniqueId.keys(); + + while (iter.hasNext()) { + String key = iter.next(); + combined.put(key, uniqueId.get(key)); + } + + System.out.println("injection string: " + combined.toString()); + } catch (JSONException e) { + e.printStackTrace(); + } + + if (combined != null) { + FieldOverrides fieldOverrides = new FieldOverrides(combined.toString()); + startFormActivity("registrasi_gizi", null, fieldOverrides.getJSONString()); + } + } + + public void saveuniqueid() { + try { + JSONObject uniqueId = new JSONObject(LoginActivity.generator.uniqueIdController().getUniqueIdJson()); + String uniq = uniqueId.getString("unique_id"); + LoginActivity.generator.uniqueIdController().updateCurrentUniqueId(uniq); + + } catch (JSONException e) { + e.printStackTrace(); + } + } + + public static boolean out; + + @Override + public void startFormActivity(final String formName, final String entityId, final String metaData) { + if(Support.ONSYNC) { + Toast.makeText(this, "Data still Synchronizing, please wait", Toast.LENGTH_SHORT).show(); + return; + } + + String start = timer.format(new Date()); + Map FS = new HashMap(); + FS.put("start", start); + FlurryAgent.logEvent(formName, FS, true); + + if(formName.equals("kunjungan_gizi")) { + if(getNumOfChild()<4) + activatingForm(formName,entityId,metaData); + else { + final int choice = new java.util.Random().nextInt(3); + CharSequence[] selections = selections(choice, entityId); + + final AlertDialog.Builder builder = new AlertDialog.Builder(GiziSmartRegisterActivity.this); + builder.setTitle(context().getStringResource(R.string.reconfirmChildName)); + builder.setItems(selections, new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // the user clicked on colors[which] + if (which == choice) { + activatingForm(formName, entityId, metaData); + } + } + }); + builder.show(); + } + } + else{ + activatingForm(formName,entityId,metaData); + } + } + + private void activatingForm(String formName, String entityId, String metaData){ + try { + int formIndex = FormUtils.getIndexForFormName(formName, formNames) + 1; // add the offset + if (entityId != null || metaData != null){ + String data = null; + data = getPreviouslySavedDataForForm(formName, metaData, entityId); + if (data == null){ + data = FormUtils.getInstance(getApplicationContext()).generateXMLInputForFormWithEntityId(entityId, formName, metaData); + } + + DisplayFormFragment displayFormFragment = getDisplayFormFragmentAtIndex(formIndex); + if (displayFormFragment != null) { + displayFormFragment.setFormData(data); + displayFormFragment.setRecordId(entityId); + displayFormFragment.setFieldOverides(metaData); + } + } + + mPager.setCurrentItem(formIndex, false); //Don't animate the view on orientation change the view disapears + + }catch (Exception e){ + e.printStackTrace(); + } + } + + /** + * Get 3 children name, 1 determined and 2 random. the determined one will be generated based on + * @entityId and stored to index @choice of char sequence array. + * @param choice + * @param entityId + * @return + */ + private CharSequence[] selections(int choice, String entityId){ + String name = org.ei.opensrp.Context.getInstance().allCommonsRepositoryobjects("ec_anak").findByCaseID(entityId).getColumnmaps().get("namaBayi"); + System.out.println("start form activity / nama = " + name); + CharSequence selections[] = new CharSequence[]{name, name, name}; + + selections[choice] = (CharSequence) name; + + String query = "SELECT namaBayi FROM ec_anak where ec_anak.is_closed = 0"; + Cursor cursor = context().commonrepository("ec_anak").RawCustomQueryForAdapter(query); + cursor.moveToFirst(); + + for (int i = 0; i < selections.length; i++) { + if (i != choice) { + cursor.move(new java.util.Random().nextInt(cursor.getCount())); + String temp = cursor.getString(cursor.getColumnIndex("namaBayi")); + if(temp==null) + i--; + else if (temp.equals(name)) + i--; + else + selections[i] = (CharSequence) temp; + cursor.moveToFirst(); + } + } + cursor.close(); + + return selections; + } + + public void switchToBaseFragment(final String data){ + final int prevPageIndex = currentPage; + runOnUiThread(new Runnable() { + @Override + public void run() { + mPager.setCurrentItem(0, false); + SecuredNativeSmartRegisterFragment registerFragment = (SecuredNativeSmartRegisterFragment) findFragmentByPosition(0); + if (registerFragment != null && data != null) { + registerFragment.refreshListView(); + } + + //hack reset the form + DisplayFormFragment displayFormFragment = getDisplayFormFragmentAtIndex(prevPageIndex); + if (displayFormFragment != null) { + displayFormFragment.hideTranslucentProgressDialog(); + displayFormFragment.setFormData(null); + + } + + displayFormFragment.setRecordId(null); + } + }); + + } + + public android.support.v4.app.Fragment findFragmentByPosition(int position) { + FragmentPagerAdapter fragmentPagerAdapter = mPagerAdapter; + return getSupportFragmentManager().findFragmentByTag("android:switcher:" + mPager.getId() + ":" + fragmentPagerAdapter.getItemId(position)); + } + + public DisplayFormFragment getDisplayFormFragmentAtIndex(int index) { + return (DisplayFormFragment)findFragmentByPosition(index); + } + + @Override + public void onBackPressed() { + nf.setCriteria("!"); + Log.e(TAG, "onBackPressed: "+currentPage ); + + if (currentPage != 0) { + switchToBaseFragment(null); + } else { + super.onBackPressed(); // allow back key only if we are + } + } + + private String[] buildFormNameList(){ + List formNames = new ArrayList(); + formNames.add("registrasi_gizi"); + formNames.add("kunjungan_gizi"); + formNames.add("close_form"); + return formNames.toArray(new String[formNames.size()]); + } + + @Override + protected void onPause() { + super.onPause(); + retrieveAndSaveUnsubmittedFormData(); + String GiziEnd = timer.format(new Date()); + Map Gizi = new HashMap(); + Gizi.put("end", GiziEnd); + FlurryAgent.logEvent("Gizi_dashboard",Gizi, true ); + } + + public void retrieveAndSaveUnsubmittedFormData(){ + if (currentActivityIsShowingForm()){ + DisplayFormFragment formFragment = getDisplayFormFragmentAtIndex(currentPage); + formFragment.saveCurrentFormData(); + } + } + + private int getNumOfChild(){ + Cursor childcountcursor = context().commonrepository("ec_anak").RawCustomQueryForAdapter(new SmartRegisterQueryBuilder().queryForCountOnRegisters("ec_anak_search", "ec_anak_search.is_closed=0")); + childcountcursor.moveToFirst(); + int childcount= childcountcursor.getInt(0); + childcountcursor.close(); + return childcount; + } + + private boolean currentActivityIsShowingForm(){ + return currentPage != 0; + } + + private DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface dialog, int which) { + String face_end = timer.format(new Date()); + FS.put("face_end", face_end); + + Log.e(TAG, "onClick: which "+ which ); + nf.setCriteria("!"); + + if (which == -1 ){ + currentPage = 0; + Log.e(TAG, "onClick: YES "); + FlurryAgent.logEvent(TAG+"search_by_face OK", true); + + } else { + Log.e(TAG, "onClick: NO "+currentPage); + FlurryAgent.logEvent(TAG+"search_by_face NOK", true); + + onBackPressed(); + + Intent intent= new Intent(GiziSmartRegisterActivity.this, GiziSmartRegisterActivity.class); + startActivity(intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)); + } + + + } + }; + + +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziZScoreChartActivity.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziZScoreChartActivity.java new file mode 100644 index 0000000..41b4b66 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/gizi/GiziZScoreChartActivity.java @@ -0,0 +1,424 @@ +package org.ei.opensrp.gizi.gizi; + +import android.app.Activity; +import android.content.Intent; +import android.os.Bundle; +import android.view.View; +import android.widget.CheckBox; +import android.widget.CompoundButton; +import android.widget.ImageButton; +import android.widget.TextView; + +import com.flurry.android.FlurryAgent; +import com.jjoe64.graphview.GraphView; + +import org.ei.opensrp.Context; +import org.ei.opensrp.commonregistry.CommonPersonObjectClient; +import org.ei.opensrp.gizi.R; +import org.ei.opensrp.repository.DetailsRepository; + +import util.ZScore.ZScoreSystemCalculation; +import util.formula.Support; +import util.growthChart.GraphConstant; +import util.growthChart.GrowthChartGenerator; + +/** + * Created by Null on 2016-12-06. + */ +public class GiziZScoreChartActivity extends Activity{ + + public static CommonPersonObjectClient client; + private ZScoreSystemCalculation calc; + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + final Context context = Context.getInstance(); + calc = new ZScoreSystemCalculation(); + setContentView(R.layout.gizi_z_score_activity); + FlurryAgent.logEvent("ZScore_chart_view"); + + if(client == null){ + DetailsRepository detailsRepository = org.ei.opensrp.Context.getInstance().detailsRepository(); + detailsRepository.updateDetails(client); + } + + // initializing global variable + initializeGlobalVariable(); + + // Initializing layout component + // configure nav bar option + detailActivity = (TextView)findViewById(R.id.chart_navbar_details); + back = (ImageButton)findViewById(R.id.btn_back_to_home); + lfaActivity = (TextView)findViewById(R.id.chart_navbar_growth_chart); + wfaCheckBox = (CheckBox)findViewById(R.id.wfaCheckBox); + hfaCheckBox = (CheckBox)findViewById(R.id.hfaCheckBox); + wfhCheckBox = (CheckBox)findViewById(R.id.wflCheckBox); + zScoreGraph = (GraphView)findViewById(R.id.z_score_chart); + initializeActionCheckBox(); + initializeActionNavBar(); + refreshGraph(); + } + + private void refreshGraph(){ + String [] data = initializeZScoreSeries(); + String seriesAxis = data[0]; + String seriesData = data[1]; + + generator = new GrowthChartGenerator(zScoreGraph, GraphConstant.Z_SCORE_CHART, + client.getDetails().get("tanggalLahirAnak"), + client.getDetails().get("gender"), + seriesAxis,seriesData + ); + } + + private void initializeGlobalVariable(){ + ////System.out.println("data z score client = "+client.getDetails().toString()); + historyUmur = split(Support.fixHistory(client.getDetails().get("history_berat")))[0]; + historyUmurHari = client.getDetails().get("history_umur_tinggi"); + historyBerat = split(Support.fixHistory(client.getDetails().get("history_berat")))[1]; + historyTinggi = cleanBlankValueOf(Support.fixHistory(client.getDetails().get("history_tinggi"))); + historyTinggiUmurHari = cleanBlankValueOf(client.getDetails().get("history_tinggi_umur_hari")); + + } + + private void initializeActionCheckBox(){ + wfaCheckBox.setChecked(true); + hfaCheckBox.setChecked(true); + wfhCheckBox.setChecked(true); + + wfaCheckBox.setOnCheckedChangeListener( + new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (isChecked) + generator.putSeriesOfIndex(0); + else + generator.removeSeriesOfIndex(0); + + } + } + ); + hfaCheckBox.setOnCheckedChangeListener( + new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (isChecked) + generator.putSeriesOfIndex(1); + else + generator.removeSeriesOfIndex(1); + } + } + ); + wfhCheckBox.setOnCheckedChangeListener( + new CompoundButton.OnCheckedChangeListener() { + @Override + public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) { + if (isChecked) + generator.putSeriesOfIndex(2); + else + generator.removeSeriesOfIndex(2); + } + } + ); + } + + public void initializeActionNavBar(){ + detailActivity.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + GiziDetailActivity.childclient = client; + startActivity(new Intent(GiziZScoreChartActivity.this, GiziDetailActivity.class)); + overridePendingTransition(0, 0); + } + }); + + lfaActivity.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + GiziGrowthChartActivity.client = client; + startActivity(new Intent(GiziZScoreChartActivity.this, GiziGrowthChartActivity.class)); + overridePendingTransition(0, 0); + } + }); + + back.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + finish(); + startActivity(new Intent(GiziZScoreChartActivity.this, GiziSmartRegisterActivity.class)); + overridePendingTransition(0, 0); + } + }); + } + + private String[]initializeZScoreSeries(){ + String axis1 = wfaChecked ? createWFAAxis():""; + String data1 = wfaChecked ? createWFASeries():""; + String axis2="",data2=""; + + if(hfaChecked) { + String tempAxis2 = createHFAAxis(); + if (!tempAxis2.equals("")) { + axis2 = tempAxis2.split(",").length > 0 ? Integer.toString(Integer.parseInt(tempAxis2.split(",")[0]) / 30) : ""; + for (int i = 1; i < tempAxis2.split(",").length; i++) { + axis2 = axis2 + "," + Integer.toString(Integer.parseInt(tempAxis2.split(",")[i]) / 30); + } + data2 = createHFASeries(); + } + } + + String axis3 = wfhChecked ? createWFHAxis() : ""; + String data3 = wfhChecked ? createWFHSeries() : ""; + + ////System.out.println("data 1 = "+axis1+"@"+data1); + ////System.out.println("data 2 = "+axis2+"@"+data2); + ////System.out.println("data 3 = "+axis3+"@"+data3); + + return new String[]{axis1+"@"+axis2+"@"+axis3,data1+"@"+data2+"@"+data3}; + } + + //CREATING AXIS AND SERIES DATA + private String createWFAAxis(){ + String seriesAxis = ""; + String [] temp = buildDayAgeArray(historyUmur/*, historyUmurHari*/).split(","); + seriesAxis = temp[0].equals("") ? "" : ""+(Integer.parseInt(temp[0])/30); + for(int i=1;i0) + wfa = wfa + ","; + wfa = wfa + calc.countWFA(isMale,Integer.parseInt(dayAge[i]),Double.parseDouble(weight[i+1])); + } + return wfa; + } + + private String createHFAAxis(){ + if (historyTinggi==null) + return ""; + String []historyUmur = historyTinggi.split(","); + String []historyUmurHari = historyTinggiUmurHari!=null + ? historyTinggiUmurHari.split(",") + : new String[]{""}; + + String tempUmur = historyUmur.length>1? historyUmur[0].split(":")[0]:""; + String tempUmurHari = historyUmurHari.length>1?historyUmurHari[0].split(":")[0]:""; + + for(int i=1;ii) + tempUmurHari = tempUmurHari+ ","+historyUmurHari[i].split(":")[0]; + } +// return buildDayAgeArray(tempUmur,tempUmurHari); + return buildDayAgeArray(tempUmur); + } + + private String createHFASeries(){ + String []historyUmur = createHFAAxis().split(","); + if(historyUmur.length<1 || historyUmur[0].equals("")) + return ""; + String []temp = historyTinggi.split(","); + boolean isMale = !client.getDetails().get("gender").toLowerCase().contains("em"); + + + String result = ""; + for(int i=0;i0) + result = result+","; + result = result + Double.toString(calc.countHFA(isMale,Integer.parseInt(historyUmur[i]),Double.parseDouble(temp[i+1].split(":")[1]))); + } + //////System.out.println("hfa result = "+result); + return result; + } + + private String createWFHAxis(){ + String axis = createHFAAxis(); + if(axis.equals("")) + return ""; + String result = ""; + + for(int i=0;i1) + age[1]= age[0] == age[1] ? age[1]++ : age[1]; + for (int i = 2; i < age.length - 1; i++) { + if (age[i - 1] == age[i]) { + if (age[i - 1] - age[i - 2] == 2) + age[i - 1]--; + else + age[i]++; + } + } + + // step 4. convert month age to daily unit and transform it into string + result = Integer.toString(age[0] * 30); + for(int i=1;i 0 && !huhLength[0].equals("") && huhLength.length > 1 + ? result + "," + huhLength[1] + : huhLength.length > 1 + ? huhLength[1] + : ""; + + for (int i = 2; i < huhLength.length; i++) { + result = result + "," + huhLength[i]; + } + } + //////System.out.println("result = "+result); + return result; + } + + public String cleanBlankValueOf(String string){ + if(string==null) + return null; + String[] tempArray = string.split(","); + String tempString = ""; + for(int i=0;i=3 ? (history_berat[(history_berat.length)-3]) : "0"); + String umurs = history[0]; + String[] history_umur = umurs.split(","); + String tinggi = submission.getFieldValue("history_tinggi")!= null ? submission.getFieldValue("history_tinggi") :"0#0"; + String lastVisitDate = submission.getFieldValue("tanggalPenimbangan") != null + ? !submission.getFieldValue("tanggalPenimbangan").toLowerCase().equals("nan") + ? submission.getFieldValue("tanggalPenimbangan") + : "-" + : "-"; + String gender = submission.getFieldValue("gender") != null ? submission.getFieldValue("gender") : "-"; + String tgllahir = submission.getFieldValue("tanggalLahirAnak") != null + ? submission.getFieldValue("tanggalLahirAnak").substring(0,10) + : "-"; + String dateOfBirth = tgllahir.substring(0, 10); + + detailsRepository.add(entityID, "preload_umur", umurs, tsLong); + detailsRepository.add(entityID, "berat_preload", submission.getFieldValue("history_berat")!= null ? submission.getFieldValue("history_berat") : "0:0", tsLong); +// detailsRepository.add(entityID, "history_umur", umurs, tsLong); + + // detailsRepository.add(entityID, "preload_history_tinggi", submission.getFieldValue("history_tinggi")!= null ? submission.getFieldValue("history_tinggi") :"0#0", tsLong); + detailsRepository.add(entityID, "preload_history_tinggi", tinggi, tsLong); + detailsRepository.add(entityID, "kunjunganSebelumnya", lastVisitDate, tsLong); + ZScoreSystemCalculation zScore = new ZScoreSystemCalculation(); + if(submission.getFieldValue("tanggalPenimbangan") != null ? !submission.getFieldValue("tanggalPenimbangan").toLowerCase().equals("") : false) + { + if(zScore.dailyUnitCalculationOf(dateOfBirth, lastVisitDate) < 1857) { + String[]tempAgeW = history[0].split(","); + String[]tempAgeH = history2[0].split(","); + String[]tempWeight = history[1].split(","); + String[]tempHeight = history2[1].split(","); + int weightAge = Integer.parseInt(tempAgeW[tempAgeW.length - 1]); + double weight = Double.parseDouble(tempWeight[tempWeight.length - 1]); + int lengthAge = Integer.parseInt(tempAgeH[tempAgeH.length - 1]); + double length = tempHeight.length>0 ? Double.parseDouble(tempHeight[tempHeight.length-1]) : 0; + + double weight_for_age = zScore.countWFA(!gender.toLowerCase().contains("em"), weightAge, weight); + String wfaStatus = zScore.getWFAZScoreClassification(weight_for_age); + if (length != 0) { + double heigh_for_age = zScore.countHFA(!gender.toLowerCase().contains("em"), lengthAge, length); + String hfaStatus = zScore.getHFAZScoreClassification(heigh_for_age); + + double wight_for_lenght; + String wflStatus; + if (zScore.dailyUnitCalculationOf(dateOfBirth, lastVisitDate) < 730) { + wight_for_lenght = zScore.countWFL(gender, weight, length); + } else { + wight_for_lenght = zScore.countWFH(gender, weight, length); + } + wflStatus = zScore.getWFLZScoreClassification(wight_for_lenght); + + detailsRepository.add(entityID, "underweight", wfaStatus, tsLong); + detailsRepository.add(entityID, "stunting", hfaStatus, tsLong); + detailsRepository.add(entityID, "wasting", wflStatus, tsLong); + + } else { + detailsRepository.add(entityID, "underweight", wfaStatus, tsLong); + detailsRepository.add(entityID, "stunting", "-", tsLong); + detailsRepository.add(entityID, "wasting", "-", tsLong); + + + } + } + } + /** + * kms calculation + * NOTE - Need a better way to handle z-score data to sqllite + */ + + + double berat=0.0; + double beraSebelum=0.0; + String tanggal_sebelumnya="", tanggal2sblmnya=""; + + if(submission.getFieldValue("history_berat") != null && submission.getFieldValue("tanggalLahirAnak") != null) { + if(submission.getFieldValue("tanggalPenimbangan") != null ? !submission.getFieldValue("tanggalPenimbangan").toLowerCase().equals("") : false) { + String[] historyBerat = Support.insertionSort(submission.getFieldValue("history_berat")); + String latestDate = Support.findDate(submission.getFieldValue("tanggalLahirAnak"), Integer.parseInt(historyBerat[historyBerat.length - 1].split(":")[0])); + if (submission.getFieldValue("tanggalPenimbangan").toLowerCase().equals(latestDate.toLowerCase()) && submission.getFieldValue("kunjunganSebelumnya") != null) { + berat = Double.parseDouble(submission.getFieldValue("beratBadan") != null ? submission.getFieldValue("beratBadan") : "0"); + beraSebelum = Double.parseDouble((history_berat.length) >= 2 ? (history_berat[(history_berat.length) - 2]) : "0"); + tanggal_sebelumnya = (submission.getFieldValue("kunjunganSebelumnya") != null ? submission.getFieldValue("kunjunganSebelumnya") : "0"); + } else { + berat = Double.parseDouble(historyBerat[historyBerat.length - 1].split(":")[1]); + beraSebelum = historyBerat.length > 2 ? Double.parseDouble(historyBerat[historyBerat.length - 2].split(":")[1]) : 0.0; + tanggal_sebelumnya = historyBerat.length > 2 ? Support.findDate(submission.getFieldValue("tanggalLahirAnak"), Integer.parseInt(historyBerat[historyBerat.length - 2].split(":")[0])) : ""; + } + tanggal2sblmnya = historyBerat.length > 3 ? Support.findDate(submission.getFieldValue("tanggalLahirAnak"), Integer.parseInt(historyBerat[historyBerat.length - 3].split(":")[0])) : ""; + + //KMS calculation lastVisitDate + KmsPerson data = new KmsPerson(!gender.toLowerCase().contains("em"), dateOfBirth, berat, beraSebelum, lastVisitDate, berat_sebelum, tanggal_sebelumnya, tanggal2sblmnya); + KmsCalc calculator = new KmsCalc(); + ////System.out.println("tanggal penimbangan = "+submission.getFieldValue("tanggalPenimbangan")+", "+lastVisitDate); + + String duat = history_berat.length <= 2 ? "-" : (Integer.parseInt(history_umur[history_umur.length - 1]) / 30) - (Integer.parseInt(history_umur[history_umur.length - 2]) / 30) >= 2 ? "-" : calculator.cek2T(data); + String status = history_berat.length <= 2 ? "No" : calculator.cekWeightStatus(data); + + detailsRepository.add(entityID, "bgm", calculator.cekBGM(data), tsLong); + detailsRepository.add(entityID, "dua_t", duat, tsLong); + detailsRepository.add(entityID, "garis_kuning", calculator.cekBawahKuning(data), tsLong); + detailsRepository.add(entityID, "nutrition_status", status, tsLong); + + if (submission.getFieldValue("vitA") != null) { + if (submission.getFieldValue("vitA").equalsIgnoreCase("yes") || submission.getFieldValue("vitA").equalsIgnoreCase("ya")) { + detailsRepository.add(entityID, "lastVitA", submission.getFieldValue("tanggalPenimbangan"), tsLong); + } + } else { + detailsRepository.add(entityID, "lastVitA", submission.getFieldValue("lastVitA"), tsLong); + } + if (submission.getFieldValue("obatcacing") != null) { + if (submission.getFieldValue("obatcacing").equalsIgnoreCase("yes") || submission.getFieldValue("obatcacing").equalsIgnoreCase("ya")) { + detailsRepository.add(entityID, "lastAnthelmintic", submission.getFieldValue("tanggalPenimbangan"), tsLong); + } + } else { + detailsRepository.add(entityID, "lastAnthelmintic", submission.getFieldValue("lastAnthelmintic"), tsLong); + } + } + } + } + + private String[]split(String data){ + if(!data.contains(":")) + return new String[]{"0","0"}; + String []temp = data.split(","); + String []result = {"",""}; + for (String aTemp : temp) { + result[0] = result[0] + "," + aTemp.split(":")[0]; + result[1] = result[1] + "," + (aTemp.split(":").length>1 ? aTemp.split(":")[1] : ""); + } + + result[0]=result[0].substring(1,result[0].length()); + result[1]=result[1].substring(1,result[1].length()); + + if(result[0].length()>2 && result[1].length()>2){ + result[0] = result[0].substring(0,2).equals("0,")? result[0].substring(2,result[0].length()):result[0]; + result[1] = result[1].substring(0,2).equals("0,")? result[1].substring(2,result[1].length()):result[1]; + } + + return result; + } +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/giziIbu/IbuDateSort.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/giziIbu/IbuDateSort.java new file mode 100644 index 0000000..716e7a5 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/giziIbu/IbuDateSort.java @@ -0,0 +1,72 @@ +package org.ei.opensrp.gizi.giziIbu; + +import org.ei.opensrp.commonregistry.CommonPersonObjectClient; +import org.ei.opensrp.view.contract.SmartRegisterClient; +import org.ei.opensrp.view.contract.SmartRegisterClients; +import org.ei.opensrp.view.dialog.SortOption; + +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Collections; +import java.util.Comparator; +import java.util.Date; + +/** + * Created by Iq on 30/03/16. + */ +public class IbuDateSort implements SortOption { + String field; + ByColumnAndByDetails byColumnAndByDetails; + + public enum ByColumnAndByDetails{ + byColumn,byDetails; + } + + public IbuDateSort() { + + } + + @Override + public String name() { + return "Due Status"; + } + + @Override + public SmartRegisterClients sort(SmartRegisterClients allClients) { + Collections.sort(allClients, commoncomparator); + return allClients; + } + + Comparator commoncomparator = new Comparator() { + @Override + public int compare(SmartRegisterClient oneClient, SmartRegisterClient anotherClient2) { + CommonPersonObjectClient commonPersonObjectClient = (CommonPersonObjectClient)oneClient; + CommonPersonObjectClient commonPersonObjectClient2 = (CommonPersonObjectClient)anotherClient2; + switch (byColumnAndByDetails){ + case byColumn: + try { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + Date date1 = dateFormat.parse(commonPersonObjectClient.getColumnmaps().get(field)); + Date date2 = dateFormat.parse(commonPersonObjectClient2.getColumnmaps().get(field)); + + return date1.compareTo(date2); + }catch (Exception e){ + break; + } + + + case byDetails: + try { + DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd"); + Date date1 = dateFormat.parse(commonPersonObjectClient.getDetails().get(field)); + Date date2 = dateFormat.parse(commonPersonObjectClient2.getDetails().get(field)); + return date1.compareTo(date2); + }catch (Exception e){ + break; + } + + } + return 0; + } + }; +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/giziIbu/IbuSearchOption.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/giziIbu/IbuSearchOption.java new file mode 100644 index 0000000..55afe8b --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/giziIbu/IbuSearchOption.java @@ -0,0 +1,36 @@ +package org.ei.opensrp.gizi.giziIbu; + +import org.ei.opensrp.Context; +import org.ei.opensrp.commonregistry.CommonPersonObjectClient; +import org.ei.opensrp.gizi.R; +import org.ei.opensrp.view.contract.SmartRegisterClient; +import org.ei.opensrp.view.dialog.FilterOption; + +public class IbuSearchOption implements FilterOption { + private final String criteria; + + public IbuSearchOption(String criteria) { + this.criteria = criteria; + } + + @Override + public String name() { + return Context.getInstance().applicationContext().getResources().getString(R.string.hh_search_hint); + } + + @Override + public boolean filter(SmartRegisterClient client) { + boolean result = false; + CommonPersonObjectClient currentclient = (CommonPersonObjectClient) client; +// AllCommonsRepository allElcoRepository = new AllCommonsRepository("elco"); + if(!result) { + if(currentclient.getDetails().get("namaLengkap") != null) { + if (currentclient.getDetails().get("namaLengkap").toLowerCase().contains(criteria.toLowerCase())) { + result = true; + } + } + } + + return result; + } +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/giziIbu/IbuServiceModeOption.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/giziIbu/IbuServiceModeOption.java new file mode 100644 index 0000000..9215764 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/giziIbu/IbuServiceModeOption.java @@ -0,0 +1,81 @@ +package org.ei.opensrp.gizi.giziIbu; + +import android.view.View; + +import org.ei.opensrp.Context; +import org.ei.opensrp.gizi.R; +import org.ei.opensrp.provider.SmartRegisterClientsProvider; +import org.ei.opensrp.view.contract.ANCSmartRegisterClient; +import org.ei.opensrp.view.contract.ChildSmartRegisterClient; +import org.ei.opensrp.view.contract.FPSmartRegisterClient; +import org.ei.opensrp.view.contract.pnc.PNCSmartRegisterClient; +import org.ei.opensrp.view.dialog.ServiceModeOption; +import org.ei.opensrp.view.viewHolder.NativeANCSmartRegisterViewHolder; +import org.ei.opensrp.view.viewHolder.NativeChildSmartRegisterViewHolder; +import org.ei.opensrp.view.viewHolder.NativeFPSmartRegisterViewHolder; +import org.ei.opensrp.view.viewHolder.NativePNCSmartRegisterViewHolder; + +import static org.ei.opensrp.view.activity.SecuredNativeSmartRegisterActivity.ClientsHeaderProvider; + +public class IbuServiceModeOption extends ServiceModeOption { + + public IbuServiceModeOption(SmartRegisterClientsProvider provider) { + super(provider); + } + + @Override + public String name() { + return Context.getInstance().getStringResource(R.string.test_register); + } + + @Override + public ClientsHeaderProvider getHeaderProvider() { + return new ClientsHeaderProvider() { + @Override + public int count() { + return 6; + } + + @Override + public int weightSum() { + return 200; + } + + @Override + public int[] weights() { + return new int[]{20,42,40,39,45,14}; + } + + @Override + public int[] headerTextResourceIds() { + return new int[]{ + R.string.header_edit,R.string.detail_ibu,R.string.anthopometri,R.string.hasil_lab,R.string.post_partum_care,R.string.header_edit + }; + } + }; + } + + @Override + public void setupListView(ChildSmartRegisterClient client, + NativeChildSmartRegisterViewHolder viewHolder, + View.OnClickListener clientSectionClickListener) { + + } + + @Override + public void setupListView(ANCSmartRegisterClient client, NativeANCSmartRegisterViewHolder viewHolder, View.OnClickListener clientSectionClickListener) { + + } + + @Override + public void setupListView(FPSmartRegisterClient client, NativeFPSmartRegisterViewHolder viewHolder, View.OnClickListener clientSectionClickListener) { + + } + + @Override + public void setupListView(PNCSmartRegisterClient client, NativePNCSmartRegisterViewHolder viewHolder, View.OnClickListener clientSectionClickListener) { + + } + + +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/giziIbu/IbuSmartClientsProvider.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/giziIbu/IbuSmartClientsProvider.java new file mode 100644 index 0000000..1ffb834 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/giziIbu/IbuSmartClientsProvider.java @@ -0,0 +1,309 @@ +package org.ei.opensrp.gizi.giziIbu; + +import android.app.Activity; +import android.content.Context; +import android.graphics.drawable.Drawable; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.AbsListView; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import org.ei.opensrp.commonregistry.AllCommonsRepository; +import org.ei.opensrp.commonregistry.CommonPersonObject; +import org.ei.opensrp.commonregistry.CommonPersonObjectClient; +import org.ei.opensrp.commonregistry.CommonPersonObjectController; +import org.ei.opensrp.cursoradapter.SmartRegisterCLientsProviderForCursorAdapter; +import org.ei.opensrp.gizi.R; +import org.ei.opensrp.gizi.gizi.GiziDetailActivity; +import org.ei.opensrp.repository.DetailsRepository; +import org.ei.opensrp.service.AlertService; +import org.ei.opensrp.util.OpenSRPImageLoader; +import org.ei.opensrp.view.activity.DrishtiApplication; +import org.ei.opensrp.view.contract.SmartRegisterClient; +import org.ei.opensrp.view.contract.SmartRegisterClients; +import org.ei.opensrp.view.dialog.FilterOption; +import org.ei.opensrp.view.dialog.ServiceModeOption; +import org.ei.opensrp.view.dialog.SortOption; +import org.ei.opensrp.view.viewHolder.OnClickFormLauncher; + +import java.io.File; +import java.text.SimpleDateFormat; +import java.util.Map; + +import static android.view.ViewGroup.LayoutParams.MATCH_PARENT; + +/** + * Created by user on 2/12/15. + */ +public class IbuSmartClientsProvider implements SmartRegisterCLientsProviderForCursorAdapter { + private static final String TAG = IbuSmartClientsProvider.class.getSimpleName(); + private final LayoutInflater inflater; + private final Context context; + private final View.OnClickListener onClickListener; + private Drawable iconPencilDrawable; + private final int txtColorBlack; + private final AbsListView.LayoutParams clientViewLayoutParams; + + protected CommonPersonObjectController controller; + + AlertService alertService; + private String bindobject; + private String entityid; + + public IbuSmartClientsProvider(Context context, + View.OnClickListener onClickListener, + AlertService alertService) { + this.onClickListener = onClickListener; +// this.controller = controller; + this.context = context; + this.alertService = alertService; + this.inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + + clientViewLayoutParams = new AbsListView.LayoutParams(MATCH_PARENT, + (int) context.getResources().getDimension(org.ei.opensrp.R.dimen.list_item_height)); + txtColorBlack = context.getResources().getColor(org.ei.opensrp.R.color.text_black); + + } + + @Override + public void getView(SmartRegisterClient smartRegisterClient, View convertView) { + ViewHolder viewHolder; + CommonPersonObjectClient pc = (CommonPersonObjectClient) smartRegisterClient; + + if(convertView.getTag() == null || !(convertView.getTag() instanceof ViewHolder)){ + viewHolder = new ViewHolder(); + viewHolder.profilelayout = (LinearLayout)convertView.findViewById(R.id.profile_info_layout); + + viewHolder.namaLengkap = (TextView)convertView.findViewById(R.id.giziIbuMotherName); + viewHolder.namaSuami = (TextView) convertView.findViewById(R.id.giziIbuHusbandName); + viewHolder.dusun = (TextView) convertView.findViewById(R.id.giziIbuSubVilage); + viewHolder.umur = (TextView)convertView.findViewById(R.id.giziIbuAge); + viewHolder.tanggalLahir = (TextView) convertView.findViewById(R.id.giziIbuDateOfBirth); + + viewHolder.lastANCVisit = (TextView)convertView.findViewById(R.id.giziIbuVisitDate); + viewHolder.HPHT = (TextView)convertView.findViewById(R.id.gizi_usia_kandungan); + viewHolder.lila = (TextView)convertView.findViewById(R.id.gizi_ibu_lila); + viewHolder.hbLevel = (TextView)convertView.findViewById(R.id.gizi_ibu_HB); + viewHolder.weight = (TextView)convertView.findViewById(R.id.gizi_ibu_bb); + + viewHolder.sistolik = (TextView)convertView.findViewById(R.id.gizi_ibu_sistolik); + viewHolder.diastolik = (TextView)convertView.findViewById(R.id.gizi_ibu_diastolik); + viewHolder.vitaminA2 = (TextView)convertView.findViewById(R.id.gizi_ibu_VitaminA2); + viewHolder.vitaminA24 = (TextView)convertView.findViewById(R.id.gizi_ibu_VitaminA24); + +// viewHolder.weightText = (TextView)convertView.findViewById(R.id.weightSchedule); +// viewHolder.weightLogo = (ImageView)convertView.findViewById(R.id.weightSymbol); +// viewHolder.heightText = (TextView)convertView.findViewById(R.id.heightSchedule); +// viewHolder.heightLogo = (ImageView)convertView.findViewById(R.id.heightSymbol); +// viewHolder.vitALogo = (ImageView)convertView.findViewById(R.id.vitASymbol); +// viewHolder.vitAText = (TextView)convertView.findViewById(R.id.vitASchedule); +// viewHolder.antihelminticLogo = (ImageView)convertView.findViewById(R.id.antihelminticSymbol); +// viewHolder.antihelminticText = (TextView)convertView.findViewById(R.id.antihelminticText); + +// viewHolder.profilepic =(ImageView)convertView.findViewById(R.id.profilepic); +// viewHolder.follow_up = (ImageButton)convertView.findViewById(R.id.btn_edit); + viewHolder.profilepic =(ImageView)convertView.findViewById(R.id.profilepic); + +// final ImageView kiview = (ImageView)convertView.findViewById(R.id.profilepic); +// if (pc.getDetails().get("profilepic") != null) { +//// KIDetailActivity.setImagetoHolderFromUri((Activity) context, pc.getDetails().get("profilepic"), kiview, R.mipmap.woman_placeholder); +// kiview.setTag(smartRegisterClient); +// } +// else { +// viewHolder.profilepic.setImageDrawable(context.getResources().getDrawable(R.drawable.woman_placeholder)); +// } + + //start profile image + viewHolder.profilepic.setTag(R.id.entity_id, pc.getColumnmaps().get("_id"));//required when saving file to disk +// if(pc.getCaseId()!=null){//image already in local storage most likey ): + + //set profile image by passing the client id.If the image doesn't exist in the image repository then download and save locally +// DrishtiApplication.getCachedImageLoaderInstance().getImageByClientId(pc.getCaseId(), +// OpenSRPImageLoader.getStaticImageListener(viewHolder.profilepic, R.mipmap.woman_placeholder, R.mipmap.woman_placeholder)); +// } + viewHolder.profilepic.setTag(R.id.entity_id, pc.getColumnmaps().get("_id"));//required when saving file to disk + util.formula.Support.setImagetoHolderFromUri((Activity) context, + DrishtiApplication.getAppDir() + File.separator + pc.getDetails().get("base_entity_id") + ".JPEG", + viewHolder.profilepic, R.mipmap.woman_placeholder); + + + convertView.setTag(viewHolder); + } else { + viewHolder = (ViewHolder) convertView.getTag(); + } + +// viewHolder.follow_up.setOnClickListener(onClickListener); +// viewHolder.follow_up.setTag(smartRegisterClient); + viewHolder.profilelayout.setOnClickListener(onClickListener); + viewHolder.profilelayout.setTag(smartRegisterClient); + + // IMPORTANT : data has 2 type: columnMaps and details + + AllCommonsRepository allancRepository = org.ei.opensrp.Context.getInstance().allCommonsRepositoryobjects("ec_ibu");// get all data from ec_ibu table + CommonPersonObject ancobject = allancRepository.findByCaseID(pc.entityId()); // get all data related to entity id and transform it into CommonPersonObject + + DetailsRepository detailsRepository = org.ei.opensrp.Context.getInstance().detailsRepository(); // gather all details from repository + Map details = detailsRepository.getAllDetailsForClient(pc.entityId()); // get specific detail from all details based on entity id + details.putAll(ancobject.getColumnmaps()); // combine all columnMaps and details into 1 object. + + if (pc.getDetails() != null) { // used to update client details with details built on previous step + pc.getDetails().putAll(details); + } else { + pc.setDetails(details); + } + + viewHolder.namaLengkap.setText(getColumnMaps("namalengkap", pc)); + viewHolder.namaSuami.setText(getColumnMaps("namaSuami", pc)); + viewHolder.dusun.setText(getDetails("posyandu", pc)); + viewHolder.tanggalLahir.setText(getDetails("tanggalLahir",pc).length()>10?getDetails("tanggalLahir",pc).substring(0,10) : "-"); + viewHolder.umur.setText(String.format("%s %s", getDetails("umur", pc), context.getString(R.string.years_unit))); + + viewHolder.lastANCVisit.setText(String.format("%s: %s", context.getString(R.string.kunjunganTerakhir), getDetails("ancDate", pc))); + int usiaKandungan = usiaKandungan(getDetails("tanggalHPHT",pc),getDetails("ancDate",pc)); + viewHolder.HPHT.setText(String.format("%s: %s%s", context.getString(R.string.usiaKandungan), usiaKandungan != -1 + ? Integer.toString(usiaKandungan) + : "-", context.getString(R.string.str_weeks))); + viewHolder.lila.setText(String.format("%s: %s cm", context.getString(R.string.lila), getDetails("hasilPemeriksaanLILA", pc))); + viewHolder.hbLevel.setText(String.format("%s: %s", context.getString(R.string.hb_level), getDetails("laboratoriumPeriksaHbHasil", pc))); + viewHolder.weight.setText(String.format("%s %s %s", context.getString(R.string.str_weight), getDetails("bbKg", pc), context.getString(R.string.weight_unit))); + + viewHolder.sistolik.setText(String.format("%s: %s", context.getString(R.string.sistolik), getDetails("tandaVitalTDSistolik", pc))); + viewHolder.diastolik.setText(String.format("%s: %s", context.getString(R.string.diastolik), getDetails("tandaVitalTDDiastolik", pc))); + + + viewHolder.vitaminA2.setText(String.format("%s%s", context.getString(R.string.vitamin_a_pnc_2), getDetails("vitaminA2jamPP", pc))); + viewHolder.vitaminA24.setText(String.format("%s%s", context.getString(R.string.vitamin_a_pnc_24), getDetails("vitaminA24jamPP", pc))); + //start profile image + viewHolder.profilepic.setTag(R.id.entity_id, pc.getColumnmaps().get("_id"));//required when saving file to disk +// if(pc.getCaseId()!=null){//image already in local storage most likey ): + //set profile image by passing the client id.If the image doesn't exist in the image repository then download and save locally +// DrishtiApplication.getCachedImageLoaderInstance().getImageByClientId(pc.getCaseId(), OpenSRPImageLoader.getStaticImageListener(viewHolder.profilepic, R.mipmap.woman_placeholder, R.mipmap.woman_placeholder)); +// } + //end profile image + + viewHolder.profilepic.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { +// FlurryFacade.logEvent("taking_anak_pictures_on_child_detail_view"); +// bindobject = "anak"; +// entityid = pc.entityId(); +// android.util.Log.e(TAG, "onClick: " + entityid); +// dispatchTakePictureIntent(childview); + + } + }); + } + public SmartRegisterClients getClients() { + return controller.getClients(); + } + + @Override + public SmartRegisterClients updateClients(FilterOption villageFilter, ServiceModeOption serviceModeOption, + FilterOption searchFilter, SortOption sortOption) { + return getClients().applyFilter(villageFilter, serviceModeOption, searchFilter, sortOption); + } + + @Override + public void onServiceModeSelected(ServiceModeOption serviceModeOption) { + // do nothing. + } + + @Override + public OnClickFormLauncher newFormLauncher(String formName, String entityId, String metaData) { + return null; + } + + public LayoutInflater inflater() { + return inflater; + } + @Override + public View inflatelayoutForCursorAdapter() { + View View = inflater().inflate(R.layout.smart_register_gizi_ibu_client, null); + return View; + } + + private String getColumnMaps(String tag, CommonPersonObjectClient client){ + return client.getColumnmaps().get(tag) != null ? client.getColumnmaps().get(tag) : "-"; + } + + private String getDetails(String tag, CommonPersonObjectClient client){ + return client.getDetails().get(tag) != null ? client.getDetails().get(tag) : "-"; + } + + private int usiaKandungan(String hpht, String lastANC){ + return (hpht.equals("") || lastANC.equals("")) ? -1 : dailyUnitCalculationOf(hpht,lastANC); + } + + private int dailyUnitCalculationOf(String dateFrom,String dateTo){ + if(dateFrom.length()<10 || dateTo.length()<10) + return -1; + String[]d1 = dateFrom.split("-"); + String[]d2 = dateTo.split("-"); + + int day1=Integer.parseInt(d1[2]),month1=Integer.parseInt(d1[1]),year1=Integer.parseInt(d1[0]); + int day2=Integer.parseInt(d2[2]),month2=Integer.parseInt(d2[1]),year2=Integer.parseInt(d2[0]); + + if (month2dayLength[month1-1]){ +// day1 = 1; +// month1++; +// } +// if (month1 > 12){ +// month1=1; +// year1++; +// dayLength[1] = year1 % 4 == 0 ? 29:28; +// } +// } + + return (((year2-year1)*52) + ((month2-month1)* 4 + ((month2-month1)/3)) + ((day2-day1)/7)); + } + + class ViewHolder { + + TextView namaLengkap, tanggalLahir, umur, dusun, namaSuami; + + LinearLayout profilelayout; + ImageView profilepic; + + TextView HPHT, lastANCVisit, lila, hbLevel, weight; + + TextView sistolik, diastolik, vitaminA2, vitaminA24; + +// TextView stunting_status; +// TextView wasting_status; +// TextView absentAlert; +// TextView weightText; +// ImageView weightLogo; +// TextView heightText; +// ImageView heightLogo; +// ImageView vitALogo; +// TextView vitAText; +// ImageView antihelminticLogo; +// TextView antihelminticText; + + + public void setVitAVisibility(){ + int month = Integer.parseInt(new SimpleDateFormat("MM").format(new java.util.Date())); + int visibility = month == 2 || month == 8 ? View.VISIBLE : View.INVISIBLE; +// vitALogo.setVisibility(visibility); +// vitAText.setVisibility(visibility); + } +// +// public void setAntihelminticVisibility(int visibility){ +// antihelminticLogo.setVisibility(visibility); +// antihelminticText.setVisibility(visibility); +// } + } +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/giziIbu/IbuSmartRegisterActivity.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/giziIbu/IbuSmartRegisterActivity.java new file mode 100644 index 0000000..fdd9498 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/giziIbu/IbuSmartRegisterActivity.java @@ -0,0 +1,433 @@ +package org.ei.opensrp.gizi.giziIbu; + +import android.app.AlertDialog; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.pm.ActivityInfo; +import android.os.Bundle; +import android.support.v4.app.FragmentPagerAdapter; +import android.support.v4.view.ViewPager; +import android.util.Log; + +import com.flurry.android.FlurryAgent; + +import org.ei.opensrp.domain.form.FieldOverrides; +import org.ei.opensrp.domain.form.FormSubmission; +import org.ei.opensrp.gizi.LoginActivity; +import org.ei.opensrp.gizi.R; +import org.ei.opensrp.gizi.fragment.GiziIbuSmartRegisterFragment; +import org.ei.opensrp.gizi.fragment.GiziSmartRegisterFragment; +import org.ei.opensrp.gizi.gizi.FlurryFacade; +import org.ei.opensrp.gizi.gizi.KmsHandler; +import org.ei.opensrp.gizi.pageradapter.BaseRegisterActivityPagerAdapter; +import org.ei.opensrp.provider.SmartRegisterClientsProvider; +import org.ei.opensrp.service.ZiggyService; +import org.ei.opensrp.sync.ClientProcessor; +import org.ei.opensrp.util.FormUtils; +import org.ei.opensrp.view.activity.SecuredNativeSmartRegisterActivity; +import org.ei.opensrp.view.dialog.DialogOption; +import org.ei.opensrp.view.dialog.LocationSelectorDialogFragment; +import org.ei.opensrp.view.dialog.OpenFormOption; +import org.ei.opensrp.view.fragment.DisplayFormFragment; +import org.ei.opensrp.view.fragment.SecuredNativeSmartRegisterFragment; +import org.ei.opensrp.view.viewpager.OpenSRPViewPager; +import org.json.JSONException; +import org.json.JSONObject; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import butterknife.Bind; +import butterknife.ButterKnife; + +//import org.ei.opensrp.gizi.fragment.HouseHoldSmartRegisterFragment; + +public class IbuSmartRegisterActivity extends SecuredNativeSmartRegisterActivity implements + LocationSelectorDialogFragment.OnLocationSelectedListener{ + + SimpleDateFormat timer = new SimpleDateFormat("hh:mm:ss"); + + public static final String TAG = "GiziIbuActivity"; + @Bind(R.id.view_pager) + OpenSRPViewPager mPager; + private FragmentPagerAdapter mPagerAdapter; + private int currentPage; + private ClientProcessor clientProcessor; + private String[] formNames = new String[]{}; + private android.support.v4.app.Fragment mBaseFragment = null; + + ZiggyService ziggyService; + + GiziIbuSmartRegisterFragment nf = new GiziIbuSmartRegisterFragment(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + ButterKnife.bind(this); + + setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); + String GiziStart = timer.format(new Date()); + Map Gizi = new HashMap(); + Gizi.put("start", GiziStart); +// FlurryAgent.logEvent("Gizi_dashboard",Gizi, true ); + // FlurryFacade.logEvent("Gizi_dashboard"); + + formNames = this.buildFormNameList(); + + // WD + Bundle extras = getIntent().getExtras(); + if (extras != null) { + boolean mode_face = extras.getBoolean("org.ei.opensrp.indonesia.face.face_mode"); + String base_id = extras.getString("org.ei.opensrp.indonesia.face.base_id"); + double proc_time = extras.getDouble("org.ei.opensrp.indonesia.face.proc_time"); +// Log.e(TAG, "onCreate: "+proc_time ); + + if (mode_face) { + nf.setCriteria(base_id); + mBaseFragment = new GiziIbuSmartRegisterFragment(); + + Log.e(TAG, "onCreate: id " + base_id); +// showToast("id "+base_id); + AlertDialog.Builder builder = new AlertDialog.Builder(this); + builder.setTitle("Is it Right Person ?"); +// builder.setTitle("Is it Right Clients ?" + base_id); +// builder.setTitle("Is it Right Clients ?"+ pc.getName()); + + // TODO : get name by base_id +// builder.setMessage("Process Time : " + proc_time + " s"); + + builder.setNegativeButton("CANCEL", listener ); + builder.setPositiveButton("YES", listener ); + builder.show(); + } + } else { + mBaseFragment = new GiziIbuSmartRegisterFragment(); + } + + + // Instantiate a ViewPager and a PagerAdapter. + mPagerAdapter = new BaseRegisterActivityPagerAdapter(getSupportFragmentManager(), formNames, mBaseFragment); + mPager.setOffscreenPageLimit(formNames.length); + mPager.setAdapter(mPagerAdapter); + mPager.setOnPageChangeListener(new ViewPager.SimpleOnPageChangeListener() { + @Override + public void onPageSelected(int position) { + currentPage = position; + onPageChanged(position); + } + }); + + ziggyService = context().ziggyService(); + } + public void onPageChanged(int page){ + setRequestedOrientation(page == 0 ? ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE : ActivityInfo.SCREEN_ORIENTATION_PORTRAIT); + LoginActivity.setLanguage(); + } + + @Override + protected DefaultOptionsProvider getDefaultOptionsProvider() {return null;} + + @Override + protected void setupViews() { + + + } + + @Override + protected void onResumption(){} + + @Override + protected NavBarOptionsProvider getNavBarOptionsProvider() {return null;} + + @Override + protected SmartRegisterClientsProvider clientsProvider() {return null;} + + @Override + protected void onInitialization() { + context().formSubmissionRouter().getHandlerMap().put("kunjungan_gizi", new KmsHandler()); + } + + @Override + public void startRegistration() { + } + + public DialogOption[] getEditOptions() { + return new DialogOption[]{ + new OpenFormOption("Kunjungan Per Bulan ", "kunjungan_gizi", formController), + new OpenFormOption("Edit Registrasi Gizi ", "edit_registrasi_gizi", formController), + new OpenFormOption("Close Form","close_form",formController) + }; + } + + + @Override + public void saveFormSubmission(String formSubmission, String id, String formName, JSONObject fieldOverrides){ + Log.v("fieldoverride", fieldOverrides.toString()); + // save the form + try{ + FormUtils formUtils = FormUtils.getInstance(getApplicationContext()); + FormSubmission submission = formUtils.generateFormSubmisionFromXMLString(id, formSubmission, formName, fieldOverrides); + ziggyService.saveForm(getParams(submission), submission.instance()); + ClientProcessor.getInstance(getApplicationContext()).processClient(); + + context().formSubmissionService().updateFTSsearch(submission); + context().formSubmissionRouter().handleSubmission(submission, formName); + //switch to forms list fragment + switchToBaseFragment(formSubmission); // Unnecessary!! passing on data + + }catch (Exception e){ + // TODO: show error dialog on the formfragment if the submission fails + DisplayFormFragment displayFormFragment = getDisplayFormFragmentAtIndex(currentPage); + if (displayFormFragment != null) { + displayFormFragment.hideTranslucentProgressDialog(); + } + e.printStackTrace(); + } + // KMSCalculation(); + } + + /*@Override + public void saveFormSubmission(String formSubmission, String id, String formName, JSONObject fieldOverrides){ + Log.v("fieldoverride", fieldOverrides.toString()); + // save the form + try{ + FormUtils formUtils = FormUtils.getInstance(getApplicationContext()); + FormSubmission submission = formUtils.generateFormSubmisionFromXMLString(id, formSubmission, formName, fieldOverrides); + + ziggyService.saveForm(getParams(submission), submission.instance()); + + //switch to forms list fragment + switchToBaseFragment(formSubmission); // Unnecessary!! passing on data + + }catch (Exception e){ + // TODO: show error dialog on the formfragment if the submission fails + DisplayFormFragment displayFormFragment = getDisplayFormFragmentAtIndex(currentPage); + if (displayFormFragment != null) { + displayFormFragment.hideTranslucentProgressDialog(); + } + e.printStackTrace(); + } + *//* if(formName.equals("registrasi_gizi")) { + saveuniqueid(); + }*//* + //end capture flurry log for FS + String end = timer.format(new Date()); + Map FS = new HashMap(); + FS.put("end", end); + FlurryAgent.logEvent(formName,FS, true); + + } +*/ + @Override + public void OnLocationSelected(String locationJSONString) { + JSONObject combined = null; + + try { + JSONObject locationJSON = new JSONObject(locationJSONString); + // JSONObject uniqueId = new JSONObject(context().uniqueIdController().getUniqueIdJson()); + + combined = locationJSON; + // Iterator iter = uniqueId.keys(); + + /* while (iter.hasNext()) { + String key = iter.next(); + combined.put(key, uniqueId.get(key)); + } +*/ + } catch (JSONException e) { + e.printStackTrace(); + } + + if (combined != null) { + FieldOverrides fieldOverrides = new FieldOverrides(combined.toString()); + startFormActivity("registrasi_gizi", null, fieldOverrides.getJSONString()); + } + } + + /* public void saveuniqueid() { + try { + JSONObject uniqueId = new JSONObject(context().uniqueIdController().getUniqueIdJson()); + String uniq = uniqueId.getString("unique_id"); + context().uniqueIdController().updateCurrentUniqueId(uniq); + + } catch (JSONException e) { + e.printStackTrace(); + } + }*/ + + @Override + public void startFormActivity(String formName, String entityId, String metaData) { + FlurryFacade.logEvent(formName); +// Log.v("fieldoverride", metaData); + try { + int formIndex = FormUtils.getIndexForFormName(formName, formNames) + 1; // add the offset + if (entityId != null || metaData != null){ + String data = null; + //check if there is previously saved data for the form + data = getPreviouslySavedDataForForm(formName, metaData, entityId); + if (data == null){ + data = FormUtils.getInstance(getApplicationContext()).generateXMLInputForFormWithEntityId(entityId, formName, metaData); + } + + DisplayFormFragment displayFormFragment = getDisplayFormFragmentAtIndex(formIndex); + if (displayFormFragment != null) { + displayFormFragment.setFormData(data); + displayFormFragment.setRecordId(entityId); + displayFormFragment.setFieldOverides(metaData); + } + } + + mPager.setCurrentItem(formIndex, false); //Don't animate the view on orientation change the view disapears + + }catch (Exception e){ + e.printStackTrace(); + } + + } + + /*@Override + public void startFormActivity(String formName, String entityId, String metaData) { + // Log.v("fieldoverride", metaData); + String start = timer.format(new Date()); + Map FS = new HashMap(); + FS.put("start", start); + FlurryAgent.logEvent(formName,FS, true ); + //FlurryFacade.logEvent(formName); + try { + int formIndex = FormUtils.getIndexForFormName(formName, formNames) + 1; // add the offset + if (entityId != null || metaData != null){ + String data = null; + //check if there is previously saved data for the form + data = getPreviouslySavedDataForForm(formName, metaData, entityId); + if (data == null){ + data = FormUtils.getInstance(getApplicationContext()).generateXMLInputForFormWithEntityId(entityId, formName, metaData); + } + + DisplayFormFragment displayFormFragment = getDisplayFormFragmentAtIndex(formIndex); + if (displayFormFragment != null) { + displayFormFragment.setFormData(data); + displayFormFragment.loadFormData(); + displayFormFragment.setRecordId(entityId); + displayFormFragment.setFieldOverides(metaData); + } + } + + mPager.setCurrentItem(formIndex, false); //Don't animate the view on orientation change the view disapears + + }catch (Exception e){ + e.printStackTrace(); + } + + }*/ + + public void switchToBaseFragment(final String data){ + final int prevPageIndex = currentPage; + runOnUiThread(new Runnable() { + @Override + public void run() { + mPager.setCurrentItem(0, false); + SecuredNativeSmartRegisterFragment registerFragment = (SecuredNativeSmartRegisterFragment) findFragmentByPosition(0); + if (registerFragment != null && data != null) { + registerFragment.refreshListView(); + } + + //hack reset the form + DisplayFormFragment displayFormFragment = getDisplayFormFragmentAtIndex(prevPageIndex); + if (displayFormFragment != null) { + displayFormFragment.hideTranslucentProgressDialog(); + displayFormFragment.setFormData(null); + + } + + displayFormFragment.setRecordId(null); + } + }); + + } + + public android.support.v4.app.Fragment findFragmentByPosition(int position) { + FragmentPagerAdapter fragmentPagerAdapter = mPagerAdapter; + return getSupportFragmentManager().findFragmentByTag("android:switcher:" + mPager.getId() + ":" + fragmentPagerAdapter.getItemId(position)); + } + + public DisplayFormFragment getDisplayFormFragmentAtIndex(int index) { + return (DisplayFormFragment)findFragmentByPosition(index); + } + + @Override + public void onBackPressed() { + nf.setCriteria(""); + if (currentPage != 0) { + switchToBaseFragment(null); + } else if (currentPage == 0) { + super.onBackPressed(); // allow back key only if we are + } + } + + private String[] buildFormNameList(){ + List formNames = new ArrayList(); + formNames.add("registrasi_gizi"); + formNames.add("kunjungan_gizi"); + formNames.add("edit_registrasi_gizi"); + formNames.add("close_form"); + + + // formNames.add("census_enrollment_form"); +// DialogOption[] options = getEditOptions(); +// for (int i = 0; i < options.length; i++){ +// formNames.add(((OpenFormOption) options[i]).getFormName()); +// } + return formNames.toArray(new String[formNames.size()]); + } + + @Override + protected void onPause() { + super.onPause(); + retrieveAndSaveUnsubmittedFormData(); + /* String GiziEnd = timer.format(new Date()); + Map Gizi = new HashMap(); + Gizi.put("end", GiziEnd); + FlurryAgent.logEvent("Gizi_dashboard",Gizi, true );*/ + } + + public void retrieveAndSaveUnsubmittedFormData(){ + if (currentActivityIsShowingForm()){ + DisplayFormFragment formFragment = getDisplayFormFragmentAtIndex(currentPage); + formFragment.saveCurrentFormData(); + } + } + + private boolean currentActivityIsShowingForm(){ + return currentPage != 0; + } + + private DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + + if (which == -1 ){ + nf.setCriteria("!"); + currentPage = 0; + Log.e(TAG, "onClick: YES " + currentPage); + FlurryAgent.logEvent(TAG+"search_by_face OK", true); + + } else { + nf.setCriteria(""); + onBackPressed(); + Log.e(TAG, "onClick: NO " + currentPage); + FlurryAgent.logEvent(TAG + "search_by_face NOK", true); + + Intent intent= new Intent(IbuSmartRegisterActivity.this, IbuSmartRegisterActivity.class); + startActivity(intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT)); + } + + + } + }; + +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/giziIbu/KICommonObjectFilterOption.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/giziIbu/KICommonObjectFilterOption.java new file mode 100644 index 0000000..e286013 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/giziIbu/KICommonObjectFilterOption.java @@ -0,0 +1,41 @@ +package org.ei.opensrp.gizi.giziIbu; + +import org.apache.commons.lang3.StringUtils; +import org.ei.opensrp.cursoradapter.CursorFilterOption; +import org.ei.opensrp.view.contract.SmartRegisterClient; + +public class KICommonObjectFilterOption implements CursorFilterOption { + public final String criteria; + public final String fieldname; + private final String filterOptionName; + private final String tablename; + + @Override + public String filter() { + if(StringUtils.isNotBlank(fieldname) && !fieldname.equals("location_name")){ + return " AND " + tablename+ ".base_entity_id IN (SELECT DISTINCT base_entity_id FROM ec_details WHERE key MATCH '"+fieldname+"' INTERSECT SELECT DISTINCT base_entity_id FROM ec_details WHERE value MATCH '"+criteria+"' ) "; + } else{ + return " AND " + tablename+ ".base_entity_id IN (SELECT DISTINCT base_entity_id FROM ec_details WHERE value MATCH '"+criteria+"' ) "; + } + } + + + + public KICommonObjectFilterOption(String criteria, String fieldname, String filteroptionname, String tablename) { + this.criteria = criteria; + this.fieldname = fieldname; + this.filterOptionName = filteroptionname; + this.tablename = tablename; + } + + @Override + public String name() { + return filterOptionName; + } + + @Override + public boolean filter(SmartRegisterClient client) { + + return false; + } +} diff --git a/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/pageradapter/BaseRegisterActivityPagerAdapter.java b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/pageradapter/BaseRegisterActivityPagerAdapter.java new file mode 100644 index 0000000..6c019e4 --- /dev/null +++ b/opensrp-gizi/src/main/java/org/ei/opensrp/gizi/pageradapter/BaseRegisterActivityPagerAdapter.java @@ -0,0 +1,71 @@ +package org.ei.opensrp.gizi.pageradapter; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.v4.app.FragmentManager; +import android.support.v4.app.FragmentPagerAdapter; + +import org.ei.opensrp.view.fragment.DisplayFormFragment; + + + +/** + * Created by koros on 11/2/15. + */ +public class BaseRegisterActivityPagerAdapter extends FragmentPagerAdapter { + public static final String ARG_PAGE = "page"; + String[] dialogOptions; + Fragment mBaseFragment; + Fragment mProfileFragment; + public int offset = 0; + + public BaseRegisterActivityPagerAdapter(FragmentManager fragmentManager, String[] dialogOptions, Fragment baseFragment) { + super(fragmentManager); + this.dialogOptions = dialogOptions; + this.mBaseFragment = baseFragment; + offset += 1; + } + public BaseRegisterActivityPagerAdapter(FragmentManager fragmentManager, String[] dialogOptions, Fragment baseFragment, Fragment mProfileFragment) { + super(fragmentManager); + this.dialogOptions = dialogOptions; + this.mBaseFragment = baseFragment; + this.mProfileFragment = mProfileFragment; + offset += 2; + } + + + @Override + public Fragment getItem(int position) { + Fragment fragment = null; + switch (position) { + case 0: + fragment = mBaseFragment; + break; + case 1: + if(mProfileFragment != null) { + fragment = mProfileFragment; + break; + } + default: + String formName = dialogOptions[position - offset]; // account for the base fragment + DisplayFormFragment f = new DisplayFormFragment(); + f.setFormName(formName); + fragment = f; + break; + } + + Bundle args = new Bundle(); + args.putInt(ARG_PAGE, position); + fragment.setArguments(args); + return fragment; + } + + @Override + public int getCount() { + return dialogOptions.length + offset; // index 0 is always occupied by the base fragment + } + + public int offset() { + return offset; + } + +} \ No newline at end of file diff --git a/opensrp-gizi/src/main/java/util/AsyncTask.java b/opensrp-gizi/src/main/java/util/AsyncTask.java new file mode 100644 index 0000000..061fc91 --- /dev/null +++ b/opensrp-gizi/src/main/java/util/AsyncTask.java @@ -0,0 +1,693 @@ +/* + * Copyright (C) 2008 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package util; + +import android.annotation.TargetApi; +import android.os.Handler; +import android.os.Message; +import android.os.Process; + +import java.util.ArrayDeque; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.Callable; +import java.util.concurrent.CancellationException; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Executor; +import java.util.concurrent.Executors; +import java.util.concurrent.FutureTask; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.TimeoutException; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; + +/** + * ************************************* + * Copied from JB release framework: + * https://android.googlesource.com/platform/frameworks/base/+/jb-release/core/java/android/os/AsyncTask.java + * + * so that threading behavior on all OS versions is the same and we can tweak behavior by using + * executeOnExecutor() if needed. + * + * There are 3 changes in this copy of AsyncTask: + * -pre-HC a single thread executor is used for serial operation + * (Executors.newSingleThreadExecutor) and is the default + * -the default THREAD_POOL_EXECUTOR was changed to use DiscardOldestPolicy + * -a new fixed thread pool called DUAL_THREAD_EXECUTOR was added + * ************************************* + * + *

AsyncTask enables proper and easy use of the UI thread. This class allows to + * perform background operations and publish results on the UI thread without + * having to manipulate threads and/or handlers.

+ * + *

AsyncTask is designed to be a helper class around {@link Thread} and {@link Handler} + * and does not constitute a generic threading framework. AsyncTasks should ideally be + * used for short operations (a few seconds at the most.) If you need to keep threads + * running for long periods of time, it is highly recommended you use the various APIs + * provided by the java.util.concurrent pacakge such as {@link Executor}, + * {@link ThreadPoolExecutor} and {@link FutureTask}.

+ * + *

An asynchronous task is defined by a computation that runs on a background thread and + * whose result is published on the UI thread. An asynchronous task is defined by 3 generic + * types, called Params, Progress and Result, + * and 4 steps, called onPreExecute, doInBackground, + * onProgressUpdate and onPostExecute.

+ * + *
+ *

Developer Guides

+ *

For more information about using tasks and threads, read the + * Processes and + * Threads developer guide.

+ *
+ * + *

Usage

+ *

AsyncTask must be subclassed to be used. The subclass will override at least + * one method ({@link #doInBackground}), and most often will override a + * second one ({@link #onPostExecute}.)

+ * + *

Here is an example of subclassing:

+ *
+ * private class DownloadFilesTask extends AsyncTask<URL, Integer, Long> {
+ *     protected Long doInBackground(URL... urls) {
+ *         int count = urls.length;
+ *         long totalSize = 0;
+ *         for (int i = 0; i < count; i++) {
+ *             totalSize += Downloader.downloadFile(urls[i]);
+ *             publishProgress((int) ((i / (float) count) * 100));
+ *             // Escape early if cancel() is called
+ *             if (isCancelled()) break;
+ *         }
+ *         return totalSize;
+ *     }
+ *
+ *     protected void onProgressUpdate(Integer... progress) {
+ *         setProgressPercent(progress[0]);
+ *     }
+ *
+ *     protected void onPostExecute(Long result) {
+ *         showDialog("Downloaded " + result + " bytes");
+ *     }
+ * }
+ * 
+ * + *

Once created, a task is executed very simply:

+ *
+ * new DownloadFilesTask().execute(url1, url2, url3);
+ * 
+ * + *

AsyncTask's generic types

+ *

The three types used by an asynchronous task are the following:

+ *
    + *
  1. Params, the type of the parameters sent to the task upon + * execution.
  2. + *
  3. Progress, the type of the progress units published during + * the background computation.
  4. + *
  5. Result, the type of the result of the background + * computation.
  6. + *
+ *

Not all types are always used by an asynchronous task. To mark a type as unused, + * simply use the type {@link Void}:

+ *
+ * private class MyTask extends AsyncTask<Void, Void, Void> { ... }
+ * 
+ * + *

The 4 steps

+ *

When an asynchronous task is executed, the task goes through 4 steps:

+ *
    + *
  1. {@link #onPreExecute()}, invoked on the UI thread immediately after the task + * is executed. This step is normally used to setup the task, for instance by + * showing a progress bar in the user interface.
  2. + *
  3. {@link #doInBackground}, invoked on the background thread + * immediately after {@link #onPreExecute()} finishes executing. This step is used + * to perform background computation that can take a long time. The parameters + * of the asynchronous task are passed to this step. The result of the computation must + * be returned by this step and will be passed back to the last step. This step + * can also use {@link #publishProgress} to publish one or more units + * of progress. These values are published on the UI thread, in the + * {@link #onProgressUpdate} step.
  4. + *
  5. {@link #onProgressUpdate}, invoked on the UI thread after a + * call to {@link #publishProgress}. The timing of the execution is + * undefined. This method is used to display any form of progress in the user + * interface while the background computation is still executing. For instance, + * it can be used to animate a progress bar or show logs in a text field.
  6. + *
  7. {@link #onPostExecute}, invoked on the UI thread after the background + * computation finishes. The result of the background computation is passed to + * this step as a parameter.
  8. + *
+ * + *

Cancelling a task

+ *

A task can be cancelled at any time by invoking {@link #cancel(boolean)}. Invoking + * this method will cause subsequent calls to {@link #isCancelled()} to return true. + * After invoking this method, {@link #onCancelled(Object)}, instead of + * {@link #onPostExecute(Object)} will be invoked after {@link #doInBackground(Object[])} + * returns. To ensure that a task is cancelled as quickly as possible, you should always + * check the return value of {@link #isCancelled()} periodically from + * {@link #doInBackground(Object[])}, if possible (inside a loop for instance.)

+ * + *

Threading rules

+ *

There are a few threading rules that must be followed for this class to + * work properly:

+ *
    + *
  • The AsyncTask class must be loaded on the UI thread. This is done + * automatically as of {@link android.os.Build.VERSION_CODES#JELLY_BEAN}.
  • + *
  • The task instance must be created on the UI thread.
  • + *
  • {@link #execute} must be invoked on the UI thread.
  • + *
  • Do not call {@link #onPreExecute()}, {@link #onPostExecute}, + * {@link #doInBackground}, {@link #onProgressUpdate} manually.
  • + *
  • The task can be executed only once (an exception will be thrown if + * a second execution is attempted.)
  • + *
+ * + *

Memory observability

+ *

AsyncTask guarantees that all callback calls are synchronized in such a way that the following + * operations are safe without explicit synchronizations.

+ *
    + *
  • Set member fields in the constructor or {@link #onPreExecute}, and refer to them + * in {@link #doInBackground}. + *
  • Set member fields in {@link #doInBackground}, and refer to them in + * {@link #onProgressUpdate} and {@link #onPostExecute}. + *
+ * + *

Order of execution

+ *

When first introduced, AsyncTasks were executed serially on a single background + * thread. Starting with {@link android.os.Build.VERSION_CODES#DONUT}, this was changed + * to a pool of threads allowing multiple tasks to operate in parallel. Starting with + * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, tasks are executed on a single + * thread to avoid common application errors caused by parallel execution.

+ *

If you truly want parallel execution, you can invoke + * {@link #executeOnExecutor(Executor, Object[])} with + * {@link #THREAD_POOL_EXECUTOR}.

+ */ +public abstract class AsyncTask { + private static final String LOG_TAG = "AsyncTask"; + + private static final int CORE_POOL_SIZE = 5; + private static final int MAXIMUM_POOL_SIZE = 128; + private static final int KEEP_ALIVE = 1; + + private static final ThreadFactory sThreadFactory = new ThreadFactory() { + private final AtomicInteger mCount = new AtomicInteger(1); + + public Thread newThread(Runnable r) { + return new Thread(r, "AsyncTask #" + mCount.getAndIncrement()); + } + }; + + private static final BlockingQueue sPoolWorkQueue = + new LinkedBlockingQueue(10); + + /** + * An {@link Executor} that can be used to execute tasks in parallel. + */ + public static final Executor THREAD_POOL_EXECUTOR + = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, + TimeUnit.SECONDS, sPoolWorkQueue, sThreadFactory, + new ThreadPoolExecutor.DiscardOldestPolicy()); + + /** + * An {@link Executor} that executes tasks one at a time in serial + * order. This serialization is global to a particular process. + */ + public static final Executor SERIAL_EXECUTOR = Utils.hasHoneycomb() ? new SerialExecutor() : + Executors.newSingleThreadExecutor(sThreadFactory); + + public static final Executor DUAL_THREAD_EXECUTOR = + Executors.newFixedThreadPool(2, sThreadFactory); + + private static final int MESSAGE_POST_RESULT = 0x1; + private static final int MESSAGE_POST_PROGRESS = 0x2; + + private static final InternalHandler sHandler = new InternalHandler(); + + private static volatile Executor sDefaultExecutor = SERIAL_EXECUTOR; + private final WorkerRunnable mWorker; + private final FutureTask mFuture; + + private volatile Status mStatus = Status.PENDING; + + private final AtomicBoolean mCancelled = new AtomicBoolean(); + private final AtomicBoolean mTaskInvoked = new AtomicBoolean(); + + @TargetApi(11) + private static class SerialExecutor implements Executor { + final ArrayDeque mTasks = new ArrayDeque(); + Runnable mActive; + + public synchronized void execute(final Runnable r) { + mTasks.offer(new Runnable() { + public void run() { + try { + r.run(); + } finally { + scheduleNext(); + } + } + }); + if (mActive == null) { + scheduleNext(); + } + } + + protected synchronized void scheduleNext() { + if ((mActive = mTasks.poll()) != null) { + THREAD_POOL_EXECUTOR.execute(mActive); + } + } + } + + /** + * Indicates the current status of the task. Each status will be set only once + * during the lifetime of a task. + */ + public enum Status { + /** + * Indicates that the task has not been executed yet. + */ + PENDING, + /** + * Indicates that the task is running. + */ + RUNNING, + /** + * Indicates that {@link AsyncTask#onPostExecute} has finished. + */ + FINISHED, + } + + /** @hide Used to force static handler to be created. */ + public static void init() { + sHandler.getLooper(); + } + + /** @hide */ + public static void setDefaultExecutor(Executor exec) { + sDefaultExecutor = exec; + } + + /** + * Creates a new asynchronous task. This constructor must be invoked on the UI thread. + */ + public AsyncTask() { + mWorker = new WorkerRunnable() { + public Result call() throws Exception { + mTaskInvoked.set(true); + + Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); + //noinspection unchecked + return postResult(doInBackground(mParams)); + } + }; + + mFuture = new FutureTask(mWorker) { + @Override + protected void done() { + try { + postResultIfNotInvoked(get()); + } catch (InterruptedException e) { + android.util.Log.w(LOG_TAG, e); + } catch (ExecutionException e) { + throw new RuntimeException("An error occured while executing doInBackground()", + e.getCause()); + } catch (CancellationException e) { + postResultIfNotInvoked(null); + } + } + }; + } + + private void postResultIfNotInvoked(Result result) { + final boolean wasTaskInvoked = mTaskInvoked.get(); + if (!wasTaskInvoked) { + postResult(result); + } + } + + private Result postResult(Result result) { + @SuppressWarnings("unchecked") + Message message = sHandler.obtainMessage(MESSAGE_POST_RESULT, + new AsyncTaskResult(this, result)); + message.sendToTarget(); + return result; + } + + /** + * Returns the current status of this task. + * + * @return The current status. + */ + public final Status getStatus() { + return mStatus; + } + + /** + * Override this method to perform a computation on a background thread. The + * specified parameters are the parameters passed to {@link #execute} + * by the caller of this task. + * + * This method can call {@link #publishProgress} to publish updates + * on the UI thread. + * + * @param params The parameters of the task. + * + * @return A result, defined by the subclass of this task. + * + * @see #onPreExecute() + * @see #onPostExecute + * @see #publishProgress + */ + protected abstract Result doInBackground(Params... params); + + /** + * Runs on the UI thread before {@link #doInBackground}. + * + * @see #onPostExecute + * @see #doInBackground + */ + protected void onPreExecute() { + } + + /** + *

Runs on the UI thread after {@link #doInBackground}. The + * specified result is the value returned by {@link #doInBackground}.

+ * + *

This method won't be invoked if the task was cancelled.

+ * + * @param result The result of the operation computed by {@link #doInBackground}. + * + * @see #onPreExecute + * @see #doInBackground + * @see #onCancelled(Object) + */ + @SuppressWarnings({"UnusedDeclaration"}) + protected void onPostExecute(Result result) { + } + + /** + * Runs on the UI thread after {@link #publishProgress} is invoked. + * The specified values are the values passed to {@link #publishProgress}. + * + * @param values The values indicating progress. + * + * @see #publishProgress + * @see #doInBackground + */ + @SuppressWarnings({"UnusedDeclaration"}) + protected void onProgressUpdate(Progress... values) { + } + + /** + *

Runs on the UI thread after {@link #cancel(boolean)} is invoked and + * {@link #doInBackground(Object[])} has finished.

+ * + *

The default implementation simply invokes {@link #onCancelled()} and + * ignores the result. If you write your own implementation, do not call + * super.onCancelled(result).

+ * + * @param result The result, if any, computed in + * {@link #doInBackground(Object[])}, can be null + * + * @see #cancel(boolean) + * @see #isCancelled() + */ + @SuppressWarnings({"UnusedParameters"}) + protected void onCancelled(Result result) { + onCancelled(); + } + + /** + *

Applications should preferably override {@link #onCancelled(Object)}. + * This method is invoked by the default implementation of + * {@link #onCancelled(Object)}.

+ * + *

Runs on the UI thread after {@link #cancel(boolean)} is invoked and + * {@link #doInBackground(Object[])} has finished.

+ * + * @see #onCancelled(Object) + * @see #cancel(boolean) + * @see #isCancelled() + */ + protected void onCancelled() { + } + + /** + * Returns true if this task was cancelled before it completed + * normally. If you are calling {@link #cancel(boolean)} on the task, + * the value returned by this method should be checked periodically from + * {@link #doInBackground(Object[])} to end the task as soon as possible. + * + * @return true if task was cancelled before it completed + * + * @see #cancel(boolean) + */ + public final boolean isCancelled() { + return mCancelled.get(); + } + + /** + *

Attempts to cancel execution of this task. This attempt will + * fail if the task has already completed, already been cancelled, + * or could not be cancelled for some other reason. If successful, + * and this task has not started when cancel is called, + * this task should never run. If the task has already started, + * then the mayInterruptIfRunning parameter determines + * whether the thread executing this task should be interrupted in + * an attempt to stop the task.

+ * + *

Calling this method will result in {@link #onCancelled(Object)} being + * invoked on the UI thread after {@link #doInBackground(Object[])} + * returns. Calling this method guarantees that {@link #onPostExecute(Object)} + * is never invoked. After invoking this method, you should check the + * value returned by {@link #isCancelled()} periodically from + * {@link #doInBackground(Object[])} to finish the task as early as + * possible.

+ * + * @param mayInterruptIfRunning true if the thread executing this + * task should be interrupted; otherwise, in-progress tasks are allowed + * to complete. + * + * @return false if the task could not be cancelled, + * typically because it has already completed normally; + * true otherwise + * + * @see #isCancelled() + * @see #onCancelled(Object) + */ + public final boolean cancel(boolean mayInterruptIfRunning) { + mCancelled.set(true); + return mFuture.cancel(mayInterruptIfRunning); + } + + /** + * Waits if necessary for the computation to complete, and then + * retrieves its result. + * + * @return The computed result. + * + * @throws CancellationException If the computation was cancelled. + * @throws ExecutionException If the computation threw an exception. + * @throws InterruptedException If the current thread was interrupted + * while waiting. + */ + public final Result get() throws InterruptedException, ExecutionException { + return mFuture.get(); + } + + /** + * Waits if necessary for at most the given time for the computation + * to complete, and then retrieves its result. + * + * @param timeout Time to wait before cancelling the operation. + * @param unit The time unit for the timeout. + * + * @return The computed result. + * + * @throws CancellationException If the computation was cancelled. + * @throws ExecutionException If the computation threw an exception. + * @throws InterruptedException If the current thread was interrupted + * while waiting. + * @throws TimeoutException If the wait timed out. + */ + public final Result get(long timeout, TimeUnit unit) throws InterruptedException, + ExecutionException, TimeoutException { + return mFuture.get(timeout, unit); + } + + /** + * Executes the task with the specified parameters. The task returns + * itself (this) so that the caller can keep a reference to it. + * + *

Note: this function schedules the task on a queue for a single background + * thread or pool of threads depending on the platform version. When first + * introduced, AsyncTasks were executed serially on a single background thread. + * Starting with {@link android.os.Build.VERSION_CODES#DONUT}, this was changed + * to a pool of threads allowing multiple tasks to operate in parallel. Starting + * {@link android.os.Build.VERSION_CODES#HONEYCOMB}, tasks are back to being + * executed on a single thread to avoid common application errors caused + * by parallel execution. If you truly want parallel execution, you can use + * the {@link #executeOnExecutor} version of this method + * with {@link #THREAD_POOL_EXECUTOR}; however, see commentary there for warnings + * on its use. + * + *

This method must be invoked on the UI thread. + * + * @param params The parameters of the task. + * + * @return This instance of AsyncTask. + * + * @throws IllegalStateException If {@link #getStatus()} returns either + * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}. + * + * @see #executeOnExecutor(Executor, Object[]) + * @see #execute(Runnable) + */ + public final AsyncTask execute(Params... params) { + return executeOnExecutor(sDefaultExecutor, params); + } + + /** + * Executes the task with the specified parameters. The task returns + * itself (this) so that the caller can keep a reference to it. + * + *

This method is typically used with {@link #THREAD_POOL_EXECUTOR} to + * allow multiple tasks to run in parallel on a pool of threads managed by + * AsyncTask, however you can also use your own {@link Executor} for custom + * behavior. + * + *

Warning: Allowing multiple tasks to run in parallel from + * a thread pool is generally not what one wants, because the order + * of their operation is not defined. For example, if these tasks are used + * to modify any state in common (such as writing a file due to a button click), + * there are no guarantees on the order of the modifications. + * Without careful work it is possible in rare cases for the newer version + * of the data to be over-written by an older one, leading to obscure data + * loss and stability issues. Such changes are best + * executed in serial; to guarantee such work is serialized regardless of + * platform version you can use this function with {@link #SERIAL_EXECUTOR}. + * + *

This method must be invoked on the UI thread. + * + * @param exec The executor to use. {@link #THREAD_POOL_EXECUTOR} is available as a + * convenient process-wide thread pool for tasks that are loosely coupled. + * @param params The parameters of the task. + * + * @return This instance of AsyncTask. + * + * @throws IllegalStateException If {@link #getStatus()} returns either + * {@link AsyncTask.Status#RUNNING} or {@link AsyncTask.Status#FINISHED}. + * + * @see #execute(Object[]) + */ + public final AsyncTask executeOnExecutor(Executor exec, + Params... params) { + if (mStatus != Status.PENDING) { + switch (mStatus) { + case RUNNING: + throw new IllegalStateException("Cannot execute task:" + + " the task is already running."); + case FINISHED: + throw new IllegalStateException("Cannot execute task:" + + " the task has already been executed " + + "(a task can be executed only once)"); + } + } + + mStatus = Status.RUNNING; + + onPreExecute(); + + mWorker.mParams = params; + exec.execute(mFuture); + + return this; + } + + /** + * Convenience version of {@link #execute(Object...)} for use with + * a simple Runnable object. See {@link #execute(Object[])} for more + * information on the order of execution. + * + * @see #execute(Object[]) + * @see #executeOnExecutor(Executor, Object[]) + */ + public static void execute(Runnable runnable) { + sDefaultExecutor.execute(runnable); + } + + /** + * This method can be invoked from {@link #doInBackground} to + * publish updates on the UI thread while the background computation is + * still running. Each call to this method will trigger the execution of + * {@link #onProgressUpdate} on the UI thread. + * + * {@link #onProgressUpdate} will note be called if the task has been + * canceled. + * + * @param values The progress values to update the UI with. + * + * @see #onProgressUpdate + * @see #doInBackground + */ + protected final void publishProgress(Progress... values) { + if (!isCancelled()) { + sHandler.obtainMessage(MESSAGE_POST_PROGRESS, + new AsyncTaskResult(this, values)).sendToTarget(); + } + } + + private void finish(Result result) { + if (isCancelled()) { + onCancelled(result); + } else { + onPostExecute(result); + } + mStatus = Status.FINISHED; + } + + private static class InternalHandler extends Handler { + @SuppressWarnings({"unchecked", "RawUseOfParameterizedType"}) + @Override + public void handleMessage(Message msg) { + AsyncTaskResult result = (AsyncTaskResult) msg.obj; + switch (msg.what) { + case MESSAGE_POST_RESULT: + // There is only one result + result.mTask.finish(result.mData[0]); + break; + case MESSAGE_POST_PROGRESS: + result.mTask.onProgressUpdate(result.mData); + break; + } + } + } + + private static abstract class WorkerRunnable implements Callable { + Params[] mParams; + } + + @SuppressWarnings({"RawUseOfParameterizedType"}) + private static class AsyncTaskResult { + final AsyncTask mTask; + final Data[] mData; + + AsyncTaskResult(AsyncTask task, Data... data) { + mTask = task; + mData = data; + } + } +} \ No newline at end of file diff --git a/opensrp-gizi/src/main/java/util/DiskLruCache.java b/opensrp-gizi/src/main/java/util/DiskLruCache.java new file mode 100644 index 0000000..e460d1e --- /dev/null +++ b/opensrp-gizi/src/main/java/util/DiskLruCache.java @@ -0,0 +1,953 @@ +/* + * Copyright (C) 2011 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package util; + +import java.io.BufferedInputStream; +import java.io.BufferedWriter; +import java.io.Closeable; +import java.io.EOFException; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.FileOutputStream; +import java.io.FileWriter; +import java.io.FilterOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.io.Reader; +import java.io.StringWriter; +import java.io.Writer; +import java.lang.reflect.Array; +import java.nio.charset.Charset; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.concurrent.Callable; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +/** + ****************************************************************************** + * Taken from the JB source code, can be found in: + * libcore/luni/src/main/java/libcore/io/DiskLruCache.java + * or direct link: + * https://android.googlesource.com/platform/libcore/+/android-4.1.1_r1/luni/src/main/java/libcore/io/DiskLruCache.java + ****************************************************************************** + * + * A cache that uses a bounded amount of space on a filesystem. Each cache + * entry has a string key and a fixed number of values. Values are byte + * sequences, accessible as streams or files. Each value must be between {@code + * 0} and {@code Integer.MAX_VALUE} bytes in length. + * + *

The cache stores its data in a directory on the filesystem. This + * directory must be exclusive to the cache; the cache may delete or overwrite + * files from its directory. It is an error for multiple processes to use the + * same cache directory at the same time. + * + *

This cache limits the number of bytes that it will store on the + * filesystem. When the number of stored bytes exceeds the limit, the cache will + * remove entries in the background until the limit is satisfied. The limit is + * not strict: the cache may temporarily exceed it while waiting for files to be + * deleted. The limit does not include filesystem overhead or the cache + * journal so space-sensitive applications should set a conservative limit. + * + *

Clients call {@link #edit} to create or update the values of an entry. An + * entry may have only one editor at one time; if a value is not available to be + * edited then {@link #edit} will return null. + *

    + *
  • When an entry is being created it is necessary to + * supply a full set of values; the empty value should be used as a + * placeholder if necessary. + *
  • When an entry is being edited, it is not necessary + * to supply data for every value; values default to their previous + * value. + *
+ * Every {@link #edit} call must be matched by a call to {@link Editor#commit} + * or {@link Editor#abort}. Committing is atomic: a read observes the full set + * of values as they were before or after the commit, but never a mix of values. + * + *

Clients call {@link #get} to read a snapshot of an entry. The read will + * observe the value at the time that {@link #get} was called. Updates and + * removals after the call do not impact ongoing reads. + * + *

This class is tolerant of some I/O errors. If files are missing from the + * filesystem, the corresponding entries will be dropped from the cache. If + * an error occurs while writing a cache value, the edit will fail silently. + * Callers should handle other problems by catching {@code IOException} and + * responding appropriately. + */ +public final class DiskLruCache implements Closeable { + static final String JOURNAL_FILE = "journal"; + static final String JOURNAL_FILE_TMP = "journal.tmp"; + static final String MAGIC = "libcore.io.DiskLruCache"; + static final String VERSION_1 = "1"; + static final long ANY_SEQUENCE_NUMBER = -1; + private static final String CLEAN = "CLEAN"; + private static final String DIRTY = "DIRTY"; + private static final String REMOVE = "REMOVE"; + private static final String READ = "READ"; + + private static final Charset UTF_8 = Charset.forName("UTF-8"); + private static final int IO_BUFFER_SIZE = 8 * 1024; + + /* + * This cache uses a journal file named "journal". A typical journal file + * looks like this: + * libcore.io.DiskLruCache + * 1 + * 100 + * 2 + * + * CLEAN 3400330d1dfc7f3f7f4b8d4d803dfcf6 832 21054 + * DIRTY 335c4c6028171cfddfbaae1a9c313c52 + * CLEAN 335c4c6028171cfddfbaae1a9c313c52 3934 2342 + * REMOVE 335c4c6028171cfddfbaae1a9c313c52 + * DIRTY 1ab96a171faeeee38496d8b330771a7a + * CLEAN 1ab96a171faeeee38496d8b330771a7a 1600 234 + * READ 335c4c6028171cfddfbaae1a9c313c52 + * READ 3400330d1dfc7f3f7f4b8d4d803dfcf6 + * + * The first five lines of the journal form its header. They are the + * constant string "libcore.io.DiskLruCache", the disk cache's version, + * the application's version, the value count, and a blank line. + * + * Each of the subsequent lines in the file is a record of the state of a + * cache entry. Each line contains space-separated values: a state, a key, + * and optional state-specific values. + * o DIRTY lines track that an entry is actively being created or updated. + * Every successful DIRTY action should be followed by a CLEAN or REMOVE + * action. DIRTY lines without a matching CLEAN or REMOVE indicate that + * temporary files may need to be deleted. + * o CLEAN lines track a cache entry that has been successfully published + * and may be read. A publish line is followed by the lengths of each of + * its values. + * o READ lines track accesses for LRU. + * o REMOVE lines track entries that have been deleted. + * + * The journal file is appended to as cache operations occur. The journal may + * occasionally be compacted by dropping redundant lines. A temporary file named + * "journal.tmp" will be used during compaction; that file should be deleted if + * it exists when the cache is opened. + */ + + private final File directory; + private final File journalFile; + private final File journalFileTmp; + private final int appVersion; + private final long maxSize; + private final int valueCount; + private long size = 0; + private Writer journalWriter; + private final LinkedHashMap lruEntries + = new LinkedHashMap(0, 0.75f, true); + private int redundantOpCount; + + /** + * To differentiate between old and current snapshots, each entry is given + * a sequence number each time an edit is committed. A snapshot is stale if + * its sequence number is not equal to its entry's sequence number. + */ + private long nextSequenceNumber = 0; + + /* From java.util.Arrays */ + @SuppressWarnings("unchecked") + private static T[] copyOfRange(T[] original, int start, int end) { + final int originalLength = original.length; // For exception priority compatibility. + if (start > end) { + throw new IllegalArgumentException(); + } + if (start < 0 || start > originalLength) { + throw new ArrayIndexOutOfBoundsException(); + } + final int resultLength = end - start; + final int copyLength = Math.min(resultLength, originalLength - start); + final T[] result = (T[]) Array + .newInstance(original.getClass().getComponentType(), resultLength); + System.arraycopy(original, start, result, 0, copyLength); + return result; + } + + /** + * Returns the remainder of 'reader' as a string, closing it when done. + */ + public static String readFully(Reader reader) throws IOException { + try { + StringWriter writer = new StringWriter(); + char[] buffer = new char[1024]; + int count; + while ((count = reader.read(buffer)) != -1) { + writer.write(buffer, 0, count); + } + return writer.toString(); + } finally { + reader.close(); + } + } + + /** + * Returns the ASCII characters up to but not including the next "\r\n", or + * "\n". + * + * @throws EOFException if the stream is exhausted before the next newline + * character. + */ + public static String readAsciiLine(InputStream in) throws IOException { + // TODO: support UTF-8 here instead + + StringBuilder result = new StringBuilder(80); + while (true) { + int c = in.read(); + if (c == -1) { + throw new EOFException(); + } else if (c == '\n') { + break; + } + + result.append((char) c); + } + int length = result.length(); + if (length > 0 && result.charAt(length - 1) == '\r') { + result.setLength(length - 1); + } + return result.toString(); + } + + /** + * Closes 'closeable', ignoring any checked exceptions. Does nothing if 'closeable' is null. + */ + public static void closeQuietly(Closeable closeable) { + if (closeable != null) { + try { + closeable.close(); + } catch (RuntimeException rethrown) { + throw rethrown; + } catch (Exception ignored) { + } + } + } + + /** + * Recursively delete everything in {@code dir}. + */ + // TODO: this should specify paths as Strings rather than as Files + public static void deleteContents(File dir) throws IOException { + File[] files = dir.listFiles(); + if (files == null) { + throw new IllegalArgumentException("not a directory: " + dir); + } + for (File file : files) { + if (file.isDirectory()) { + deleteContents(file); + } + if (!file.delete()) { + throw new IOException("failed to delete file: " + file); + } + } + } + + /** This cache uses a single background thread to evict entries. */ + private final ExecutorService executorService = new ThreadPoolExecutor(0, 1, + 60L, TimeUnit.SECONDS, new LinkedBlockingQueue()); + private final Callable cleanupCallable = new Callable() { + @Override public Void call() throws Exception { + synchronized (DiskLruCache.this) { + if (journalWriter == null) { + return null; // closed + } + trimToSize(); + if (journalRebuildRequired()) { + rebuildJournal(); + redundantOpCount = 0; + } + } + return null; + } + }; + + private DiskLruCache(File directory, int appVersion, int valueCount, long maxSize) { + this.directory = directory; + this.appVersion = appVersion; + this.journalFile = new File(directory, JOURNAL_FILE); + this.journalFileTmp = new File(directory, JOURNAL_FILE_TMP); + this.valueCount = valueCount; + this.maxSize = maxSize; + } + + /** + * Opens the cache in {@code directory}, creating a cache if none exists + * there. + * + * @param directory a writable directory + * @param appVersion + * @param valueCount the number of values per cache entry. Must be positive. + * @param maxSize the maximum number of bytes this cache should use to store + * @throws IOException if reading or writing the cache directory fails + */ + public static DiskLruCache open(File directory, int appVersion, int valueCount, long maxSize) + throws IOException { + if (maxSize <= 0) { + throw new IllegalArgumentException("maxSize <= 0"); + } + if (valueCount <= 0) { + throw new IllegalArgumentException("valueCount <= 0"); + } + + // prefer to pick up where we left off + DiskLruCache cache = new DiskLruCache(directory, appVersion, valueCount, maxSize); + if (cache.journalFile.exists()) { + try { + cache.readJournal(); + cache.processJournal(); + cache.journalWriter = new BufferedWriter(new FileWriter(cache.journalFile, true), + IO_BUFFER_SIZE); + return cache; + } catch (IOException journalIsCorrupt) { +// System.logW("DiskLruCache " + directory + " is corrupt: " +// + journalIsCorrupt.getMessage() + ", removing"); + cache.delete(); + } + } + + // create a new empty cache + directory.mkdirs(); + cache = new DiskLruCache(directory, appVersion, valueCount, maxSize); + cache.rebuildJournal(); + return cache; + } + + private void readJournal() throws IOException { + InputStream in = new BufferedInputStream(new FileInputStream(journalFile), IO_BUFFER_SIZE); + try { + String magic = readAsciiLine(in); + String version = readAsciiLine(in); + String appVersionString = readAsciiLine(in); + String valueCountString = readAsciiLine(in); + String blank = readAsciiLine(in); + if (!MAGIC.equals(magic) + || !VERSION_1.equals(version) + || !Integer.toString(appVersion).equals(appVersionString) + || !Integer.toString(valueCount).equals(valueCountString) + || !"".equals(blank)) { + throw new IOException("unexpected journal header: [" + + magic + ", " + version + ", " + valueCountString + ", " + blank + "]"); + } + + while (true) { + try { + readJournalLine(readAsciiLine(in)); + } catch (EOFException endOfJournal) { + break; + } + } + } finally { + closeQuietly(in); + } + } + + private void readJournalLine(String line) throws IOException { + String[] parts = line.split(" "); + if (parts.length < 2) { + throw new IOException("unexpected journal line: " + line); + } + + String key = parts[1]; + if (parts[0].equals(REMOVE) && parts.length == 2) { + lruEntries.remove(key); + return; + } + + Entry entry = lruEntries.get(key); + if (entry == null) { + entry = new Entry(key); + lruEntries.put(key, entry); + } + + if (parts[0].equals(CLEAN) && parts.length == 2 + valueCount) { + entry.readable = true; + entry.currentEditor = null; + entry.setLengths(copyOfRange(parts, 2, parts.length)); + } else if (parts[0].equals(DIRTY) && parts.length == 2) { + entry.currentEditor = new Editor(entry); + } else if (parts[0].equals(READ) && parts.length == 2) { + // this work was already done by calling lruEntries.get() + } else { + throw new IOException("unexpected journal line: " + line); + } + } + + /** + * Computes the initial size and collects garbage as a part of opening the + * cache. Dirty entries are assumed to be inconsistent and will be deleted. + */ + private void processJournal() throws IOException { + deleteIfExists(journalFileTmp); + for (Iterator i = lruEntries.values().iterator(); i.hasNext(); ) { + Entry entry = i.next(); + if (entry.currentEditor == null) { + for (int t = 0; t < valueCount; t++) { + size += entry.lengths[t]; + } + } else { + entry.currentEditor = null; + for (int t = 0; t < valueCount; t++) { + deleteIfExists(entry.getCleanFile(t)); + deleteIfExists(entry.getDirtyFile(t)); + } + i.remove(); + } + } + } + + /** + * Creates a new journal that omits redundant information. This replaces the + * current journal if it exists. + */ + private synchronized void rebuildJournal() throws IOException { + if (journalWriter != null) { + journalWriter.close(); + } + + Writer writer = new BufferedWriter(new FileWriter(journalFileTmp), IO_BUFFER_SIZE); + writer.write(MAGIC); + writer.write("\n"); + writer.write(VERSION_1); + writer.write("\n"); + writer.write(Integer.toString(appVersion)); + writer.write("\n"); + writer.write(Integer.toString(valueCount)); + writer.write("\n"); + writer.write("\n"); + + for (Entry entry : lruEntries.values()) { + if (entry.currentEditor != null) { + writer.write(DIRTY + ' ' + entry.key + '\n'); + } else { + writer.write(CLEAN + ' ' + entry.key + entry.getLengths() + '\n'); + } + } + + writer.close(); + journalFileTmp.renameTo(journalFile); + journalWriter = new BufferedWriter(new FileWriter(journalFile, true), IO_BUFFER_SIZE); + } + + private static void deleteIfExists(File file) throws IOException { +// try { +// Libcore.os.remove(file.getPath()); +// } catch (ErrnoException errnoException) { +// if (errnoException.errno != OsConstants.ENOENT) { +// throw errnoException.rethrowAsIOException(); +// } +// } + if (file.exists() && !file.delete()) { + throw new IOException(); + } + } + + /** + * Returns a snapshot of the entry named {@code key}, or null if it doesn't + * exist is not currently readable. If a value is returned, it is moved to + * the head of the LRU queue. + */ + public synchronized Snapshot get(String key) throws IOException { + checkNotClosed(); + validateKey(key); + Entry entry = lruEntries.get(key); + if (entry == null) { + return null; + } + + if (!entry.readable) { + return null; + } + + /* + * Open all streams eagerly to guarantee that we see a single published + * snapshot. If we opened streams lazily then the streams could come + * from different edits. + */ + InputStream[] ins = new InputStream[valueCount]; + try { + for (int i = 0; i < valueCount; i++) { + ins[i] = new FileInputStream(entry.getCleanFile(i)); + } + } catch (FileNotFoundException e) { + // a file must have been deleted manually! + return null; + } + + redundantOpCount++; + journalWriter.append(READ + ' ' + key + '\n'); + if (journalRebuildRequired()) { + executorService.submit(cleanupCallable); + } + + return new Snapshot(key, entry.sequenceNumber, ins); + } + + /** + * Returns an editor for the entry named {@code key}, or null if another + * edit is in progress. + */ + public Editor edit(String key) throws IOException { + return edit(key, ANY_SEQUENCE_NUMBER); + } + + private synchronized Editor edit(String key, long expectedSequenceNumber) throws IOException { + checkNotClosed(); + validateKey(key); + Entry entry = lruEntries.get(key); + if (expectedSequenceNumber != ANY_SEQUENCE_NUMBER + && (entry == null || entry.sequenceNumber != expectedSequenceNumber)) { + return null; // snapshot is stale + } + if (entry == null) { + entry = new Entry(key); + lruEntries.put(key, entry); + } else if (entry.currentEditor != null) { + return null; // another edit is in progress + } + + Editor editor = new Editor(entry); + entry.currentEditor = editor; + + // flush the journal before creating files to prevent file leaks + journalWriter.write(DIRTY + ' ' + key + '\n'); + journalWriter.flush(); + return editor; + } + + /** + * Returns the directory where this cache stores its data. + */ + public File getDirectory() { + return directory; + } + + /** + * Returns the maximum number of bytes that this cache should use to store + * its data. + */ + public long maxSize() { + return maxSize; + } + + /** + * Returns the number of bytes currently being used to store the values in + * this cache. This may be greater than the max size if a background + * deletion is pending. + */ + public synchronized long size() { + return size; + } + + private synchronized void completeEdit(Editor editor, boolean success) throws IOException { + Entry entry = editor.entry; + if (entry.currentEditor != editor) { + throw new IllegalStateException(); + } + + // if this edit is creating the entry for the first time, every index must have a value + if (success && !entry.readable) { + for (int i = 0; i < valueCount; i++) { + if (!entry.getDirtyFile(i).exists()) { + editor.abort(); + throw new IllegalStateException("edit didn't create file " + i); + } + } + } + + for (int i = 0; i < valueCount; i++) { + File dirty = entry.getDirtyFile(i); + if (success) { + if (dirty.exists()) { + File clean = entry.getCleanFile(i); + dirty.renameTo(clean); + long oldLength = entry.lengths[i]; + long newLength = clean.length(); + entry.lengths[i] = newLength; + size = size - oldLength + newLength; + } + } else { + deleteIfExists(dirty); + } + } + + redundantOpCount++; + entry.currentEditor = null; + if (entry.readable | success) { + entry.readable = true; + journalWriter.write(CLEAN + ' ' + entry.key + entry.getLengths() + '\n'); + if (success) { + entry.sequenceNumber = nextSequenceNumber++; + } + } else { + lruEntries.remove(entry.key); + journalWriter.write(REMOVE + ' ' + entry.key + '\n'); + } + + if (size > maxSize || journalRebuildRequired()) { + executorService.submit(cleanupCallable); + } + } + + /** + * We only rebuild the journal when it will halve the size of the journal + * and eliminate at least 2000 ops. + */ + private boolean journalRebuildRequired() { + final int REDUNDANT_OP_COMPACT_THRESHOLD = 2000; + return redundantOpCount >= REDUNDANT_OP_COMPACT_THRESHOLD + && redundantOpCount >= lruEntries.size(); + } + + /** + * Drops the entry for {@code key} if it exists and can be removed. Entries + * actively being edited cannot be removed. + * + * @return true if an entry was removed. + */ + public synchronized boolean remove(String key) throws IOException { + checkNotClosed(); + validateKey(key); + Entry entry = lruEntries.get(key); + if (entry == null || entry.currentEditor != null) { + return false; + } + + for (int i = 0; i < valueCount; i++) { + File file = entry.getCleanFile(i); + if (!file.delete()) { + throw new IOException("failed to delete " + file); + } + size -= entry.lengths[i]; + entry.lengths[i] = 0; + } + + redundantOpCount++; + journalWriter.append(REMOVE + ' ' + key + '\n'); + lruEntries.remove(key); + + if (journalRebuildRequired()) { + executorService.submit(cleanupCallable); + } + + return true; + } + + /** + * Returns true if this cache has been closed. + */ + public boolean isClosed() { + return journalWriter == null; + } + + private void checkNotClosed() { + if (journalWriter == null) { + throw new IllegalStateException("cache is closed"); + } + } + + /** + * Force buffered operations to the filesystem. + */ + public synchronized void flush() throws IOException { + checkNotClosed(); + trimToSize(); + journalWriter.flush(); + } + + /** + * Closes this cache. Stored values will remain on the filesystem. + */ + public synchronized void close() throws IOException { + if (journalWriter == null) { + return; // already closed + } + for (Entry entry : new ArrayList(lruEntries.values())) { + if (entry.currentEditor != null) { + entry.currentEditor.abort(); + } + } + trimToSize(); + journalWriter.close(); + journalWriter = null; + } + + private void trimToSize() throws IOException { + while (size > maxSize) { +// Map.Entry toEvict = lruEntries.eldest(); + final Map.Entry toEvict = lruEntries.entrySet().iterator().next(); + remove(toEvict.getKey()); + } + } + + /** + * Closes the cache and deletes all of its stored values. This will delete + * all files in the cache directory including files that weren't created by + * the cache. + */ + public void delete() throws IOException { + close(); + deleteContents(directory); + } + + private void validateKey(String key) { + if (key.contains(" ") || key.contains("\n") || key.contains("\r")) { + throw new IllegalArgumentException( + "keys must not contain spaces or newlines: \"" + key + "\""); + } + } + + private static String inputStreamToString(InputStream in) throws IOException { + return readFully(new InputStreamReader(in, UTF_8)); + } + + /** + * A snapshot of the values for an entry. + */ + public final class Snapshot implements Closeable { + private final String key; + private final long sequenceNumber; + private final InputStream[] ins; + + private Snapshot(String key, long sequenceNumber, InputStream[] ins) { + this.key = key; + this.sequenceNumber = sequenceNumber; + this.ins = ins; + } + + /** + * Returns an editor for this snapshot's entry, or null if either the + * entry has changed since this snapshot was created or if another edit + * is in progress. + */ + public Editor edit() throws IOException { + return DiskLruCache.this.edit(key, sequenceNumber); + } + + /** + * Returns the unbuffered stream with the value for {@code index}. + */ + public InputStream getInputStream(int index) { + return ins[index]; + } + + /** + * Returns the string value for {@code index}. + */ + public String getString(int index) throws IOException { + return inputStreamToString(getInputStream(index)); + } + + @Override public void close() { + for (InputStream in : ins) { + closeQuietly(in); + } + } + } + + /** + * Edits the values for an entry. + */ + public final class Editor { + private final Entry entry; + private boolean hasErrors; + + private Editor(Entry entry) { + this.entry = entry; + } + + /** + * Returns an unbuffered input stream to read the last committed value, + * or null if no value has been committed. + */ + public InputStream newInputStream(int index) throws IOException { + synchronized (DiskLruCache.this) { + if (entry.currentEditor != this) { + throw new IllegalStateException(); + } + if (!entry.readable) { + return null; + } + return new FileInputStream(entry.getCleanFile(index)); + } + } + + /** + * Returns the last committed value as a string, or null if no value + * has been committed. + */ + public String getString(int index) throws IOException { + InputStream in = newInputStream(index); + return in != null ? inputStreamToString(in) : null; + } + + /** + * Returns a new unbuffered output stream to write the value at + * {@code index}. If the underlying output stream encounters errors + * when writing to the filesystem, this edit will be aborted when + * {@link #commit} is called. The returned output stream does not throw + * IOExceptions. + */ + public OutputStream newOutputStream(int index) throws IOException { + synchronized (DiskLruCache.this) { + if (entry.currentEditor != this) { + throw new IllegalStateException(); + } + return new FaultHidingOutputStream(new FileOutputStream(entry.getDirtyFile(index))); + } + } + + /** + * Sets the value at {@code index} to {@code value}. + */ + public void set(int index, String value) throws IOException { + Writer writer = null; + try { + writer = new OutputStreamWriter(newOutputStream(index), UTF_8); + writer.write(value); + } finally { + closeQuietly(writer); + } + } + + /** + * Commits this edit so it is visible to readers. This releases the + * edit lock so another edit may be started on the same key. + */ + public void commit() throws IOException { + if (hasErrors) { + completeEdit(this, false); + remove(entry.key); // the previous entry is stale + } else { + completeEdit(this, true); + } + } + + /** + * Aborts this edit. This releases the edit lock so another edit may be + * started on the same key. + */ + public void abort() throws IOException { + completeEdit(this, false); + } + + private class FaultHidingOutputStream extends FilterOutputStream { + private FaultHidingOutputStream(OutputStream out) { + super(out); + } + + @Override public void write(int oneByte) { + try { + out.write(oneByte); + } catch (IOException e) { + hasErrors = true; + } + } + + @Override public void write(byte[] buffer, int offset, int length) { + try { + out.write(buffer, offset, length); + } catch (IOException e) { + hasErrors = true; + } + } + + @Override public void close() { + try { + out.close(); + } catch (IOException e) { + hasErrors = true; + } + } + + @Override public void flush() { + try { + out.flush(); + } catch (IOException e) { + hasErrors = true; + } + } + } + } + + private final class Entry { + private final String key; + + /** Lengths of this entry's files. */ + private final long[] lengths; + + /** True if this entry has ever been published */ + private boolean readable; + + /** The ongoing edit or null if this entry is not being edited. */ + private Editor currentEditor; + + /** The sequence number of the most recently committed edit to this entry. */ + private long sequenceNumber; + + private Entry(String key) { + this.key = key; + this.lengths = new long[valueCount]; + } + + public String getLengths() throws IOException { + StringBuilder result = new StringBuilder(); + for (long size : lengths) { + result.append(' ').append(size); + } + return result.toString(); + } + + /** + * Set lengths using decimal numbers like "10123". + */ + private void setLengths(String[] strings) throws IOException { + if (strings.length != valueCount) { + throw invalidLengths(strings); + } + + try { + for (int i = 0; i < strings.length; i++) { + lengths[i] = Long.parseLong(strings[i]); + } + } catch (NumberFormatException e) { + throw invalidLengths(strings); + } + } + + private IOException invalidLengths(String[] strings) throws IOException { + throw new IOException("unexpected journal line: " + Arrays.toString(strings)); + } + + public File getCleanFile(int i) { + return new File(directory, key + "." + i); + } + + public File getDirtyFile(int i) { + return new File(directory, key + "." + i + ".tmp"); + } + } +} diff --git a/opensrp-gizi/src/main/java/util/ImageCache.java b/opensrp-gizi/src/main/java/util/ImageCache.java new file mode 100644 index 0000000..98c17b9 --- /dev/null +++ b/opensrp-gizi/src/main/java/util/ImageCache.java @@ -0,0 +1,738 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package util; + +import android.annotation.TargetApi; +import android.app.Fragment; +import android.app.FragmentManager; +import android.content.Context; +import android.graphics.Bitmap; +import android.graphics.Bitmap.CompressFormat; +import android.graphics.Bitmap.Config; +import android.graphics.BitmapFactory; +import android.graphics.drawable.BitmapDrawable; +import android.os.Build.VERSION_CODES; +import android.os.Bundle; +import android.os.Environment; +import android.os.StatFs; +import android.util.Log; +import android.util.LruCache; + +import org.ei.opensrp.BuildConfig; + +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.lang.ref.SoftReference; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; + +/** + * This class handles disk and memory caching of bitmaps in conjunction with the + * {@link ImageWorker} class and its subclasses. Use + * to get an instance of this + * class, although usually a cache should be added directly to an {@link ImageWorker} by calling + * . + */ +public class ImageCache { + private static final String TAG = "ImageCache"; + + // Default memory cache size in kilobytes + private static final int DEFAULT_MEM_CACHE_SIZE = 1024 * 5; // 5MB + + // Default disk cache size in bytes + private static final int DEFAULT_DISK_CACHE_SIZE = 1024 * 1024 * 10; // 10MB + + // Compression settings when writing images to disk cache + private static final CompressFormat DEFAULT_COMPRESS_FORMAT = CompressFormat.JPEG; + private static final int DEFAULT_COMPRESS_QUALITY = 70; + private static final int DISK_CACHE_INDEX = 0; + + // Constants to easily toggle various caches + private static final boolean DEFAULT_MEM_CACHE_ENABLED = true; + private static final boolean DEFAULT_DISK_CACHE_ENABLED = true; + private static final boolean DEFAULT_INIT_DISK_CACHE_ON_CREATE = false; + + private DiskLruCache mDiskLruCache; + private LruCache mMemoryCache; + private ImageCacheParams mCacheParams; + private final Object mDiskCacheLock = new Object(); + private boolean mDiskCacheStarting = true; + + private Set> mReusableBitmaps; + + /** + * Create a new ImageCache object using the specified parameters. This should not be + * called directly by other classes, instead use + * to fetch an ImageCache + * instance. + * + * @param cacheParams The cache parameters to use to initialize the cache + */ + private ImageCache(ImageCacheParams cacheParams) { + init(cacheParams); + } + + /** + * Return an {@link ImageCache} instance. A {@link RetainFragment} is used to retain the + * ImageCache object across configuration changes such as a change in device orientation. + * + * @param fragmentManager The fragment manager to use when dealing with the retained fragment. + * @param cacheParams The cache parameters to use if the ImageCache needs instantiation. + * @return An existing retained ImageCache object or a new one if one did not exist + */ + public static ImageCache getInstance( + FragmentManager fragmentManager, ImageCacheParams cacheParams) { + + // Search for, or create an instance of the non-UI RetainFragment + final RetainFragment mRetainFragment = findOrCreateRetainFragment(fragmentManager); + + // See if we already have an ImageCache stored in RetainFragment + ImageCache imageCache = (ImageCache) mRetainFragment.getObject(); + + // No existing ImageCache, create one and store it in RetainFragment + if (imageCache == null) { + imageCache = new ImageCache(cacheParams); + mRetainFragment.setObject(imageCache); + } + + return imageCache; + } + + /** + * Initialize the cache, providing all parameters. + * + * @param cacheParams The cache parameters to initialize the cache + */ + private void init(ImageCacheParams cacheParams) { + mCacheParams = cacheParams; + + //BEGIN_INCLUDE(init_memory_cache) + // Set up memory cache + if (mCacheParams.memoryCacheEnabled) { + if (BuildConfig.DEBUG) { + Log.d(TAG, "Memory cache created (size = " + mCacheParams.memCacheSize + ")"); + } + + // If we're running on Honeycomb or newer, create a set of reusable bitmaps that can be + // populated into the inBitmap field of BitmapFactory.Options. Note that the set is + // of SoftReferences which will actually not be very effective due to the garbage + // collector being aggressive clearing Soft/WeakReferences. A better approach + // would be to use a strongly references bitmaps, however this would require some + // balancing of memory usage between this set and the bitmap LruCache. It would also + // require knowledge of the expected size of the bitmaps. From Honeycomb to JellyBean + // the size would need to be precise, from KitKat onward the size would just need to + // be the upper bound (due to changes in how inBitmap can re-use bitmaps). + if (Utils.hasHoneycomb()) { + mReusableBitmaps = + Collections.synchronizedSet(new HashSet>()); + } + + mMemoryCache = new LruCache(mCacheParams.memCacheSize) { + + /** + * Notify the removed entry that is no longer being cached + */ + @Override + protected void entryRemoved(boolean evicted, String key, + BitmapDrawable oldValue, BitmapDrawable newValue) { + if (RecyclingBitmapDrawable.class.isInstance(oldValue)) { + // The removed entry is a recycling drawable, so notify it + // that it has been removed from the memory cache + ((RecyclingBitmapDrawable) oldValue).setIsCached(false); + } else { + // The removed entry is a standard BitmapDrawable + + if (Utils.hasHoneycomb()) { + // We're running on Honeycomb or later, so add the bitmap + // to a SoftReference set for possible use with inBitmap later + mReusableBitmaps.add(new SoftReference(oldValue.getBitmap())); + } + } + } + + /** + * Measure item size in kilobytes rather than units which is more practical + * for a bitmap cache + */ + @Override + protected int sizeOf(String key, BitmapDrawable value) { + final int bitmapSize = getBitmapSize(value) / 1024; + return bitmapSize == 0 ? 1 : bitmapSize; + } + }; + } + //END_INCLUDE(init_memory_cache) + + // By default the disk cache is not initialized here as it should be initialized + // on a separate thread due to disk access. + if (cacheParams.initDiskCacheOnCreate) { + // Set up disk cache + initDiskCache(); + } + } + + /** + * Initializes the disk cache. Note that this includes disk access so this should not be + * executed on the main/UI thread. By default an ImageCache does not initialize the disk + * cache when it is created, instead you should call initDiskCache() to initialize it on a + * background thread. + */ + public void initDiskCache() { + // Set up disk cache + synchronized (mDiskCacheLock) { + if (mDiskLruCache == null || mDiskLruCache.isClosed()) { + File diskCacheDir = mCacheParams.diskCacheDir; + if (mCacheParams.diskCacheEnabled && diskCacheDir != null) { + if (!diskCacheDir.exists()) { + diskCacheDir.mkdirs(); + } + if (getUsableSpace(diskCacheDir) > mCacheParams.diskCacheSize) { + try { + mDiskLruCache = DiskLruCache.open( + diskCacheDir, 1, 1, mCacheParams.diskCacheSize); + if (BuildConfig.DEBUG) { + Log.d(TAG, "Disk cache initialized"); + } + } catch (final IOException e) { + mCacheParams.diskCacheDir = null; + Log.e(TAG, "initDiskCache - " + e); + } + } + } + } + mDiskCacheStarting = false; + mDiskCacheLock.notifyAll(); + } + } + + /** + * Adds a bitmap to both memory and disk cache. + * @param data Unique identifier for the bitmap to store + * @param value The bitmap drawable to store + */ + public void addBitmapToCache(String data, BitmapDrawable value) { + //BEGIN_INCLUDE(add_bitmap_to_cache) + if (data == null || value == null) { + return; + } + + // Add to memory cache + if (mMemoryCache != null) { + if (RecyclingBitmapDrawable.class.isInstance(value)) { + // The removed entry is a recycling drawable, so notify it + // that it has been added into the memory cache + ((RecyclingBitmapDrawable) value).setIsCached(true); + } + mMemoryCache.put(data, value); + } + + synchronized (mDiskCacheLock) { + // Add to disk cache + if (mDiskLruCache != null) { + final String key = hashKeyForDisk(data); + OutputStream out = null; + try { + DiskLruCache.Snapshot snapshot = mDiskLruCache.get(key); + if (snapshot == null) { + final DiskLruCache.Editor editor = mDiskLruCache.edit(key); + if (editor != null) { + out = editor.newOutputStream(DISK_CACHE_INDEX); + value.getBitmap().compress( + mCacheParams.compressFormat, mCacheParams.compressQuality, out); + editor.commit(); + out.close(); + } + } else { + snapshot.getInputStream(DISK_CACHE_INDEX).close(); + } + } catch (final IOException e) { + Log.e(TAG, "addBitmapToCache - " + e); + } catch (Exception e) { + Log.e(TAG, "addBitmapToCache - " + e); + } finally { + try { + if (out != null) { + out.close(); + } + } catch (IOException e) {} + } + } + } + //END_INCLUDE(add_bitmap_to_cache) + } + + /** + * Get from memory cache. + * + * @param data Unique identifier for which item to get + * @return The bitmap drawable if found in cache, null otherwise + */ + public BitmapDrawable getBitmapFromMemCache(String data) { + //BEGIN_INCLUDE(get_bitmap_from_mem_cache) + BitmapDrawable memValue = null; + + if (mMemoryCache != null) { + memValue = mMemoryCache.get(data); + } + + if (BuildConfig.DEBUG && memValue != null) { + Log.d(TAG, "Memory cache hit"); + } + + return memValue; + //END_INCLUDE(get_bitmap_from_mem_cache) + } + + /** + * Get from disk cache. + * + * @param data Unique identifier for which item to get + * @return The bitmap if found in cache, null otherwise + */ + public Bitmap getBitmapFromDiskCache(String data) { + //BEGIN_INCLUDE(get_bitmap_from_disk_cache) + final String key = hashKeyForDisk(data); + Bitmap bitmap = null; + + synchronized (mDiskCacheLock) { + while (mDiskCacheStarting) { + try { + mDiskCacheLock.wait(); + } catch (InterruptedException e) {} + } + if (mDiskLruCache != null) { + InputStream inputStream = null; + try { + final DiskLruCache.Snapshot snapshot = mDiskLruCache.get(key); + if (snapshot != null) { + if (BuildConfig.DEBUG) { + Log.d(TAG, "Disk cache hit"); + } + inputStream = snapshot.getInputStream(DISK_CACHE_INDEX); + if (inputStream != null) { + FileDescriptor fd = ((FileInputStream) inputStream).getFD(); + + // Decode bitmap, but we don't want to sample so give + // MAX_VALUE as the target dimensions + bitmap = ImageResizer.decodeSampledBitmapFromDescriptor( + fd, Integer.MAX_VALUE, Integer.MAX_VALUE, this); + } + } + } catch (final IOException e) { + Log.e(TAG, "getBitmapFromDiskCache - " + e); + } finally { + try { + if (inputStream != null) { + inputStream.close(); + } + } catch (IOException e) {} + } + } + return bitmap; + } + //END_INCLUDE(get_bitmap_from_disk_cache) + } + + /** + * @param options - BitmapFactory.Options with out* options populated + * @return Bitmap that case be used for inBitmap + */ + protected Bitmap getBitmapFromReusableSet(BitmapFactory.Options options) { + //BEGIN_INCLUDE(get_bitmap_from_reusable_set) + Bitmap bitmap = null; + + if (mReusableBitmaps != null && !mReusableBitmaps.isEmpty()) { + synchronized (mReusableBitmaps) { + final Iterator> iterator = mReusableBitmaps.iterator(); + Bitmap item; + + while (iterator.hasNext()) { + item = iterator.next().get(); + + if (null != item && item.isMutable()) { + // Check to see it the item can be used for inBitmap + if (canUseForInBitmap(item, options)) { + bitmap = item; + + // Remove from reusable set so it can't be used again + iterator.remove(); + break; + } + } else { + // Remove from the set if the reference has been cleared. + iterator.remove(); + } + } + } + } + + return bitmap; + //END_INCLUDE(get_bitmap_from_reusable_set) + } + + /** + * Clears both the memory and disk cache associated with this ImageCache object. Note that + * this includes disk access so this should not be executed on the main/UI thread. + */ + public void clearCache() { + if (mMemoryCache != null) { + mMemoryCache.evictAll(); + if (BuildConfig.DEBUG) { + Log.d(TAG, "Memory cache cleared"); + } + } + + synchronized (mDiskCacheLock) { + mDiskCacheStarting = true; + if (mDiskLruCache != null && !mDiskLruCache.isClosed()) { + try { + mDiskLruCache.delete(); + if (BuildConfig.DEBUG) { + Log.d(TAG, "Disk cache cleared"); + } + } catch (IOException e) { + Log.e(TAG, "clearCache - " + e); + } + mDiskLruCache = null; + initDiskCache(); + } + } + } + + /** + * Flushes the disk cache associated with this ImageCache object. Note that this includes + * disk access so this should not be executed on the main/UI thread. + */ + public void flush() { + synchronized (mDiskCacheLock) { + if (mDiskLruCache != null) { + try { + mDiskLruCache.flush(); + if (BuildConfig.DEBUG) { + Log.d(TAG, "Disk cache flushed"); + } + } catch (IOException e) { + Log.e(TAG, "flush - " + e); + } + } + } + } + + /** + * Closes the disk cache associated with this ImageCache object. Note that this includes + * disk access so this should not be executed on the main/UI thread. + */ + public void close() { + synchronized (mDiskCacheLock) { + if (mDiskLruCache != null) { + try { + if (!mDiskLruCache.isClosed()) { + mDiskLruCache.close(); + mDiskLruCache = null; + if (BuildConfig.DEBUG) { + Log.d(TAG, "Disk cache closed"); + } + } + } catch (IOException e) { + Log.e(TAG, "close - " + e); + } + } + } + } + + /** + * A holder class that contains cache parameters. + */ + public static class ImageCacheParams { + public int memCacheSize = DEFAULT_MEM_CACHE_SIZE; + public int diskCacheSize = DEFAULT_DISK_CACHE_SIZE; + public File diskCacheDir; + public CompressFormat compressFormat = DEFAULT_COMPRESS_FORMAT; + public int compressQuality = DEFAULT_COMPRESS_QUALITY; + public boolean memoryCacheEnabled = DEFAULT_MEM_CACHE_ENABLED; + public boolean diskCacheEnabled = DEFAULT_DISK_CACHE_ENABLED; + public boolean initDiskCacheOnCreate = DEFAULT_INIT_DISK_CACHE_ON_CREATE; + + /** + * Create a set of image cache parameters that can be provided to + * or + * . + * @param context A context to use. + * @param diskCacheDirectoryName A unique subdirectory name that will be appended to the + * application cache directory. Usually "cache" or "images" + * is sufficient. + */ + public ImageCacheParams(Context context, String diskCacheDirectoryName) { + diskCacheDir = getDiskCacheDir(context, diskCacheDirectoryName); + } + + /** + * Sets the memory cache size based on a percentage of the max available VM memory. + * Eg. setting percent to 0.2 would set the memory cache to one fifth of the available + * memory. Throws {@link IllegalArgumentException} if percent is < 0.01 or > .8. + * memCacheSize is stored in kilobytes instead of bytes as this will eventually be passed + * to construct a LruCache which takes an int in its constructor. + * + * This value should be chosen carefully based on a number of factors + * Refer to the corresponding Android Training class for more discussion: + * http://developer.android.com/training/displaying-bitmaps/ + * + * @param percent Percent of available app memory to use to size memory cache + */ + public void setMemCacheSizePercent(float percent) { + if (percent < 0.01f || percent > 0.8f) { + throw new IllegalArgumentException("setMemCacheSizePercent - percent must be " + + "between 0.01 and 0.8 (inclusive)"); + } + memCacheSize = Math.round(percent * Runtime.getRuntime().maxMemory() / 1024); + } + } + + /** + * @param candidate - Bitmap to check + * @param targetOptions - Options that have the out* value populated + * @return true if candidate can be used for inBitmap re-use with + * targetOptions + */ + @TargetApi(VERSION_CODES.JELLY_BEAN) + private static boolean canUseForInBitmap( + Bitmap candidate, BitmapFactory.Options targetOptions) { + //BEGIN_INCLUDE(can_use_for_inbitmap) + if (!Utils.hasJellyBean()) { + // On earlier versions, the dimensions must match exactly and the inSampleSize must be 1 + return candidate.getWidth() == targetOptions.outWidth + && candidate.getHeight() == targetOptions.outHeight + && targetOptions.inSampleSize == 1; + } + + // From Android 4.4 (KitKat) onward we can re-use if the byte size of the new bitmap + // is smaller than the reusable bitmap candidate allocation byte count. + int width = targetOptions.outWidth / targetOptions.inSampleSize; + int height = targetOptions.outHeight / targetOptions.inSampleSize; + int byteCount = width * height * getBytesPerPixel(candidate.getConfig()); + return byteCount <= candidate.getByteCount(); + //END_INCLUDE(can_use_for_inbitmap) + } + + /** + * Return the byte usage per pixel of a bitmap based on its configuration. + * @param config The bitmap configuration. + * @return The byte usage per pixel. + */ + private static int getBytesPerPixel(Config config) { + if (config == Config.ARGB_8888) { + return 4; + } else if (config == Config.RGB_565) { + return 2; + } else if (config == Config.ARGB_4444) { + return 2; + } else if (config == Config.ALPHA_8) { + return 1; + } + return 1; + } + + /** + * Get a usable cache directory (external if available, internal otherwise). + * + * @param context The context to use + * @param uniqueName A unique directory name to append to the cache dir + * @return The cache dir + */ + public static File getDiskCacheDir(Context context, String uniqueName) { + // Check if media is mounted or storage is built-in, if so, try and use external cache dir + // otherwise use internal cache dir + final String cachePath = + Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) || + !isExternalStorageRemovable() ? getExternalCacheDir(context).getPath() : + context.getCacheDir().getPath(); + + return new File(cachePath + File.separator + uniqueName); + } + + /** + * A hashing method that changes a string (like a URL) into a hash suitable for using as a + * disk filename. + */ + public static String hashKeyForDisk(String key) { + String cacheKey; + try { + final MessageDigest mDigest = MessageDigest.getInstance("MD5"); + mDigest.update(key.getBytes()); + cacheKey = bytesToHexString(mDigest.digest()); + } catch (NoSuchAlgorithmException e) { + cacheKey = String.valueOf(key.hashCode()); + } + return cacheKey; + } + + private static String bytesToHexString(byte[] bytes) { + // http://stackoverflow.com/questions/332079 + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < bytes.length; i++) { + String hex = Integer.toHexString(0xFF & bytes[i]); + if (hex.length() == 1) { + sb.append('0'); + } + sb.append(hex); + } + return sb.toString(); + } + + /** + * Get the size in bytes of a bitmap in a BitmapDrawable. Note that from Android 4.4 (KitKat) + * onward this returns the allocated memory size of the bitmap which can be larger than the + * actual bitmap data byte count (in the case it was re-used). + * + * @param value + * @return size in bytes + */ + @TargetApi(VERSION_CODES.JELLY_BEAN) + public static int getBitmapSize(BitmapDrawable value) { + Bitmap bitmap = value.getBitmap(); + + // From KitKat onward use getAllocationByteCount() as allocated bytes can potentially be + // larger than bitmap byte count. + if (Utils.hasJellyBean()) { + return bitmap.getByteCount(); + } + + if (Utils.hasHoneycombMR1()) { + return bitmap.getByteCount(); + } + + // Pre HC-MR1 + return bitmap.getRowBytes() * bitmap.getHeight(); + } + + /** + * Check if external storage is built-in or removable. + * + * @return True if external storage is removable (like an SD card), false + * otherwise. + */ + @TargetApi(VERSION_CODES.GINGERBREAD) + public static boolean isExternalStorageRemovable() { + if (Utils.hasGingerbread()) { + return Environment.isExternalStorageRemovable(); + } + return true; + } + + /** + * Get the external app cache directory. + * + * @param context The context to use + * @return The external cache dir + */ + @TargetApi(VERSION_CODES.FROYO) + public static File getExternalCacheDir(Context context) { + if (Utils.hasFroyo()) { + return context.getExternalCacheDir(); + } + + // Before Froyo we need to construct the external cache dir ourselves + final String cacheDir = "/Android/data/" + context.getPackageName() + "/cache/"; + return new File(Environment.getExternalStorageDirectory().getPath() + cacheDir); + } + + /** + * Check how much usable space is available at a given path. + * + * @param path The path to check + * @return The space available in bytes + */ + @TargetApi(VERSION_CODES.GINGERBREAD) + public static long getUsableSpace(File path) { + if (Utils.hasGingerbread()) { + return path.getUsableSpace(); + } + final StatFs stats = new StatFs(path.getPath()); + return (long) stats.getBlockSize() * (long) stats.getAvailableBlocks(); + } + + /** + * Locate an existing instance of this Fragment or if not found, create and + * add it using FragmentManager. + * + * @param fm The FragmentManager manager to use. + * @return The existing instance of the Fragment or the new instance if just + * created. + */ + private static RetainFragment findOrCreateRetainFragment(FragmentManager fm) { + //BEGIN_INCLUDE(find_create_retain_fragment) + // Check to see if we have retained the worker fragment. + RetainFragment mRetainFragment = (RetainFragment) fm.findFragmentByTag(TAG); + + // If not retained (or first time running), we need to create and add it. + if (mRetainFragment == null) { + mRetainFragment = new RetainFragment(); + fm.beginTransaction().add(mRetainFragment, TAG).commitAllowingStateLoss(); + } + + return mRetainFragment; + //END_INCLUDE(find_create_retain_fragment) + } + + /** + * A simple non-UI Fragment that stores a single Object and is retained over configuration + * changes. It will be used to retain the ImageCache object. + */ + public static class RetainFragment extends Fragment { + private Object mObject; + + /** + * Empty constructor as per the Fragment documentation + */ + public RetainFragment() {} + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + // Make sure this Fragment is retained over a configuration change + setRetainInstance(true); + } + + /** + * Store a single object in this Fragment. + * + * @param object The object to store + */ + public void setObject(Object object) { + mObject = object; + } + + /** + * Get the stored object. + * + * @return The stored object + */ + public Object getObject() { + return mObject; + } + } + +} diff --git a/opensrp-gizi/src/main/java/util/ImageFetcher.java b/opensrp-gizi/src/main/java/util/ImageFetcher.java new file mode 100644 index 0000000..f84a878 --- /dev/null +++ b/opensrp-gizi/src/main/java/util/ImageFetcher.java @@ -0,0 +1,310 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package util; + +import android.content.Context; +import android.graphics.Bitmap; +import android.net.ConnectivityManager; +import android.net.NetworkInfo; +import android.os.Build; +import android.util.Log; +import android.widget.Toast; + +import org.ei.opensrp.BuildConfig; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.File; +import java.io.FileDescriptor; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.net.URLConnection; + +/** + * A simple subclass of {@link ImageResizer} that fetches and resizes images fetched from a URL. + */ +public class ImageFetcher extends ImageResizer { + private static final String TAG = "ImageFetcher"; + private static final int HTTP_CACHE_SIZE = 10 * 1024 * 1024; // 10MB + private static final String HTTP_CACHE_DIR = "http"; + private static final int IO_BUFFER_SIZE = 8 * 1024; + + private DiskLruCache mHttpDiskCache; + private File mHttpCacheDir; + private boolean mHttpDiskCacheStarting = true; + private final Object mHttpDiskCacheLock = new Object(); + private static final int DISK_CACHE_INDEX = 0; + + /** + * Initialize providing a target image width and height for the processing images. + * + * @param context + * @param imageWidth + * @param imageHeight + */ + public ImageFetcher(Context context, int imageWidth, int imageHeight) { + super(context, imageWidth, imageHeight); + init(context); + } + + /** + * Initialize providing a single target image size (used for both width and height); + * + * @param context + * @param imageSize + */ + public ImageFetcher(Context context, int imageSize) { + super(context, imageSize); + init(context); + } + + private void init(Context context) { + checkConnection(context); + mHttpCacheDir = ImageCache.getDiskCacheDir(context, HTTP_CACHE_DIR); + } + + @Override + protected void initDiskCacheInternal() { + super.initDiskCacheInternal(); + initHttpDiskCache(); + } + + private void initHttpDiskCache() { + if (!mHttpCacheDir.exists()) { + mHttpCacheDir.mkdirs(); + } + synchronized (mHttpDiskCacheLock) { + if (ImageCache.getUsableSpace(mHttpCacheDir) > HTTP_CACHE_SIZE) { + try { + mHttpDiskCache = DiskLruCache.open(mHttpCacheDir, 1, 1, HTTP_CACHE_SIZE); + if (BuildConfig.DEBUG) { + Log.d(TAG, "HTTP cache initialized"); + } + } catch (IOException e) { + mHttpDiskCache = null; + } + } + mHttpDiskCacheStarting = false; + mHttpDiskCacheLock.notifyAll(); + } + } + + @Override + protected void clearCacheInternal() { + super.clearCacheInternal(); + synchronized (mHttpDiskCacheLock) { + if (mHttpDiskCache != null && !mHttpDiskCache.isClosed()) { + try { + mHttpDiskCache.delete(); + if (BuildConfig.DEBUG) { + Log.d(TAG, "HTTP cache cleared"); + } + } catch (IOException e) { + Log.e(TAG, "clearCacheInternal - " + e); + } + mHttpDiskCache = null; + mHttpDiskCacheStarting = true; + initHttpDiskCache(); + } + } + } + + @Override + protected void flushCacheInternal() { + super.flushCacheInternal(); + synchronized (mHttpDiskCacheLock) { + if (mHttpDiskCache != null) { + try { + mHttpDiskCache.flush(); + if (BuildConfig.DEBUG) { + Log.d(TAG, "HTTP cache flushed"); + } + } catch (IOException e) { + Log.e(TAG, "flush - " + e); + } + } + } + } + + @Override + protected void closeCacheInternal() { + super.closeCacheInternal(); + synchronized (mHttpDiskCacheLock) { + if (mHttpDiskCache != null) { + try { + if (!mHttpDiskCache.isClosed()) { + mHttpDiskCache.close(); + mHttpDiskCache = null; + if (BuildConfig.DEBUG) { + Log.d(TAG, "HTTP cache closed"); + } + } + } catch (IOException e) { + Log.e(TAG, "closeCacheInternal - " + e); + } + } + } + } + + /** + * Simple network connection check. + * + * @param context + */ + private void checkConnection(Context context) { + final ConnectivityManager cm = + (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); + final NetworkInfo networkInfo = cm.getActiveNetworkInfo(); + if (networkInfo == null || !networkInfo.isConnectedOrConnecting()) { + Toast.makeText(context, "no network connection", Toast.LENGTH_LONG).show(); + Log.e(TAG, "checkConnection - no connection found"); + } + } + + /** + * The main process method, which will be called by the ImageWorker in the AsyncTask background + * thread. + * + * @param data The data to load the bitmap, in this case, a regular http URL + * @return The downloaded and resized bitmap + */ + private Bitmap processBitmap(String data) { + if (BuildConfig.DEBUG) { + Log.d(TAG, "processBitmap - " + data); + } + + final String key = ImageCache.hashKeyForDisk(data); + FileDescriptor fileDescriptor = null; + FileInputStream fileInputStream = null; + DiskLruCache.Snapshot snapshot; + synchronized (mHttpDiskCacheLock) { + // Wait for disk cache to initialize + while (mHttpDiskCacheStarting) { + try { + mHttpDiskCacheLock.wait(); + } catch (InterruptedException e) {} + } + + if (mHttpDiskCache != null) { + try { + snapshot = mHttpDiskCache.get(key); + if (snapshot == null) { + if (BuildConfig.DEBUG) { + Log.d(TAG, "processBitmap, not found in http cache, downloading..."); + } + DiskLruCache.Editor editor = mHttpDiskCache.edit(key); + if (editor != null) { + if (downloadUrlToStream(data, + editor.newOutputStream(DISK_CACHE_INDEX))) { + editor.commit(); + } else { + editor.abort(); + } + } + snapshot = mHttpDiskCache.get(key); + } + if (snapshot != null) { + fileInputStream = + (FileInputStream) snapshot.getInputStream(DISK_CACHE_INDEX); + fileDescriptor = fileInputStream.getFD(); + } + } catch (IOException e) { + Log.e(TAG, "processBitmap - " + e); + } catch (IllegalStateException e) { + Log.e(TAG, "processBitmap - " + e); + } finally { + if (fileDescriptor == null && fileInputStream != null) { + try { + fileInputStream.close(); + } catch (IOException e) {} + } + } + } + } + + Bitmap bitmap = null; + if (fileDescriptor != null) { + bitmap = decodeSampledBitmapFromDescriptor(fileDescriptor, mImageWidth, + mImageHeight, getImageCache()); + } + if (fileInputStream != null) { + try { + fileInputStream.close(); + } catch (IOException e) {} + } + return bitmap; + } + + @Override + protected Bitmap processBitmap(Object data) { + return processBitmap(String.valueOf(data)); + } + + /** + * Download a bitmap from a URL and write the content to an output stream. + * + * @param urlString The URL to fetch + * @return true if successful, false otherwise + */ + public boolean downloadUrlToStream(String urlString, OutputStream outputStream) { + disableConnectionReuseIfNecessary(); + URLConnection urlConnection = null; + BufferedOutputStream out = null; + BufferedInputStream in = null; + + try { + final URL url = new URL(urlString); + urlConnection = (URLConnection) url.openConnection(); + in = new BufferedInputStream(urlConnection.getInputStream(), IO_BUFFER_SIZE); + out = new BufferedOutputStream(outputStream, IO_BUFFER_SIZE); + + int b; + while ((b = in.read()) != -1) { + out.write(b); + } + return true; + } catch (final IOException e) { + Log.e(TAG, "Error in downloadBitmap - " + e); + } finally { + if (urlConnection != null) { +// urlConnection.disconnect(); + } + try { + if (out != null) { + out.close(); + } + if (in != null) { + in.close(); + } + } catch (final IOException e) {} + } + return false; + } + + /** + * Workaround for bug pre-Froyo, see here for more info: + * http://android-developers.blogspot.com/2011/09/androids-http-clients.html + */ + public static void disableConnectionReuseIfNecessary() { + // HTTP connection reuse which was buggy pre-froyo + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.FROYO) { + System.setProperty("http.keepAlive", "false"); + } + } +} diff --git a/opensrp-gizi/src/main/java/util/ImageResizer.java b/opensrp-gizi/src/main/java/util/ImageResizer.java new file mode 100644 index 0000000..7844b2e --- /dev/null +++ b/opensrp-gizi/src/main/java/util/ImageResizer.java @@ -0,0 +1,270 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package util; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.os.Build; +import android.util.Log; + +import org.ei.opensrp.BuildConfig; + +import java.io.FileDescriptor; + +/** + * A simple subclass of {@link ImageWorker} that resizes images from resources given a target width + * and height. Useful for when the input images might be too large to simply load directly into + * memory. + */ +public class ImageResizer extends ImageWorker { + private static final String TAG = "ImageResizer"; + protected int mImageWidth; + protected int mImageHeight; + + /** + * Initialize providing a single target image size (used for both width and height); + * + * @param context + * @param imageWidth + * @param imageHeight + */ + public ImageResizer(Context context, int imageWidth, int imageHeight) { + super(context); + setImageSize(imageWidth, imageHeight); + } + + /** + * Initialize providing a single target image size (used for both width and height); + * + * @param context + * @param imageSize + */ + public ImageResizer(Context context, int imageSize) { + super(context); + setImageSize(imageSize); + } + + /** + * Set the target image width and height. + * + * @param width + * @param height + */ + public void setImageSize(int width, int height) { + mImageWidth = width; + mImageHeight = height; + } + + /** + * Set the target image size (width and height will be the same). + * + * @param size + */ + public void setImageSize(int size) { + setImageSize(size, size); + } + + /** + * The main processing method. This happens in a background task. In this case we are just + * sampling down the bitmap and returning it from a resource. + * + * @param resId + * @return + */ + private Bitmap processBitmap(int resId) { + if (BuildConfig.DEBUG) { + Log.d(TAG, "processBitmap - " + resId); + } + return decodeSampledBitmapFromResource(mResources, resId, mImageWidth, + mImageHeight, getImageCache()); + } + + @Override + protected Bitmap processBitmap(Object data) { + return processBitmap(Integer.parseInt(String.valueOf(data))); + } + + /** + * Decode and sample down a bitmap from resources to the requested width and height. + * + * @param res The resources object containing the image data + * @param resId The resource id of the image data + * @param reqWidth The requested width of the resulting bitmap + * @param reqHeight The requested height of the resulting bitmap + * @param cache The ImageCache used to find candidate bitmaps for use with inBitmap + * @return A bitmap sampled down from the original with the same aspect ratio and dimensions + * that are equal to or greater than the requested width and height + */ + public static Bitmap decodeSampledBitmapFromResource(Resources res, int resId, + int reqWidth, int reqHeight, ImageCache cache) { + + // BEGIN_INCLUDE (read_bitmap_dimensions) + // First decode with inJustDecodeBounds=true to check dimensions + final BitmapFactory.Options options = new BitmapFactory.Options(); + options.inJustDecodeBounds = true; + BitmapFactory.decodeResource(res, resId, options); + + // Calculate inSampleSize + options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); + // END_INCLUDE (read_bitmap_dimensions) + + // If we're running on Honeycomb or newer, try to use inBitmap + if (Utils.hasHoneycomb()) { + addInBitmapOptions(options, cache); + } + + // Decode bitmap with inSampleSize set + options.inJustDecodeBounds = false; + return BitmapFactory.decodeResource(res, resId, options); + } + + /** + * Decode and sample down a bitmap from a file to the requested width and height. + * + * @param filename The full path of the file to decode + * @param reqWidth The requested width of the resulting bitmap + * @param reqHeight The requested height of the resulting bitmap + * @param cache The ImageCache used to find candidate bitmaps for use with inBitmap + * @return A bitmap sampled down from the original with the same aspect ratio and dimensions + * that are equal to or greater than the requested width and height + */ + public static Bitmap decodeSampledBitmapFromFile(String filename, + int reqWidth, int reqHeight, ImageCache cache) { + + // First decode with inJustDecodeBounds=true to check dimensions + final BitmapFactory.Options options = new BitmapFactory.Options(); + options.inJustDecodeBounds = true; + BitmapFactory.decodeFile(filename, options); + + // Calculate inSampleSize + options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); + + // If we're running on Honeycomb or newer, try to use inBitmap + if (Utils.hasHoneycomb()) { + addInBitmapOptions(options, cache); + } + + // Decode bitmap with inSampleSize set + options.inJustDecodeBounds = false; + return BitmapFactory.decodeFile(filename, options); + } + + /** + * Decode and sample down a bitmap from a file input stream to the requested width and height. + * + * @param fileDescriptor The file descriptor to read from + * @param reqWidth The requested width of the resulting bitmap + * @param reqHeight The requested height of the resulting bitmap + * @param cache The ImageCache used to find candidate bitmaps for use with inBitmap + * @return A bitmap sampled down from the original with the same aspect ratio and dimensions + * that are equal to or greater than the requested width and height + */ + public static Bitmap decodeSampledBitmapFromDescriptor( + FileDescriptor fileDescriptor, int reqWidth, int reqHeight, ImageCache cache) { + + // First decode with inJustDecodeBounds=true to check dimensions + final BitmapFactory.Options options = new BitmapFactory.Options(); + options.inJustDecodeBounds = true; + BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options); + + // Calculate inSampleSize + options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight); + + // Decode bitmap with inSampleSize set + options.inJustDecodeBounds = false; + + // If we're running on Honeycomb or newer, try to use inBitmap + if (Utils.hasHoneycomb()) { + addInBitmapOptions(options, cache); + } + + return BitmapFactory.decodeFileDescriptor(fileDescriptor, null, options); + } + + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + private static void addInBitmapOptions(BitmapFactory.Options options, ImageCache cache) { + //BEGIN_INCLUDE(add_bitmap_options) + // inBitmap only works with mutable bitmaps so force the decoder to + // return mutable bitmaps. + options.inMutable = true; + + if (cache != null) { + // Try and find a bitmap to use for inBitmap + Bitmap inBitmap = cache.getBitmapFromReusableSet(options); + + if (inBitmap != null) { + options.inBitmap = inBitmap; + } + } + //END_INCLUDE(add_bitmap_options) + } + + /** + * Calculate an inSampleSize for use in a {@link BitmapFactory.Options} object when decoding + * bitmaps using the decode* methods from {@link BitmapFactory}. This implementation calculates + * the closest inSampleSize that is a power of 2 and will result in the final decoded bitmap + * having a width and height equal to or larger than the requested width and height. + * + * @param options An options object with out* params already populated (run through a decode* + * method with inJustDecodeBounds==true + * @param reqWidth The requested width of the resulting bitmap + * @param reqHeight The requested height of the resulting bitmap + * @return The value to be used for inSampleSize + */ + public static int calculateInSampleSize(BitmapFactory.Options options, + int reqWidth, int reqHeight) { + // BEGIN_INCLUDE (calculate_sample_size) + // Raw height and width of image + final int height = options.outHeight; + final int width = options.outWidth; + int inSampleSize = 1; + + if (height > reqHeight || width > reqWidth) { + + final int halfHeight = height / 2; + final int halfWidth = width / 2; + + // Calculate the largest inSampleSize value that is a power of 2 and keeps both + // height and width larger than the requested height and width. + while ((halfHeight / inSampleSize) > reqHeight + && (halfWidth / inSampleSize) > reqWidth) { + inSampleSize *= 2; + } + + // This offers some additional logic in case the image has a strange + // aspect ratio. For example, a panorama may have a much larger + // width than height. In these cases the total pixels might still + // end up being too large to fit comfortably in memory, so we should + // be more aggressive with sample down the image (=larger inSampleSize). + + long totalPixels = width * height / inSampleSize; + + // Anything more than 2x the requested pixels we'll sample down further + final long totalReqPixelsCap = reqWidth * reqHeight * 2; + + while (totalPixels > totalReqPixelsCap) { + inSampleSize *= 2; + totalPixels /= 2; + } + } + return inSampleSize; + // END_INCLUDE (calculate_sample_size) + } +} diff --git a/opensrp-gizi/src/main/java/util/ImageWorker.java b/opensrp-gizi/src/main/java/util/ImageWorker.java new file mode 100644 index 0000000..c98ac62 --- /dev/null +++ b/opensrp-gizi/src/main/java/util/ImageWorker.java @@ -0,0 +1,485 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package util; + +import android.app.Activity; +import android.app.FragmentManager; +import android.content.Context; +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.graphics.drawable.TransitionDrawable; +import android.util.Log; +import android.widget.ImageView; + +import org.ei.opensrp.BuildConfig; + +import java.lang.ref.WeakReference; + +/** + * This class wraps up completing some arbitrary long running work when loading a bitmap to an + * ImageView. It handles things like using a memory and disk cache, running the work in a background + * thread and setting a placeholder image. + */ +public abstract class ImageWorker { + private static final String TAG = "ImageWorker"; + private static final int FADE_IN_TIME = 200; + + private ImageCache mImageCache; + private ImageCache.ImageCacheParams mImageCacheParams; + private Bitmap mLoadingBitmap; + private boolean mFadeInBitmap = true; + private boolean mExitTasksEarly = false; + protected boolean mPauseWork = false; + private final Object mPauseWorkLock = new Object(); + + protected Resources mResources; + + private static final int MESSAGE_CLEAR = 0; + private static final int MESSAGE_INIT_DISK_CACHE = 1; + private static final int MESSAGE_FLUSH = 2; + private static final int MESSAGE_CLOSE = 3; + + protected ImageWorker(Context context) { + mResources = context.getResources(); + } + + /** + * Load an image specified by the data parameter into an ImageView (override + * {@link ImageWorker#processBitmap(Object)} to define the processing logic). A memory and + * disk cache will be used if an {@link ImageCache} has been added using + * . If the + * image is found in the memory cache, it is set immediately, otherwise an {@link AsyncTask} + * will be created to asynchronously load the bitmap. + * + * @param data The URL of the image to download. + * @param imageView The ImageView to bind the downloaded image to. + */ + public void loadImage(Object data, ImageView imageView) { + if (data == null) { + return; + } + + BitmapDrawable value = null; + + if (mImageCache != null) { + value = mImageCache.getBitmapFromMemCache(String.valueOf(data)); + } + + if (value != null) { + // Bitmap found in memory cache + imageView.setImageDrawable(value); + } else if (cancelPotentialWork(data, imageView)) { + //BEGIN_INCLUDE(execute_background_task) + final BitmapWorkerTask task = new BitmapWorkerTask(data, imageView); + final AsyncDrawable asyncDrawable = + new AsyncDrawable(mResources, mLoadingBitmap, task); + imageView.setImageDrawable(asyncDrawable); + + // NOTE: This uses a custom version of AsyncTask that has been pulled from the + // framework and slightly modified. Refer to the docs at the top of the class + // for more info on what was changed. + task.executeOnExecutor(AsyncTask.DUAL_THREAD_EXECUTOR); + //END_INCLUDE(execute_background_task) + } + } + + /** + * Set placeholder bitmap that shows when the the background thread is running. + * + * @param bitmap + */ + public void setLoadingImage(Bitmap bitmap) { + mLoadingBitmap = bitmap; + } + + /** + * Set placeholder bitmap that shows when the the background thread is running. + * + * @param resId + */ + public void setLoadingImage(int resId) { + mLoadingBitmap = BitmapFactory.decodeResource(mResources, resId); + } + + /** + * Adds an {@link ImageCache} to this {@link ImageWorker} to handle disk and memory bitmap + * caching. + * @param fragmentManager + * @param cacheParams The cache parameters to use for the image cache. + */ + public void addImageCache(FragmentManager fragmentManager, + ImageCache.ImageCacheParams cacheParams) { + mImageCacheParams = cacheParams; + mImageCache = ImageCache.getInstance(fragmentManager, mImageCacheParams); + new CacheAsyncTask().execute(MESSAGE_INIT_DISK_CACHE); + } + + /** + * Adds an {@link ImageCache} to this {@link ImageWorker} to handle disk and memory bitmap + * caching. + * @param activity + * @param diskCacheDirectoryName See + * {@link ImageCache.ImageCacheParams#ImageCacheParams(Context, String)}. + */ + public void addImageCache(Activity activity, String diskCacheDirectoryName) { + mImageCacheParams = new ImageCache.ImageCacheParams(activity, diskCacheDirectoryName); + mImageCache = ImageCache.getInstance(activity.getFragmentManager(), mImageCacheParams); + new CacheAsyncTask().execute(MESSAGE_INIT_DISK_CACHE); + } + + /** + * If set to true, the image will fade-in once it has been loaded by the background thread. + */ + public void setImageFadeIn(boolean fadeIn) { + mFadeInBitmap = fadeIn; + } + + public void setExitTasksEarly(boolean exitTasksEarly) { + mExitTasksEarly = exitTasksEarly; + setPauseWork(false); + } + + /** + * Subclasses should override this to define any processing or work that must happen to produce + * the final bitmap. This will be executed in a background thread and be long running. For + * example, you could resize a large bitmap here, or pull down an image from the network. + * + * @param data The data to identify which image to process, as provided by + * {@link ImageWorker#loadImage(Object, ImageView)} + * @return The processed bitmap + */ + protected abstract Bitmap processBitmap(Object data); + + /** + * @return The {@link ImageCache} object currently being used by this ImageWorker. + */ + protected ImageCache getImageCache() { + return mImageCache; + } + + /** + * Cancels any pending work attached to the provided ImageView. + * @param imageView + */ + public static void cancelWork(ImageView imageView) { + final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); + if (bitmapWorkerTask != null) { + bitmapWorkerTask.cancel(true); + if (BuildConfig.DEBUG) { + final Object bitmapData = bitmapWorkerTask.mData; + Log.d(TAG, "cancelWork - cancelled work for " + bitmapData); + } + } + } + + /** + * Returns true if the current work has been canceled or if there was no work in + * progress on this image view. + * Returns false if the work in progress deals with the same data. The work is not + * stopped in that case. + */ + public static boolean cancelPotentialWork(Object data, ImageView imageView) { + //BEGIN_INCLUDE(cancel_potential_work) + final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); + + if (bitmapWorkerTask != null) { + final Object bitmapData = bitmapWorkerTask.mData; + if (bitmapData == null || !bitmapData.equals(data)) { + bitmapWorkerTask.cancel(true); + if (BuildConfig.DEBUG) { + Log.d(TAG, "cancelPotentialWork - cancelled work for " + data); + } + } else { + // The same work is already in progress. + return false; + } + } + return true; + //END_INCLUDE(cancel_potential_work) + } + + /** + * @param imageView Any imageView + * @return Retrieve the currently active work task (if any) associated with this imageView. + * null if there is no such task. + */ + private static BitmapWorkerTask getBitmapWorkerTask(ImageView imageView) { + if (imageView != null) { + final Drawable drawable = imageView.getDrawable(); + if (drawable instanceof AsyncDrawable) { + final AsyncDrawable asyncDrawable = (AsyncDrawable) drawable; + return asyncDrawable.getBitmapWorkerTask(); + } + } + return null; + } + + /** + * The actual AsyncTask that will asynchronously process the image. + */ + private class BitmapWorkerTask extends AsyncTask { + private Object mData; + private final WeakReference imageViewReference; + + public BitmapWorkerTask(Object data, ImageView imageView) { + mData = data; + imageViewReference = new WeakReference(imageView); + } + + /** + * Background processing. + */ + @Override + protected BitmapDrawable doInBackground(Void... params) { + //BEGIN_INCLUDE(load_bitmap_in_background) + if (BuildConfig.DEBUG) { + Log.d(TAG, "doInBackground - starting work"); + } + + final String dataString = String.valueOf(mData); + Bitmap bitmap = null; + BitmapDrawable drawable = null; + + // Wait here if work is paused and the task is not cancelled + synchronized (mPauseWorkLock) { + while (mPauseWork && !isCancelled()) { + try { + mPauseWorkLock.wait(); + } catch (InterruptedException e) {} + } + } + + // If the image cache is available and this task has not been cancelled by another + // thread and the ImageView that was originally bound to this task is still bound back + // to this task and our "exit early" flag is not set then try and fetch the bitmap from + // the cache + if (mImageCache != null && !isCancelled() && getAttachedImageView() != null + && !mExitTasksEarly) { + bitmap = mImageCache.getBitmapFromDiskCache(dataString); + } + + // If the bitmap was not found in the cache and this task has not been cancelled by + // another thread and the ImageView that was originally bound to this task is still + // bound back to this task and our "exit early" flag is not set, then call the main + // process method (as implemented by a subclass) + if (bitmap == null && !isCancelled() && getAttachedImageView() != null + && !mExitTasksEarly) { + bitmap = processBitmap(mData); + } + + // If the bitmap was processed and the image cache is available, then add the processed + // bitmap to the cache for future use. Note we don't check if the task was cancelled + // here, if it was, and the thread is still running, we may as well add the processed + // bitmap to our cache as it might be used again in the future + if (bitmap != null) { + if (Utils.hasHoneycomb()) { + // Running on Honeycomb or newer, so wrap in a standard BitmapDrawable + drawable = new BitmapDrawable(mResources, bitmap); + } else { + // Running on Gingerbread or older, so wrap in a RecyclingBitmapDrawable + // which will recycle automagically + drawable = new RecyclingBitmapDrawable(mResources, bitmap); + } + + if (mImageCache != null) { + mImageCache.addBitmapToCache(dataString, drawable); + } + } + + if (BuildConfig.DEBUG) { + Log.d(TAG, "doInBackground - finished work"); + } + + return drawable; + //END_INCLUDE(load_bitmap_in_background) + } + + /** + * Once the image is processed, associates it to the imageView + */ + @Override + protected void onPostExecute(BitmapDrawable value) { + //BEGIN_INCLUDE(complete_background_work) + // if cancel was called on this task or the "exit early" flag is set then we're done + if (isCancelled() || mExitTasksEarly) { + value = null; + } + + final ImageView imageView = getAttachedImageView(); + if (value != null && imageView != null) { + if (BuildConfig.DEBUG) { + Log.d(TAG, "onPostExecute - setting bitmap"); + } + setImageDrawable(imageView, value); + } + //END_INCLUDE(complete_background_work) + } + + @Override + protected void onCancelled(BitmapDrawable value) { + super.onCancelled(value); + synchronized (mPauseWorkLock) { + mPauseWorkLock.notifyAll(); + } + } + + /** + * Returns the ImageView associated with this task as long as the ImageView's task still + * points to this task as well. Returns null otherwise. + */ + private ImageView getAttachedImageView() { + final ImageView imageView = imageViewReference.get(); + final BitmapWorkerTask bitmapWorkerTask = getBitmapWorkerTask(imageView); + + if (this == bitmapWorkerTask) { + return imageView; + } + + return null; + } + } + + /** + * A custom Drawable that will be attached to the imageView while the work is in progress. + * Contains a reference to the actual worker task, so that it can be stopped if a new binding is + * required, and makes sure that only the last started worker process can bind its result, + * independently of the finish order. + */ + private static class AsyncDrawable extends BitmapDrawable { + private final WeakReference bitmapWorkerTaskReference; + + public AsyncDrawable(Resources res, Bitmap bitmap, BitmapWorkerTask bitmapWorkerTask) { + super(res, bitmap); + bitmapWorkerTaskReference = + new WeakReference(bitmapWorkerTask); + } + + public BitmapWorkerTask getBitmapWorkerTask() { + return bitmapWorkerTaskReference.get(); + } + } + + /** + * Called when the processing is complete and the final drawable should be + * set on the ImageView. + * + * @param imageView + * @param drawable + */ + private void setImageDrawable(ImageView imageView, Drawable drawable) { + if (mFadeInBitmap) { + // Transition drawable with a transparent drawable and the final drawable + final TransitionDrawable td = + new TransitionDrawable(new Drawable[] { + new ColorDrawable(android.R.color.transparent), + drawable + }); + // Set background to loading bitmap + imageView.setBackgroundDrawable( + new BitmapDrawable(mResources, mLoadingBitmap)); + + imageView.setImageDrawable(td); + td.startTransition(FADE_IN_TIME); + } else { + imageView.setImageDrawable(drawable); + } + } + + /** + * Pause any ongoing background work. This can be used as a temporary + * measure to improve performance. For example background work could + * be paused when a ListView or GridView is being scrolled using a + * {@link android.widget.AbsListView.OnScrollListener} to keep + * scrolling smooth. + *

+ * If work is paused, be sure setPauseWork(false) is called again + * before your fragment or activity is destroyed (for example during + * {@link Activity#onPause()}), or there is a risk the + * background thread will never finish. + */ + public void setPauseWork(boolean pauseWork) { + synchronized (mPauseWorkLock) { + mPauseWork = pauseWork; + if (!mPauseWork) { + mPauseWorkLock.notifyAll(); + } + } + } + + protected class CacheAsyncTask extends AsyncTask { + + @Override + protected Void doInBackground(Object... params) { + switch ((Integer)params[0]) { + case MESSAGE_CLEAR: + clearCacheInternal(); + break; + case MESSAGE_INIT_DISK_CACHE: + initDiskCacheInternal(); + break; + case MESSAGE_FLUSH: + flushCacheInternal(); + break; + case MESSAGE_CLOSE: + closeCacheInternal(); + break; + } + return null; + } + } + + protected void initDiskCacheInternal() { + if (mImageCache != null) { + mImageCache.initDiskCache(); + } + } + + protected void clearCacheInternal() { + if (mImageCache != null) { + mImageCache.clearCache(); + } + } + + protected void flushCacheInternal() { + if (mImageCache != null) { + mImageCache.flush(); + } + } + + protected void closeCacheInternal() { + if (mImageCache != null) { + mImageCache.close(); + mImageCache = null; + } + } + + public void clearCache() { + new CacheAsyncTask().execute(MESSAGE_CLEAR); + } + + public void flushCache() { + new CacheAsyncTask().execute(MESSAGE_FLUSH); + } + + public void closeCache() { + new CacheAsyncTask().execute(MESSAGE_CLOSE); + } +} diff --git a/opensrp-gizi/src/main/java/util/KMS/KmsCalc.java b/opensrp-gizi/src/main/java/util/KMS/KmsCalc.java new file mode 100644 index 0000000..50c8e96 --- /dev/null +++ b/opensrp-gizi/src/main/java/util/KMS/KmsCalc.java @@ -0,0 +1,83 @@ +package util.KMS; + +import org.apache.http.io.SessionOutputBuffer; + +/** + * Created by Iq on 27/05/16. + */ +public class KmsCalc { + + public int monthAges(String lastVisitDate,String currentDate){ + if(lastVisitDate.length()<10 || currentDate.length()<10) + return 0; + int tahun = Integer.parseInt(currentDate.substring(0, 4)) - Integer.parseInt(lastVisitDate.substring(0, 4)); + int bulan = Integer.parseInt(currentDate.substring(5, 7)) - Integer.parseInt(lastVisitDate.substring(5, 7)); + int hari = Integer.parseInt(currentDate.substring(8)) - Integer.parseInt(lastVisitDate.substring(8)); + return (tahun * 12 + bulan + (int) (hari / 30)); + } + + public String cek2T(KmsPerson bayi){ + boolean status = true; + String measureDate[] = {bayi.getLastVisitDate(),bayi.getSecondLastVisitDate()}; + double weight[] = {bayi.getWeight(),bayi.getPreviousWeight()}; + status = status && (cekWeightStatus(bayi.isMale(), bayi.getDateOfBirth(), measureDate, weight).toLowerCase().equals("not gaining weight")); + String measureDate2[] = {bayi.getSecondLastVisitDate(),bayi.getThirdLastVisitDate()}; + double weight2[] = {bayi.getPreviousWeight(),bayi.getSecondLastWeight()}; + status = status && (cekWeightStatus(bayi.isMale(), bayi.getDateOfBirth(), measureDate2, weight2).toLowerCase().equals("not gaining weight")); + bayi.Tidak2Kali = status; + return (bayi.Tidak2Kali ? "Yes":"No"); + } + + + + public String cekWeightStatus(KmsPerson bayi){ + ////System.out.println("check weight status"); + String measureDate[] = {bayi.getLastVisitDate(),bayi.getSecondLastVisitDate()}; + double weight[] = {bayi.getWeight(),bayi.getPreviousWeight()}; + bayi.StatusBeratBadan = cekWeightStatus(bayi.isMale(),bayi.getDateOfBirth(),measureDate,weight); + return bayi.StatusBeratBadan; + } + + public String cekWeightStatus(boolean isMale, String dateOfBirth, String measureDate[], double weight[]){ + if( measureDate[1].equals("0") || measureDate[0].equals("") || measureDate[1].equals("")) + return "New"; + else { + System.out.println("check weight status"); + System.out.println("date of birth "+dateOfBirth); + System.out.println("measure date "+measureDate[0]+", "+measureDate[1]); + System.out.println("weight "+weight[0]+", "+weight[1]); + int age = monthAges(dateOfBirth, measureDate[0]); + int range = monthAges(measureDate[1], measureDate[0]); + int stagnanIndicator = (isMale ? 12 : 11); + int index = age > stagnanIndicator ? stagnanIndicator : age; + + return range > 1 + ? "Not attending previous visit" + : ((weight[0] - weight[1] + 0.000000000000004) * 1000) >= KmsConstants.maleWeightUpIndicator[index] + ? "Weight Increase" + : "Not gaining weight"; + } + } + + public String cekBGM(KmsPerson bayi){ + if(bayi.getAge()>60) + return "No"; + bayi.BGM = bayi.isMale() + ? KmsConstants.maleBGM[bayi.getAge()]>bayi.getWeight() + : KmsConstants.femaleBGM[bayi.getAge()]>bayi.getWeight(); + return ""+(bayi.BGM ? "Yes":"No"); + } + + public String cekBawahKuning(KmsPerson bayi){ + if(bayi.getAge()>60) + return "No"; + bayi.GarisKuning = bayi.isMale() + ? ((KmsConstants.maleGarisKuning[bayi.getAge()][0]<=bayi.getWeight()) + && (bayi.getWeight()<=KmsConstants.maleGarisKuning[bayi.getAge()][1])) + : ((KmsConstants.femaleGarisKuning[bayi.getAge()][0]<=bayi.getWeight()) + && (bayi.getWeight()<=KmsConstants.femaleGarisKuning[bayi.getAge()][1])) + ; + return ""+(bayi.GarisKuning ? "Yes":"No"); + } + +} diff --git a/opensrp-gizi/src/main/java/util/KMS/KmsConstants.java b/opensrp-gizi/src/main/java/util/KMS/KmsConstants.java new file mode 100644 index 0000000..5541b05 --- /dev/null +++ b/opensrp-gizi/src/main/java/util/KMS/KmsConstants.java @@ -0,0 +1,52 @@ +package util.KMS; + +/** + * Created by Iq on 02/05/16. + */ +public class KmsConstants { + public static final double []maleBGM = {2.1,2.9,3.8,4.4,4.9,5.3,5.7,5.9,6.2,6.4,6.6,6.8,6.9, + 7.1,7.2,7.4,7.5,7.7,7.8,8,8.1,8.2,8.4,8.5,8.6,8.8, + 8.9,9,9.1,9.2,9.3,9.5,9.6,9.7,9.8,9.9,10,10.1,10.2, + 10.3,10.4,10.5,10.6,10.7,10.8,10.9,11,11.1,11.2,11.3, + 11.4,11.5,11.6,11.7,11.8,11.9,12,12.1,12.2,12.3,12.4 + }; + + public static final double []femaleBGM={2.0,2.7,3.4,4,4.4,4.8,5.1,5.3,5.6,5.8,5.9,6.1,6.3, + 6.4,6.6,6.7,6.9,7,7.2,7.3,7.5,7.6,7.8,7.9,8.1, + 8.2,8.4,8.5,8.6,8.8,8.9,9,9.1,9.2,9.4,9.5,9.6, + 9.7,9.8,9.9,10,10.2,10.3,10.4,10.5,10.6,10.7, + 10.8,10.9,11,11.1,11.2,11.3,11.4,11.5,11.6,11.7, + 11.8,11.9,12,12.1 + }; + + public static final double [][]maleGarisKuning={ + {2.1,2.6},{2.9,3.4},{3.8,4.3},{4.4,5},{4.9,5.5},{5.3,6},{5.7,6.4},{5.9,6.6},{6.2,6.9}, + {6.4,7.1},{6.6,7.3},{6.8,7.5},{6.9,7.7},{7.1,7.9},{7.2,8.1},{7.4,8.3}, + {7.5,8.4},{7.7,8.6},{7.8,8.8},{8,8.9},{8.1,9.1},{8.2,9.2},{8.4,9.4}, + {8.5,9.5},{8.6,9.7},{8.8,9.8},{8.9,10},{9,10.1},{9.1,10.3},{9.2,10.4}, + {9.3,10.5},{9.5,10.7},{9.6,10.8},{9.7,10.9},{9.8,11},{9.9,11.2},{10,11.3}, + {10.1,11.4},{10.2,11.5},{10.3,11.6},{10.4,11.8},{10.5,11.9},{10.6,12}, + {10.7,12.1},{10.8,12.2},{10.9,12.4},{11,12.5},{11.1,12.6},{11.2,12.7}, + {11.3,12.8},{11.4,12.9},{11.5,13.1},{11.6,13.2},{11.7,13.3},{11.8,13.4}, + {11.9,13.5},{12,13.6},{12.1,13.7},{12.2,13.8},{12.3,13.9},{12.4,14.1} + }; + + public static final double [][]femaleGarisKuning={ + {2.0,2.4},{2.7,3.1},{3.4,3.9},{4,4.5},{4.4,5},{4.8,5.4},{5.1,5.7},{5.3,6},{5.6,6.2}, + {5.8,6.5},{5.9,6.7},{6.1,6.9},{6.3,7},{6.4,7.2},{6.6,7.4},{6.7,7.6},{6.9,7.7}, + {7,7.9},{7.2,8.1},{7.3,8.2},{7.5,8.4},{7.6,8.6},{7.8,8.7},{7.9,8.9},{8.1,9}, + {8.2,9.2},{8.4,9.3},{8.5,9.5},{8.6,9.7},{8.8,9.8},{8.9,10},{9,10.1},{9.1,10.3}, + {9.2,10.4},{9.4,10.5},{9.5,10.7},{9.6,10.8},{9.7,10.9},{9.8,11.1},{9.9,11.2}, + {10,11.3},{10.2,11.5},{10.3,11.6},{10.4,11.7},{10.5,11.8},{10.6,12},{10.7,12.1}, + {10.8,12.2},{10.9,12.3},{11,12.5},{11.1,12.6},{11.2,12.7},{11.3,12.8}, + {11.4,12.9},{11.5,13},{11.6,13.1},{11.7,13.2},{11.8,13.4},{11.9,13.5}, + {12,13.6},{12.1,13.7} + }; + + public static final double [] maleWeightUpIndicator={ + 0,800,900,800,600,500,400,400,300,300,300,300,200}; + + public static final double[] femaleWeightUpIndicator={ + 0,800,900,800,600,500,400,300,300,300,300,200}; + +} diff --git a/opensrp-gizi/src/main/java/util/KMS/KmsPerson.java b/opensrp-gizi/src/main/java/util/KMS/KmsPerson.java new file mode 100644 index 0000000..08184bd --- /dev/null +++ b/opensrp-gizi/src/main/java/util/KMS/KmsPerson.java @@ -0,0 +1,90 @@ +package util.KMS; + +import org.ei.opensrp.commonregistry.CommonPersonObjectClient; + +import util.formula.Support; + +/** + * Created by Iq on 02/05/16. + */ +public class KmsPerson { + + private String name; + private boolean isMale; + private int age; + private String dateOfBirth; + private double weight; + private double previousWeight; + private double secondLastWeight; + private String lastVisitDate; + private String secondLastVisitDate; + private String thirdLastVisitDate; + + //ditanya + public String StatusBeratBadan; // value : naik, tidak, ukur pertama + public boolean BGM; + public boolean GarisKuning; + public boolean Tidak2Kali; + + + //constructor + public KmsPerson( boolean isMale,String dateOfBirth,double weight,double previousWeight, + String lastVisitDate,double secondLastWeight,String secondLastVisitDate, + String thirdLastVisitDate){ + + this.setParameters(isMale, dateOfBirth, weight, previousWeight, lastVisitDate, secondLastWeight, + secondLastVisitDate, thirdLastVisitDate + ); + } + + public KmsPerson(CommonPersonObjectClient client){ + String[]history = Support.split(Support.fixHistory(Support.getDetails(client,"history_berat"))); + String[]historyUmur = Support.replace(history[0].split(","), "", "0"); + String[]historyBerat = Support.replace(history[1].split(","), "", "0"); + String dob = Support.getDetails(client, "tanggalLahirAnak").substring(0, 10); + + this.setParameters( + !Support.getDetails(client, "gender").toLowerCase().contains("em"), + dob, + historyBerat.length > 0 ? Double.parseDouble(historyBerat[historyBerat.length - 1]) : 0, + historyBerat.length > 1 ? Double.parseDouble(historyBerat[historyBerat.length - 2]) : 0, + historyUmur.length > 0 ? Support.findDate(dob, Integer.parseInt(historyUmur[historyUmur.length - 1])) : "", + historyBerat.length > 2 ? Double.parseDouble(historyBerat[historyBerat.length - 3]) : 0, + historyUmur.length > 1 + ? historyUmur[historyUmur.length - 2].equals("0") + ? "0" + : Support.findDate(dob, Integer.parseInt(historyUmur[historyUmur.length - 2])) + : "", + historyUmur.length > 2 + ? historyUmur[historyUmur.length - 3].equals("0") + ? "0" + : Support.findDate(dob, Integer.parseInt(historyUmur[historyUmur.length - 3])) + :"" + ); + } + + // mutators + private void setParameters(boolean isMale,String dateOfBirth,double weight,double previousWeight, + String lastVisitDate,double secondLastWeight,String secondLastVisitDate,String thirdLastVisitDate){ + this.isMale = isMale; + this.dateOfBirth = dateOfBirth; + this.age = Support.monthAges(dateOfBirth,lastVisitDate); + this.weight = weight; + this.previousWeight = previousWeight; + this.lastVisitDate = lastVisitDate; + this.secondLastWeight = secondLastWeight; + this.secondLastVisitDate = secondLastVisitDate; + this.thirdLastVisitDate = thirdLastVisitDate; + } + + // accessors + public boolean isMale(){return isMale;} + public int getAge(){return age;} + public String getDateOfBirth(){return dateOfBirth;} + public double getWeight(){return weight;} + public double getPreviousWeight(){return previousWeight;} + public String getLastVisitDate(){return lastVisitDate;} + public double getSecondLastWeight(){return secondLastWeight;} + public String getSecondLastVisitDate(){return secondLastVisitDate;} + public String getThirdLastVisitDate() {return thirdLastVisitDate;} +} diff --git a/opensrp-gizi/src/main/java/util/RecyclingBitmapDrawable.java b/opensrp-gizi/src/main/java/util/RecyclingBitmapDrawable.java new file mode 100644 index 0000000..acf06c2 --- /dev/null +++ b/opensrp-gizi/src/main/java/util/RecyclingBitmapDrawable.java @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2013 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package util; + +import android.content.res.Resources; +import android.graphics.Bitmap; +import android.graphics.drawable.BitmapDrawable; +import android.util.Log; + +import org.ei.opensrp.BuildConfig; + +/** + * A BitmapDrawable that keeps track of whether it is being displayed or cached. + * When the drawable is no longer being displayed or cached, + * {@link Bitmap#recycle() recycle()} will be called on this drawable's bitmap. + */ +public class RecyclingBitmapDrawable extends BitmapDrawable { + + static final String TAG = "CountingBitmapDrawable"; + + private int mCacheRefCount = 0; + private int mDisplayRefCount = 0; + + private boolean mHasBeenDisplayed; + + public RecyclingBitmapDrawable(Resources res, Bitmap bitmap) { + super(res, bitmap); + } + + /** + * Notify the drawable that the displayed state has changed. Internally a + * count is kept so that the drawable knows when it is no longer being + * displayed. + * + * @param isDisplayed - Whether the drawable is being displayed or not + */ + public void setIsDisplayed(boolean isDisplayed) { + //BEGIN_INCLUDE(set_is_displayed) + synchronized (this) { + if (isDisplayed) { + mDisplayRefCount++; + mHasBeenDisplayed = true; + } else { + mDisplayRefCount--; + } + } + + // Check to see if recycle() can be called + checkState(); + //END_INCLUDE(set_is_displayed) + } + + /** + * Notify the drawable that the cache state has changed. Internally a count + * is kept so that the drawable knows when it is no longer being cached. + * + * @param isCached - Whether the drawable is being cached or not + */ + public void setIsCached(boolean isCached) { + //BEGIN_INCLUDE(set_is_cached) + synchronized (this) { + if (isCached) { + mCacheRefCount++; + } else { + mCacheRefCount--; + } + } + + // Check to see if recycle() can be called + checkState(); + //END_INCLUDE(set_is_cached) + } + + private synchronized void checkState() { + //BEGIN_INCLUDE(check_state) + // If the drawable cache and display ref counts = 0, and this drawable + // has been displayed, then recycle + if (mCacheRefCount <= 0 && mDisplayRefCount <= 0 && mHasBeenDisplayed + && hasValidBitmap()) { + if (BuildConfig.DEBUG) { + Log.d(TAG, "No longer being used or cached so recycling. " + + toString()); + } + + getBitmap().recycle(); + } + //END_INCLUDE(check_state) + } + + private synchronized boolean hasValidBitmap() { + Bitmap bitmap = getBitmap(); + return bitmap != null && !bitmap.isRecycled(); + } + +} diff --git a/opensrp-gizi/src/main/java/util/Utils.java b/opensrp-gizi/src/main/java/util/Utils.java new file mode 100644 index 0000000..c1949d5 --- /dev/null +++ b/opensrp-gizi/src/main/java/util/Utils.java @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2012 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package util; + +import android.os.Build; +import android.os.Build.VERSION_CODES; + + +/** + * Class containing some static utility methods. + */ +public class Utils { + private Utils() {}; + + + + + public static boolean hasFroyo() { + // Can use static final constants like FROYO, declared in later versions + // of the OS since they are inlined at compile time. This is guaranteed behavior. + return Build.VERSION.SDK_INT >= VERSION_CODES.FROYO; + } + + public static boolean hasGingerbread() { + return Build.VERSION.SDK_INT >= VERSION_CODES.GINGERBREAD; + } + + public static boolean hasHoneycomb() { + return Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB; + } + + public static boolean hasHoneycombMR1() { + return Build.VERSION.SDK_INT >= VERSION_CODES.HONEYCOMB_MR1; + } + + public static boolean hasJellyBean() { + return Build.VERSION.SDK_INT >= VERSION_CODES.JELLY_BEAN; + } + +} diff --git a/opensrp-gizi/src/main/java/util/ZScore/ReferenceTableForDailyIndex.java b/opensrp-gizi/src/main/java/util/ZScore/ReferenceTableForDailyIndex.java new file mode 100644 index 0000000..8a5cf76 --- /dev/null +++ b/opensrp-gizi/src/main/java/util/ZScore/ReferenceTableForDailyIndex.java @@ -0,0 +1,13636 @@ +package util.ZScore; + +import android.content.Context; + +import org.ei.opensrp.gizi.R; + +/** + * Created by Iq on 24/05/16. + */ +public class ReferenceTableForDailyIndex { + public double[]getBoysWeightForAge(int index){ + double[][]boysWeightForAge={ + {0,0.3487,3.3464,0.14602}, + {1,0.3127,3.3174,0.14693}, + {2,0.3029,3.337,0.14676}, + {3,0.2959,3.3627,0.14647}, + {4,0.2903,3.3915,0.14611}, + {5,0.2855,3.4223,0.14571}, + {6,0.2813,3.4545,0.14528}, + {7,0.2776,3.4879,0.14483}, + {8,0.2742,3.5222,0.14436}, + {9,0.2711,3.5576,0.14388}, + {10,0.2681,3.5941,0.14339}, + {11,0.2654,3.6319,0.1429}, + {12,0.2628,3.671,0.14241}, + {13,0.2604,3.7113,0.14192}, + {14,0.2581,3.7529,0.14142}, + {15,0.2558,3.7956,0.14093}, + {16,0.2537,3.8389,0.14044}, + {17,0.2517,3.8828,0.13996}, + {18,0.2497,3.927,0.13948}, + {19,0.2478,3.9714,0.139}, + {20,0.246,4.0158,0.13853}, + {21,0.2442,4.0603,0.13807}, + {22,0.2425,4.1046,0.13761}, + {23,0.2408,4.1489,0.13715}, + {24,0.2392,4.193,0.1367}, + {25,0.2376,4.2369,0.13626}, + {26,0.2361,4.2806,0.13582}, + {27,0.2346,4.324,0.13539}, + {28,0.2331,4.3671,0.13497}, + {29,0.2317,4.41,0.13455}, + {30,0.2303,4.4525,0.13413}, + {31,0.229,4.4946,0.13372}, + {32,0.2276,4.5363,0.13332}, + {33,0.2263,4.5776,0.13292}, + {34,0.225,4.6185,0.13253}, + {35,0.2237,4.659,0.13215}, + {36,0.2225,4.699,0.13177}, + {37,0.2213,4.7386,0.13139}, + {38,0.2201,4.7778,0.13102}, + {39,0.2189,4.8166,0.13066}, + {40,0.2178,4.8549,0.1303}, + {41,0.2166,4.8928,0.12994}, + {42,0.2155,4.9303,0.1296}, + {43,0.2144,4.9674,0.12925}, + {44,0.2133,5.0041,0.12891}, + {45,0.2122,5.0404,0.12858}, + {46,0.2112,5.0763,0.12825}, + {47,0.2101,5.1118,0.12792}, + {48,0.2091,5.1469,0.1276}, + {49,0.2081,5.1817,0.12729}, + {50,0.2071,5.2161,0.12698}, + {51,0.2061,5.2501,0.12667}, + {52,0.2052,5.2837,0.12637}, + {53,0.2042,5.3171,0.12607}, + {54,0.2032,5.35,0.12577}, + {55,0.2023,5.3826,0.12548}, + {56,0.2014,5.4149,0.1252}, + {57,0.2005,5.4468,0.12491}, + {58,0.1996,5.4784,0.12463}, + {59,0.1987,5.5097,0.12436}, + {60,0.1978,5.5407,0.12409}, + {61,0.1969,5.5714,0.12382}, + {62,0.196,5.6018,0.12356}, + {63,0.1952,5.6319,0.1233}, + {64,0.1943,5.6617,0.12304}, + {65,0.1935,5.6912,0.12279}, + {66,0.1926,5.7205,0.12254}, + {67,0.1918,5.7494,0.12229}, + {68,0.191,5.7781,0.12205}, + {69,0.1902,5.8065,0.12181}, + {70,0.1894,5.8346,0.12157}, + {71,0.1886,5.8625,0.12134}, + {72,0.1878,5.8901,0.12111}, + {73,0.187,5.9174,0.12088}, + {74,0.1863,5.9445,0.12066}, + {75,0.1855,5.9713,0.12044}, + {76,0.1847,5.9979,0.12022}, + {77,0.184,6.0242,0.12001}, + {78,0.1832,6.0503,0.1198}, + {79,0.1825,6.0762,0.11959}, + {80,0.1818,6.1018,0.11939}, + {81,0.181,6.1272,0.11918}, + {82,0.1803,6.1523,0.11899}, + {83,0.1796,6.1772,0.11879}, + {84,0.1789,6.2019,0.1186}, + {85,0.1782,6.2264,0.11841}, + {86,0.1775,6.2507,0.11822}, + {87,0.1768,6.2748,0.11803}, + {88,0.1761,6.2986,0.11785}, + {89,0.1754,6.3223,0.11767}, + {90,0.1747,6.3457,0.1175}, + {91,0.174,6.369,0.11732}, + {92,0.1734,6.3921,0.11715}, + {93,0.1727,6.4149,0.11698}, + {94,0.172,6.4376,0.11682}, + {95,0.1714,6.4601,0.11666}, + {96,0.1707,6.4824,0.11649}, + {97,0.1701,6.5046,0.11634}, + {98,0.1694,6.5265,0.11618}, + {99,0.1688,6.5483,0.11603}, + {100,0.1682,6.5699,0.11588}, + {101,0.1675,6.5914,0.11573}, + {102,0.1669,6.6126,0.11558}, + {103,0.1663,6.6338,0.11544}, + {104,0.1657,6.6547,0.1153}, + {105,0.1651,6.6755,0.11516}, + {106,0.1644,6.6962,0.11502}, + {107,0.1638,6.7166,0.11489}, + {108,0.1632,6.737,0.11476}, + {109,0.1626,6.7572,0.11463}, + {110,0.162,6.7772,0.1145}, + {111,0.1614,6.7971,0.11438}, + {112,0.1609,6.8168,0.11425}, + {113,0.1603,6.8365,0.11413}, + {114,0.1597,6.8559,0.11401}, + {115,0.1591,6.8753,0.1139}, + {116,0.1585,6.8945,0.11378}, + {117,0.158,6.9135,0.11367}, + {118,0.1574,6.9325,0.11356}, + {119,0.1568,6.9513,0.11345}, + {120,0.1563,6.9699,0.11334}, + {121,0.1557,6.9885,0.11324}, + {122,0.1551,7.0069,0.11313}, + {123,0.1546,7.0252,0.11303}, + {124,0.154,7.0434,0.11293}, + {125,0.1535,7.0615,0.11283}, + {126,0.1529,7.0794,0.11274}, + {127,0.1524,7.0972,0.11265}, + {128,0.1519,7.1149,0.11255}, + {129,0.1513,7.1325,0.11246}, + {130,0.1508,7.15,0.11237}, + {131,0.1502,7.1674,0.11229}, + {132,0.1497,7.1846,0.1122}, + {133,0.1492,7.2018,0.11212}, + {134,0.1487,7.2188,0.11204}, + {135,0.1481,7.2357,0.11196}, + {136,0.1476,7.2525,0.11188}, + {137,0.1471,7.2692,0.1118}, + {138,0.1466,7.2858,0.11172}, + {139,0.1461,7.3023,0.11165}, + {140,0.1456,7.3187,0.11158}, + {141,0.1451,7.335,0.1115}, + {142,0.1446,7.3512,0.11143}, + {143,0.1441,7.3673,0.11137}, + {144,0.1436,7.3833,0.1113}, + {145,0.1431,7.3992,0.11123}, + {146,0.1426,7.415,0.11117}, + {147,0.1421,7.4307,0.11111}, + {148,0.1416,7.4463,0.11104}, + {149,0.1411,7.4618,0.11098}, + {150,0.1406,7.4772,0.11092}, + {151,0.1401,7.4925,0.11087}, + {152,0.1396,7.5077,0.11081}, + {153,0.1391,7.5228,0.11075}, + {154,0.1387,7.5379,0.1107}, + {155,0.1382,7.5528,0.11065}, + {156,0.1377,7.5677,0.11059}, + {157,0.1372,7.5824,0.11054}, + {158,0.1368,7.5971,0.11049}, + {159,0.1363,7.6117,0.11044}, + {160,0.1358,7.6262,0.1104}, + {161,0.1354,7.6406,0.11035}, + {162,0.1349,7.655,0.11031}, + {163,0.1344,7.6692,0.11026}, + {164,0.134,7.6834,0.11022}, + {165,0.1335,7.6975,0.11018}, + {166,0.1331,7.7115,0.11013}, + {167,0.1326,7.7255,0.11009}, + {168,0.1322,7.7394,0.11005}, + {169,0.1317,7.7532,0.11002}, + {170,0.1313,7.7669,0.10998}, + {171,0.1308,7.7805,0.10994}, + {172,0.1304,7.7941,0.10991}, + {173,0.1299,7.8076,0.10987}, + {174,0.1295,7.821,0.10984}, + {175,0.129,7.8344,0.1098}, + {176,0.1286,7.8477,0.10977}, + {177,0.1282,7.8609,0.10974}, + {178,0.1277,7.8741,0.10971}, + {179,0.1273,7.8871,0.10968}, + {180,0.1269,7.9002,0.10965}, + {181,0.1264,7.9131,0.10962}, + {182,0.126,7.926,0.10959}, + {183,0.1256,7.9389,0.10957}, + {184,0.1251,7.9516,0.10954}, + {185,0.1247,7.9643,0.10951}, + {186,0.1243,7.977,0.10949}, + {187,0.1239,7.9895,0.10946}, + {188,0.1235,8.0021,0.10944}, + {189,0.123,8.0145,0.10942}, + {190,0.1226,8.0269,0.1094}, + {191,0.1222,8.0392,0.10937}, + {192,0.1218,8.0515,0.10935}, + {193,0.1214,8.0637,0.10933}, + {194,0.121,8.0759,0.10931}, + {195,0.1206,8.0879,0.10929}, + {196,0.1201,8.1,0.10927}, + {197,0.1197,8.112,0.10925}, + {198,0.1193,8.1239,0.10924}, + {199,0.1189,8.1357,0.10922}, + {200,0.1185,8.1475,0.1092}, + {201,0.1181,8.1593,0.10919}, + {202,0.1177,8.171,0.10917}, + {203,0.1173,8.1826,0.10915}, + {204,0.1169,8.1942,0.10914}, + {205,0.1165,8.2058,0.10913}, + {206,0.1161,8.2173,0.10911}, + {207,0.1157,8.2287,0.1091}, + {208,0.1153,8.2401,0.10908}, + {209,0.1149,8.2514,0.10907}, + {210,0.1145,8.2627,0.10906}, + {211,0.1142,8.2739,0.10905}, + {212,0.1138,8.2851,0.10903}, + {213,0.1134,8.2963,0.10902}, + {214,0.113,8.3074,0.10901}, + {215,0.1126,8.3184,0.109}, + {216,0.1122,8.3294,0.10899}, + {217,0.1118,8.3404,0.10898}, + {218,0.1115,8.3513,0.10897}, + {219,0.1111,8.3621,0.10896}, + {220,0.1107,8.3729,0.10895}, + {221,0.1103,8.3837,0.10894}, + {222,0.1099,8.3944,0.10894}, + {223,0.1096,8.4051,0.10893}, + {224,0.1092,8.4157,0.10892}, + {225,0.1088,8.4263,0.10891}, + {226,0.1084,8.4369,0.10891}, + {227,0.1081,8.4474,0.1089}, + {228,0.1077,8.4578,0.10889}, + {229,0.1073,8.4683,0.10889}, + {230,0.107,8.4787,0.10888}, + {231,0.1066,8.489,0.10887}, + {232,0.1062,8.4993,0.10887}, + {233,0.1059,8.5096,0.10886}, + {234,0.1055,8.5198,0.10886}, + {235,0.1051,8.53,0.10885}, + {236,0.1048,8.5401,0.10885}, + {237,0.1044,8.5502,0.10884}, + {238,0.104,8.5603,0.10884}, + {239,0.1037,8.5704,0.10884}, + {240,0.1033,8.5804,0.10883}, + {241,0.103,8.5903,0.10883}, + {242,0.1026,8.6003,0.10882}, + {243,0.1023,8.6102,0.10882}, + {244,0.1019,8.62,0.10882}, + {245,0.1015,8.6299,0.10882}, + {246,0.1012,8.6397,0.10881}, + {247,0.1008,8.6494,0.10881}, + {248,0.1005,8.6592,0.10881}, + {249,0.1001,8.6689,0.10881}, + {250,0.0998,8.6785,0.10881}, + {251,0.0994,8.6882,0.1088}, + {252,0.0991,8.6978,0.1088}, + {253,0.0987,8.7073,0.1088}, + {254,0.0984,8.7169,0.1088}, + {255,0.0981,8.7264,0.1088}, + {256,0.0977,8.7359,0.1088}, + {257,0.0974,8.7453,0.1088}, + {258,0.097,8.7548,0.1088}, + {259,0.0967,8.7642,0.1088}, + {260,0.0963,8.7735,0.1088}, + {261,0.096,8.7829,0.1088}, + {262,0.0957,8.7922,0.1088}, + {263,0.0953,8.8015,0.1088}, + {264,0.095,8.8107,0.1088}, + {265,0.0947,8.82,0.1088}, + {266,0.0943,8.8292,0.1088}, + {267,0.094,8.8384,0.1088}, + {268,0.0937,8.8475,0.1088}, + {269,0.0933,8.8567,0.1088}, + {270,0.093,8.8658,0.1088}, + {271,0.0927,8.8748,0.1088}, + {272,0.0923,8.8839,0.10881}, + {273,0.092,8.8929,0.10881}, + {274,0.0917,8.9019,0.10881}, + {275,0.0913,8.9109,0.10881}, + {276,0.091,8.9199,0.10881}, + {277,0.0907,8.9288,0.10882}, + {278,0.0904,8.9377,0.10882}, + {279,0.09,8.9466,0.10882}, + {280,0.0897,8.9555,0.10882}, + {281,0.0894,8.9643,0.10882}, + {282,0.0891,8.9731,0.10883}, + {283,0.0887,8.9819,0.10883}, + {284,0.0884,8.9907,0.10883}, + {285,0.0881,8.9995,0.10884}, + {286,0.0878,9.0082,0.10884}, + {287,0.0875,9.0169,0.10884}, + {288,0.0871,9.0256,0.10884}, + {289,0.0868,9.0342,0.10885}, + {290,0.0865,9.0429,0.10885}, + {291,0.0862,9.0515,0.10885}, + {292,0.0859,9.0601,0.10886}, + {293,0.0856,9.0687,0.10886}, + {294,0.0852,9.0772,0.10887}, + {295,0.0849,9.0858,0.10887}, + {296,0.0846,9.0943,0.10887}, + {297,0.0843,9.1028,0.10888}, + {298,0.084,9.1113,0.10888}, + {299,0.0837,9.1198,0.10888}, + {300,0.0834,9.1282,0.10889}, + {301,0.0831,9.1366,0.10889}, + {302,0.0827,9.145,0.1089}, + {303,0.0824,9.1534,0.1089}, + {304,0.0821,9.1618,0.1089}, + {305,0.0818,9.1701,0.10891}, + {306,0.0815,9.1785,0.10891}, + {307,0.0812,9.1868,0.10892}, + {308,0.0809,9.1951,0.10892}, + {309,0.0806,9.2034,0.10893}, + {310,0.0803,9.2117,0.10893}, + {311,0.08,9.2199,0.10894}, + {312,0.0797,9.2282,0.10894}, + {313,0.0794,9.2364,0.10894}, + {314,0.0791,9.2446,0.10895}, + {315,0.0788,9.2528,0.10895}, + {316,0.0785,9.261,0.10896}, + {317,0.0782,9.2691,0.10896}, + {318,0.0779,9.2773,0.10897}, + {319,0.0776,9.2854,0.10897}, + {320,0.0773,9.2935,0.10898}, + {321,0.077,9.3016,0.10898}, + {322,0.0767,9.3097,0.10899}, + {323,0.0764,9.3178,0.10899}, + {324,0.0761,9.3258,0.109}, + {325,0.0758,9.3339,0.10901}, + {326,0.0755,9.3419,0.10901}, + {327,0.0752,9.3499,0.10902}, + {328,0.0749,9.3579,0.10902}, + {329,0.0746,9.3659,0.10903}, + {330,0.0744,9.3739,0.10903}, + {331,0.0741,9.3819,0.10904}, + {332,0.0738,9.3898,0.10904}, + {333,0.0735,9.3978,0.10905}, + {334,0.0732,9.4057,0.10905}, + {335,0.0729,9.4136,0.10906}, + {336,0.0726,9.4215,0.10907}, + {337,0.0723,9.4294,0.10907}, + {338,0.072,9.4373,0.10908}, + {339,0.0718,9.4452,0.10908}, + {340,0.0715,9.453,0.10909}, + {341,0.0712,9.4609,0.1091}, + {342,0.0709,9.4687,0.1091}, + {343,0.0706,9.4765,0.10911}, + {344,0.0703,9.4844,0.10911}, + {345,0.0701,9.4922,0.10912}, + {346,0.0698,9.4999,0.10913}, + {347,0.0695,9.5077,0.10913}, + {348,0.0692,9.5155,0.10914}, + {349,0.0689,9.5232,0.10915}, + {350,0.0686,9.531,0.10915}, + {351,0.0684,9.5387,0.10916}, + {352,0.0681,9.5464,0.10916}, + {353,0.0678,9.5542,0.10917}, + {354,0.0675,9.5619,0.10918}, + {355,0.0672,9.5696,0.10918}, + {356,0.067,9.5772,0.10919}, + {357,0.0667,9.5849,0.1092}, + {358,0.0664,9.5926,0.1092}, + {359,0.0661,9.6002,0.10921}, + {360,0.0659,9.6079,0.10922}, + {361,0.0656,9.6155,0.10922}, + {362,0.0653,9.6231,0.10923}, + {363,0.065,9.6308,0.10924}, + {364,0.0648,9.6384,0.10925}, + {365,0.0645,9.646,0.10925}, + {366,0.0642,9.6535,0.10926}, + {367,0.064,9.6611,0.10927}, + {368,0.0637,9.6687,0.10927}, + {369,0.0634,9.6763,0.10928}, + {370,0.0631,9.6838,0.10929}, + {371,0.0629,9.6914,0.1093}, + {372,0.0626,9.6989,0.1093}, + {373,0.0623,9.7064,0.10931}, + {374,0.0621,9.7139,0.10932}, + {375,0.0618,9.7214,0.10933}, + {376,0.0615,9.7289,0.10933}, + {377,0.0613,9.7364,0.10934}, + {378,0.061,9.7439,0.10935}, + {379,0.0607,9.7514,0.10936}, + {380,0.0605,9.7588,0.10936}, + {381,0.0602,9.7663,0.10937}, + {382,0.0599,9.7738,0.10938}, + {383,0.0597,9.7812,0.10939}, + {384,0.0594,9.7886,0.10939}, + {385,0.0591,9.796,0.1094}, + {386,0.0589,9.8035,0.10941}, + {387,0.0586,9.8109,0.10942}, + {388,0.0583,9.8183,0.10943}, + {389,0.0581,9.8257,0.10943}, + {390,0.0578,9.833,0.10944}, + {391,0.0576,9.8404,0.10945}, + {392,0.0573,9.8478,0.10946}, + {393,0.057,9.8551,0.10947}, + {394,0.0568,9.8625,0.10948}, + {395,0.0565,9.8699,0.10948}, + {396,0.0563,9.8772,0.10949}, + {397,0.056,9.8845,0.1095}, + {398,0.0557,9.8918,0.10951}, + {399,0.0555,9.8992,0.10952}, + {400,0.0552,9.9065,0.10953}, + {401,0.055,9.9138,0.10954}, + {402,0.0547,9.9211,0.10954}, + {403,0.0545,9.9284,0.10955}, + {404,0.0542,9.9357,0.10956}, + {405,0.054,9.9429,0.10957}, + {406,0.0537,9.9502,0.10958}, + {407,0.0534,9.9575,0.10959}, + {408,0.0532,9.9647,0.1096}, + {409,0.0529,9.972,0.10961}, + {410,0.0527,9.9792,0.10961}, + {411,0.0524,9.9865,0.10962}, + {412,0.0522,9.9937,0.10963}, + {413,0.0519,10.0009,0.10964}, + {414,0.0517,10.0082,0.10965}, + {415,0.0514,10.0154,0.10966}, + {416,0.0512,10.0226,0.10967}, + {417,0.0509,10.0298,0.10968}, + {418,0.0507,10.037,0.10969}, + {419,0.0504,10.0442,0.1097}, + {420,0.0502,10.0514,0.10971}, + {421,0.0499,10.0586,0.10971}, + {422,0.0497,10.0657,0.10972}, + {423,0.0494,10.0729,0.10973}, + {424,0.0492,10.0801,0.10974}, + {425,0.0489,10.0872,0.10975}, + {426,0.0487,10.0944,0.10976}, + {427,0.0484,10.1015,0.10977}, + {428,0.0482,10.1087,0.10978}, + {429,0.0479,10.1158,0.10979}, + {430,0.0477,10.123,0.1098}, + {431,0.0475,10.1301,0.10981}, + {432,0.0472,10.1372,0.10982}, + {433,0.047,10.1443,0.10983}, + {434,0.0467,10.1515,0.10984}, + {435,0.0465,10.1586,0.10985}, + {436,0.0462,10.1657,0.10986}, + {437,0.046,10.1728,0.10987}, + {438,0.0458,10.1799,0.10988}, + {439,0.0455,10.187,0.10989}, + {440,0.0453,10.1941,0.1099}, + {441,0.045,10.2011,0.10991}, + {442,0.0448,10.2082,0.10992}, + {443,0.0445,10.2153,0.10993}, + {444,0.0443,10.2224,0.10994}, + {445,0.0441,10.2294,0.10995}, + {446,0.0438,10.2365,0.10996}, + {447,0.0436,10.2435,0.10997}, + {448,0.0433,10.2506,0.10998}, + {449,0.0431,10.2576,0.10999}, + {450,0.0429,10.2647,0.11}, + {451,0.0426,10.2717,0.11001}, + {452,0.0424,10.2788,0.11002}, + {453,0.0422,10.2858,0.11003}, + {454,0.0419,10.2928,0.11005}, + {455,0.0417,10.2998,0.11006}, + {456,0.0414,10.3069,0.11007}, + {457,0.0412,10.3139,0.11008}, + {458,0.041,10.3209,0.11009}, + {459,0.0407,10.3279,0.1101}, + {460,0.0405,10.3349,0.11011}, + {461,0.0403,10.3419,0.11012}, + {462,0.04,10.3489,0.11013}, + {463,0.0398,10.3559,0.11014}, + {464,0.0396,10.3629,0.11015}, + {465,0.0393,10.3699,0.11016}, + {466,0.0391,10.3769,0.11017}, + {467,0.0389,10.3839,0.11019}, + {468,0.0386,10.3908,0.1102}, + {469,0.0384,10.3978,0.11021}, + {470,0.0382,10.4048,0.11022}, + {471,0.0379,10.4118,0.11023}, + {472,0.0377,10.4187,0.11024}, + {473,0.0375,10.4257,0.11025}, + {474,0.0373,10.4326,0.11026}, + {475,0.037,10.4396,0.11027}, + {476,0.0368,10.4465,0.11029}, + {477,0.0366,10.4535,0.1103}, + {478,0.0363,10.4604,0.11031}, + {479,0.0361,10.4674,0.11032}, + {480,0.0359,10.4743,0.11033}, + {481,0.0357,10.4813,0.11034}, + {482,0.0354,10.4882,0.11035}, + {483,0.0352,10.4951,0.11037}, + {484,0.035,10.502,0.11038}, + {485,0.0347,10.509,0.11039}, + {486,0.0345,10.5159,0.1104}, + {487,0.0343,10.5228,0.11041}, + {488,0.0341,10.5297,0.11042}, + {489,0.0338,10.5366,0.11044}, + {490,0.0336,10.5435,0.11045}, + {491,0.0334,10.5505,0.11046}, + {492,0.0332,10.5574,0.11047}, + {493,0.0329,10.5643,0.11048}, + {494,0.0327,10.5712,0.1105}, + {495,0.0325,10.578,0.11051}, + {496,0.0323,10.5849,0.11052}, + {497,0.032,10.5918,0.11053}, + {498,0.0318,10.5987,0.11054}, + {499,0.0316,10.6056,0.11056}, + {500,0.0314,10.6125,0.11057}, + {501,0.0312,10.6193,0.11058}, + {502,0.0309,10.6262,0.11059}, + {503,0.0307,10.6331,0.1106}, + {504,0.0305,10.6399,0.11062}, + {505,0.0303,10.6468,0.11063}, + {506,0.03,10.6537,0.11064}, + {507,0.0298,10.6605,0.11065}, + {508,0.0296,10.6674,0.11067}, + {509,0.0294,10.6742,0.11068}, + {510,0.0292,10.6811,0.11069}, + {511,0.0289,10.6879,0.1107}, + {512,0.0287,10.6948,0.11072}, + {513,0.0285,10.7016,0.11073}, + {514,0.0283,10.7084,0.11074}, + {515,0.0281,10.7153,0.11075}, + {516,0.0279,10.7221,0.11077}, + {517,0.0276,10.7289,0.11078}, + {518,0.0274,10.7357,0.11079}, + {519,0.0272,10.7426,0.11081}, + {520,0.027,10.7494,0.11082}, + {521,0.0268,10.7562,0.11083}, + {522,0.0266,10.763,0.11084}, + {523,0.0263,10.7698,0.11086}, + {524,0.0261,10.7766,0.11087}, + {525,0.0259,10.7835,0.11088}, + {526,0.0257,10.7903,0.1109}, + {527,0.0255,10.7971,0.11091}, + {528,0.0253,10.8039,0.11092}, + {529,0.025,10.8107,0.11094}, + {530,0.0248,10.8174,0.11095}, + {531,0.0246,10.8242,0.11096}, + {532,0.0244,10.831,0.11098}, + {533,0.0242,10.8378,0.11099}, + {534,0.024,10.8446,0.111}, + {535,0.0238,10.8514,0.11102}, + {536,0.0236,10.8582,0.11103}, + {537,0.0233,10.8649,0.11104}, + {538,0.0231,10.8717,0.11106}, + {539,0.0229,10.8785,0.11107}, + {540,0.0227,10.8852,0.11108}, + {541,0.0225,10.892,0.1111}, + {542,0.0223,10.8988,0.11111}, + {543,0.0221,10.9055,0.11113}, + {544,0.0219,10.9123,0.11114}, + {545,0.0217,10.9191,0.11115}, + {546,0.0214,10.9258,0.11117}, + {547,0.0212,10.9326,0.11118}, + {548,0.021,10.9393,0.1112}, + {549,0.0208,10.9461,0.11121}, + {550,0.0206,10.9528,0.11122}, + {551,0.0204,10.9596,0.11124}, + {552,0.0202,10.9663,0.11125}, + {553,0.02,10.973,0.11127}, + {554,0.0198,10.9798,0.11128}, + {555,0.0196,10.9865,0.11129}, + {556,0.0194,10.9932,0.11131}, + {557,0.0192,11,0.11132}, + {558,0.0189,11.0067,0.11134}, + {559,0.0187,11.0134,0.11135}, + {560,0.0185,11.0202,0.11137}, + {561,0.0183,11.0269,0.11138}, + {562,0.0181,11.0336,0.11139}, + {563,0.0179,11.0403,0.11141}, + {564,0.0177,11.047,0.11142}, + {565,0.0175,11.0537,0.11144}, + {566,0.0173,11.0605,0.11145}, + {567,0.0171,11.0672,0.11147}, + {568,0.0169,11.0739,0.11148}, + {569,0.0167,11.0806,0.1115}, + {570,0.0165,11.0873,0.11151}, + {571,0.0163,11.094,0.11153}, + {572,0.0161,11.1007,0.11154}, + {573,0.0159,11.1074,0.11156}, + {574,0.0157,11.1141,0.11157}, + {575,0.0155,11.1208,0.11159}, + {576,0.0153,11.1275,0.1116}, + {577,0.0151,11.1342,0.11162}, + {578,0.0149,11.1409,0.11163}, + {579,0.0147,11.1476,0.11165}, + {580,0.0144,11.1543,0.11166}, + {581,0.0142,11.161,0.11168}, + {582,0.014,11.1676,0.11169}, + {583,0.0138,11.1743,0.11171}, + {584,0.0136,11.181,0.11172}, + {585,0.0134,11.1877,0.11174}, + {586,0.0132,11.1944,0.11175}, + {587,0.013,11.2011,0.11177}, + {588,0.0128,11.2077,0.11178}, + {589,0.0126,11.2144,0.1118}, + {590,0.0124,11.2211,0.11182}, + {591,0.0122,11.2278,0.11183}, + {592,0.012,11.2345,0.11185}, + {593,0.0118,11.2411,0.11186}, + {594,0.0116,11.2478,0.11188}, + {595,0.0114,11.2545,0.11189}, + {596,0.0112,11.2612,0.11191}, + {597,0.0111,11.2678,0.11192}, + {598,0.0109,11.2745,0.11194}, + {599,0.0107,11.2812,0.11196}, + {600,0.0105,11.2878,0.11197}, + {601,0.0103,11.2945,0.11199}, + {602,0.0101,11.3012,0.112}, + {603,0.0099,11.3078,0.11202}, + {604,0.0097,11.3145,0.11204}, + {605,0.0095,11.3212,0.11205}, + {606,0.0093,11.3278,0.11207}, + {607,0.0091,11.3345,0.11208}, + {608,0.0089,11.3412,0.1121}, + {609,0.0087,11.3478,0.11212}, + {610,0.0085,11.3545,0.11213}, + {611,0.0083,11.3612,0.11215}, + {612,0.0081,11.3678,0.11216}, + {613,0.0079,11.3745,0.11218}, + {614,0.0077,11.3811,0.1122}, + {615,0.0075,11.3878,0.11221}, + {616,0.0073,11.3945,0.11223}, + {617,0.0071,11.4011,0.11224}, + {618,0.0069,11.4078,0.11226}, + {619,0.0067,11.4144,0.11228}, + {620,0.0066,11.4211,0.11229}, + {621,0.0064,11.4277,0.11231}, + {622,0.0062,11.4344,0.11233}, + {623,0.006,11.441,0.11234}, + {624,0.0058,11.4477,0.11236}, + {625,0.0056,11.4543,0.11238}, + {626,0.0054,11.461,0.11239}, + {627,0.0052,11.4676,0.11241}, + {628,0.005,11.4743,0.11243}, + {629,0.0048,11.4809,0.11244}, + {630,0.0046,11.4876,0.11246}, + {631,0.0044,11.4942,0.11248}, + {632,0.0043,11.5009,0.11249}, + {633,0.0041,11.5075,0.11251}, + {634,0.0039,11.5142,0.11253}, + {635,0.0037,11.5208,0.11254}, + {636,0.0035,11.5274,0.11256}, + {637,0.0033,11.5341,0.11258}, + {638,0.0031,11.5407,0.11259}, + {639,0.0029,11.5474,0.11261}, + {640,0.0027,11.554,0.11263}, + {641,0.0025,11.5606,0.11265}, + {642,0.0024,11.5673,0.11266}, + {643,0.0022,11.5739,0.11268}, + {644,0.002,11.5806,0.1127}, + {645,0.0018,11.5872,0.11271}, + {646,0.0016,11.5938,0.11273}, + {647,0.0014,11.6005,0.11275}, + {648,0.0012,11.6071,0.11276}, + {649,0.001,11.6137,0.11278}, + {650,0.0008,11.6204,0.1128}, + {651,0.0007,11.627,0.11282}, + {652,0.0005,11.6336,0.11283}, + {653,0.0003,11.6403,0.11285}, + {654,0.0001,11.6469,0.11287}, + {655,-0.0001,11.6535,0.11289}, + {656,-0.0003,11.6601,0.1129}, + {657,-0.0005,11.6668,0.11292}, + {658,-0.0006,11.6734,0.11294}, + {659,-0.0008,11.68,0.11296}, + {660,-0.001,11.6866,0.11297}, + {661,-0.0012,11.6933,0.11299}, + {662,-0.0014,11.6999,0.11301}, + {663,-0.0016,11.7065,0.11303}, + {664,-0.0018,11.7131,0.11304}, + {665,-0.0019,11.7198,0.11306}, + {666,-0.0021,11.7264,0.11308}, + {667,-0.0023,11.733,0.1131}, + {668,-0.0025,11.7396,0.11311}, + {669,-0.0027,11.7462,0.11313}, + {670,-0.0029,11.7528,0.11315}, + {671,-0.003,11.7595,0.11317}, + {672,-0.0032,11.7661,0.11318}, + {673,-0.0034,11.7727,0.1132}, + {674,-0.0036,11.7793,0.11322}, + {675,-0.0038,11.7859,0.11324}, + {676,-0.004,11.7925,0.11326}, + {677,-0.0041,11.7991,0.11327}, + {678,-0.0043,11.8057,0.11329}, + {679,-0.0045,11.8124,0.11331}, + {680,-0.0047,11.819,0.11333}, + {681,-0.0049,11.8256,0.11335}, + {682,-0.0051,11.8322,0.11336}, + {683,-0.0052,11.8388,0.11338}, + {684,-0.0054,11.8454,0.1134}, + {685,-0.0056,11.852,0.11342}, + {686,-0.0058,11.8586,0.11344}, + {687,-0.006,11.8652,0.11345}, + {688,-0.0061,11.8718,0.11347}, + {689,-0.0063,11.8784,0.11349}, + {690,-0.0065,11.885,0.11351}, + {691,-0.0067,11.8916,0.11353}, + {692,-0.0069,11.8982,0.11354}, + {693,-0.007,11.9048,0.11356}, + {694,-0.0072,11.9114,0.11358}, + {695,-0.0074,11.918,0.1136}, + {696,-0.0076,11.9246,0.11362}, + {697,-0.0078,11.9312,0.11364}, + {698,-0.0079,11.9378,0.11365}, + {699,-0.0081,11.9444,0.11367}, + {700,-0.0083,11.951,0.11369}, + {701,-0.0085,11.9576,0.11371}, + {702,-0.0087,11.9642,0.11373}, + {703,-0.0088,11.9707,0.11375}, + {704,-0.009,11.9773,0.11376}, + {705,-0.0092,11.9839,0.11378}, + {706,-0.0094,11.9905,0.1138}, + {707,-0.0095,11.9971,0.11382}, + {708,-0.0097,12.0037,0.11384}, + {709,-0.0099,12.0103,0.11386}, + {710,-0.0101,12.0168,0.11388}, + {711,-0.0102,12.0234,0.11389}, + {712,-0.0104,12.03,0.11391}, + {713,-0.0106,12.0366,0.11393}, + {714,-0.0108,12.0431,0.11395}, + {715,-0.011,12.0497,0.11397}, + {716,-0.0111,12.0563,0.11399}, + {717,-0.0113,12.0629,0.11401}, + {718,-0.0115,12.0694,0.11403}, + {719,-0.0117,12.076,0.11404}, + {720,-0.0118,12.0826,0.11406}, + {721,-0.012,12.0891,0.11408}, + {722,-0.0122,12.0957,0.1141}, + {723,-0.0124,12.1023,0.11412}, + {724,-0.0125,12.1088,0.11414}, + {725,-0.0127,12.1154,0.11416}, + {726,-0.0129,12.122,0.11418}, + {727,-0.0131,12.1285,0.1142}, + {728,-0.0132,12.1351,0.11421}, + {729,-0.0134,12.1416,0.11423}, + {730,-0.0136,12.1482,0.11425}, + {731,-0.0137,12.1548,0.11427}, + {732,-0.0139,12.1613,0.11429}, + {733,-0.0141,12.1679,0.11431}, + {734,-0.0143,12.1744,0.11433}, + {735,-0.0144,12.181,0.11435}, + {736,-0.0146,12.1875,0.11437}, + {737,-0.0148,12.1941,0.11439}, + {738,-0.015,12.2006,0.1144}, + {739,-0.0151,12.2072,0.11442}, + {740,-0.0153,12.2137,0.11444}, + {741,-0.0155,12.2202,0.11446}, + {742,-0.0156,12.2268,0.11448}, + {743,-0.0158,12.2333,0.1145}, + {744,-0.016,12.2398,0.11452}, + {745,-0.0162,12.2464,0.11454}, + {746,-0.0163,12.2529,0.11456}, + {747,-0.0165,12.2594,0.11458}, + {748,-0.0167,12.266,0.1146}, + {749,-0.0168,12.2725,0.11462}, + {750,-0.017,12.279,0.11464}, + {751,-0.0172,12.2855,0.11465}, + {752,-0.0174,12.292,0.11467}, + {753,-0.0175,12.2986,0.11469}, + {754,-0.0177,12.3051,0.11471}, + {755,-0.0179,12.3116,0.11473}, + {756,-0.018,12.3181,0.11475}, + {757,-0.0182,12.3246,0.11477}, + {758,-0.0184,12.3311,0.11479}, + {759,-0.0185,12.3376,0.11481}, + {760,-0.0187,12.3441,0.11483}, + {761,-0.0189,12.3506,0.11485}, + {762,-0.0191,12.3571,0.11487}, + {763,-0.0192,12.3636,0.11489}, + {764,-0.0194,12.3701,0.11491}, + {765,-0.0196,12.3766,0.11493}, + {766,-0.0197,12.383,0.11495}, + {767,-0.0199,12.3895,0.11497}, + {768,-0.0201,12.396,0.11498}, + {769,-0.0202,12.4025,0.115}, + {770,-0.0204,12.409,0.11502}, + {771,-0.0206,12.4154,0.11504}, + {772,-0.0207,12.4219,0.11506}, + {773,-0.0209,12.4284,0.11508}, + {774,-0.0211,12.4348,0.1151}, + {775,-0.0212,12.4413,0.11512}, + {776,-0.0214,12.4477,0.11514}, + {777,-0.0216,12.4542,0.11516}, + {778,-0.0217,12.4606,0.11518}, + {779,-0.0219,12.4671,0.1152}, + {780,-0.0221,12.4735,0.11522}, + {781,-0.0222,12.48,0.11524}, + {782,-0.0224,12.4864,0.11526}, + {783,-0.0226,12.4929,0.11528}, + {784,-0.0227,12.4993,0.1153}, + {785,-0.0229,12.5057,0.11532}, + {786,-0.0231,12.5121,0.11534}, + {787,-0.0232,12.5186,0.11536}, + {788,-0.0234,12.525,0.11538}, + {789,-0.0236,12.5314,0.1154}, + {790,-0.0237,12.5378,0.11542}, + {791,-0.0239,12.5442,0.11544}, + {792,-0.0241,12.5506,0.11545}, + {793,-0.0242,12.557,0.11547}, + {794,-0.0244,12.5634,0.11549}, + {795,-0.0246,12.5698,0.11551}, + {796,-0.0247,12.5762,0.11553}, + {797,-0.0249,12.5826,0.11555}, + {798,-0.025,12.589,0.11557}, + {799,-0.0252,12.5954,0.11559}, + {800,-0.0254,12.6018,0.11561}, + {801,-0.0255,12.6082,0.11563}, + {802,-0.0257,12.6145,0.11565}, + {803,-0.0259,12.6209,0.11567}, + {804,-0.026,12.6273,0.11569}, + {805,-0.0262,12.6336,0.11571}, + {806,-0.0264,12.64,0.11573}, + {807,-0.0265,12.6464,0.11575}, + {808,-0.0267,12.6527,0.11577}, + {809,-0.0268,12.6591,0.11579}, + {810,-0.027,12.6654,0.11581}, + {811,-0.0272,12.6718,0.11583}, + {812,-0.0273,12.6781,0.11585}, + {813,-0.0275,12.6844,0.11587}, + {814,-0.0277,12.6908,0.11589}, + {815,-0.0278,12.6971,0.11591}, + {816,-0.028,12.7034,0.11593}, + {817,-0.0281,12.7098,0.11595}, + {818,-0.0283,12.7161,0.11597}, + {819,-0.0285,12.7224,0.11599}, + {820,-0.0286,12.7287,0.11601}, + {821,-0.0288,12.735,0.11602}, + {822,-0.0289,12.7413,0.11604}, + {823,-0.0291,12.7476,0.11606}, + {824,-0.0293,12.7539,0.11608}, + {825,-0.0294,12.7602,0.1161}, + {826,-0.0296,12.7665,0.11612}, + {827,-0.0297,12.7728,0.11614}, + {828,-0.0299,12.7791,0.11616}, + {829,-0.0301,12.7854,0.11618}, + {830,-0.0302,12.7916,0.1162}, + {831,-0.0304,12.7979,0.11622}, + {832,-0.0305,12.8042,0.11624}, + {833,-0.0307,12.8104,0.11626}, + {834,-0.0309,12.8167,0.11628}, + {835,-0.031,12.823,0.1163}, + {836,-0.0312,12.8292,0.11632}, + {837,-0.0313,12.8355,0.11634}, + {838,-0.0315,12.8417,0.11636}, + {839,-0.0317,12.848,0.11638}, + {840,-0.0318,12.8542,0.1164}, + {841,-0.032,12.8604,0.11642}, + {842,-0.0321,12.8667,0.11644}, + {843,-0.0323,12.8729,0.11646}, + {844,-0.0324,12.8791,0.11647}, + {845,-0.0326,12.8853,0.11649}, + {846,-0.0328,12.8915,0.11651}, + {847,-0.0329,12.8978,0.11653}, + {848,-0.0331,12.904,0.11655}, + {849,-0.0332,12.9102,0.11657}, + {850,-0.0334,12.9164,0.11659}, + {851,-0.0336,12.9226,0.11661}, + {852,-0.0337,12.9288,0.11663}, + {853,-0.0339,12.935,0.11665}, + {854,-0.034,12.9411,0.11667}, + {855,-0.0342,12.9473,0.11669}, + {856,-0.0343,12.9535,0.11671}, + {857,-0.0345,12.9597,0.11673}, + {858,-0.0346,12.9658,0.11675}, + {859,-0.0348,12.972,0.11677}, + {860,-0.035,12.9782,0.11679}, + {861,-0.0351,12.9843,0.11681}, + {862,-0.0353,12.9905,0.11683}, + {863,-0.0354,12.9966,0.11684}, + {864,-0.0356,13.0028,0.11686}, + {865,-0.0357,13.0089,0.11688}, + {866,-0.0359,13.0151,0.1169}, + {867,-0.0361,13.0212,0.11692}, + {868,-0.0362,13.0273,0.11694}, + {869,-0.0364,13.0334,0.11696}, + {870,-0.0365,13.0396,0.11698}, + {871,-0.0367,13.0457,0.117}, + {872,-0.0368,13.0518,0.11702}, + {873,-0.037,13.0579,0.11704}, + {874,-0.0371,13.064,0.11706}, + {875,-0.0373,13.0701,0.11708}, + {876,-0.0374,13.0762,0.1171}, + {877,-0.0376,13.0823,0.11712}, + {878,-0.0378,13.0884,0.11713}, + {879,-0.0379,13.0945,0.11715}, + {880,-0.0381,13.1006,0.11717}, + {881,-0.0382,13.1067,0.11719}, + {882,-0.0384,13.1127,0.11721}, + {883,-0.0385,13.1188,0.11723}, + {884,-0.0387,13.1249,0.11725}, + {885,-0.0388,13.131,0.11727}, + {886,-0.039,13.137,0.11729}, + {887,-0.0391,13.1431,0.11731}, + {888,-0.0393,13.1491,0.11733}, + {889,-0.0394,13.1552,0.11735}, + {890,-0.0396,13.1612,0.11737}, + {891,-0.0397,13.1673,0.11739}, + {892,-0.0399,13.1733,0.1174}, + {893,-0.0401,13.1793,0.11742}, + {894,-0.0402,13.1854,0.11744}, + {895,-0.0404,13.1914,0.11746}, + {896,-0.0405,13.1974,0.11748}, + {897,-0.0407,13.2034,0.1175}, + {898,-0.0408,13.2095,0.11752}, + {899,-0.041,13.2155,0.11754}, + {900,-0.0411,13.2215,0.11756}, + {901,-0.0413,13.2275,0.11758}, + {902,-0.0414,13.2335,0.1176}, + {903,-0.0416,13.2395,0.11762}, + {904,-0.0417,13.2455,0.11763}, + {905,-0.0419,13.2515,0.11765}, + {906,-0.042,13.2575,0.11767}, + {907,-0.0422,13.2634,0.11769}, + {908,-0.0423,13.2694,0.11771}, + {909,-0.0425,13.2754,0.11773}, + {910,-0.0426,13.2814,0.11775}, + {911,-0.0428,13.2873,0.11777}, + {912,-0.0429,13.2933,0.11779}, + {913,-0.0431,13.2993,0.11781}, + {914,-0.0432,13.3052,0.11783}, + {915,-0.0434,13.3112,0.11785}, + {916,-0.0435,13.3171,0.11786}, + {917,-0.0437,13.3231,0.11788}, + {918,-0.0438,13.329,0.1179}, + {919,-0.044,13.335,0.11792}, + {920,-0.0441,13.3409,0.11794}, + {921,-0.0443,13.3468,0.11796}, + {922,-0.0444,13.3528,0.11798}, + {923,-0.0446,13.3587,0.118}, + {924,-0.0447,13.3646,0.11802}, + {925,-0.0449,13.3705,0.11804}, + {926,-0.045,13.3765,0.11805}, + {927,-0.0452,13.3824,0.11807}, + {928,-0.0453,13.3883,0.11809}, + {929,-0.0455,13.3942,0.11811}, + {930,-0.0456,13.4001,0.11813}, + {931,-0.0458,13.406,0.11815}, + {932,-0.0459,13.4119,0.11817}, + {933,-0.0461,13.4178,0.11819}, + {934,-0.0462,13.4237,0.11821}, + {935,-0.0464,13.4296,0.11823}, + {936,-0.0465,13.4354,0.11825}, + {937,-0.0466,13.4413,0.11826}, + {938,-0.0468,13.4472,0.11828}, + {939,-0.0469,13.4531,0.1183}, + {940,-0.0471,13.4589,0.11832}, + {941,-0.0472,13.4648,0.11834}, + {942,-0.0474,13.4707,0.11836}, + {943,-0.0475,13.4765,0.11838}, + {944,-0.0477,13.4824,0.1184}, + {945,-0.0478,13.4883,0.11842}, + {946,-0.048,13.4941,0.11843}, + {947,-0.0481,13.5,0.11845}, + {948,-0.0483,13.5058,0.11847}, + {949,-0.0484,13.5116,0.11849}, + {950,-0.0486,13.5175,0.11851}, + {951,-0.0487,13.5233,0.11853}, + {952,-0.0489,13.5291,0.11855}, + {953,-0.049,13.535,0.11857}, + {954,-0.0491,13.5408,0.11859}, + {955,-0.0493,13.5466,0.1186}, + {956,-0.0494,13.5524,0.11862}, + {957,-0.0496,13.5583,0.11864}, + {958,-0.0497,13.5641,0.11866}, + {959,-0.0499,13.5699,0.11868}, + {960,-0.05,13.5757,0.1187}, + {961,-0.0502,13.5815,0.11872}, + {962,-0.0503,13.5873,0.11874}, + {963,-0.0505,13.5931,0.11876}, + {964,-0.0506,13.5989,0.11877}, + {965,-0.0507,13.6047,0.11879}, + {966,-0.0509,13.6105,0.11881}, + {967,-0.051,13.6163,0.11883}, + {968,-0.0512,13.622,0.11885}, + {969,-0.0513,13.6278,0.11887}, + {970,-0.0515,13.6336,0.11889}, + {971,-0.0516,13.6394,0.11891}, + {972,-0.0518,13.6452,0.11892}, + {973,-0.0519,13.6509,0.11894}, + {974,-0.052,13.6567,0.11896}, + {975,-0.0522,13.6625,0.11898}, + {976,-0.0523,13.6682,0.119}, + {977,-0.0525,13.674,0.11902}, + {978,-0.0526,13.6797,0.11904}, + {979,-0.0528,13.6855,0.11906}, + {980,-0.0529,13.6912,0.11907}, + {981,-0.053,13.697,0.11909}, + {982,-0.0532,13.7027,0.11911}, + {983,-0.0533,13.7085,0.11913}, + {984,-0.0535,13.7142,0.11915}, + {985,-0.0536,13.7199,0.11917}, + {986,-0.0538,13.7257,0.11919}, + {987,-0.0539,13.7314,0.1192}, + {988,-0.054,13.7371,0.11922}, + {989,-0.0542,13.7429,0.11924}, + {990,-0.0543,13.7486,0.11926}, + {991,-0.0545,13.7543,0.11928}, + {992,-0.0546,13.76,0.1193}, + {993,-0.0548,13.7657,0.11932}, + {994,-0.0549,13.7715,0.11933}, + {995,-0.055,13.7772,0.11935}, + {996,-0.0552,13.7829,0.11937}, + {997,-0.0553,13.7886,0.11939}, + {998,-0.0555,13.7943,0.11941}, + {999,-0.0556,13.8,0.11943}, + {1000,-0.0558,13.8057,0.11945}, + {1001,-0.0559,13.8114,0.11946}, + {1002,-0.056,13.8171,0.11948}, + {1003,-0.0562,13.8228,0.1195}, + {1004,-0.0563,13.8285,0.11952}, + {1005,-0.0565,13.8341,0.11954}, + {1006,-0.0566,13.8398,0.11956}, + {1007,-0.0567,13.8455,0.11957}, + {1008,-0.0569,13.8512,0.11959}, + {1009,-0.057,13.8569,0.11961}, + {1010,-0.0572,13.8625,0.11963}, + {1011,-0.0573,13.8682,0.11965}, + {1012,-0.0574,13.8739,0.11967}, + {1013,-0.0576,13.8796,0.11968}, + {1014,-0.0577,13.8852,0.1197}, + {1015,-0.0579,13.8909,0.11972}, + {1016,-0.058,13.8966,0.11974}, + {1017,-0.0581,13.9022,0.11976}, + {1018,-0.0583,13.9079,0.11978}, + {1019,-0.0584,13.9135,0.11979}, + {1020,-0.0586,13.9192,0.11981}, + {1021,-0.0587,13.9248,0.11983}, + {1022,-0.0588,13.9305,0.11985}, + {1023,-0.059,13.9361,0.11987}, + {1024,-0.0591,13.9418,0.11988}, + {1025,-0.0593,13.9474,0.1199}, + {1026,-0.0594,13.9531,0.11992}, + {1027,-0.0595,13.9587,0.11994}, + {1028,-0.0597,13.9644,0.11996}, + {1029,-0.0598,13.97,0.11998}, + {1030,-0.06,13.9756,0.11999}, + {1031,-0.0601,13.9813,0.12001}, + {1032,-0.0602,13.9869,0.12003}, + {1033,-0.0604,13.9925,0.12005}, + {1034,-0.0605,13.9982,0.12007}, + {1035,-0.0607,14.0038,0.12008}, + {1036,-0.0608,14.0094,0.1201}, + {1037,-0.0609,14.015,0.12012}, + {1038,-0.0611,14.0207,0.12014}, + {1039,-0.0612,14.0263,0.12016}, + {1040,-0.0613,14.0319,0.12017}, + {1041,-0.0615,14.0375,0.12019}, + {1042,-0.0616,14.0431,0.12021}, + {1043,-0.0618,14.0488,0.12023}, + {1044,-0.0619,14.0544,0.12025}, + {1045,-0.062,14.06,0.12026}, + {1046,-0.0622,14.0656,0.12028}, + {1047,-0.0623,14.0712,0.1203}, + {1048,-0.0624,14.0768,0.12032}, + {1049,-0.0626,14.0824,0.12033}, + {1050,-0.0627,14.088,0.12035}, + {1051,-0.0629,14.0936,0.12037}, + {1052,-0.063,14.0992,0.12039}, + {1053,-0.0631,14.1048,0.12041}, + {1054,-0.0633,14.1104,0.12042}, + {1055,-0.0634,14.116,0.12044}, + {1056,-0.0635,14.1216,0.12046}, + {1057,-0.0637,14.1272,0.12048}, + {1058,-0.0638,14.1328,0.1205}, + {1059,-0.0639,14.1384,0.12051}, + {1060,-0.0641,14.144,0.12053}, + {1061,-0.0642,14.1495,0.12055}, + {1062,-0.0644,14.1551,0.12057}, + {1063,-0.0645,14.1607,0.12058}, + {1064,-0.0646,14.1663,0.1206}, + {1065,-0.0648,14.1719,0.12062}, + {1066,-0.0649,14.1775,0.12064}, + {1067,-0.065,14.183,0.12065}, + {1068,-0.0652,14.1886,0.12067}, + {1069,-0.0653,14.1942,0.12069}, + {1070,-0.0654,14.1998,0.12071}, + {1071,-0.0656,14.2053,0.12073}, + {1072,-0.0657,14.2109,0.12074}, + {1073,-0.0658,14.2165,0.12076}, + {1074,-0.066,14.2221,0.12078}, + {1075,-0.0661,14.2276,0.1208}, + {1076,-0.0663,14.2332,0.12081}, + {1077,-0.0664,14.2388,0.12083}, + {1078,-0.0665,14.2443,0.12085}, + {1079,-0.0667,14.2499,0.12087}, + {1080,-0.0668,14.2554,0.12088}, + {1081,-0.0669,14.261,0.1209}, + {1082,-0.0671,14.2666,0.12092}, + {1083,-0.0672,14.2721,0.12094}, + {1084,-0.0673,14.2777,0.12095}, + {1085,-0.0675,14.2832,0.12097}, + {1086,-0.0676,14.2888,0.12099}, + {1087,-0.0677,14.2944,0.12101}, + {1088,-0.0679,14.2999,0.12102}, + {1089,-0.068,14.3055,0.12104}, + {1090,-0.0681,14.311,0.12106}, + {1091,-0.0683,14.3166,0.12108}, + {1092,-0.0684,14.3221,0.12109}, + {1093,-0.0685,14.3277,0.12111}, + {1094,-0.0687,14.3332,0.12113}, + {1095,-0.0688,14.3387,0.12115}, + {1096,-0.0689,14.3443,0.12116}, + {1097,-0.0691,14.3498,0.12118}, + {1098,-0.0692,14.3554,0.1212}, + {1099,-0.0693,14.3609,0.12121}, + {1100,-0.0695,14.3665,0.12123}, + {1101,-0.0696,14.372,0.12125}, + {1102,-0.0697,14.3775,0.12127}, + {1103,-0.0699,14.3831,0.12128}, + {1104,-0.07,14.3886,0.1213}, + {1105,-0.0701,14.3942,0.12132}, + {1106,-0.0703,14.3997,0.12134}, + {1107,-0.0704,14.4052,0.12135}, + {1108,-0.0705,14.4108,0.12137}, + {1109,-0.0707,14.4163,0.12139}, + {1110,-0.0708,14.4218,0.12141}, + {1111,-0.0709,14.4274,0.12142}, + {1112,-0.0711,14.4329,0.12144}, + {1113,-0.0712,14.4384,0.12146}, + {1114,-0.0713,14.4439,0.12147}, + {1115,-0.0715,14.4495,0.12149}, + {1116,-0.0716,14.455,0.12151}, + {1117,-0.0717,14.4605,0.12153}, + {1118,-0.0718,14.4661,0.12154}, + {1119,-0.072,14.4716,0.12156}, + {1120,-0.0721,14.4771,0.12158}, + {1121,-0.0722,14.4826,0.12159}, + {1122,-0.0724,14.4881,0.12161}, + {1123,-0.0725,14.4937,0.12163}, + {1124,-0.0726,14.4992,0.12165}, + {1125,-0.0728,14.5047,0.12166}, + {1126,-0.0729,14.5102,0.12168}, + {1127,-0.073,14.5158,0.1217}, + {1128,-0.0732,14.5213,0.12171}, + {1129,-0.0733,14.5268,0.12173}, + {1130,-0.0734,14.5323,0.12175}, + {1131,-0.0736,14.5378,0.12177}, + {1132,-0.0737,14.5433,0.12178}, + {1133,-0.0738,14.5489,0.1218}, + {1134,-0.0739,14.5544,0.12182}, + {1135,-0.0741,14.5599,0.12183}, + {1136,-0.0742,14.5654,0.12185}, + {1137,-0.0743,14.5709,0.12187}, + {1138,-0.0745,14.5764,0.12189}, + {1139,-0.0746,14.5819,0.1219}, + {1140,-0.0747,14.5875,0.12192}, + {1141,-0.0749,14.593,0.12194}, + {1142,-0.075,14.5985,0.12195}, + {1143,-0.0751,14.604,0.12197}, + {1144,-0.0752,14.6095,0.12199}, + {1145,-0.0754,14.615,0.122}, + {1146,-0.0755,14.6205,0.12202}, + {1147,-0.0756,14.626,0.12204}, + {1148,-0.0758,14.6315,0.12206}, + {1149,-0.0759,14.6371,0.12207}, + {1150,-0.076,14.6426,0.12209}, + {1151,-0.0762,14.6481,0.12211}, + {1152,-0.0763,14.6536,0.12212}, + {1153,-0.0764,14.6591,0.12214}, + {1154,-0.0765,14.6646,0.12216}, + {1155,-0.0767,14.6701,0.12217}, + {1156,-0.0768,14.6756,0.12219}, + {1157,-0.0769,14.6811,0.12221}, + {1158,-0.0771,14.6866,0.12222}, + {1159,-0.0772,14.6921,0.12224}, + {1160,-0.0773,14.6976,0.12226}, + {1161,-0.0774,14.7032,0.12228}, + {1162,-0.0776,14.7087,0.12229}, + {1163,-0.0777,14.7142,0.12231}, + {1164,-0.0778,14.7197,0.12233}, + {1165,-0.078,14.7252,0.12234}, + {1166,-0.0781,14.7307,0.12236}, + {1167,-0.0782,14.7362,0.12238}, + {1168,-0.0783,14.7417,0.12239}, + {1169,-0.0785,14.7472,0.12241}, + {1170,-0.0786,14.7527,0.12243}, + {1171,-0.0787,14.7582,0.12244}, + {1172,-0.0788,14.7637,0.12246}, + {1173,-0.079,14.7692,0.12248}, + {1174,-0.0791,14.7747,0.12249}, + {1175,-0.0792,14.7802,0.12251}, + {1176,-0.0794,14.7857,0.12253}, + {1177,-0.0795,14.7912,0.12254}, + {1178,-0.0796,14.7967,0.12256}, + {1179,-0.0797,14.8022,0.12258}, + {1180,-0.0799,14.8077,0.12259}, + {1181,-0.08,14.8132,0.12261}, + {1182,-0.0801,14.8187,0.12263}, + {1183,-0.0802,14.8242,0.12265}, + {1184,-0.0804,14.8297,0.12266}, + {1185,-0.0805,14.8352,0.12268}, + {1186,-0.0806,14.8407,0.1227}, + {1187,-0.0808,14.8462,0.12271}, + {1188,-0.0809,14.8517,0.12273}, + {1189,-0.081,14.8572,0.12275}, + {1190,-0.0811,14.8627,0.12276}, + {1191,-0.0813,14.8682,0.12278}, + {1192,-0.0814,14.8737,0.1228}, + {1193,-0.0815,14.8792,0.12281}, + {1194,-0.0816,14.8847,0.12283}, + {1195,-0.0818,14.8902,0.12285}, + {1196,-0.0819,14.8957,0.12286}, + {1197,-0.082,14.9012,0.12288}, + {1198,-0.0821,14.9067,0.1229}, + {1199,-0.0823,14.9122,0.12291}, + {1200,-0.0824,14.9177,0.12293}, + {1201,-0.0825,14.9232,0.12295}, + {1202,-0.0826,14.9287,0.12296}, + {1203,-0.0828,14.9342,0.12298}, + {1204,-0.0829,14.9397,0.123}, + {1205,-0.083,14.9452,0.12301}, + {1206,-0.0831,14.9507,0.12303}, + {1207,-0.0833,14.9562,0.12305}, + {1208,-0.0834,14.9617,0.12306}, + {1209,-0.0835,14.9672,0.12308}, + {1210,-0.0836,14.9727,0.1231}, + {1211,-0.0838,14.9782,0.12311}, + {1212,-0.0839,14.9837,0.12313}, + {1213,-0.084,14.9892,0.12315}, + {1214,-0.0841,14.9947,0.12316}, + {1215,-0.0843,15.0002,0.12318}, + {1216,-0.0844,15.0057,0.1232}, + {1217,-0.0845,15.0112,0.12321}, + {1218,-0.0846,15.0167,0.12323}, + {1219,-0.0848,15.0222,0.12325}, + {1220,-0.0849,15.0277,0.12326}, + {1221,-0.085,15.0332,0.12328}, + {1222,-0.0851,15.0387,0.1233}, + {1223,-0.0853,15.0442,0.12331}, + {1224,-0.0854,15.0497,0.12333}, + {1225,-0.0855,15.0552,0.12335}, + {1226,-0.0856,15.0607,0.12336}, + {1227,-0.0858,15.0662,0.12338}, + {1228,-0.0859,15.0717,0.1234}, + {1229,-0.086,15.0772,0.12342}, + {1230,-0.0861,15.0827,0.12343}, + {1231,-0.0863,15.0882,0.12345}, + {1232,-0.0864,15.0937,0.12347}, + {1233,-0.0865,15.0992,0.12348}, + {1234,-0.0866,15.1047,0.1235}, + {1235,-0.0868,15.1102,0.12352}, + {1236,-0.0869,15.1157,0.12353}, + {1237,-0.087,15.1212,0.12355}, + {1238,-0.0871,15.1267,0.12357}, + {1239,-0.0872,15.1322,0.12358}, + {1240,-0.0874,15.1377,0.1236}, + {1241,-0.0875,15.1432,0.12362}, + {1242,-0.0876,15.1487,0.12363}, + {1243,-0.0877,15.1542,0.12365}, + {1244,-0.0879,15.1596,0.12367}, + {1245,-0.088,15.1651,0.12368}, + {1246,-0.0881,15.1706,0.1237}, + {1247,-0.0882,15.1761,0.12372}, + {1248,-0.0883,15.1816,0.12373}, + {1249,-0.0885,15.1871,0.12375}, + {1250,-0.0886,15.1926,0.12377}, + {1251,-0.0887,15.1981,0.12379}, + {1252,-0.0888,15.2036,0.1238}, + {1253,-0.089,15.2091,0.12382}, + {1254,-0.0891,15.2146,0.12384}, + {1255,-0.0892,15.2201,0.12385}, + {1256,-0.0893,15.2256,0.12387}, + {1257,-0.0894,15.2311,0.12389}, + {1258,-0.0896,15.2366,0.1239}, + {1259,-0.0897,15.2421,0.12392}, + {1260,-0.0898,15.2476,0.12394}, + {1261,-0.0899,15.2531,0.12395}, + {1262,-0.0901,15.2586,0.12397}, + {1263,-0.0902,15.2641,0.12399}, + {1264,-0.0903,15.2696,0.12401}, + {1265,-0.0904,15.2751,0.12402}, + {1266,-0.0905,15.2806,0.12404}, + {1267,-0.0907,15.2861,0.12406}, + {1268,-0.0908,15.2916,0.12407}, + {1269,-0.0909,15.2971,0.12409}, + {1270,-0.091,15.3026,0.12411}, + {1271,-0.0912,15.3081,0.12412}, + {1272,-0.0913,15.3135,0.12414}, + {1273,-0.0914,15.319,0.12416}, + {1274,-0.0915,15.3245,0.12418}, + {1275,-0.0916,15.33,0.12419}, + {1276,-0.0918,15.3355,0.12421}, + {1277,-0.0919,15.341,0.12423}, + {1278,-0.092,15.3465,0.12424}, + {1279,-0.0921,15.352,0.12426}, + {1280,-0.0922,15.3575,0.12428}, + {1281,-0.0924,15.363,0.1243}, + {1282,-0.0925,15.3685,0.12431}, + {1283,-0.0926,15.374,0.12433}, + {1284,-0.0927,15.3795,0.12435}, + {1285,-0.0928,15.385,0.12436}, + {1286,-0.093,15.3905,0.12438}, + {1287,-0.0931,15.396,0.1244}, + {1288,-0.0932,15.4015,0.12442}, + {1289,-0.0933,15.407,0.12443}, + {1290,-0.0934,15.4125,0.12445}, + {1291,-0.0936,15.4179,0.12447}, + {1292,-0.0937,15.4234,0.12448}, + {1293,-0.0938,15.4289,0.1245}, + {1294,-0.0939,15.4344,0.12452}, + {1295,-0.094,15.4399,0.12454}, + {1296,-0.0942,15.4454,0.12455}, + {1297,-0.0943,15.4509,0.12457}, + {1298,-0.0944,15.4564,0.12459}, + {1299,-0.0945,15.4619,0.12461}, + {1300,-0.0946,15.4674,0.12462}, + {1301,-0.0948,15.4729,0.12464}, + {1302,-0.0949,15.4784,0.12466}, + {1303,-0.095,15.4839,0.12467}, + {1304,-0.0951,15.4894,0.12469}, + {1305,-0.0952,15.4948,0.12471}, + {1306,-0.0954,15.5003,0.12473}, + {1307,-0.0955,15.5058,0.12474}, + {1308,-0.0956,15.5113,0.12476}, + {1309,-0.0957,15.5168,0.12478}, + {1310,-0.0958,15.5223,0.1248}, + {1311,-0.0959,15.5278,0.12481}, + {1312,-0.0961,15.5333,0.12483}, + {1313,-0.0962,15.5388,0.12485}, + {1314,-0.0963,15.5443,0.12487}, + {1315,-0.0964,15.5498,0.12488}, + {1316,-0.0965,15.5552,0.1249}, + {1317,-0.0967,15.5607,0.12492}, + {1318,-0.0968,15.5662,0.12494}, + {1319,-0.0969,15.5717,0.12495}, + {1320,-0.097,15.5772,0.12497}, + {1321,-0.0971,15.5827,0.12499}, + {1322,-0.0972,15.5882,0.12501}, + {1323,-0.0974,15.5937,0.12502}, + {1324,-0.0975,15.5992,0.12504}, + {1325,-0.0976,15.6047,0.12506}, + {1326,-0.0977,15.6101,0.12508}, + {1327,-0.0978,15.6156,0.1251}, + {1328,-0.098,15.6211,0.12511}, + {1329,-0.0981,15.6266,0.12513}, + {1330,-0.0982,15.6321,0.12515}, + {1331,-0.0983,15.6376,0.12517}, + {1332,-0.0984,15.6431,0.12518}, + {1333,-0.0985,15.6486,0.1252}, + {1334,-0.0987,15.654,0.12522}, + {1335,-0.0988,15.6595,0.12524}, + {1336,-0.0989,15.665,0.12526}, + {1337,-0.099,15.6705,0.12527}, + {1338,-0.0991,15.676,0.12529}, + {1339,-0.0992,15.6815,0.12531}, + {1340,-0.0994,15.687,0.12533}, + {1341,-0.0995,15.6924,0.12534}, + {1342,-0.0996,15.6979,0.12536}, + {1343,-0.0997,15.7034,0.12538}, + {1344,-0.0998,15.7089,0.1254}, + {1345,-0.0999,15.7144,0.12542}, + {1346,-0.1001,15.7199,0.12543}, + {1347,-0.1002,15.7253,0.12545}, + {1348,-0.1003,15.7308,0.12547}, + {1349,-0.1004,15.7363,0.12549}, + {1350,-0.1005,15.7418,0.12551}, + {1351,-0.1006,15.7473,0.12552}, + {1352,-0.1008,15.7528,0.12554}, + {1353,-0.1009,15.7582,0.12556}, + {1354,-0.101,15.7637,0.12558}, + {1355,-0.1011,15.7692,0.1256}, + {1356,-0.1012,15.7747,0.12561}, + {1357,-0.1013,15.7802,0.12563}, + {1358,-0.1015,15.7856,0.12565}, + {1359,-0.1016,15.7911,0.12567}, + {1360,-0.1017,15.7966,0.12569}, + {1361,-0.1018,15.8021,0.1257}, + {1362,-0.1019,15.8076,0.12572}, + {1363,-0.102,15.813,0.12574}, + {1364,-0.1022,15.8185,0.12576}, + {1365,-0.1023,15.824,0.12578}, + {1366,-0.1024,15.8295,0.1258}, + {1367,-0.1025,15.835,0.12581}, + {1368,-0.1026,15.8404,0.12583}, + {1369,-0.1027,15.8459,0.12585}, + {1370,-0.1028,15.8514,0.12587}, + {1371,-0.103,15.8569,0.12589}, + {1372,-0.1031,15.8623,0.12591}, + {1373,-0.1032,15.8678,0.12592}, + {1374,-0.1033,15.8733,0.12594}, + {1375,-0.1034,15.8788,0.12596}, + {1376,-0.1035,15.8842,0.12598}, + {1377,-0.1037,15.8897,0.126}, + {1378,-0.1038,15.8952,0.12602}, + {1379,-0.1039,15.9007,0.12603}, + {1380,-0.104,15.9061,0.12605}, + {1381,-0.1041,15.9116,0.12607}, + {1382,-0.1042,15.9171,0.12609}, + {1383,-0.1043,15.9226,0.12611}, + {1384,-0.1045,15.928,0.12613}, + {1385,-0.1046,15.9335,0.12615}, + {1386,-0.1047,15.939,0.12616}, + {1387,-0.1048,15.9445,0.12618}, + {1388,-0.1049,15.9499,0.1262}, + {1389,-0.105,15.9554,0.12622}, + {1390,-0.1051,15.9609,0.12624}, + {1391,-0.1053,15.9664,0.12626}, + {1392,-0.1054,15.9718,0.12627}, + {1393,-0.1055,15.9773,0.12629}, + {1394,-0.1056,15.9828,0.12631}, + {1395,-0.1057,15.9882,0.12633}, + {1396,-0.1058,15.9937,0.12635}, + {1397,-0.1059,15.9992,0.12637}, + {1398,-0.1061,16.0047,0.12639}, + {1399,-0.1062,16.0101,0.12641}, + {1400,-0.1063,16.0156,0.12642}, + {1401,-0.1064,16.0211,0.12644}, + {1402,-0.1065,16.0265,0.12646}, + {1403,-0.1066,16.032,0.12648}, + {1404,-0.1067,16.0375,0.1265}, + {1405,-0.1068,16.043,0.12652}, + {1406,-0.107,16.0484,0.12654}, + {1407,-0.1071,16.0539,0.12656}, + {1408,-0.1072,16.0594,0.12657}, + {1409,-0.1073,16.0648,0.12659}, + {1410,-0.1074,16.0703,0.12661}, + {1411,-0.1075,16.0758,0.12663}, + {1412,-0.1076,16.0812,0.12665}, + {1413,-0.1078,16.0867,0.12667}, + {1414,-0.1079,16.0922,0.12669}, + {1415,-0.108,16.0976,0.12671}, + {1416,-0.1081,16.1031,0.12673}, + {1417,-0.1082,16.1086,0.12674}, + {1418,-0.1083,16.114,0.12676}, + {1419,-0.1084,16.1195,0.12678}, + {1420,-0.1085,16.125,0.1268}, + {1421,-0.1087,16.1304,0.12682}, + {1422,-0.1088,16.1359,0.12684}, + {1423,-0.1089,16.1414,0.12686}, + {1424,-0.109,16.1468,0.12688}, + {1425,-0.1091,16.1523,0.1269}, + {1426,-0.1092,16.1578,0.12692}, + {1427,-0.1093,16.1632,0.12693}, + {1428,-0.1094,16.1687,0.12695}, + {1429,-0.1096,16.1742,0.12697}, + {1430,-0.1097,16.1796,0.12699}, + {1431,-0.1098,16.1851,0.12701}, + {1432,-0.1099,16.1906,0.12703}, + {1433,-0.11,16.196,0.12705}, + {1434,-0.1101,16.2015,0.12707}, + {1435,-0.1102,16.2069,0.12709}, + {1436,-0.1103,16.2124,0.12711}, + {1437,-0.1105,16.2179,0.12713}, + {1438,-0.1106,16.2233,0.12715}, + {1439,-0.1107,16.2288,0.12717}, + {1440,-0.1108,16.2343,0.12718}, + {1441,-0.1109,16.2397,0.1272}, + {1442,-0.111,16.2452,0.12722}, + {1443,-0.1111,16.2506,0.12724}, + {1444,-0.1112,16.2561,0.12726}, + {1445,-0.1113,16.2616,0.12728}, + {1446,-0.1115,16.267,0.1273}, + {1447,-0.1116,16.2725,0.12732}, + {1448,-0.1117,16.2779,0.12734}, + {1449,-0.1118,16.2834,0.12736}, + {1450,-0.1119,16.2889,0.12738}, + {1451,-0.112,16.2943,0.1274}, + {1452,-0.1121,16.2998,0.12742}, + {1453,-0.1122,16.3053,0.12744}, + {1454,-0.1123,16.3107,0.12746}, + {1455,-0.1125,16.3162,0.12747}, + {1456,-0.1126,16.3216,0.12749}, + {1457,-0.1127,16.3271,0.12751}, + {1458,-0.1128,16.3325,0.12753}, + {1459,-0.1129,16.338,0.12755}, + {1460,-0.113,16.3435,0.12757}, + {1461,-0.1131,16.3489,0.12759}, + {1462,-0.1132,16.3544,0.12761}, + {1463,-0.1133,16.3598,0.12763}, + {1464,-0.1134,16.3653,0.12765}, + {1465,-0.1136,16.3708,0.12767}, + {1466,-0.1137,16.3762,0.12769}, + {1467,-0.1138,16.3817,0.12771}, + {1468,-0.1139,16.3871,0.12773}, + {1469,-0.114,16.3926,0.12775}, + {1470,-0.1141,16.3981,0.12777}, + {1471,-0.1142,16.4035,0.12779}, + {1472,-0.1143,16.409,0.12781}, + {1473,-0.1144,16.4144,0.12783}, + {1474,-0.1146,16.4199,0.12785}, + {1475,-0.1147,16.4253,0.12787}, + {1476,-0.1148,16.4308,0.12789}, + {1477,-0.1149,16.4363,0.12791}, + {1478,-0.115,16.4417,0.12793}, + {1479,-0.1151,16.4472,0.12795}, + {1480,-0.1152,16.4526,0.12797}, + {1481,-0.1153,16.4581,0.12799}, + {1482,-0.1154,16.4635,0.12801}, + {1483,-0.1155,16.469,0.12803}, + {1484,-0.1156,16.4745,0.12804}, + {1485,-0.1158,16.4799,0.12806}, + {1486,-0.1159,16.4854,0.12808}, + {1487,-0.116,16.4908,0.1281}, + {1488,-0.1161,16.4963,0.12812}, + {1489,-0.1162,16.5017,0.12814}, + {1490,-0.1163,16.5072,0.12816}, + {1491,-0.1164,16.5126,0.12818}, + {1492,-0.1165,16.5181,0.1282}, + {1493,-0.1166,16.5236,0.12822}, + {1494,-0.1167,16.529,0.12824}, + {1495,-0.1168,16.5345,0.12826}, + {1496,-0.117,16.5399,0.12828}, + {1497,-0.1171,16.5454,0.1283}, + {1498,-0.1172,16.5508,0.12832}, + {1499,-0.1173,16.5563,0.12834}, + {1500,-0.1174,16.5618,0.12836}, + {1501,-0.1175,16.5672,0.12838}, + {1502,-0.1176,16.5727,0.1284}, + {1503,-0.1177,16.5781,0.12842}, + {1504,-0.1178,16.5836,0.12844}, + {1505,-0.1179,16.589,0.12846}, + {1506,-0.118,16.5945,0.12848}, + {1507,-0.1182,16.5999,0.1285}, + {1508,-0.1183,16.6054,0.12852}, + {1509,-0.1184,16.6109,0.12854}, + {1510,-0.1185,16.6163,0.12856}, + {1511,-0.1186,16.6218,0.12858}, + {1512,-0.1187,16.6272,0.1286}, + {1513,-0.1188,16.6327,0.12863}, + {1514,-0.1189,16.6381,0.12865}, + {1515,-0.119,16.6436,0.12867}, + {1516,-0.1191,16.649,0.12869}, + {1517,-0.1192,16.6545,0.12871}, + {1518,-0.1193,16.6599,0.12873}, + {1519,-0.1195,16.6654,0.12875}, + {1520,-0.1196,16.6709,0.12877}, + {1521,-0.1197,16.6763,0.12879}, + {1522,-0.1198,16.6818,0.12881}, + {1523,-0.1199,16.6872,0.12883}, + {1524,-0.12,16.6927,0.12885}, + {1525,-0.1201,16.6981,0.12887}, + {1526,-0.1202,16.7036,0.12889}, + {1527,-0.1203,16.709,0.12891}, + {1528,-0.1204,16.7145,0.12893}, + {1529,-0.1205,16.72,0.12895}, + {1530,-0.1206,16.7254,0.12897}, + {1531,-0.1207,16.7309,0.12899}, + {1532,-0.1208,16.7363,0.12901}, + {1533,-0.121,16.7418,0.12903}, + {1534,-0.1211,16.7472,0.12905}, + {1535,-0.1212,16.7527,0.12907}, + {1536,-0.1213,16.7581,0.12909}, + {1537,-0.1214,16.7636,0.12911}, + {1538,-0.1215,16.769,0.12913}, + {1539,-0.1216,16.7745,0.12915}, + {1540,-0.1217,16.78,0.12917}, + {1541,-0.1218,16.7854,0.12919}, + {1542,-0.1219,16.7909,0.12921}, + {1543,-0.122,16.7963,0.12923}, + {1544,-0.1221,16.8018,0.12925}, + {1545,-0.1222,16.8072,0.12928}, + {1546,-0.1223,16.8127,0.1293}, + {1547,-0.1225,16.8181,0.12932}, + {1548,-0.1226,16.8236,0.12934}, + {1549,-0.1227,16.829,0.12936}, + {1550,-0.1228,16.8345,0.12938}, + {1551,-0.1229,16.84,0.1294}, + {1552,-0.123,16.8454,0.12942}, + {1553,-0.1231,16.8509,0.12944}, + {1554,-0.1232,16.8563,0.12946}, + {1555,-0.1233,16.8618,0.12948}, + {1556,-0.1234,16.8672,0.1295}, + {1557,-0.1235,16.8727,0.12952}, + {1558,-0.1236,16.8781,0.12954}, + {1559,-0.1237,16.8836,0.12956}, + {1560,-0.1238,16.8891,0.12958}, + {1561,-0.1239,16.8945,0.1296}, + {1562,-0.124,16.9,0.12962}, + {1563,-0.1242,16.9054,0.12965}, + {1564,-0.1243,16.9109,0.12967}, + {1565,-0.1244,16.9163,0.12969}, + {1566,-0.1245,16.9218,0.12971}, + {1567,-0.1246,16.9272,0.12973}, + {1568,-0.1247,16.9327,0.12975}, + {1569,-0.1248,16.9382,0.12977}, + {1570,-0.1249,16.9436,0.12979}, + {1571,-0.125,16.9491,0.12981}, + {1572,-0.1251,16.9545,0.12983}, + {1573,-0.1252,16.96,0.12985}, + {1574,-0.1253,16.9654,0.12987}, + {1575,-0.1254,16.9709,0.12989}, + {1576,-0.1255,16.9763,0.12991}, + {1577,-0.1256,16.9818,0.12993}, + {1578,-0.1257,16.9873,0.12996}, + {1579,-0.1258,16.9927,0.12998}, + {1580,-0.1259,16.9982,0.13}, + {1581,-0.126,17.0036,0.13002}, + {1582,-0.1262,17.0091,0.13004}, + {1583,-0.1263,17.0145,0.13006}, + {1584,-0.1264,17.02,0.13008}, + {1585,-0.1265,17.0255,0.1301}, + {1586,-0.1266,17.0309,0.13012}, + {1587,-0.1267,17.0364,0.13014}, + {1588,-0.1268,17.0418,0.13016}, + {1589,-0.1269,17.0473,0.13018}, + {1590,-0.127,17.0527,0.1302}, + {1591,-0.1271,17.0582,0.13023}, + {1592,-0.1272,17.0636,0.13025}, + {1593,-0.1273,17.0691,0.13027}, + {1594,-0.1274,17.0746,0.13029}, + {1595,-0.1275,17.08,0.13031}, + {1596,-0.1276,17.0855,0.13033}, + {1597,-0.1277,17.0909,0.13035}, + {1598,-0.1278,17.0964,0.13037}, + {1599,-0.1279,17.1018,0.13039}, + {1600,-0.128,17.1073,0.13041}, + {1601,-0.1281,17.1127,0.13043}, + {1602,-0.1282,17.1182,0.13045}, + {1603,-0.1283,17.1237,0.13047}, + {1604,-0.1285,17.1291,0.1305}, + {1605,-0.1286,17.1346,0.13052}, + {1606,-0.1287,17.14,0.13054}, + {1607,-0.1288,17.1455,0.13056}, + {1608,-0.1289,17.1509,0.13058}, + {1609,-0.129,17.1564,0.1306}, + {1610,-0.1291,17.1618,0.13062}, + {1611,-0.1292,17.1673,0.13064}, + {1612,-0.1293,17.1728,0.13066}, + {1613,-0.1294,17.1782,0.13068}, + {1614,-0.1295,17.1837,0.1307}, + {1615,-0.1296,17.1891,0.13073}, + {1616,-0.1297,17.1946,0.13075}, + {1617,-0.1298,17.2,0.13077}, + {1618,-0.1299,17.2055,0.13079}, + {1619,-0.13,17.2109,0.13081}, + {1620,-0.1301,17.2164,0.13083}, + {1621,-0.1302,17.2218,0.13085}, + {1622,-0.1303,17.2273,0.13087}, + {1623,-0.1304,17.2328,0.13089}, + {1624,-0.1305,17.2382,0.13091}, + {1625,-0.1306,17.2437,0.13093}, + {1626,-0.1307,17.2491,0.13096}, + {1627,-0.1308,17.2546,0.13098}, + {1628,-0.1309,17.26,0.131}, + {1629,-0.131,17.2655,0.13102}, + {1630,-0.1311,17.2709,0.13104}, + {1631,-0.1312,17.2764,0.13106}, + {1632,-0.1314,17.2818,0.13108}, + {1633,-0.1315,17.2873,0.1311}, + {1634,-0.1316,17.2927,0.13112}, + {1635,-0.1317,17.2982,0.13114}, + {1636,-0.1318,17.3037,0.13117}, + {1637,-0.1319,17.3091,0.13119}, + {1638,-0.132,17.3146,0.13121}, + {1639,-0.1321,17.32,0.13123}, + {1640,-0.1322,17.3255,0.13125}, + {1641,-0.1323,17.3309,0.13127}, + {1642,-0.1324,17.3364,0.13129}, + {1643,-0.1325,17.3418,0.13131}, + {1644,-0.1326,17.3473,0.13133}, + {1645,-0.1327,17.3527,0.13135}, + {1646,-0.1328,17.3582,0.13137}, + {1647,-0.1329,17.3636,0.1314}, + {1648,-0.133,17.3691,0.13142}, + {1649,-0.1331,17.3745,0.13144}, + {1650,-0.1332,17.38,0.13146}, + {1651,-0.1333,17.3854,0.13148}, + {1652,-0.1334,17.3909,0.1315}, + {1653,-0.1335,17.3963,0.13152}, + {1654,-0.1336,17.4018,0.13154}, + {1655,-0.1337,17.4072,0.13156}, + {1656,-0.1338,17.4127,0.13159}, + {1657,-0.1339,17.4181,0.13161}, + {1658,-0.134,17.4236,0.13163}, + {1659,-0.1341,17.429,0.13165}, + {1660,-0.1342,17.4345,0.13167}, + {1661,-0.1343,17.4399,0.13169}, + {1662,-0.1344,17.4454,0.13171}, + {1663,-0.1345,17.4508,0.13173}, + {1664,-0.1346,17.4563,0.13175}, + {1665,-0.1347,17.4617,0.13177}, + {1666,-0.1348,17.4672,0.1318}, + {1667,-0.1349,17.4726,0.13182}, + {1668,-0.135,17.4781,0.13184}, + {1669,-0.1351,17.4835,0.13186}, + {1670,-0.1352,17.489,0.13188}, + {1671,-0.1353,17.4944,0.1319}, + {1672,-0.1354,17.4999,0.13192}, + {1673,-0.1355,17.5053,0.13194}, + {1674,-0.1356,17.5107,0.13196}, + {1675,-0.1357,17.5162,0.13199}, + {1676,-0.1358,17.5216,0.13201}, + {1677,-0.1359,17.5271,0.13203}, + {1678,-0.136,17.5325,0.13205}, + {1679,-0.1361,17.538,0.13207}, + {1680,-0.1362,17.5434,0.13209}, + {1681,-0.1363,17.5489,0.13211}, + {1682,-0.1364,17.5543,0.13213}, + {1683,-0.1365,17.5598,0.13215}, + {1684,-0.1366,17.5652,0.13218}, + {1685,-0.1367,17.5706,0.1322}, + {1686,-0.1368,17.5761,0.13222}, + {1687,-0.1369,17.5815,0.13224}, + {1688,-0.137,17.587,0.13226}, + {1689,-0.1371,17.5924,0.13228}, + {1690,-0.1373,17.5979,0.1323}, + {1691,-0.1374,17.6033,0.13232}, + {1692,-0.1375,17.6087,0.13234}, + {1693,-0.1376,17.6142,0.13237}, + {1694,-0.1377,17.6196,0.13239}, + {1695,-0.1378,17.6251,0.13241}, + {1696,-0.1379,17.6305,0.13243}, + {1697,-0.138,17.636,0.13245}, + {1698,-0.1381,17.6414,0.13247}, + {1699,-0.1382,17.6468,0.13249}, + {1700,-0.1383,17.6523,0.13251}, + {1701,-0.1384,17.6577,0.13253}, + {1702,-0.1385,17.6632,0.13256}, + {1703,-0.1386,17.6686,0.13258}, + {1704,-0.1387,17.674,0.1326}, + {1705,-0.1388,17.6795,0.13262}, + {1706,-0.1389,17.6849,0.13264}, + {1707,-0.139,17.6904,0.13266}, + {1708,-0.1391,17.6958,0.13268}, + {1709,-0.1392,17.7012,0.1327}, + {1710,-0.1393,17.7067,0.13272}, + {1711,-0.1394,17.7121,0.13275}, + {1712,-0.1395,17.7175,0.13277}, + {1713,-0.1396,17.723,0.13279}, + {1714,-0.1397,17.7284,0.13281}, + {1715,-0.1398,17.7339,0.13283}, + {1716,-0.1399,17.7393,0.13285}, + {1717,-0.14,17.7447,0.13287}, + {1718,-0.1401,17.7502,0.13289}, + {1719,-0.1402,17.7556,0.13291}, + {1720,-0.1403,17.761,0.13294}, + {1721,-0.1404,17.7665,0.13296}, + {1722,-0.1404,17.7719,0.13298}, + {1723,-0.1405,17.7773,0.133}, + {1724,-0.1406,17.7828,0.13302}, + {1725,-0.1407,17.7882,0.13304}, + {1726,-0.1408,17.7936,0.13306}, + {1727,-0.1409,17.7991,0.13308}, + {1728,-0.141,17.8045,0.1331}, + {1729,-0.1411,17.8099,0.13313}, + {1730,-0.1412,17.8154,0.13315}, + {1731,-0.1413,17.8208,0.13317}, + {1732,-0.1414,17.8262,0.13319}, + {1733,-0.1415,17.8317,0.13321}, + {1734,-0.1416,17.8371,0.13323}, + {1735,-0.1417,17.8425,0.13325}, + {1736,-0.1418,17.848,0.13327}, + {1737,-0.1419,17.8534,0.13329}, + {1738,-0.142,17.8588,0.13332}, + {1739,-0.1421,17.8642,0.13334}, + {1740,-0.1422,17.8697,0.13336}, + {1741,-0.1423,17.8751,0.13338}, + {1742,-0.1424,17.8805,0.1334}, + {1743,-0.1425,17.886,0.13342}, + {1744,-0.1426,17.8914,0.13344}, + {1745,-0.1427,17.8968,0.13346}, + {1746,-0.1428,17.9022,0.13348}, + {1747,-0.1429,17.9077,0.13351}, + {1748,-0.143,17.9131,0.13353}, + {1749,-0.1431,17.9185,0.13355}, + {1750,-0.1432,17.924,0.13357}, + {1751,-0.1433,17.9294,0.13359}, + {1752,-0.1434,17.9348,0.13361}, + {1753,-0.1435,17.9402,0.13363}, + {1754,-0.1436,17.9457,0.13365}, + {1755,-0.1437,17.9511,0.13367}, + {1756,-0.1438,17.9565,0.1337}, + {1757,-0.1439,17.9619,0.13372}, + {1758,-0.144,17.9674,0.13374}, + {1759,-0.1441,17.9728,0.13376}, + {1760,-0.1442,17.9782,0.13378}, + {1761,-0.1443,17.9836,0.1338}, + {1762,-0.1444,17.989,0.13382}, + {1763,-0.1445,17.9945,0.13384}, + {1764,-0.1446,17.9999,0.13386}, + {1765,-0.1447,18.0053,0.13389}, + {1766,-0.1448,18.0107,0.13391}, + {1767,-0.1449,18.0162,0.13393}, + {1768,-0.145,18.0216,0.13395}, + {1769,-0.1451,18.027,0.13397}, + {1770,-0.1452,18.0324,0.13399}, + {1771,-0.1453,18.0378,0.13401}, + {1772,-0.1454,18.0432,0.13403}, + {1773,-0.1455,18.0487,0.13405}, + {1774,-0.1456,18.0541,0.13408}, + {1775,-0.1457,18.0595,0.1341}, + {1776,-0.1458,18.0649,0.13412}, + {1777,-0.1459,18.0703,0.13414}, + {1778,-0.146,18.0758,0.13416}, + {1779,-0.1461,18.0812,0.13418}, + {1780,-0.1462,18.0866,0.1342}, + {1781,-0.1462,18.092,0.13422}, + {1782,-0.1463,18.0974,0.13424}, + {1783,-0.1464,18.1028,0.13426}, + {1784,-0.1465,18.1082,0.13429}, + {1785,-0.1466,18.1137,0.13431}, + {1786,-0.1467,18.1191,0.13433}, + {1787,-0.1468,18.1245,0.13435}, + {1788,-0.1469,18.1299,0.13437}, + {1789,-0.147,18.1353,0.13439}, + {1790,-0.1471,18.1407,0.13441}, + {1791,-0.1472,18.1461,0.13443}, + {1792,-0.1473,18.1515,0.13445}, + {1793,-0.1474,18.157,0.13448}, + {1794,-0.1475,18.1624,0.1345}, + {1795,-0.1476,18.1678,0.13452}, + {1796,-0.1477,18.1732,0.13454}, + {1797,-0.1478,18.1786,0.13456}, + {1798,-0.1479,18.184,0.13458}, + {1799,-0.148,18.1894,0.1346}, + {1800,-0.1481,18.1948,0.13462}, + {1801,-0.1482,18.2002,0.13464}, + {1802,-0.1483,18.2056,0.13466}, + {1803,-0.1484,18.211,0.13469}, + {1804,-0.1485,18.2164,0.13471}, + {1805,-0.1486,18.2218,0.13473}, + {1806,-0.1487,18.2272,0.13475}, + {1807,-0.1488,18.2327,0.13477}, + {1808,-0.1489,18.2381,0.13479}, + {1809,-0.149,18.2435,0.13481}, + {1810,-0.1491,18.2489,0.13483}, + {1811,-0.1491,18.2543,0.13485}, + {1812,-0.1492,18.2597,0.13487}, + {1813,-0.1493,18.2651,0.1349}, + {1814,-0.1494,18.2705,0.13492}, + {1815,-0.1495,18.2759,0.13494}, + {1816,-0.1496,18.2813,0.13496}, + {1817,-0.1497,18.2867,0.13498}, + {1818,-0.1498,18.2921,0.135}, + {1819,-0.1499,18.2975,0.13502}, + {1820,-0.15,18.3029,0.13504}, + {1821,-0.1501,18.3083,0.13506}, + {1822,-0.1502,18.3137,0.13508}, + {1823,-0.1503,18.319,0.13511}, + {1824,-0.1504,18.3244,0.13513}, + {1825,-0.1505,18.3298,0.13515}, + {1826,-0.1506,18.3352,0.13517}, + {1827,-0.1507,18.3406,0.13519}, + {1828,-0.1508,18.346,0.13521}, + {1829,-0.1509,18.3514,0.13523}, + {1830,-0.151,18.3568,0.13525}, + {1831,-0.1511,18.3622,0.13527}, + {1832,-0.1512,18.3676,0.13529}, + {1833,-0.1513,18.373,0.13531}, + {1834,-0.1514,18.3784,0.13534}, + {1835,-0.1514,18.3838,0.13536}, + {1836,-0.1515,18.3891,0.13538}, + {1837,-0.1516,18.3945,0.1354}, + {1838,-0.1517,18.3999,0.13542}, + {1839,-0.1518,18.4053,0.13544}, + {1840,-0.1519,18.4107,0.13546}, + {1841,-0.152,18.4161,0.13548}, + {1842,-0.1521,18.4215,0.1355}, + {1843,-0.1522,18.4268,0.13552}, + {1844,-0.1523,18.4322,0.13554}, + {1845,-0.1524,18.4376,0.13557}, + {1846,-0.1525,18.443,0.13559}, + {1847,-0.1526,18.4484,0.13561}, + {1848,-0.1527,18.4538,0.13563}, + {1849,-0.1528,18.4591,0.13565}, + {1850,-0.1529,18.4645,0.13567}, + {1851,-0.153,18.4699,0.13569}, + {1852,-0.1531,18.4753,0.13571}, + {1853,-0.1532,18.4807,0.13573}, + {1854,-0.1533,18.486,0.13575}, + {1855,-0.1533,18.4914,0.13577}, + {1856,-0.1534,18.4968,0.1358}, + + }; + return boysWeightForAge[index < boysWeightForAge.length ? index : boysWeightForAge.length]; + } + + public double[]getGirlsWeightForAge(int index){ + double[][]girlsWeightForAge={ + {0,0.3809,3.2322,0.14171}, + {1,0.3259,3.1957,0.14578}, + {2,0.3101,3.2104,0.14637}, + {3,0.2986,3.2315,0.14657}, + {4,0.2891,3.2558,0.14658}, + {5,0.281,3.2821,0.14646}, + {6,0.2737,3.3099,0.14626}, + {7,0.2671,3.3388,0.146}, + {8,0.2609,3.3687,0.14569}, + {9,0.2551,3.3995,0.14534}, + {10,0.2497,3.4314,0.14498}, + {11,0.2446,3.4643,0.14459}, + {12,0.2397,3.4983,0.1442}, + {13,0.2349,3.5333,0.1438}, + {14,0.2304,3.5693,0.14339}, + {15,0.226,3.6063,0.14299}, + {16,0.2218,3.6438,0.14258}, + {17,0.2177,3.6818,0.14218}, + {18,0.2137,3.7201,0.14177}, + {19,0.2099,3.7584,0.14138}, + {20,0.2061,3.7968,0.14098}, + {21,0.2024,3.8352,0.1406}, + {22,0.1989,3.8735,0.14021}, + {23,0.1954,3.9116,0.13984}, + {24,0.1919,3.9495,0.13947}, + {25,0.1886,3.9872,0.1391}, + {26,0.1853,4.0247,0.13875}, + {27,0.1821,4.0618,0.1384}, + {28,0.1789,4.0987,0.13805}, + {29,0.1758,4.1353,0.13771}, + {30,0.1727,4.1716,0.13738}, + {31,0.1697,4.2075,0.13706}, + {32,0.1668,4.2431,0.13674}, + {33,0.1638,4.2783,0.13643}, + {34,0.161,4.3131,0.13613}, + {35,0.1582,4.3476,0.13583}, + {36,0.1554,4.3818,0.13554}, + {37,0.1526,4.4155,0.13526}, + {38,0.1499,4.449,0.13498}, + {39,0.1473,4.482,0.1347}, + {40,0.1446,4.5148,0.13444}, + {41,0.142,4.5472,0.13418}, + {42,0.1395,4.5793,0.13392}, + {43,0.1369,4.611,0.13367}, + {44,0.1344,4.6425,0.13342}, + {45,0.132,4.6736,0.13318}, + {46,0.1295,4.7044,0.13295}, + {47,0.1271,4.7349,0.13272}, + {48,0.1247,4.7651,0.1325}, + {49,0.1224,4.795,0.13228}, + {50,0.12,4.8245,0.13206}, + {51,0.1177,4.8538,0.13185}, + {52,0.1154,4.8828,0.13165}, + {53,0.1132,4.9115,0.13145}, + {54,0.1109,4.9399,0.13125}, + {55,0.1087,4.968,0.13106}, + {56,0.1065,4.9959,0.13087}, + {57,0.1044,5.0235,0.13068}, + {58,0.1022,5.0509,0.1305}, + {59,0.1001,5.078,0.13033}, + {60,0.098,5.1049,0.13015}, + {61,0.0959,5.1315,0.12998}, + {62,0.0938,5.158,0.12982}, + {63,0.0918,5.1842,0.12966}, + {64,0.0897,5.2102,0.1295}, + {65,0.0877,5.236,0.12934}, + {66,0.0857,5.2616,0.12919}, + {67,0.0838,5.287,0.12904}, + {68,0.0818,5.3121,0.12889}, + {69,0.0798,5.337,0.12875}, + {70,0.0779,5.3618,0.12861}, + {71,0.076,5.3863,0.12847}, + {72,0.0741,5.4107,0.12834}, + {73,0.0722,5.4348,0.12821}, + {74,0.0704,5.4587,0.12808}, + {75,0.0685,5.4825,0.12795}, + {76,0.0667,5.5061,0.12783}, + {77,0.0648,5.5295,0.1277}, + {78,0.063,5.5527,0.12758}, + {79,0.0612,5.5757,0.12747}, + {80,0.0595,5.5986,0.12735}, + {81,0.0577,5.6213,0.12724}, + {82,0.0559,5.6438,0.12713}, + {83,0.0542,5.6662,0.12702}, + {84,0.0525,5.6883,0.12691}, + {85,0.0508,5.7104,0.12681}, + {86,0.049,5.7322,0.12671}, + {87,0.0474,5.7539,0.1266}, + {88,0.0457,5.7755,0.12651}, + {89,0.044,5.7969,0.12641}, + {90,0.0424,5.8181,0.12631}, + {91,0.0407,5.8393,0.12622}, + {92,0.0391,5.8602,0.12613}, + {93,0.0375,5.881,0.12604}, + {94,0.0358,5.9017,0.12595}, + {95,0.0342,5.9223,0.12586}, + {96,0.0327,5.9427,0.12577}, + {97,0.0311,5.9629,0.12569}, + {98,0.0295,5.9831,0.12561}, + {99,0.0279,6.0031,0.12553}, + {100,0.0264,6.0229,0.12545}, + {101,0.0249,6.0426,0.12537}, + {102,0.0233,6.0622,0.12529}, + {103,0.0218,6.0817,0.12522}, + {104,0.0203,6.101,0.12514}, + {105,0.0188,6.1202,0.12507}, + {106,0.0173,6.1393,0.125}, + {107,0.0158,6.1582,0.12493}, + {108,0.0144,6.1771,0.12486}, + {109,0.0129,6.1958,0.12479}, + {110,0.0114,6.2143,0.12472}, + {111,0.01,6.2328,0.12466}, + {112,0.0086,6.2511,0.12459}, + {113,0.0071,6.2693,0.12453}, + {114,0.0057,6.2874,0.12447}, + {115,0.0043,6.3054,0.12441}, + {116,0.0029,6.3232,0.12435}, + {117,0.0015,6.341,0.12429}, + {118,0.0001,6.3586,0.12423}, + {119,-0.0013,6.3761,0.12417}, + {120,-0.0026,6.3935,0.12412}, + {121,-0.004,6.4108,0.12406}, + {122,-0.0053,6.428,0.12401}, + {123,-0.0067,6.445,0.12395}, + {124,-0.008,6.462,0.1239}, + {125,-0.0094,6.4788,0.12385}, + {126,-0.0107,6.4956,0.1238}, + {127,-0.012,6.5122,0.12375}, + {128,-0.0133,6.5288,0.1237}, + {129,-0.0146,6.5452,0.12365}, + {130,-0.0159,6.5615,0.1236}, + {131,-0.0172,6.5777,0.12355}, + {132,-0.0185,6.5939,0.12351}, + {133,-0.0198,6.6099,0.12346}, + {134,-0.021,6.6258,0.12342}, + {135,-0.0223,6.6416,0.12337}, + {136,-0.0235,6.6573,0.12333}, + {137,-0.0248,6.6729,0.12329}, + {138,-0.026,6.6884,0.12325}, + {139,-0.0273,6.7039,0.12321}, + {140,-0.0285,6.7192,0.12317}, + {141,-0.0297,6.7344,0.12313}, + {142,-0.0309,6.7495,0.12309}, + {143,-0.0321,6.7646,0.12305}, + {144,-0.0333,6.7795,0.12301}, + {145,-0.0345,6.7944,0.12298}, + {146,-0.0357,6.8091,0.12294}, + {147,-0.0369,6.8238,0.12291}, + {148,-0.0381,6.8384,0.12287}, + {149,-0.0393,6.8529,0.12284}, + {150,-0.0404,6.8673,0.12281}, + {151,-0.0416,6.8816,0.12277}, + {152,-0.0428,6.8959,0.12274}, + {153,-0.0439,6.91,0.12271}, + {154,-0.045,6.9241,0.12268}, + {155,-0.0462,6.9381,0.12265}, + {156,-0.0473,6.952,0.12262}, + {157,-0.0484,6.9659,0.12259}, + {158,-0.0496,6.9797,0.12256}, + {159,-0.0507,6.9934,0.12254}, + {160,-0.0518,7.007,0.12251}, + {161,-0.0529,7.0205,0.12248}, + {162,-0.054,7.034,0.12246}, + {163,-0.0551,7.0474,0.12243}, + {164,-0.0562,7.0607,0.12241}, + {165,-0.0573,7.074,0.12238}, + {166,-0.0583,7.0872,0.12236}, + {167,-0.0594,7.1003,0.12234}, + {168,-0.0605,7.1133,0.12231}, + {169,-0.0615,7.1263,0.12229}, + {170,-0.0626,7.1393,0.12227}, + {171,-0.0637,7.1521,0.12225}, + {172,-0.0647,7.1649,0.12223}, + {173,-0.0658,7.1776,0.12221}, + {174,-0.0668,7.1903,0.12219}, + {175,-0.0678,7.2029,0.12217}, + {176,-0.0689,7.2154,0.12215}, + {177,-0.0699,7.2279,0.12214}, + {178,-0.0709,7.2403,0.12212}, + {179,-0.0719,7.2527,0.1221}, + {180,-0.0729,7.265,0.12208}, + {181,-0.0739,7.2772,0.12207}, + {182,-0.0749,7.2894,0.12205}, + {183,-0.0759,7.3016,0.12204}, + {184,-0.0769,7.3136,0.12202}, + {185,-0.0779,7.3256,0.12201}, + {186,-0.0789,7.3376,0.122}, + {187,-0.0799,7.3495,0.12198}, + {188,-0.0808,7.3614,0.12197}, + {189,-0.0818,7.3732,0.12196}, + {190,-0.0828,7.3849,0.12195}, + {191,-0.0837,7.3966,0.12194}, + {192,-0.0847,7.4082,0.12192}, + {193,-0.0857,7.4198,0.12191}, + {194,-0.0866,7.4314,0.1219}, + {195,-0.0875,7.4429,0.12189}, + {196,-0.0885,7.4543,0.12188}, + {197,-0.0894,7.4657,0.12188}, + {198,-0.0904,7.477,0.12187}, + {199,-0.0913,7.4883,0.12186}, + {200,-0.0922,7.4995,0.12185}, + {201,-0.0931,7.5107,0.12184}, + {202,-0.094,7.5219,0.12184}, + {203,-0.095,7.533,0.12183}, + {204,-0.0959,7.544,0.12182}, + {205,-0.0968,7.5551,0.12182}, + {206,-0.0977,7.566,0.12181}, + {207,-0.0986,7.5769,0.12181}, + {208,-0.0995,7.5878,0.1218}, + {209,-0.1003,7.5986,0.1218}, + {210,-0.1012,7.6094,0.12179}, + {211,-0.1021,7.6202,0.12179}, + {212,-0.103,7.6309,0.12179}, + {213,-0.1039,7.6416,0.12178}, + {214,-0.1047,7.6522,0.12178}, + {215,-0.1056,7.6628,0.12178}, + {216,-0.1065,7.6733,0.12177}, + {217,-0.1073,7.6838,0.12177}, + {218,-0.1082,7.6943,0.12177}, + {219,-0.109,7.7047,0.12177}, + {220,-0.1099,7.7151,0.12177}, + {221,-0.1107,7.7254,0.12177}, + {222,-0.1116,7.7357,0.12177}, + {223,-0.1124,7.746,0.12176}, + {224,-0.1132,7.7562,0.12176}, + {225,-0.1141,7.7664,0.12176}, + {226,-0.1149,7.7766,0.12176}, + {227,-0.1157,7.7867,0.12177}, + {228,-0.1165,7.7968,0.12177}, + {229,-0.1173,7.8068,0.12177}, + {230,-0.1181,7.8169,0.12177}, + {231,-0.119,7.8268,0.12177}, + {232,-0.1198,7.8368,0.12177}, + {233,-0.1206,7.8467,0.12177}, + {234,-0.1214,7.8566,0.12178}, + {235,-0.1222,7.8664,0.12178}, + {236,-0.1229,7.8762,0.12178}, + {237,-0.1237,7.886,0.12178}, + {238,-0.1245,7.8957,0.12179}, + {239,-0.1253,7.9054,0.12179}, + {240,-0.1261,7.9151,0.12179}, + {241,-0.1269,7.9247,0.1218}, + {242,-0.1276,7.9343,0.1218}, + {243,-0.1284,7.9439,0.1218}, + {244,-0.1292,7.9534,0.12181}, + {245,-0.1299,7.9629,0.12181}, + {246,-0.1307,7.9724,0.12182}, + {247,-0.1314,7.9819,0.12182}, + {248,-0.1322,7.9913,0.12182}, + {249,-0.1329,8.0007,0.12183}, + {250,-0.1337,8.01,0.12183}, + {251,-0.1344,8.0193,0.12184}, + {252,-0.1352,8.0286,0.12185}, + {253,-0.1359,8.0379,0.12185}, + {254,-0.1367,8.0471,0.12186}, + {255,-0.1374,8.0563,0.12186}, + {256,-0.1381,8.0655,0.12187}, + {257,-0.1388,8.0746,0.12187}, + {258,-0.1396,8.0837,0.12188}, + {259,-0.1403,8.0928,0.12189}, + {260,-0.141,8.1019,0.12189}, + {261,-0.1417,8.1109,0.1219}, + {262,-0.1424,8.1199,0.1219}, + {263,-0.1431,8.1289,0.12191}, + {264,-0.1438,8.1378,0.12192}, + {265,-0.1445,8.1468,0.12192}, + {266,-0.1452,8.1557,0.12193}, + {267,-0.1459,8.1645,0.12194}, + {268,-0.1466,8.1734,0.12194}, + {269,-0.1473,8.1822,0.12195}, + {270,-0.148,8.191,0.12196}, + {271,-0.1487,8.1998,0.12197}, + {272,-0.1494,8.2085,0.12197}, + {273,-0.1501,8.2172,0.12198}, + {274,-0.1507,8.2259,0.12199}, + {275,-0.1514,8.2346,0.12199}, + {276,-0.1521,8.2432,0.122}, + {277,-0.1528,8.2519,0.12201}, + {278,-0.1534,8.2605,0.12202}, + {279,-0.1541,8.269,0.12202}, + {280,-0.1547,8.2776,0.12203}, + {281,-0.1554,8.2861,0.12204}, + {282,-0.1561,8.2946,0.12205}, + {283,-0.1567,8.3031,0.12206}, + {284,-0.1574,8.3116,0.12206}, + {285,-0.158,8.3201,0.12207}, + {286,-0.1587,8.3285,0.12208}, + {287,-0.1593,8.3369,0.12209}, + {288,-0.1599,8.3453,0.12209}, + {289,-0.1606,8.3536,0.1221}, + {290,-0.1612,8.362,0.12211}, + {291,-0.1618,8.3703,0.12212}, + {292,-0.1625,8.3786,0.12213}, + {293,-0.1631,8.3869,0.12213}, + {294,-0.1637,8.3952,0.12214}, + {295,-0.1643,8.4035,0.12215}, + {296,-0.165,8.4117,0.12216}, + {297,-0.1656,8.4199,0.12217}, + {298,-0.1662,8.4281,0.12218}, + {299,-0.1668,8.4363,0.12218}, + {300,-0.1674,8.4445,0.12219}, + {301,-0.168,8.4526,0.1222}, + {302,-0.1686,8.4607,0.12221}, + {303,-0.1692,8.4688,0.12222}, + {304,-0.1698,8.4769,0.12222}, + {305,-0.1704,8.485,0.12223}, + {306,-0.171,8.4931,0.12224}, + {307,-0.1716,8.5011,0.12225}, + {308,-0.1722,8.5092,0.12226}, + {309,-0.1728,8.5172,0.12227}, + {310,-0.1734,8.5252,0.12227}, + {311,-0.174,8.5332,0.12228}, + {312,-0.1745,8.5411,0.12229}, + {313,-0.1751,8.5491,0.1223}, + {314,-0.1757,8.557,0.12231}, + {315,-0.1763,8.565,0.12231}, + {316,-0.1768,8.5729,0.12232}, + {317,-0.1774,8.5808,0.12233}, + {318,-0.178,8.5887,0.12234}, + {319,-0.1785,8.5965,0.12235}, + {320,-0.1791,8.6044,0.12235}, + {321,-0.1797,8.6122,0.12236}, + {322,-0.1802,8.6201,0.12237}, + {323,-0.1808,8.6279,0.12238}, + {324,-0.1813,8.6357,0.12239}, + {325,-0.1819,8.6435,0.12239}, + {326,-0.1824,8.6512,0.1224}, + {327,-0.183,8.659,0.12241}, + {328,-0.1835,8.6667,0.12242}, + {329,-0.1841,8.6745,0.12243}, + {330,-0.1846,8.6822,0.12243}, + {331,-0.1851,8.6899,0.12244}, + {332,-0.1857,8.6976,0.12245}, + {333,-0.1862,8.7053,0.12246}, + {334,-0.1867,8.713,0.12246}, + {335,-0.1873,8.7207,0.12247}, + {336,-0.1878,8.7283,0.12248}, + {337,-0.1883,8.736,0.12249}, + {338,-0.1889,8.7436,0.12249}, + {339,-0.1894,8.7512,0.1225}, + {340,-0.1899,8.7588,0.12251}, + {341,-0.1904,8.7664,0.12252}, + {342,-0.1909,8.774,0.12252}, + {343,-0.1914,8.7816,0.12253}, + {344,-0.192,8.7892,0.12254}, + {345,-0.1925,8.7968,0.12254}, + {346,-0.193,8.8043,0.12255}, + {347,-0.1935,8.8119,0.12256}, + {348,-0.194,8.8194,0.12256}, + {349,-0.1945,8.8269,0.12257}, + {350,-0.195,8.8344,0.12258}, + {351,-0.1955,8.842,0.12259}, + {352,-0.196,8.8495,0.12259}, + {353,-0.1965,8.8569,0.1226}, + {354,-0.197,8.8644,0.12261}, + {355,-0.1974,8.8719,0.12261}, + {356,-0.1979,8.8794,0.12262}, + {357,-0.1984,8.8868,0.12262}, + {358,-0.1989,8.8943,0.12263}, + {359,-0.1994,8.9017,0.12264}, + {360,-0.1999,8.9092,0.12264}, + {361,-0.2003,8.9166,0.12265}, + {362,-0.2008,8.924,0.12266}, + {363,-0.2013,8.9314,0.12266}, + {364,-0.2018,8.9388,0.12267}, + {365,-0.2022,8.9462,0.12267}, + {366,-0.2027,8.9536,0.12268}, + {367,-0.2032,8.961,0.12269}, + {368,-0.2036,8.9684,0.12269}, + {369,-0.2041,8.9757,0.1227}, + {370,-0.2046,8.9831,0.1227}, + {371,-0.205,8.9904,0.12271}, + {372,-0.2055,8.9978,0.12272}, + {373,-0.2059,9.0051,0.12272}, + {374,-0.2064,9.0125,0.12273}, + {375,-0.2068,9.0198,0.12273}, + {376,-0.2073,9.0271,0.12274}, + {377,-0.2077,9.0344,0.12274}, + {378,-0.2082,9.0417,0.12275}, + {379,-0.2086,9.049,0.12275}, + {380,-0.2091,9.0563,0.12276}, + {381,-0.2095,9.0636,0.12276}, + {382,-0.21,9.0709,0.12277}, + {383,-0.2104,9.0782,0.12277}, + {384,-0.2108,9.0854,0.12278}, + {385,-0.2113,9.0927,0.12278}, + {386,-0.2117,9.0999,0.12279}, + {387,-0.2121,9.1072,0.12279}, + {388,-0.2126,9.1144,0.1228}, + {389,-0.213,9.1217,0.1228}, + {390,-0.2134,9.1289,0.12281}, + {391,-0.2139,9.1361,0.12281}, + {392,-0.2143,9.1434,0.12282}, + {393,-0.2147,9.1506,0.12282}, + {394,-0.2151,9.1578,0.12282}, + {395,-0.2155,9.165,0.12283}, + {396,-0.216,9.1722,0.12283}, + {397,-0.2164,9.1794,0.12284}, + {398,-0.2168,9.1866,0.12284}, + {399,-0.2172,9.1938,0.12285}, + {400,-0.2176,9.2009,0.12285}, + {401,-0.218,9.2081,0.12285}, + {402,-0.2184,9.2153,0.12286}, + {403,-0.2188,9.2225,0.12286}, + {404,-0.2192,9.2296,0.12287}, + {405,-0.2196,9.2368,0.12287}, + {406,-0.22,9.2439,0.12287}, + {407,-0.2204,9.2511,0.12288}, + {408,-0.2208,9.2582,0.12288}, + {409,-0.2212,9.2654,0.12288}, + {410,-0.2216,9.2725,0.12289}, + {411,-0.222,9.2796,0.12289}, + {412,-0.2224,9.2867,0.12289}, + {413,-0.2228,9.2939,0.1229}, + {414,-0.2232,9.301,0.1229}, + {415,-0.2236,9.3081,0.1229}, + {416,-0.224,9.3152,0.12291}, + {417,-0.2243,9.3223,0.12291}, + {418,-0.2247,9.3294,0.12291}, + {419,-0.2251,9.3365,0.12292}, + {420,-0.2255,9.3436,0.12292}, + {421,-0.2259,9.3507,0.12292}, + {422,-0.2262,9.3578,0.12292}, + {423,-0.2266,9.3649,0.12293}, + {424,-0.227,9.372,0.12293}, + {425,-0.2274,9.379,0.12293}, + {426,-0.2277,9.3861,0.12294}, + {427,-0.2281,9.3932,0.12294}, + {428,-0.2285,9.4002,0.12294}, + {429,-0.2288,9.4073,0.12294}, + {430,-0.2292,9.4144,0.12295}, + {431,-0.2296,9.4214,0.12295}, + {432,-0.2299,9.4285,0.12295}, + {433,-0.2303,9.4355,0.12295}, + {434,-0.2307,9.4426,0.12295}, + {435,-0.231,9.4496,0.12296}, + {436,-0.2314,9.4567,0.12296}, + {437,-0.2317,9.4637,0.12296}, + {438,-0.2321,9.4707,0.12296}, + {439,-0.2324,9.4778,0.12296}, + {440,-0.2328,9.4848,0.12297}, + {441,-0.2331,9.4918,0.12297}, + {442,-0.2335,9.4988,0.12297}, + {443,-0.2338,9.5058,0.12297}, + {444,-0.2342,9.5129,0.12297}, + {445,-0.2345,9.5199,0.12298}, + {446,-0.2349,9.5269,0.12298}, + {447,-0.2352,9.5339,0.12298}, + {448,-0.2355,9.5409,0.12298}, + {449,-0.2359,9.5479,0.12298}, + {450,-0.2362,9.5549,0.12298}, + {451,-0.2366,9.5619,0.12299}, + {452,-0.2369,9.5689,0.12299}, + {453,-0.2372,9.5759,0.12299}, + {454,-0.2376,9.5829,0.12299}, + {455,-0.2379,9.5898,0.12299}, + {456,-0.2382,9.5968,0.12299}, + {457,-0.2385,9.6038,0.12299}, + {458,-0.2389,9.6108,0.123}, + {459,-0.2392,9.6178,0.123}, + {460,-0.2395,9.6247,0.123}, + {461,-0.2398,9.6317,0.123}, + {462,-0.2402,9.6387,0.123}, + {463,-0.2405,9.6457,0.123}, + {464,-0.2408,9.6526,0.123}, + {465,-0.2411,9.6596,0.123}, + {466,-0.2414,9.6665,0.12301}, + {467,-0.2418,9.6735,0.12301}, + {468,-0.2421,9.6805,0.12301}, + {469,-0.2424,9.6874,0.12301}, + {470,-0.2427,9.6944,0.12301}, + {471,-0.243,9.7013,0.12301}, + {472,-0.2433,9.7083,0.12301}, + {473,-0.2436,9.7152,0.12301}, + {474,-0.2439,9.7222,0.12301}, + {475,-0.2442,9.7291,0.12302}, + {476,-0.2446,9.7361,0.12302}, + {477,-0.2449,9.743,0.12302}, + {478,-0.2452,9.75,0.12302}, + {479,-0.2455,9.7569,0.12302}, + {480,-0.2458,9.7638,0.12302}, + {481,-0.2461,9.7708,0.12302}, + {482,-0.2464,9.7777,0.12302}, + {483,-0.2467,9.7846,0.12302}, + {484,-0.247,9.7916,0.12302}, + {485,-0.2472,9.7985,0.12303}, + {486,-0.2475,9.8054,0.12303}, + {487,-0.2478,9.8124,0.12303}, + {488,-0.2481,9.8193,0.12303}, + {489,-0.2484,9.8262,0.12303}, + {490,-0.2487,9.8331,0.12303}, + {491,-0.249,9.8401,0.12303}, + {492,-0.2493,9.847,0.12303}, + {493,-0.2496,9.8539,0.12303}, + {494,-0.2499,9.8608,0.12303}, + {495,-0.2501,9.8677,0.12303}, + {496,-0.2504,9.8746,0.12304}, + {497,-0.2507,9.8816,0.12304}, + {498,-0.251,9.8885,0.12304}, + {499,-0.2513,9.8954,0.12304}, + {500,-0.2515,9.9023,0.12304}, + {501,-0.2518,9.9092,0.12304}, + {502,-0.2521,9.9161,0.12304}, + {503,-0.2524,9.923,0.12304}, + {504,-0.2526,9.9299,0.12304}, + {505,-0.2529,9.9368,0.12304}, + {506,-0.2532,9.9437,0.12304}, + {507,-0.2535,9.9506,0.12305}, + {508,-0.2537,9.9575,0.12305}, + {509,-0.254,9.9644,0.12305}, + {510,-0.2543,9.9713,0.12305}, + {511,-0.2545,9.9782,0.12305}, + {512,-0.2548,9.9851,0.12305}, + {513,-0.2551,9.992,0.12305}, + {514,-0.2553,9.9989,0.12305}, + {515,-0.2556,10.0058,0.12305}, + {516,-0.2558,10.0127,0.12305}, + {517,-0.2561,10.0196,0.12305}, + {518,-0.2564,10.0265,0.12306}, + {519,-0.2566,10.0334,0.12306}, + {520,-0.2569,10.0402,0.12306}, + {521,-0.2571,10.0471,0.12306}, + {522,-0.2574,10.054,0.12306}, + {523,-0.2577,10.0609,0.12306}, + {524,-0.2579,10.0678,0.12306}, + {525,-0.2582,10.0746,0.12306}, + {526,-0.2584,10.0815,0.12306}, + {527,-0.2587,10.0884,0.12307}, + {528,-0.2589,10.0953,0.12307}, + {529,-0.2592,10.1021,0.12307}, + {530,-0.2594,10.109,0.12307}, + {531,-0.2597,10.1159,0.12307}, + {532,-0.2599,10.1227,0.12307}, + {533,-0.2601,10.1296,0.12307}, + {534,-0.2604,10.1365,0.12307}, + {535,-0.2606,10.1433,0.12308}, + {536,-0.2609,10.1502,0.12308}, + {537,-0.2611,10.157,0.12308}, + {538,-0.2614,10.1639,0.12308}, + {539,-0.2616,10.1707,0.12308}, + {540,-0.2618,10.1776,0.12308}, + {541,-0.2621,10.1845,0.12308}, + {542,-0.2623,10.1913,0.12309}, + {543,-0.2625,10.1982,0.12309}, + {544,-0.2628,10.205,0.12309}, + {545,-0.263,10.2119,0.12309}, + {546,-0.2632,10.2187,0.12309}, + {547,-0.2635,10.2255,0.12309}, + {548,-0.2637,10.2324,0.12309}, + {549,-0.2639,10.2392,0.1231}, + {550,-0.2642,10.2461,0.1231}, + {551,-0.2644,10.2529,0.1231}, + {552,-0.2646,10.2597,0.1231}, + {553,-0.2649,10.2666,0.1231}, + {554,-0.2651,10.2734,0.1231}, + {555,-0.2653,10.2803,0.12311}, + {556,-0.2655,10.2871,0.12311}, + {557,-0.2658,10.2939,0.12311}, + {558,-0.266,10.3008,0.12311}, + {559,-0.2662,10.3076,0.12311}, + {560,-0.2664,10.3144,0.12311}, + {561,-0.2666,10.3213,0.12312}, + {562,-0.2669,10.3281,0.12312}, + {563,-0.2671,10.3349,0.12312}, + {564,-0.2673,10.3417,0.12312}, + {565,-0.2675,10.3486,0.12312}, + {566,-0.2677,10.3554,0.12313}, + {567,-0.2679,10.3622,0.12313}, + {568,-0.2682,10.369,0.12313}, + {569,-0.2684,10.3759,0.12313}, + {570,-0.2686,10.3827,0.12313}, + {571,-0.2688,10.3895,0.12314}, + {572,-0.269,10.3963,0.12314}, + {573,-0.2692,10.4031,0.12314}, + {574,-0.2694,10.41,0.12314}, + {575,-0.2696,10.4168,0.12314}, + {576,-0.2698,10.4236,0.12315}, + {577,-0.27,10.4304,0.12315}, + {578,-0.2702,10.4372,0.12315}, + {579,-0.2705,10.444,0.12315}, + {580,-0.2707,10.4508,0.12316}, + {581,-0.2709,10.4577,0.12316}, + {582,-0.2711,10.4645,0.12316}, + {583,-0.2713,10.4713,0.12316}, + {584,-0.2715,10.4781,0.12316}, + {585,-0.2717,10.4849,0.12317}, + {586,-0.2719,10.4917,0.12317}, + {587,-0.2721,10.4985,0.12317}, + {588,-0.2723,10.5053,0.12317}, + {589,-0.2725,10.5121,0.12318}, + {590,-0.2727,10.5189,0.12318}, + {591,-0.2729,10.5257,0.12318}, + {592,-0.273,10.5325,0.12319}, + {593,-0.2732,10.5393,0.12319}, + {594,-0.2734,10.5461,0.12319}, + {595,-0.2736,10.5529,0.12319}, + {596,-0.2738,10.5597,0.1232}, + {597,-0.274,10.5665,0.1232}, + {598,-0.2742,10.5733,0.1232}, + {599,-0.2744,10.5801,0.1232}, + {600,-0.2746,10.5869,0.12321}, + {601,-0.2748,10.5937,0.12321}, + {602,-0.275,10.6005,0.12321}, + {603,-0.2751,10.6073,0.12322}, + {604,-0.2753,10.6141,0.12322}, + {605,-0.2755,10.6209,0.12322}, + {606,-0.2757,10.6277,0.12323}, + {607,-0.2759,10.6345,0.12323}, + {608,-0.2761,10.6413,0.12323}, + {609,-0.2763,10.6481,0.12324}, + {610,-0.2764,10.6549,0.12324}, + {611,-0.2766,10.6617,0.12324}, + {612,-0.2768,10.6685,0.12325}, + {613,-0.277,10.6753,0.12325}, + {614,-0.2772,10.6821,0.12325}, + {615,-0.2773,10.6889,0.12326}, + {616,-0.2775,10.6957,0.12326}, + {617,-0.2777,10.7025,0.12326}, + {618,-0.2779,10.7093,0.12327}, + {619,-0.278,10.7161,0.12327}, + {620,-0.2782,10.7229,0.12327}, + {621,-0.2784,10.7297,0.12328}, + {622,-0.2786,10.7365,0.12328}, + {623,-0.2787,10.7433,0.12328}, + {624,-0.2789,10.7501,0.12329}, + {625,-0.2791,10.7569,0.12329}, + {626,-0.2793,10.7637,0.1233}, + {627,-0.2794,10.7705,0.1233}, + {628,-0.2796,10.7773,0.1233}, + {629,-0.2798,10.7841,0.12331}, + {630,-0.2799,10.7909,0.12331}, + {631,-0.2801,10.7977,0.12332}, + {632,-0.2803,10.8045,0.12332}, + {633,-0.2804,10.8113,0.12332}, + {634,-0.2806,10.8181,0.12333}, + {635,-0.2808,10.8249,0.12333}, + {636,-0.2809,10.8317,0.12334}, + {637,-0.2811,10.8385,0.12334}, + {638,-0.2813,10.8453,0.12335}, + {639,-0.2814,10.8521,0.12335}, + {640,-0.2816,10.8589,0.12336}, + {641,-0.2818,10.8657,0.12336}, + {642,-0.2819,10.8725,0.12336}, + {643,-0.2821,10.8793,0.12337}, + {644,-0.2822,10.8861,0.12337}, + {645,-0.2824,10.8929,0.12338}, + {646,-0.2826,10.8997,0.12338}, + {647,-0.2827,10.9065,0.12339}, + {648,-0.2829,10.9133,0.12339}, + {649,-0.283,10.9202,0.1234}, + {650,-0.2832,10.927,0.1234}, + {651,-0.2834,10.9338,0.12341}, + {652,-0.2835,10.9406,0.12341}, + {653,-0.2837,10.9474,0.12342}, + {654,-0.2838,10.9542,0.12342}, + {655,-0.284,10.961,0.12343}, + {656,-0.2841,10.9679,0.12343}, + {657,-0.2843,10.9747,0.12344}, + {658,-0.2844,10.9815,0.12344}, + {659,-0.2846,10.9883,0.12345}, + {660,-0.2847,10.9951,0.12345}, + {661,-0.2849,11.0019,0.12346}, + {662,-0.285,11.0088,0.12346}, + {663,-0.2852,11.0156,0.12347}, + {664,-0.2853,11.0224,0.12347}, + {665,-0.2855,11.0292,0.12348}, + {666,-0.2856,11.036,0.12348}, + {667,-0.2858,11.0429,0.12349}, + {668,-0.2859,11.0497,0.1235}, + {669,-0.2861,11.0565,0.1235}, + {670,-0.2862,11.0633,0.12351}, + {671,-0.2864,11.0702,0.12351}, + {672,-0.2865,11.077,0.12352}, + {673,-0.2866,11.0838,0.12352}, + {674,-0.2868,11.0906,0.12353}, + {675,-0.2869,11.0975,0.12353}, + {676,-0.2871,11.1043,0.12354}, + {677,-0.2872,11.1111,0.12355}, + {678,-0.2874,11.118,0.12355}, + {679,-0.2875,11.1248,0.12356}, + {680,-0.2876,11.1316,0.12356}, + {681,-0.2878,11.1384,0.12357}, + {682,-0.2879,11.1453,0.12358}, + {683,-0.2881,11.1521,0.12358}, + {684,-0.2882,11.1589,0.12359}, + {685,-0.2883,11.1658,0.12359}, + {686,-0.2885,11.1726,0.1236}, + {687,-0.2886,11.1795,0.12361}, + {688,-0.2887,11.1863,0.12361}, + {689,-0.2889,11.1931,0.12362}, + {690,-0.289,11.2,0.12362}, + {691,-0.2891,11.2068,0.12363}, + {692,-0.2893,11.2137,0.12364}, + {693,-0.2894,11.2205,0.12364}, + {694,-0.2895,11.2273,0.12365}, + {695,-0.2897,11.2342,0.12366}, + {696,-0.2898,11.241,0.12366}, + {697,-0.2899,11.2479,0.12367}, + {698,-0.2901,11.2547,0.12367}, + {699,-0.2902,11.2616,0.12368}, + {700,-0.2903,11.2684,0.12369}, + {701,-0.2905,11.2753,0.12369}, + {702,-0.2906,11.2821,0.1237}, + {703,-0.2907,11.2889,0.12371}, + {704,-0.2909,11.2958,0.12371}, + {705,-0.291,11.3026,0.12372}, + {706,-0.2911,11.3095,0.12373}, + {707,-0.2912,11.3163,0.12373}, + {708,-0.2914,11.3232,0.12374}, + {709,-0.2915,11.33,0.12375}, + {710,-0.2916,11.3369,0.12375}, + {711,-0.2917,11.3438,0.12376}, + {712,-0.2919,11.3506,0.12377}, + {713,-0.292,11.3575,0.12377}, + {714,-0.2921,11.3643,0.12378}, + {715,-0.2922,11.3712,0.12379}, + {716,-0.2924,11.378,0.12379}, + {717,-0.2925,11.3849,0.1238}, + {718,-0.2926,11.3917,0.12381}, + {719,-0.2927,11.3986,0.12382}, + {720,-0.2928,11.4055,0.12382}, + {721,-0.293,11.4123,0.12383}, + {722,-0.2931,11.4192,0.12384}, + {723,-0.2932,11.426,0.12384}, + {724,-0.2933,11.4329,0.12385}, + {725,-0.2934,11.4397,0.12386}, + {726,-0.2936,11.4466,0.12387}, + {727,-0.2937,11.4535,0.12387}, + {728,-0.2938,11.4603,0.12388}, + {729,-0.2939,11.4672,0.12389}, + {730,-0.294,11.4741,0.12389}, + {731,-0.2942,11.4809,0.1239}, + {732,-0.2943,11.4878,0.12391}, + {733,-0.2944,11.4946,0.12392}, + {734,-0.2945,11.5015,0.12392}, + {735,-0.2946,11.5084,0.12393}, + {736,-0.2947,11.5152,0.12394}, + {737,-0.2948,11.5221,0.12395}, + {738,-0.295,11.529,0.12395}, + {739,-0.2951,11.5358,0.12396}, + {740,-0.2952,11.5427,0.12397}, + {741,-0.2953,11.5496,0.12398}, + {742,-0.2954,11.5564,0.12399}, + {743,-0.2955,11.5633,0.12399}, + {744,-0.2956,11.5702,0.124}, + {745,-0.2957,11.577,0.12401}, + {746,-0.2959,11.5839,0.12402}, + {747,-0.296,11.5907,0.12402}, + {748,-0.2961,11.5976,0.12403}, + {749,-0.2962,11.6045,0.12404}, + {750,-0.2963,11.6113,0.12405}, + {751,-0.2964,11.6182,0.12406}, + {752,-0.2965,11.6251,0.12406}, + {753,-0.2966,11.6319,0.12407}, + {754,-0.2967,11.6388,0.12408}, + {755,-0.2968,11.6456,0.12409}, + {756,-0.2969,11.6525,0.1241}, + {757,-0.297,11.6594,0.1241}, + {758,-0.2972,11.6662,0.12411}, + {759,-0.2973,11.6731,0.12412}, + {760,-0.2974,11.6799,0.12413}, + {761,-0.2975,11.6868,0.12414}, + {762,-0.2976,11.6937,0.12415}, + {763,-0.2977,11.7005,0.12415}, + {764,-0.2978,11.7074,0.12416}, + {765,-0.2979,11.7142,0.12417}, + {766,-0.298,11.7211,0.12418}, + {767,-0.2981,11.7279,0.12419}, + {768,-0.2982,11.7348,0.1242}, + {769,-0.2983,11.7416,0.12421}, + {770,-0.2984,11.7485,0.12421}, + {771,-0.2985,11.7553,0.12422}, + {772,-0.2986,11.7622,0.12423}, + {773,-0.2987,11.769,0.12424}, + {774,-0.2988,11.7759,0.12425}, + {775,-0.2989,11.7827,0.12426}, + {776,-0.299,11.7896,0.12427}, + {777,-0.2991,11.7964,0.12428}, + {778,-0.2992,11.8033,0.12429}, + {779,-0.2993,11.8101,0.12429}, + {780,-0.2994,11.817,0.1243}, + {781,-0.2995,11.8238,0.12431}, + {782,-0.2996,11.8307,0.12432}, + {783,-0.2997,11.8375,0.12433}, + {784,-0.2998,11.8443,0.12434}, + {785,-0.2999,11.8512,0.12435}, + {786,-0.3,11.858,0.12436}, + {787,-0.3001,11.8648,0.12437}, + {788,-0.3002,11.8717,0.12438}, + {789,-0.3003,11.8785,0.12439}, + {790,-0.3004,11.8853,0.1244}, + {791,-0.3005,11.8922,0.12441}, + {792,-0.3006,11.899,0.12441}, + {793,-0.3007,11.9058,0.12442}, + {794,-0.3007,11.9126,0.12443}, + {795,-0.3008,11.9194,0.12444}, + {796,-0.3009,11.9263,0.12445}, + {797,-0.301,11.9331,0.12446}, + {798,-0.3011,11.9399,0.12447}, + {799,-0.3012,11.9467,0.12448}, + {800,-0.3013,11.9535,0.12449}, + {801,-0.3014,11.9603,0.1245}, + {802,-0.3015,11.9671,0.12451}, + {803,-0.3016,11.9739,0.12452}, + {804,-0.3017,11.9808,0.12453}, + {805,-0.3018,11.9876,0.12454}, + {806,-0.3019,11.9944,0.12455}, + {807,-0.3019,12.0011,0.12456}, + {808,-0.302,12.0079,0.12457}, + {809,-0.3021,12.0147,0.12458}, + {810,-0.3022,12.0215,0.12459}, + {811,-0.3023,12.0283,0.1246}, + {812,-0.3024,12.0351,0.12461}, + {813,-0.3025,12.0419,0.12462}, + {814,-0.3026,12.0487,0.12463}, + {815,-0.3027,12.0554,0.12465}, + {816,-0.3027,12.0622,0.12466}, + {817,-0.3028,12.069,0.12467}, + {818,-0.3029,12.0758,0.12468}, + {819,-0.303,12.0825,0.12469}, + {820,-0.3031,12.0893,0.1247}, + {821,-0.3032,12.0961,0.12471}, + {822,-0.3033,12.1028,0.12472}, + {823,-0.3033,12.1096,0.12473}, + {824,-0.3034,12.1163,0.12474}, + {825,-0.3035,12.1231,0.12475}, + {826,-0.3036,12.1298,0.12476}, + {827,-0.3037,12.1366,0.12477}, + {828,-0.3038,12.1433,0.12479}, + {829,-0.3039,12.15,0.1248}, + {830,-0.3039,12.1568,0.12481}, + {831,-0.304,12.1635,0.12482}, + {832,-0.3041,12.1702,0.12483}, + {833,-0.3042,12.177,0.12484}, + {834,-0.3043,12.1837,0.12485}, + {835,-0.3044,12.1904,0.12486}, + {836,-0.3044,12.1971,0.12487}, + {837,-0.3045,12.2039,0.12489}, + {838,-0.3046,12.2106,0.1249}, + {839,-0.3047,12.2173,0.12491}, + {840,-0.3048,12.224,0.12492}, + {841,-0.3048,12.2307,0.12493}, + {842,-0.3049,12.2374,0.12494}, + {843,-0.305,12.2441,0.12495}, + {844,-0.3051,12.2508,0.12497}, + {845,-0.3052,12.2575,0.12498}, + {846,-0.3052,12.2642,0.12499}, + {847,-0.3053,12.2709,0.125}, + {848,-0.3054,12.2775,0.12501}, + {849,-0.3055,12.2842,0.12503}, + {850,-0.3056,12.2909,0.12504}, + {851,-0.3056,12.2976,0.12505}, + {852,-0.3057,12.3042,0.12506}, + {853,-0.3058,12.3109,0.12507}, + {854,-0.3059,12.3176,0.12509}, + {855,-0.3059,12.3242,0.1251}, + {856,-0.306,12.3309,0.12511}, + {857,-0.3061,12.3375,0.12512}, + {858,-0.3062,12.3442,0.12513}, + {859,-0.3063,12.3508,0.12515}, + {860,-0.3063,12.3575,0.12516}, + {861,-0.3064,12.3641,0.12517}, + {862,-0.3065,12.3707,0.12518}, + {863,-0.3066,12.3774,0.1252}, + {864,-0.3066,12.384,0.12521}, + {865,-0.3067,12.3906,0.12522}, + {866,-0.3068,12.3973,0.12523}, + {867,-0.3069,12.4039,0.12525}, + {868,-0.3069,12.4105,0.12526}, + {869,-0.307,12.4171,0.12527}, + {870,-0.3071,12.4237,0.12528}, + {871,-0.3072,12.4303,0.1253}, + {872,-0.3072,12.4369,0.12531}, + {873,-0.3073,12.4435,0.12532}, + {874,-0.3074,12.4501,0.12533}, + {875,-0.3074,12.4567,0.12535}, + {876,-0.3075,12.4633,0.12536}, + {877,-0.3076,12.4699,0.12537}, + {878,-0.3077,12.4765,0.12539}, + {879,-0.3077,12.4831,0.1254}, + {880,-0.3078,12.4896,0.12541}, + {881,-0.3079,12.4962,0.12543}, + {882,-0.308,12.5028,0.12544}, + {883,-0.308,12.5093,0.12545}, + {884,-0.3081,12.5159,0.12547}, + {885,-0.3082,12.5225,0.12548}, + {886,-0.3082,12.529,0.12549}, + {887,-0.3083,12.5356,0.12551}, + {888,-0.3084,12.5421,0.12552}, + {889,-0.3085,12.5487,0.12553}, + {890,-0.3085,12.5552,0.12555}, + {891,-0.3086,12.5617,0.12556}, + {892,-0.3087,12.5683,0.12557}, + {893,-0.3087,12.5748,0.12559}, + {894,-0.3088,12.5813,0.1256}, + {895,-0.3089,12.5879,0.12561}, + {896,-0.3089,12.5944,0.12563}, + {897,-0.309,12.6009,0.12564}, + {898,-0.3091,12.6074,0.12566}, + {899,-0.3091,12.6139,0.12567}, + {900,-0.3092,12.6204,0.12568}, + {901,-0.3093,12.6269,0.1257}, + {902,-0.3093,12.6334,0.12571}, + {903,-0.3094,12.6399,0.12573}, + {904,-0.3095,12.6464,0.12574}, + {905,-0.3095,12.6529,0.12575}, + {906,-0.3096,12.6594,0.12577}, + {907,-0.3097,12.6659,0.12578}, + {908,-0.3097,12.6723,0.1258}, + {909,-0.3098,12.6788,0.12581}, + {910,-0.3099,12.6853,0.12583}, + {911,-0.3099,12.6918,0.12584}, + {912,-0.31,12.6982,0.12585}, + {913,-0.3101,12.7047,0.12587}, + {914,-0.3101,12.7111,0.12588}, + {915,-0.3102,12.7176,0.1259}, + {916,-0.3103,12.724,0.12591}, + {917,-0.3103,12.7305,0.12593}, + {918,-0.3104,12.7369,0.12594}, + {919,-0.3105,12.7434,0.12596}, + {920,-0.3105,12.7498,0.12597}, + {921,-0.3106,12.7563,0.12599}, + {922,-0.3107,12.7627,0.126}, + {923,-0.3107,12.7691,0.12602}, + {924,-0.3108,12.7755,0.12603}, + {925,-0.3109,12.782,0.12605}, + {926,-0.3109,12.7884,0.12606}, + {927,-0.311,12.7948,0.12608}, + {928,-0.311,12.8012,0.12609}, + {929,-0.3111,12.8076,0.12611}, + {930,-0.3112,12.814,0.12612}, + {931,-0.3112,12.8204,0.12614}, + {932,-0.3113,12.8268,0.12615}, + {933,-0.3114,12.8332,0.12617}, + {934,-0.3114,12.8396,0.12618}, + {935,-0.3115,12.846,0.1262}, + {936,-0.3116,12.8524,0.12621}, + {937,-0.3116,12.8588,0.12623}, + {938,-0.3117,12.8651,0.12625}, + {939,-0.3117,12.8715,0.12626}, + {940,-0.3118,12.8779,0.12628}, + {941,-0.3119,12.8843,0.12629}, + {942,-0.3119,12.8906,0.12631}, + {943,-0.312,12.897,0.12632}, + {944,-0.312,12.9033,0.12634}, + {945,-0.3121,12.9097,0.12636}, + {946,-0.3122,12.9161,0.12637}, + {947,-0.3122,12.9224,0.12639}, + {948,-0.3123,12.9288,0.1264}, + {949,-0.3123,12.9351,0.12642}, + {950,-0.3124,12.9415,0.12644}, + {951,-0.3125,12.9478,0.12645}, + {952,-0.3125,12.9541,0.12647}, + {953,-0.3126,12.9605,0.12648}, + {954,-0.3126,12.9668,0.1265}, + {955,-0.3127,12.9732,0.12652}, + {956,-0.3128,12.9795,0.12653}, + {957,-0.3128,12.9858,0.12655}, + {958,-0.3129,12.9921,0.12656}, + {959,-0.3129,12.9985,0.12658}, + {960,-0.313,13.0048,0.1266}, + {961,-0.3131,13.0111,0.12661}, + {962,-0.3131,13.0174,0.12663}, + {963,-0.3132,13.0237,0.12665}, + {964,-0.3132,13.03,0.12666}, + {965,-0.3133,13.0363,0.12668}, + {966,-0.3134,13.0427,0.1267}, + {967,-0.3134,13.049,0.12671}, + {968,-0.3135,13.0553,0.12673}, + {969,-0.3135,13.0616,0.12675}, + {970,-0.3136,13.0679,0.12676}, + {971,-0.3136,13.0742,0.12678}, + {972,-0.3137,13.0804,0.1268}, + {973,-0.3138,13.0867,0.12681}, + {974,-0.3138,13.093,0.12683}, + {975,-0.3139,13.0993,0.12685}, + {976,-0.3139,13.1056,0.12687}, + {977,-0.314,13.1119,0.12688}, + {978,-0.314,13.1182,0.1269}, + {979,-0.3141,13.1245,0.12692}, + {980,-0.3142,13.1307,0.12693}, + {981,-0.3142,13.137,0.12695}, + {982,-0.3143,13.1433,0.12697}, + {983,-0.3143,13.1496,0.12699}, + {984,-0.3144,13.1558,0.127}, + {985,-0.3144,13.1621,0.12702}, + {986,-0.3145,13.1684,0.12704}, + {987,-0.3145,13.1746,0.12706}, + {988,-0.3146,13.1809,0.12707}, + {989,-0.3147,13.1872,0.12709}, + {990,-0.3147,13.1934,0.12711}, + {991,-0.3148,13.1997,0.12713}, + {992,-0.3148,13.2059,0.12714}, + {993,-0.3149,13.2122,0.12716}, + {994,-0.3149,13.2185,0.12718}, + {995,-0.315,13.2247,0.1272}, + {996,-0.315,13.231,0.12721}, + {997,-0.3151,13.2372,0.12723}, + {998,-0.3152,13.2435,0.12725}, + {999,-0.3152,13.2497,0.12727}, + {1000,-0.3153,13.256,0.12729}, + {1001,-0.3153,13.2622,0.1273}, + {1002,-0.3154,13.2684,0.12732}, + {1003,-0.3154,13.2747,0.12734}, + {1004,-0.3155,13.2809,0.12736}, + {1005,-0.3155,13.2872,0.12738}, + {1006,-0.3156,13.2934,0.12739}, + {1007,-0.3156,13.2996,0.12741}, + {1008,-0.3157,13.3059,0.12743}, + {1009,-0.3158,13.3121,0.12745}, + {1010,-0.3158,13.3183,0.12747}, + {1011,-0.3159,13.3246,0.12749}, + {1012,-0.3159,13.3308,0.1275}, + {1013,-0.316,13.337,0.12752}, + {1014,-0.316,13.3433,0.12754}, + {1015,-0.3161,13.3495,0.12756}, + {1016,-0.3161,13.3557,0.12758}, + {1017,-0.3162,13.3619,0.1276}, + {1018,-0.3162,13.3682,0.12762}, + {1019,-0.3163,13.3744,0.12763}, + {1020,-0.3163,13.3806,0.12765}, + {1021,-0.3164,13.3868,0.12767}, + {1022,-0.3164,13.3931,0.12769}, + {1023,-0.3165,13.3993,0.12771}, + {1024,-0.3165,13.4055,0.12773}, + {1025,-0.3166,13.4117,0.12775}, + {1026,-0.3167,13.4179,0.12777}, + {1027,-0.3167,13.4242,0.12779}, + {1028,-0.3168,13.4304,0.12781}, + {1029,-0.3168,13.4366,0.12782}, + {1030,-0.3169,13.4428,0.12784}, + {1031,-0.3169,13.449,0.12786}, + {1032,-0.317,13.4552,0.12788}, + {1033,-0.317,13.4614,0.1279}, + {1034,-0.3171,13.4677,0.12792}, + {1035,-0.3171,13.4739,0.12794}, + {1036,-0.3172,13.4801,0.12796}, + {1037,-0.3172,13.4863,0.12798}, + {1038,-0.3173,13.4925,0.128}, + {1039,-0.3173,13.4987,0.12802}, + {1040,-0.3174,13.5049,0.12804}, + {1041,-0.3174,13.5111,0.12806}, + {1042,-0.3175,13.5173,0.12808}, + {1043,-0.3175,13.5235,0.1281}, + {1044,-0.3176,13.5297,0.12812}, + {1045,-0.3176,13.5359,0.12814}, + {1046,-0.3177,13.5421,0.12816}, + {1047,-0.3177,13.5483,0.12818}, + {1048,-0.3178,13.5545,0.12819}, + {1049,-0.3178,13.5607,0.12821}, + {1050,-0.3179,13.5669,0.12823}, + {1051,-0.3179,13.5731,0.12825}, + {1052,-0.318,13.5793,0.12827}, + {1053,-0.318,13.5855,0.12829}, + {1054,-0.3181,13.5917,0.12832}, + {1055,-0.3181,13.5979,0.12834}, + {1056,-0.3182,13.6041,0.12836}, + {1057,-0.3182,13.6103,0.12838}, + {1058,-0.3183,13.6165,0.1284}, + {1059,-0.3183,13.6227,0.12842}, + {1060,-0.3184,13.6289,0.12844}, + {1061,-0.3184,13.6351,0.12846}, + {1062,-0.3185,13.6413,0.12848}, + {1063,-0.3185,13.6475,0.1285}, + {1064,-0.3186,13.6537,0.12852}, + {1065,-0.3186,13.6599,0.12854}, + {1066,-0.3187,13.6661,0.12856}, + {1067,-0.3187,13.6723,0.12858}, + {1068,-0.3188,13.6785,0.1286}, + {1069,-0.3188,13.6847,0.12862}, + {1070,-0.3189,13.6909,0.12864}, + {1071,-0.3189,13.6971,0.12866}, + {1072,-0.319,13.7033,0.12868}, + {1073,-0.319,13.7095,0.12871}, + {1074,-0.3191,13.7157,0.12873}, + {1075,-0.3191,13.7218,0.12875}, + {1076,-0.3192,13.728,0.12877}, + {1077,-0.3192,13.7342,0.12879}, + {1078,-0.3193,13.7404,0.12881}, + {1079,-0.3193,13.7466,0.12883}, + {1080,-0.3194,13.7528,0.12885}, + {1081,-0.3194,13.759,0.12887}, + {1082,-0.3195,13.7652,0.1289}, + {1083,-0.3195,13.7714,0.12892}, + {1084,-0.3196,13.7776,0.12894}, + {1085,-0.3196,13.7838,0.12896}, + {1086,-0.3197,13.7899,0.12898}, + {1087,-0.3197,13.7961,0.129}, + {1088,-0.3198,13.8023,0.12902}, + {1089,-0.3198,13.8085,0.12905}, + {1090,-0.3198,13.8147,0.12907}, + {1091,-0.3199,13.8209,0.12909}, + {1092,-0.3199,13.8271,0.12911}, + {1093,-0.32,13.8333,0.12913}, + {1094,-0.32,13.8395,0.12915}, + {1095,-0.3201,13.8456,0.12918}, + {1096,-0.3201,13.8518,0.1292}, + {1097,-0.3202,13.858,0.12922}, + {1098,-0.3202,13.8642,0.12924}, + {1099,-0.3203,13.8704,0.12926}, + {1100,-0.3203,13.8766,0.12929}, + {1101,-0.3204,13.8828,0.12931}, + {1102,-0.3204,13.8889,0.12933}, + {1103,-0.3205,13.8951,0.12935}, + {1104,-0.3205,13.9013,0.12937}, + {1105,-0.3206,13.9075,0.1294}, + {1106,-0.3206,13.9137,0.12942}, + {1107,-0.3207,13.9199,0.12944}, + {1108,-0.3207,13.9261,0.12946}, + {1109,-0.3208,13.9322,0.12948}, + {1110,-0.3208,13.9384,0.12951}, + {1111,-0.3208,13.9446,0.12953}, + {1112,-0.3209,13.9508,0.12955}, + {1113,-0.3209,13.957,0.12957}, + {1114,-0.321,13.9632,0.1296}, + {1115,-0.321,13.9693,0.12962}, + {1116,-0.3211,13.9755,0.12964}, + {1117,-0.3211,13.9817,0.12967}, + {1118,-0.3212,13.9879,0.12969}, + {1119,-0.3212,13.9941,0.12971}, + {1120,-0.3213,14.0003,0.12973}, + {1121,-0.3213,14.0064,0.12976}, + {1122,-0.3214,14.0126,0.12978}, + {1123,-0.3214,14.0188,0.1298}, + {1124,-0.3215,14.025,0.12982}, + {1125,-0.3215,14.0312,0.12985}, + {1126,-0.3216,14.0373,0.12987}, + {1127,-0.3216,14.0435,0.12989}, + {1128,-0.3216,14.0497,0.12992}, + {1129,-0.3217,14.0559,0.12994}, + {1130,-0.3217,14.0621,0.12996}, + {1131,-0.3218,14.0682,0.12999}, + {1132,-0.3218,14.0744,0.13001}, + {1133,-0.3219,14.0806,0.13003}, + {1134,-0.3219,14.0868,0.13006}, + {1135,-0.322,14.093,0.13008}, + {1136,-0.322,14.0991,0.1301}, + {1137,-0.3221,14.1053,0.13013}, + {1138,-0.3221,14.1115,0.13015}, + {1139,-0.3222,14.1177,0.13017}, + {1140,-0.3222,14.1238,0.1302}, + {1141,-0.3222,14.13,0.13022}, + {1142,-0.3223,14.1362,0.13024}, + {1143,-0.3223,14.1424,0.13027}, + {1144,-0.3224,14.1485,0.13029}, + {1145,-0.3224,14.1547,0.13032}, + {1146,-0.3225,14.1609,0.13034}, + {1147,-0.3225,14.1671,0.13036}, + {1148,-0.3226,14.1732,0.13039}, + {1149,-0.3226,14.1794,0.13041}, + {1150,-0.3227,14.1856,0.13043}, + {1151,-0.3227,14.1917,0.13046}, + {1152,-0.3227,14.1979,0.13048}, + {1153,-0.3228,14.2041,0.13051}, + {1154,-0.3228,14.2103,0.13053}, + {1155,-0.3229,14.2164,0.13055}, + {1156,-0.3229,14.2226,0.13058}, + {1157,-0.323,14.2288,0.1306}, + {1158,-0.323,14.2349,0.13063}, + {1159,-0.3231,14.2411,0.13065}, + {1160,-0.3231,14.2473,0.13068}, + {1161,-0.3232,14.2534,0.1307}, + {1162,-0.3232,14.2596,0.13072}, + {1163,-0.3232,14.2658,0.13075}, + {1164,-0.3233,14.2719,0.13077}, + {1165,-0.3233,14.2781,0.1308}, + {1166,-0.3234,14.2843,0.13082}, + {1167,-0.3234,14.2904,0.13085}, + {1168,-0.3235,14.2966,0.13087}, + {1169,-0.3235,14.3028,0.1309}, + {1170,-0.3236,14.3089,0.13092}, + {1171,-0.3236,14.3151,0.13095}, + {1172,-0.3237,14.3213,0.13097}, + {1173,-0.3237,14.3274,0.13099}, + {1174,-0.3237,14.3336,0.13102}, + {1175,-0.3238,14.3397,0.13104}, + {1176,-0.3238,14.3459,0.13107}, + {1177,-0.3239,14.3521,0.13109}, + {1178,-0.3239,14.3582,0.13112}, + {1179,-0.324,14.3644,0.13114}, + {1180,-0.324,14.3705,0.13117}, + {1181,-0.3241,14.3767,0.13119}, + {1182,-0.3241,14.3829,0.13122}, + {1183,-0.3241,14.389,0.13124}, + {1184,-0.3242,14.3952,0.13127}, + {1185,-0.3242,14.4013,0.13129}, + {1186,-0.3243,14.4075,0.13132}, + {1187,-0.3243,14.4136,0.13134}, + {1188,-0.3244,14.4198,0.13137}, + {1189,-0.3244,14.4259,0.1314}, + {1190,-0.3245,14.4321,0.13142}, + {1191,-0.3245,14.4382,0.13145}, + {1192,-0.3245,14.4444,0.13147}, + {1193,-0.3246,14.4505,0.1315}, + {1194,-0.3246,14.4567,0.13152}, + {1195,-0.3247,14.4628,0.13155}, + {1196,-0.3247,14.469,0.13157}, + {1197,-0.3248,14.4751,0.1316}, + {1198,-0.3248,14.4813,0.13162}, + {1199,-0.3249,14.4874,0.13165}, + {1200,-0.3249,14.4936,0.13167}, + {1201,-0.3249,14.4997,0.1317}, + {1202,-0.325,14.5059,0.13173}, + {1203,-0.325,14.512,0.13175}, + {1204,-0.3251,14.5181,0.13178}, + {1205,-0.3251,14.5243,0.1318}, + {1206,-0.3252,14.5304,0.13183}, + {1207,-0.3252,14.5366,0.13185}, + {1208,-0.3253,14.5427,0.13188}, + {1209,-0.3253,14.5488,0.13191}, + {1210,-0.3253,14.555,0.13193}, + {1211,-0.3254,14.5611,0.13196}, + {1212,-0.3254,14.5673,0.13198}, + {1213,-0.3255,14.5734,0.13201}, + {1214,-0.3255,14.5795,0.13204}, + {1215,-0.3256,14.5857,0.13206}, + {1216,-0.3256,14.5918,0.13209}, + {1217,-0.3257,14.5979,0.13211}, + {1218,-0.3257,14.6041,0.13214}, + {1219,-0.3257,14.6102,0.13217}, + {1220,-0.3258,14.6163,0.13219}, + {1221,-0.3258,14.6225,0.13222}, + {1222,-0.3259,14.6286,0.13225}, + {1223,-0.3259,14.6347,0.13227}, + {1224,-0.326,14.6408,0.1323}, + {1225,-0.326,14.647,0.13232}, + {1226,-0.3261,14.6531,0.13235}, + {1227,-0.3261,14.6592,0.13238}, + {1228,-0.3261,14.6653,0.1324}, + {1229,-0.3262,14.6715,0.13243}, + {1230,-0.3262,14.6776,0.13246}, + {1231,-0.3263,14.6837,0.13248}, + {1232,-0.3263,14.6898,0.13251}, + {1233,-0.3264,14.696,0.13254}, + {1234,-0.3264,14.7021,0.13256}, + {1235,-0.3264,14.7082,0.13259}, + {1236,-0.3265,14.7143,0.13262}, + {1237,-0.3265,14.7204,0.13264}, + {1238,-0.3266,14.7265,0.13267}, + {1239,-0.3266,14.7327,0.13269}, + {1240,-0.3267,14.7388,0.13272}, + {1241,-0.3267,14.7449,0.13275}, + {1242,-0.3268,14.751,0.13278}, + {1243,-0.3268,14.7571,0.1328}, + {1244,-0.3268,14.7632,0.13283}, + {1245,-0.3269,14.7693,0.13286}, + {1246,-0.3269,14.7754,0.13288}, + {1247,-0.327,14.7816,0.13291}, + {1248,-0.327,14.7877,0.13294}, + {1249,-0.3271,14.7938,0.13296}, + {1250,-0.3271,14.7999,0.13299}, + {1251,-0.3271,14.806,0.13302}, + {1252,-0.3272,14.8121,0.13304}, + {1253,-0.3272,14.8182,0.13307}, + {1254,-0.3273,14.8243,0.1331}, + {1255,-0.3273,14.8304,0.13312}, + {1256,-0.3274,14.8365,0.13315}, + {1257,-0.3274,14.8426,0.13318}, + {1258,-0.3274,14.8487,0.13321}, + {1259,-0.3275,14.8548,0.13323}, + {1260,-0.3275,14.8609,0.13326}, + {1261,-0.3276,14.867,0.13329}, + {1262,-0.3276,14.8731,0.13331}, + {1263,-0.3277,14.8792,0.13334}, + {1264,-0.3277,14.8853,0.13337}, + {1265,-0.3278,14.8913,0.13339}, + {1266,-0.3278,14.8974,0.13342}, + {1267,-0.3278,14.9035,0.13345}, + {1268,-0.3279,14.9096,0.13348}, + {1269,-0.3279,14.9157,0.1335}, + {1270,-0.328,14.9218,0.13353}, + {1271,-0.328,14.9279,0.13356}, + {1272,-0.3281,14.934,0.13359}, + {1273,-0.3281,14.94,0.13361}, + {1274,-0.3281,14.9461,0.13364}, + {1275,-0.3282,14.9522,0.13367}, + {1276,-0.3282,14.9583,0.13369}, + {1277,-0.3283,14.9644,0.13372}, + {1278,-0.3283,14.9704,0.13375}, + {1279,-0.3284,14.9765,0.13378}, + {1280,-0.3284,14.9826,0.1338}, + {1281,-0.3284,14.9887,0.13383}, + {1282,-0.3285,14.9948,0.13386}, + {1283,-0.3285,15.0008,0.13389}, + {1284,-0.3286,15.0069,0.13391}, + {1285,-0.3286,15.013,0.13394}, + {1286,-0.3287,15.019,0.13397}, + {1287,-0.3287,15.0251,0.134}, + {1288,-0.3287,15.0312,0.13402}, + {1289,-0.3288,15.0373,0.13405}, + {1290,-0.3288,15.0433,0.13408}, + {1291,-0.3289,15.0494,0.13411}, + {1292,-0.3289,15.0555,0.13413}, + {1293,-0.329,15.0615,0.13416}, + {1294,-0.329,15.0676,0.13419}, + {1295,-0.329,15.0736,0.13422}, + {1296,-0.3291,15.0797,0.13425}, + {1297,-0.3291,15.0858,0.13427}, + {1298,-0.3292,15.0918,0.1343}, + {1299,-0.3292,15.0979,0.13433}, + {1300,-0.3293,15.1039,0.13436}, + {1301,-0.3293,15.11,0.13438}, + {1302,-0.3293,15.1161,0.13441}, + {1303,-0.3294,15.1221,0.13444}, + {1304,-0.3294,15.1282,0.13447}, + {1305,-0.3295,15.1342,0.13449}, + {1306,-0.3295,15.1403,0.13452}, + {1307,-0.3296,15.1463,0.13455}, + {1308,-0.3296,15.1524,0.13458}, + {1309,-0.3296,15.1584,0.13461}, + {1310,-0.3297,15.1645,0.13463}, + {1311,-0.3297,15.1705,0.13466}, + {1312,-0.3298,15.1766,0.13469}, + {1313,-0.3298,15.1826,0.13472}, + {1314,-0.3299,15.1887,0.13474}, + {1315,-0.3299,15.1947,0.13477}, + {1316,-0.3299,15.2008,0.1348}, + {1317,-0.33,15.2068,0.13483}, + {1318,-0.33,15.2128,0.13486}, + {1319,-0.3301,15.2189,0.13488}, + {1320,-0.3301,15.2249,0.13491}, + {1321,-0.3302,15.231,0.13494}, + {1322,-0.3302,15.237,0.13497}, + {1323,-0.3302,15.243,0.135}, + {1324,-0.3303,15.2491,0.13502}, + {1325,-0.3303,15.2551,0.13505}, + {1326,-0.3304,15.2611,0.13508}, + {1327,-0.3304,15.2672,0.13511}, + {1328,-0.3305,15.2732,0.13514}, + {1329,-0.3305,15.2792,0.13516}, + {1330,-0.3305,15.2853,0.13519}, + {1331,-0.3306,15.2913,0.13522}, + {1332,-0.3306,15.2973,0.13525}, + {1333,-0.3307,15.3034,0.13527}, + {1334,-0.3307,15.3094,0.1353}, + {1335,-0.3308,15.3154,0.13533}, + {1336,-0.3308,15.3214,0.13536}, + {1337,-0.3308,15.3275,0.13539}, + {1338,-0.3309,15.3335,0.13541}, + {1339,-0.3309,15.3395,0.13544}, + {1340,-0.331,15.3455,0.13547}, + {1341,-0.331,15.3516,0.1355}, + {1342,-0.3311,15.3576,0.13553}, + {1343,-0.3311,15.3636,0.13555}, + {1344,-0.3311,15.3696,0.13558}, + {1345,-0.3312,15.3756,0.13561}, + {1346,-0.3312,15.3817,0.13564}, + {1347,-0.3313,15.3877,0.13567}, + {1348,-0.3313,15.3937,0.13569}, + {1349,-0.3314,15.3997,0.13572}, + {1350,-0.3314,15.4057,0.13575}, + {1351,-0.3314,15.4117,0.13578}, + {1352,-0.3315,15.4178,0.13581}, + {1353,-0.3315,15.4238,0.13584}, + {1354,-0.3316,15.4298,0.13586}, + {1355,-0.3316,15.4358,0.13589}, + {1356,-0.3317,15.4418,0.13592}, + {1357,-0.3317,15.4478,0.13595}, + {1358,-0.3317,15.4538,0.13598}, + {1359,-0.3318,15.4598,0.136}, + {1360,-0.3318,15.4658,0.13603}, + {1361,-0.3319,15.4719,0.13606}, + {1362,-0.3319,15.4779,0.13609}, + {1363,-0.332,15.4839,0.13612}, + {1364,-0.332,15.4899,0.13614}, + {1365,-0.332,15.4959,0.13617}, + {1366,-0.3321,15.5019,0.1362}, + {1367,-0.3321,15.5079,0.13623}, + {1368,-0.3322,15.5139,0.13626}, + {1369,-0.3322,15.5199,0.13628}, + {1370,-0.3322,15.5259,0.13631}, + {1371,-0.3323,15.5319,0.13634}, + {1372,-0.3323,15.5379,0.13637}, + {1373,-0.3324,15.5439,0.1364}, + {1374,-0.3324,15.5499,0.13642}, + {1375,-0.3325,15.5559,0.13645}, + {1376,-0.3325,15.5619,0.13648}, + {1377,-0.3325,15.5679,0.13651}, + {1378,-0.3326,15.5739,0.13654}, + {1379,-0.3326,15.5799,0.13656}, + {1380,-0.3327,15.5859,0.13659}, + {1381,-0.3327,15.5918,0.13662}, + {1382,-0.3328,15.5978,0.13665}, + {1383,-0.3328,15.6038,0.13668}, + {1384,-0.3328,15.6098,0.1367}, + {1385,-0.3329,15.6158,0.13673}, + {1386,-0.3329,15.6218,0.13676}, + {1387,-0.333,15.6278,0.13679}, + {1388,-0.333,15.6338,0.13682}, + {1389,-0.3331,15.6398,0.13684}, + {1390,-0.3331,15.6458,0.13687}, + {1391,-0.3331,15.6517,0.1369}, + {1392,-0.3332,15.6577,0.13693}, + {1393,-0.3332,15.6637,0.13696}, + {1394,-0.3333,15.6697,0.13698}, + {1395,-0.3333,15.6757,0.13701}, + {1396,-0.3334,15.6817,0.13704}, + {1397,-0.3334,15.6877,0.13707}, + {1398,-0.3334,15.6936,0.1371}, + {1399,-0.3335,15.6996,0.13712}, + {1400,-0.3335,15.7056,0.13715}, + {1401,-0.3336,15.7116,0.13718}, + {1402,-0.3336,15.7176,0.13721}, + {1403,-0.3337,15.7236,0.13724}, + {1404,-0.3337,15.7295,0.13726}, + {1405,-0.3337,15.7355,0.13729}, + {1406,-0.3338,15.7415,0.13732}, + {1407,-0.3338,15.7475,0.13735}, + {1408,-0.3339,15.7534,0.13737}, + {1409,-0.3339,15.7594,0.1374}, + {1410,-0.3339,15.7654,0.13743}, + {1411,-0.334,15.7714,0.13746}, + {1412,-0.334,15.7774,0.13749}, + {1413,-0.3341,15.7833,0.13751}, + {1414,-0.3341,15.7893,0.13754}, + {1415,-0.3342,15.7953,0.13757}, + {1416,-0.3342,15.8013,0.1376}, + {1417,-0.3342,15.8072,0.13763}, + {1418,-0.3343,15.8132,0.13765}, + {1419,-0.3343,15.8192,0.13768}, + {1420,-0.3344,15.8252,0.13771}, + {1421,-0.3344,15.8311,0.13774}, + {1422,-0.3345,15.8371,0.13776}, + {1423,-0.3345,15.8431,0.13779}, + {1424,-0.3345,15.849,0.13782}, + {1425,-0.3346,15.855,0.13785}, + {1426,-0.3346,15.861,0.13788}, + {1427,-0.3347,15.8669,0.1379}, + {1428,-0.3347,15.8729,0.13793}, + {1429,-0.3348,15.8789,0.13796}, + {1430,-0.3348,15.8849,0.13799}, + {1431,-0.3348,15.8908,0.13801}, + {1432,-0.3349,15.8968,0.13804}, + {1433,-0.3349,15.9028,0.13807}, + {1434,-0.335,15.9087,0.1381}, + {1435,-0.335,15.9147,0.13813}, + {1436,-0.3351,15.9207,0.13815}, + {1437,-0.3351,15.9266,0.13818}, + {1438,-0.3351,15.9326,0.13821}, + {1439,-0.3352,15.9386,0.13824}, + {1440,-0.3352,15.9445,0.13826}, + {1441,-0.3353,15.9505,0.13829}, + {1442,-0.3353,15.9565,0.13832}, + {1443,-0.3354,15.9624,0.13835}, + {1444,-0.3354,15.9684,0.13838}, + {1445,-0.3354,15.9744,0.1384}, + {1446,-0.3355,15.9803,0.13843}, + {1447,-0.3355,15.9863,0.13846}, + {1448,-0.3356,15.9922,0.13849}, + {1449,-0.3356,15.9982,0.13851}, + {1450,-0.3357,16.0042,0.13854}, + {1451,-0.3357,16.0101,0.13857}, + {1452,-0.3357,16.0161,0.1386}, + {1453,-0.3358,16.0221,0.13862}, + {1454,-0.3358,16.028,0.13865}, + {1455,-0.3359,16.034,0.13868}, + {1456,-0.3359,16.0399,0.13871}, + {1457,-0.3359,16.0459,0.13873}, + {1458,-0.336,16.0519,0.13876}, + {1459,-0.336,16.0578,0.13879}, + {1460,-0.3361,16.0638,0.13882}, + {1461,-0.3361,16.0697,0.13884}, + {1462,-0.3362,16.0757,0.13887}, + {1463,-0.3362,16.0817,0.1389}, + {1464,-0.3362,16.0876,0.13893}, + {1465,-0.3363,16.0936,0.13895}, + {1466,-0.3363,16.0995,0.13898}, + {1467,-0.3364,16.1055,0.13901}, + {1468,-0.3364,16.1115,0.13904}, + {1469,-0.3365,16.1174,0.13907}, + {1470,-0.3365,16.1234,0.13909}, + {1471,-0.3365,16.1293,0.13912}, + {1472,-0.3366,16.1353,0.13915}, + {1473,-0.3366,16.1413,0.13918}, + {1474,-0.3367,16.1472,0.1392}, + {1475,-0.3367,16.1532,0.13923}, + {1476,-0.3368,16.1591,0.13926}, + {1477,-0.3368,16.1651,0.13928}, + {1478,-0.3368,16.171,0.13931}, + {1479,-0.3369,16.177,0.13934}, + {1480,-0.3369,16.1829,0.13937}, + {1481,-0.337,16.1889,0.13939}, + {1482,-0.337,16.1949,0.13942}, + {1483,-0.3371,16.2008,0.13945}, + {1484,-0.3371,16.2068,0.13948}, + {1485,-0.3371,16.2127,0.1395}, + {1486,-0.3372,16.2187,0.13953}, + {1487,-0.3372,16.2246,0.13956}, + {1488,-0.3373,16.2306,0.13959}, + {1489,-0.3373,16.2365,0.13961}, + {1490,-0.3374,16.2425,0.13964}, + {1491,-0.3374,16.2485,0.13967}, + {1492,-0.3374,16.2544,0.1397}, + {1493,-0.3375,16.2604,0.13972}, + {1494,-0.3375,16.2663,0.13975}, + {1495,-0.3376,16.2723,0.13978}, + {1496,-0.3376,16.2782,0.1398}, + {1497,-0.3377,16.2842,0.13983}, + {1498,-0.3377,16.2901,0.13986}, + {1499,-0.3377,16.2961,0.13989}, + {1500,-0.3378,16.302,0.13991}, + {1501,-0.3378,16.308,0.13994}, + {1502,-0.3379,16.314,0.13997}, + {1503,-0.3379,16.3199,0.14}, + {1504,-0.338,16.3259,0.14002}, + {1505,-0.338,16.3318,0.14005}, + {1506,-0.338,16.3378,0.14008}, + {1507,-0.3381,16.3437,0.1401}, + {1508,-0.3381,16.3497,0.14013}, + {1509,-0.3382,16.3556,0.14016}, + {1510,-0.3382,16.3616,0.14019}, + {1511,-0.3383,16.3675,0.14021}, + {1512,-0.3383,16.3735,0.14024}, + {1513,-0.3383,16.3794,0.14027}, + {1514,-0.3384,16.3854,0.14029}, + {1515,-0.3384,16.3913,0.14032}, + {1516,-0.3385,16.3973,0.14035}, + {1517,-0.3385,16.4032,0.14038}, + {1518,-0.3386,16.4092,0.1404}, + {1519,-0.3386,16.4151,0.14043}, + {1520,-0.3386,16.4211,0.14046}, + {1521,-0.3387,16.427,0.14048}, + {1522,-0.3387,16.433,0.14051}, + {1523,-0.3388,16.4389,0.14054}, + {1524,-0.3388,16.4449,0.14056}, + {1525,-0.3389,16.4508,0.14059}, + {1526,-0.3389,16.4568,0.14062}, + {1527,-0.3389,16.4627,0.14065}, + {1528,-0.339,16.4687,0.14067}, + {1529,-0.339,16.4746,0.1407}, + {1530,-0.3391,16.4806,0.14073}, + {1531,-0.3391,16.4865,0.14075}, + {1532,-0.3392,16.4925,0.14078}, + {1533,-0.3392,16.4984,0.14081}, + {1534,-0.3392,16.5044,0.14083}, + {1535,-0.3393,16.5103,0.14086}, + {1536,-0.3393,16.5163,0.14089}, + {1537,-0.3394,16.5222,0.14091}, + {1538,-0.3394,16.5282,0.14094}, + {1539,-0.3395,16.5341,0.14097}, + {1540,-0.3395,16.5401,0.141}, + {1541,-0.3396,16.546,0.14102}, + {1542,-0.3396,16.552,0.14105}, + {1543,-0.3396,16.5579,0.14108}, + {1544,-0.3397,16.5639,0.1411}, + {1545,-0.3397,16.5698,0.14113}, + {1546,-0.3398,16.5758,0.14116}, + {1547,-0.3398,16.5817,0.14118}, + {1548,-0.3399,16.5876,0.14121}, + {1549,-0.3399,16.5936,0.14124}, + {1550,-0.3399,16.5995,0.14126}, + {1551,-0.34,16.6055,0.14129}, + {1552,-0.34,16.6114,0.14132}, + {1553,-0.3401,16.6174,0.14134}, + {1554,-0.3401,16.6233,0.14137}, + {1555,-0.3402,16.6293,0.1414}, + {1556,-0.3402,16.6352,0.14142}, + {1557,-0.3402,16.6412,0.14145}, + {1558,-0.3403,16.6471,0.14148}, + {1559,-0.3403,16.653,0.1415}, + {1560,-0.3404,16.659,0.14153}, + {1561,-0.3404,16.6649,0.14156}, + {1562,-0.3405,16.6709,0.14158}, + {1563,-0.3405,16.6768,0.14161}, + {1564,-0.3405,16.6828,0.14164}, + {1565,-0.3406,16.6887,0.14166}, + {1566,-0.3406,16.6947,0.14169}, + {1567,-0.3407,16.7006,0.14172}, + {1568,-0.3407,16.7065,0.14174}, + {1569,-0.3408,16.7125,0.14177}, + {1570,-0.3408,16.7184,0.14179}, + {1571,-0.3408,16.7244,0.14182}, + {1572,-0.3409,16.7303,0.14185}, + {1573,-0.3409,16.7363,0.14187}, + {1574,-0.341,16.7422,0.1419}, + {1575,-0.341,16.7481,0.14193}, + {1576,-0.3411,16.7541,0.14195}, + {1577,-0.3411,16.76,0.14198}, + {1578,-0.3412,16.766,0.14201}, + {1579,-0.3412,16.7719,0.14203}, + {1580,-0.3412,16.7778,0.14206}, + {1581,-0.3413,16.7838,0.14209}, + {1582,-0.3413,16.7897,0.14211}, + {1583,-0.3414,16.7957,0.14214}, + {1584,-0.3414,16.8016,0.14216}, + {1585,-0.3415,16.8075,0.14219}, + {1586,-0.3415,16.8135,0.14222}, + {1587,-0.3415,16.8194,0.14224}, + {1588,-0.3416,16.8254,0.14227}, + {1589,-0.3416,16.8313,0.1423}, + {1590,-0.3417,16.8372,0.14232}, + {1591,-0.3417,16.8432,0.14235}, + {1592,-0.3418,16.8491,0.14237}, + {1593,-0.3418,16.855,0.1424}, + {1594,-0.3418,16.861,0.14243}, + {1595,-0.3419,16.8669,0.14245}, + {1596,-0.3419,16.8729,0.14248}, + {1597,-0.342,16.8788,0.14251}, + {1598,-0.342,16.8847,0.14253}, + {1599,-0.3421,16.8907,0.14256}, + {1600,-0.3421,16.8966,0.14258}, + {1601,-0.3421,16.9025,0.14261}, + {1602,-0.3422,16.9085,0.14264}, + {1603,-0.3422,16.9144,0.14266}, + {1604,-0.3423,16.9203,0.14269}, + {1605,-0.3423,16.9263,0.14271}, + {1606,-0.3424,16.9322,0.14274}, + {1607,-0.3424,16.9381,0.14277}, + {1608,-0.3425,16.9441,0.14279}, + {1609,-0.3425,16.95,0.14282}, + {1610,-0.3425,16.9559,0.14284}, + {1611,-0.3426,16.9619,0.14287}, + {1612,-0.3426,16.9678,0.1429}, + {1613,-0.3427,16.9737,0.14292}, + {1614,-0.3427,16.9796,0.14295}, + {1615,-0.3428,16.9856,0.14297}, + {1616,-0.3428,16.9915,0.143}, + {1617,-0.3428,16.9974,0.14303}, + {1618,-0.3429,17.0034,0.14305}, + {1619,-0.3429,17.0093,0.14308}, + {1620,-0.343,17.0152,0.1431}, + {1621,-0.343,17.0211,0.14313}, + {1622,-0.3431,17.0271,0.14315}, + {1623,-0.3431,17.033,0.14318}, + {1624,-0.3431,17.0389,0.14321}, + {1625,-0.3432,17.0448,0.14323}, + {1626,-0.3432,17.0508,0.14326}, + {1627,-0.3433,17.0567,0.14328}, + {1628,-0.3433,17.0626,0.14331}, + {1629,-0.3434,17.0685,0.14334}, + {1630,-0.3434,17.0744,0.14336}, + {1631,-0.3434,17.0804,0.14339}, + {1632,-0.3435,17.0863,0.14341}, + {1633,-0.3435,17.0922,0.14344}, + {1634,-0.3436,17.0981,0.14346}, + {1635,-0.3436,17.104,0.14349}, + {1636,-0.3437,17.11,0.14352}, + {1637,-0.3437,17.1159,0.14354}, + {1638,-0.3438,17.1218,0.14357}, + {1639,-0.3438,17.1277,0.14359}, + {1640,-0.3438,17.1336,0.14362}, + {1641,-0.3439,17.1395,0.14364}, + {1642,-0.3439,17.1455,0.14367}, + {1643,-0.344,17.1514,0.14369}, + {1644,-0.344,17.1573,0.14372}, + {1645,-0.3441,17.1632,0.14375}, + {1646,-0.3441,17.1691,0.14377}, + {1647,-0.3441,17.175,0.1438}, + {1648,-0.3442,17.1809,0.14382}, + {1649,-0.3442,17.1868,0.14385}, + {1650,-0.3443,17.1927,0.14387}, + {1651,-0.3443,17.1987,0.1439}, + {1652,-0.3444,17.2046,0.14392}, + {1653,-0.3444,17.2105,0.14395}, + {1654,-0.3444,17.2164,0.14398}, + {1655,-0.3445,17.2223,0.144}, + {1656,-0.3445,17.2282,0.14403}, + {1657,-0.3446,17.2341,0.14405}, + {1658,-0.3446,17.24,0.14408}, + {1659,-0.3447,17.2459,0.1441}, + {1660,-0.3447,17.2518,0.14413}, + {1661,-0.3448,17.2577,0.14415}, + {1662,-0.3448,17.2636,0.14418}, + {1663,-0.3448,17.2695,0.1442}, + {1664,-0.3449,17.2754,0.14423}, + {1665,-0.3449,17.2813,0.14426}, + {1666,-0.345,17.2872,0.14428}, + {1667,-0.345,17.2931,0.14431}, + {1668,-0.3451,17.299,0.14433}, + {1669,-0.3451,17.3049,0.14436}, + {1670,-0.3451,17.3108,0.14438}, + {1671,-0.3452,17.3167,0.14441}, + {1672,-0.3452,17.3226,0.14443}, + {1673,-0.3453,17.3285,0.14446}, + {1674,-0.3453,17.3344,0.14448}, + {1675,-0.3454,17.3402,0.14451}, + {1676,-0.3454,17.3461,0.14453}, + {1677,-0.3454,17.352,0.14456}, + {1678,-0.3455,17.3579,0.14458}, + {1679,-0.3455,17.3638,0.14461}, + {1680,-0.3456,17.3697,0.14463}, + {1681,-0.3456,17.3756,0.14466}, + {1682,-0.3457,17.3815,0.14468}, + {1683,-0.3457,17.3873,0.14471}, + {1684,-0.3457,17.3932,0.14473}, + {1685,-0.3458,17.3991,0.14476}, + {1686,-0.3458,17.405,0.14479}, + {1687,-0.3459,17.4109,0.14481}, + {1688,-0.3459,17.4167,0.14484}, + {1689,-0.346,17.4226,0.14486}, + {1690,-0.346,17.4285,0.14489}, + {1691,-0.346,17.4344,0.14491}, + {1692,-0.3461,17.4403,0.14494}, + {1693,-0.3461,17.4461,0.14496}, + {1694,-0.3462,17.452,0.14499}, + {1695,-0.3462,17.4579,0.14501}, + {1696,-0.3463,17.4637,0.14504}, + {1697,-0.3463,17.4696,0.14506}, + {1698,-0.3463,17.4755,0.14509}, + {1699,-0.3464,17.4814,0.14511}, + {1700,-0.3464,17.4872,0.14514}, + {1701,-0.3465,17.4931,0.14516}, + {1702,-0.3465,17.499,0.14519}, + {1703,-0.3466,17.5048,0.14521}, + {1704,-0.3466,17.5107,0.14524}, + {1705,-0.3467,17.5166,0.14526}, + {1706,-0.3467,17.5224,0.14529}, + {1707,-0.3467,17.5283,0.14531}, + {1708,-0.3468,17.5341,0.14534}, + {1709,-0.3468,17.54,0.14536}, + {1710,-0.3469,17.5459,0.14539}, + {1711,-0.3469,17.5517,0.14541}, + {1712,-0.347,17.5576,0.14544}, + {1713,-0.347,17.5634,0.14546}, + {1714,-0.347,17.5693,0.14549}, + {1715,-0.3471,17.5751,0.14551}, + {1716,-0.3471,17.581,0.14553}, + {1717,-0.3472,17.5868,0.14556}, + {1718,-0.3472,17.5927,0.14558}, + {1719,-0.3473,17.5985,0.14561}, + {1720,-0.3473,17.6044,0.14563}, + {1721,-0.3473,17.6102,0.14566}, + {1722,-0.3474,17.6161,0.14568}, + {1723,-0.3474,17.6219,0.14571}, + {1724,-0.3475,17.6278,0.14573}, + {1725,-0.3475,17.6336,0.14576}, + {1726,-0.3476,17.6394,0.14578}, + {1727,-0.3476,17.6453,0.14581}, + {1728,-0.3476,17.6511,0.14583}, + {1729,-0.3477,17.657,0.14586}, + {1730,-0.3477,17.6628,0.14588}, + {1731,-0.3478,17.6686,0.14591}, + {1732,-0.3478,17.6745,0.14593}, + {1733,-0.3479,17.6803,0.14596}, + {1734,-0.3479,17.6861,0.14598}, + {1735,-0.3479,17.692,0.146}, + {1736,-0.348,17.6978,0.14603}, + {1737,-0.348,17.7036,0.14605}, + {1738,-0.3481,17.7095,0.14608}, + {1739,-0.3481,17.7153,0.1461}, + {1740,-0.3482,17.7211,0.14613}, + {1741,-0.3482,17.7269,0.14615}, + {1742,-0.3482,17.7328,0.14618}, + {1743,-0.3483,17.7386,0.1462}, + {1744,-0.3483,17.7444,0.14623}, + {1745,-0.3484,17.7502,0.14625}, + {1746,-0.3484,17.7561,0.14628}, + {1747,-0.3485,17.7619,0.1463}, + {1748,-0.3485,17.7677,0.14632}, + {1749,-0.3485,17.7735,0.14635}, + {1750,-0.3486,17.7793,0.14637}, + {1751,-0.3486,17.7851,0.1464}, + {1752,-0.3487,17.791,0.14642}, + {1753,-0.3487,17.7968,0.14645}, + {1754,-0.3488,17.8026,0.14647}, + {1755,-0.3488,17.8084,0.1465}, + {1756,-0.3488,17.8142,0.14652}, + {1757,-0.3489,17.82,0.14654}, + {1758,-0.3489,17.8258,0.14657}, + {1759,-0.349,17.8316,0.14659}, + {1760,-0.349,17.8374,0.14662}, + {1761,-0.3491,17.8432,0.14664}, + {1762,-0.3491,17.849,0.14667}, + {1763,-0.3491,17.8548,0.14669}, + {1764,-0.3492,17.8606,0.14672}, + {1765,-0.3492,17.8664,0.14674}, + {1766,-0.3493,17.8722,0.14676}, + {1767,-0.3493,17.878,0.14679}, + {1768,-0.3493,17.8838,0.14681}, + {1769,-0.3494,17.8896,0.14684}, + {1770,-0.3494,17.8954,0.14686}, + {1771,-0.3495,17.9012,0.14689}, + {1772,-0.3495,17.907,0.14691}, + {1773,-0.3496,17.9128,0.14693}, + {1774,-0.3496,17.9186,0.14696}, + {1775,-0.3496,17.9243,0.14698}, + {1776,-0.3497,17.9301,0.14701}, + {1777,-0.3497,17.9359,0.14703}, + {1778,-0.3498,17.9417,0.14706}, + {1779,-0.3498,17.9475,0.14708}, + {1780,-0.3499,17.9533,0.1471}, + {1781,-0.3499,17.959,0.14713}, + {1782,-0.3499,17.9648,0.14715}, + {1783,-0.35,17.9706,0.14718}, + {1784,-0.35,17.9764,0.1472}, + {1785,-0.3501,17.9821,0.14722}, + {1786,-0.3501,17.9879,0.14725}, + {1787,-0.3502,17.9937,0.14727}, + {1788,-0.3502,17.9995,0.1473}, + {1789,-0.3502,18.0052,0.14732}, + {1790,-0.3503,18.011,0.14735}, + {1791,-0.3503,18.0168,0.14737}, + {1792,-0.3504,18.0225,0.14739}, + {1793,-0.3504,18.0283,0.14742}, + {1794,-0.3505,18.0341,0.14744}, + {1795,-0.3505,18.0398,0.14747}, + {1796,-0.3505,18.0456,0.14749}, + {1797,-0.3506,18.0513,0.14751}, + {1798,-0.3506,18.0571,0.14754}, + {1799,-0.3507,18.0629,0.14756}, + {1800,-0.3507,18.0686,0.14759}, + {1801,-0.3507,18.0744,0.14761}, + {1802,-0.3508,18.0801,0.14763}, + {1803,-0.3508,18.0859,0.14766}, + {1804,-0.3509,18.0916,0.14768}, + {1805,-0.3509,18.0974,0.14771}, + {1806,-0.351,18.1031,0.14773}, + {1807,-0.351,18.1089,0.14775}, + {1808,-0.351,18.1146,0.14778}, + {1809,-0.3511,18.1204,0.1478}, + {1810,-0.3511,18.1261,0.14783}, + {1811,-0.3512,18.1319,0.14785}, + {1812,-0.3512,18.1376,0.14787}, + {1813,-0.3513,18.1434,0.1479}, + {1814,-0.3513,18.1491,0.14792}, + {1815,-0.3513,18.1548,0.14794}, + {1816,-0.3514,18.1606,0.14797}, + {1817,-0.3514,18.1663,0.14799}, + {1818,-0.3515,18.172,0.14802}, + {1819,-0.3515,18.1778,0.14804}, + {1820,-0.3515,18.1835,0.14806}, + {1821,-0.3516,18.1892,0.14809}, + {1822,-0.3516,18.195,0.14811}, + {1823,-0.3517,18.2007,0.14814}, + {1824,-0.3517,18.2064,0.14816}, + {1825,-0.3518,18.2122,0.14818}, + {1826,-0.3518,18.2179,0.14821}, + {1827,-0.3518,18.2236,0.14823}, + {1828,-0.3519,18.2293,0.14825}, + {1829,-0.3519,18.235,0.14828}, + {1830,-0.352,18.2408,0.1483}, + {1831,-0.352,18.2465,0.14833}, + {1832,-0.352,18.2522,0.14835}, + {1833,-0.3521,18.2579,0.14837}, + {1834,-0.3521,18.2636,0.1484}, + {1835,-0.3522,18.2693,0.14842}, + {1836,-0.3522,18.2751,0.14844}, + {1837,-0.3523,18.2808,0.14847}, + {1838,-0.3523,18.2865,0.14849}, + {1839,-0.3523,18.2922,0.14852}, + {1840,-0.3524,18.2979,0.14854}, + {1841,-0.3524,18.3036,0.14856}, + {1842,-0.3525,18.3093,0.14859}, + {1843,-0.3525,18.315,0.14861}, + {1844,-0.3526,18.3207,0.14863}, + {1845,-0.3526,18.3264,0.14866}, + {1846,-0.3526,18.3321,0.14868}, + {1847,-0.3527,18.3378,0.14871}, + {1848,-0.3527,18.3435,0.14873}, + {1849,-0.3528,18.3492,0.14875}, + {1850,-0.3528,18.3549,0.14878}, + {1851,-0.3528,18.3606,0.1488}, + {1852,-0.3529,18.3663,0.14882}, + {1853,-0.3529,18.372,0.14885}, + {1854,-0.353,18.3777,0.14887}, + {1855,-0.353,18.3834,0.14889}, + {1856,-0.3531,18.389,0.14892} + }; + return girlsWeightForAge[index < girlsWeightForAge.length ? index : girlsWeightForAge.length]; + } + + public double[]getBoysLengthForAge(int index){ + double[][]boysLengthForAge = { + {0,1,49.8842,0.03795}, + {1,1,50.0601,0.03785}, + {2,1,50.2359,0.03775}, + {3,1,50.4118,0.03764}, + {4,1,50.5876,0.03754}, + {5,1,50.7635,0.03744}, + {6,1,50.9393,0.03734}, + {7,1,51.1152,0.03723}, + {8,1,51.291,0.03713}, + {9,1,51.4669,0.03703}, + {10,1,51.6427,0.03693}, + {11,1,51.8186,0.03682}, + {12,1,51.9944,0.03672}, + {13,1,52.1702,0.03662}, + {14,1,52.3461,0.03652}, + {15,1,52.4978,0.03645}, + {16,1,52.6488,0.03639}, + {17,1,52.799,0.03633}, + {18,1,52.9483,0.03627}, + {19,1,53.0967,0.03621}, + {20,1,53.2441,0.03615}, + {21,1,53.3905,0.03609}, + {22,1,53.536,0.03603}, + {23,1,53.6805,0.03597}, + {24,1,53.8239,0.03592}, + {25,1,53.9664,0.03586}, + {26,1,54.1079,0.03581}, + {27,1,54.2485,0.03575}, + {28,1,54.3881,0.0357}, + {29,1,54.5268,0.03565}, + {30,1,54.6645,0.03559}, + {31,1,54.8012,0.03554}, + {32,1,54.9368,0.03549}, + {33,1,55.0714,0.03544}, + {34,1,55.2049,0.03539}, + {35,1,55.3374,0.03534}, + {36,1,55.4688,0.03529}, + {37,1,55.5992,0.03524}, + {38,1,55.7285,0.0352}, + {39,1,55.8568,0.03515}, + {40,1,55.9841,0.0351}, + {41,1,56.1104,0.03506}, + {42,1,56.2357,0.03501}, + {43,1,56.3599,0.03496}, + {44,1,56.4833,0.03492}, + {45,1,56.6056,0.03488}, + {46,1,56.7269,0.03483}, + {47,1,56.8472,0.03479}, + {48,1,56.9666,0.03475}, + {49,1,57.0851,0.0347}, + {50,1,57.2026,0.03466}, + {51,1,57.3192,0.03462}, + {52,1,57.4349,0.03458}, + {53,1,57.5497,0.03454}, + {54,1,57.6637,0.0345}, + {55,1,57.7767,0.03446}, + {56,1,57.8889,0.03442}, + {57,1,58.0003,0.03438}, + {58,1,58.1109,0.03434}, + {59,1,58.2207,0.03431}, + {60,1,58.3299,0.03427}, + {61,1,58.4384,0.03423}, + {62,1,58.5463,0.0342}, + {63,1,58.6536,0.03416}, + {64,1,58.7603,0.03412}, + {65,1,58.8664,0.03409}, + {66,1,58.9718,0.03405}, + {67,1,59.0766,0.03402}, + {68,1,59.1808,0.03398}, + {69,1,59.2843,0.03395}, + {70,1,59.3872,0.03392}, + {71,1,59.4894,0.03388}, + {72,1,59.591,0.03385}, + {73,1,59.692,0.03382}, + {74,1,59.7923,0.03379}, + {75,1,59.892,0.03375}, + {76,1,59.991,0.03372}, + {77,1,60.0894,0.03369}, + {78,1,60.1872,0.03366}, + {79,1,60.2843,0.03363}, + {80,1,60.3808,0.0336}, + {81,1,60.4767,0.03357}, + {82,1,60.5719,0.03354}, + {83,1,60.6665,0.03351}, + {84,1,60.7605,0.03348}, + {85,1,60.8539,0.03345}, + {86,1,60.9466,0.03342}, + {87,1,61.0388,0.0334}, + {88,1,61.1303,0.03337}, + {89,1,61.2212,0.03334}, + {90,1,61.3115,0.03331}, + {91,1,61.4013,0.03329}, + {92,1,61.4904,0.03326}, + {93,1,61.579,0.03323}, + {94,1,61.667,0.03321}, + {95,1,61.7543,0.03318}, + {96,1,61.8411,0.03316}, + {97,1,61.9274,0.03313}, + {98,1,62.013,0.03311}, + {99,1,62.0981,0.03308}, + {100,1,62.1826,0.03306}, + {101,1,62.2665,0.03303}, + {102,1,62.3499,0.03301}, + {103,1,62.4327,0.03298}, + {104,1,62.5149,0.03296}, + {105,1,62.5966,0.03294}, + {106,1,62.6778,0.03291}, + {107,1,62.7584,0.03289}, + {108,1,62.8384,0.03287}, + {109,1,62.918,0.03284}, + {110,1,62.9969,0.03282}, + {111,1,63.0754,0.0328}, + {112,1,63.1533,0.03278}, + {113,1,63.2307,0.03276}, + {114,1,63.3076,0.03273}, + {115,1,63.3839,0.03271}, + {116,1,63.4598,0.03269}, + {117,1,63.5351,0.03267}, + {118,1,63.6099,0.03265}, + {119,1,63.6842,0.03263}, + {120,1,63.758,0.03261}, + {121,1,63.8313,0.03259}, + {122,1,63.9041,0.03257}, + {123,1,63.9765,0.03255}, + {124,1,64.0483,0.03253}, + {125,1,64.1197,0.03251}, + {126,1,64.1906,0.03249}, + {127,1,64.261,0.03247}, + {128,1,64.331,0.03245}, + {129,1,64.4006,0.03243}, + {130,1,64.4697,0.03241}, + {131,1,64.5383,0.03239}, + {132,1,64.6066,0.03238}, + {133,1,64.6744,0.03236}, + {134,1,64.7418,0.03234}, + {135,1,64.8088,0.03232}, + {136,1,64.8755,0.0323}, + {137,1,64.9417,0.03229}, + {138,1,65.0075,0.03227}, + {139,1,65.073,0.03225}, + {140,1,65.138,0.03223}, + {141,1,65.2027,0.03222}, + {142,1,65.2671,0.0322}, + {143,1,65.331,0.03218}, + {144,1,65.3946,0.03217}, + {145,1,65.4579,0.03215}, + {146,1,65.5208,0.03214}, + {147,1,65.5834,0.03212}, + {148,1,65.6456,0.0321}, + {149,1,65.7075,0.03209}, + {150,1,65.769,0.03207}, + {151,1,65.8303,0.03206}, + {152,1,65.8912,0.03204}, + {153,1,65.9518,0.03203}, + {154,1,66.0121,0.03201}, + {155,1,66.0721,0.032}, + {156,1,66.1317,0.03198}, + {157,1,66.1911,0.03197}, + {158,1,66.2502,0.03196}, + {159,1,66.3089,0.03194}, + {160,1,66.3674,0.03193}, + {161,1,66.4256,0.03191}, + {162,1,66.4835,0.0319}, + {163,1,66.5412,0.03189}, + {164,1,66.5985,0.03187}, + {165,1,66.6556,0.03186}, + {166,1,66.7125,0.03185}, + {167,1,66.7691,0.03183}, + {168,1,66.8254,0.03182}, + {169,1,66.8815,0.03181}, + {170,1,66.9373,0.0318}, + {171,1,66.993,0.03179}, + {172,1,67.0483,0.03177}, + {173,1,67.1035,0.03176}, + {174,1,67.1584,0.03175}, + {175,1,67.2132,0.03174}, + {176,1,67.2677,0.03173}, + {177,1,67.3219,0.03171}, + {178,1,67.376,0.0317}, + {179,1,67.4299,0.03169}, + {180,1,67.4836,0.03168}, + {181,1,67.5371,0.03167}, + {182,1,67.5904,0.03166}, + {183,1,67.6435,0.03165}, + {184,1,67.6964,0.03164}, + {185,1,67.7491,0.03163}, + {186,1,67.8017,0.03162}, + {187,1,67.8541,0.03161}, + {188,1,67.9062,0.0316}, + {189,1,67.9583,0.03159}, + {190,1,68.0101,0.03158}, + {191,1,68.0618,0.03157}, + {192,1,68.1133,0.03156}, + {193,1,68.1647,0.03155}, + {194,1,68.2158,0.03154}, + {195,1,68.2669,0.03153}, + {196,1,68.3177,0.03152}, + {197,1,68.3685,0.03152}, + {198,1,68.419,0.03151}, + {199,1,68.4695,0.0315}, + {200,1,68.5198,0.03149}, + {201,1,68.5699,0.03148}, + {202,1,68.6199,0.03147}, + {203,1,68.6698,0.03147}, + {204,1,68.7195,0.03146}, + {205,1,68.7691,0.03145}, + {206,1,68.8186,0.03144}, + {207,1,68.8679,0.03144}, + {208,1,68.9171,0.03143}, + {209,1,68.9662,0.03142}, + {210,1,69.0152,0.03141}, + {211,1,69.0641,0.03141}, + {212,1,69.1128,0.0314}, + {213,1,69.1615,0.03139}, + {214,1,69.21,0.03139}, + {215,1,69.2584,0.03138}, + {216,1,69.3067,0.03137}, + {217,1,69.3549,0.03137}, + {218,1,69.4031,0.03136}, + {219,1,69.4511,0.03136}, + {220,1,69.499,0.03135}, + {221,1,69.5468,0.03134}, + {222,1,69.5945,0.03134}, + {223,1,69.6421,0.03133}, + {224,1,69.6896,0.03133}, + {225,1,69.737,0.03132}, + {226,1,69.7844,0.03132}, + {227,1,69.8316,0.03131}, + {228,1,69.8787,0.03131}, + {229,1,69.9258,0.0313}, + {230,1,69.9728,0.0313}, + {231,1,70.0197,0.03129}, + {232,1,70.0665,0.03129}, + {233,1,70.1132,0.03128}, + {234,1,70.1599,0.03128}, + {235,1,70.2064,0.03127}, + {236,1,70.2529,0.03127}, + {237,1,70.2994,0.03126}, + {238,1,70.3457,0.03126}, + {239,1,70.392,0.03126}, + {240,1,70.4382,0.03125}, + {241,1,70.4843,0.03125}, + {242,1,70.5304,0.03125}, + {243,1,70.5764,0.03124}, + {244,1,70.6224,0.03124}, + {245,1,70.6683,0.03123}, + {246,1,70.7141,0.03123}, + {247,1,70.7598,0.03123}, + {248,1,70.8055,0.03122}, + {249,1,70.8511,0.03122}, + {250,1,70.8967,0.03122}, + {251,1,70.9422,0.03122}, + {252,1,70.9876,0.03121}, + {253,1,71.033,0.03121}, + {254,1,71.0783,0.03121}, + {255,1,71.1235,0.03121}, + {256,1,71.1687,0.0312}, + {257,1,71.2138,0.0312}, + {258,1,71.2589,0.0312}, + {259,1,71.3039,0.0312}, + {260,1,71.3488,0.03119}, + {261,1,71.3937,0.03119}, + {262,1,71.4385,0.03119}, + {263,1,71.4832,0.03119}, + {264,1,71.5279,0.03119}, + {265,1,71.5725,0.03118}, + {266,1,71.6171,0.03118}, + {267,1,71.6616,0.03118}, + {268,1,71.706,0.03118}, + {269,1,71.7504,0.03118}, + {270,1,71.7947,0.03118}, + {271,1,71.839,0.03118}, + {272,1,71.8832,0.03118}, + {273,1,71.9273,0.03117}, + {274,1,71.9714,0.03117}, + {275,1,72.0154,0.03117}, + {276,1,72.0594,0.03117}, + {277,1,72.1033,0.03117}, + {278,1,72.1472,0.03117}, + {279,1,72.1909,0.03117}, + {280,1,72.2347,0.03117}, + {281,1,72.2783,0.03117}, + {282,1,72.3219,0.03117}, + {283,1,72.3655,0.03117}, + {284,1,72.4089,0.03117}, + {285,1,72.4523,0.03117}, + {286,1,72.4957,0.03117}, + {287,1,72.539,0.03117}, + {288,1,72.5822,0.03117}, + {289,1,72.6253,0.03117}, + {290,1,72.6684,0.03117}, + {291,1,72.7115,0.03117}, + {292,1,72.7544,0.03117}, + {293,1,72.7974,0.03117}, + {294,1,72.8402,0.03117}, + {295,1,72.883,0.03117}, + {296,1,72.9257,0.03117}, + {297,1,72.9684,0.03117}, + {298,1,73.011,0.03117}, + {299,1,73.0535,0.03118}, + {300,1,73.096,0.03118}, + {301,1,73.1384,0.03118}, + {302,1,73.1808,0.03118}, + {303,1,73.2231,0.03118}, + {304,1,73.2653,0.03118}, + {305,1,73.3075,0.03118}, + {306,1,73.3497,0.03118}, + {307,1,73.3917,0.03119}, + {308,1,73.4337,0.03119}, + {309,1,73.4757,0.03119}, + {310,1,73.5176,0.03119}, + {311,1,73.5594,0.03119}, + {312,1,73.6012,0.03119}, + {313,1,73.6429,0.0312}, + {314,1,73.6845,0.0312}, + {315,1,73.7261,0.0312}, + {316,1,73.7677,0.0312}, + {317,1,73.8091,0.0312}, + {318,1,73.8506,0.03121}, + {319,1,73.8919,0.03121}, + {320,1,73.9333,0.03121}, + {321,1,73.9745,0.03121}, + {322,1,74.0157,0.03122}, + {323,1,74.0569,0.03122}, + {324,1,74.0979,0.03122}, + {325,1,74.139,0.03122}, + {326,1,74.18,0.03123}, + {327,1,74.2209,0.03123}, + {328,1,74.2618,0.03123}, + {329,1,74.3026,0.03124}, + {330,1,74.3433,0.03124}, + {331,1,74.3841,0.03124}, + {332,1,74.4247,0.03124}, + {333,1,74.4653,0.03125}, + {334,1,74.5059,0.03125}, + {335,1,74.5464,0.03125}, + {336,1,74.5868,0.03126}, + {337,1,74.6272,0.03126}, + {338,1,74.6676,0.03126}, + {339,1,74.7079,0.03127}, + {340,1,74.7481,0.03127}, + {341,1,74.7883,0.03127}, + {342,1,74.8285,0.03128}, + {343,1,74.8686,0.03128}, + {344,1,74.9086,0.03128}, + {345,1,74.9486,0.03129}, + {346,1,74.9886,0.03129}, + {347,1,75.0285,0.0313}, + {348,1,75.0683,0.0313}, + {349,1,75.1081,0.0313}, + {350,1,75.1479,0.03131}, + {351,1,75.1876,0.03131}, + {352,1,75.2273,0.03132}, + {353,1,75.2669,0.03132}, + {354,1,75.3065,0.03132}, + {355,1,75.346,0.03133}, + {356,1,75.3855,0.03133}, + {357,1,75.425,0.03134}, + {358,1,75.4644,0.03134}, + {359,1,75.5037,0.03135}, + {360,1,75.5431,0.03135}, + {361,1,75.5824,0.03136}, + {362,1,75.6216,0.03136}, + {363,1,75.6608,0.03136}, + {364,1,75.6999,0.03137}, + {365,1,75.7391,0.03137}, + {366,1,75.7781,0.03138}, + {367,1,75.8172,0.03138}, + {368,1,75.8562,0.03139}, + {369,1,75.8951,0.03139}, + {370,1,75.934,0.0314}, + {371,1,75.9729,0.0314}, + {372,1,76.0117,0.03141}, + {373,1,76.0505,0.03141}, + {374,1,76.0892,0.03142}, + {375,1,76.1279,0.03142}, + {376,1,76.1665,0.03143}, + {377,1,76.2051,0.03143}, + {378,1,76.2437,0.03144}, + {379,1,76.2822,0.03144}, + {380,1,76.3207,0.03145}, + {381,1,76.3591,0.03146}, + {382,1,76.3975,0.03146}, + {383,1,76.4358,0.03147}, + {384,1,76.4741,0.03147}, + {385,1,76.5124,0.03148}, + {386,1,76.5506,0.03148}, + {387,1,76.5888,0.03149}, + {388,1,76.6269,0.03149}, + {389,1,76.665,0.0315}, + {390,1,76.703,0.03151}, + {391,1,76.741,0.03151}, + {392,1,76.779,0.03152}, + {393,1,76.8169,0.03152}, + {394,1,76.8548,0.03153}, + {395,1,76.8926,0.03154}, + {396,1,76.9304,0.03154}, + {397,1,76.9682,0.03155}, + {398,1,77.0059,0.03155}, + {399,1,77.0435,0.03156}, + {400,1,77.0812,0.03157}, + {401,1,77.1187,0.03157}, + {402,1,77.1563,0.03158}, + {403,1,77.1938,0.03159}, + {404,1,77.2313,0.03159}, + {405,1,77.2687,0.0316}, + {406,1,77.306,0.0316}, + {407,1,77.3434,0.03161}, + {408,1,77.3807,0.03162}, + {409,1,77.4179,0.03162}, + {410,1,77.4551,0.03163}, + {411,1,77.4923,0.03164}, + {412,1,77.5295,0.03164}, + {413,1,77.5665,0.03165}, + {414,1,77.6036,0.03166}, + {415,1,77.6406,0.03166}, + {416,1,77.6776,0.03167}, + {417,1,77.7145,0.03168}, + {418,1,77.7514,0.03168}, + {419,1,77.7883,0.03169}, + {420,1,77.8251,0.0317}, + {421,1,77.8618,0.0317}, + {422,1,77.8986,0.03171}, + {423,1,77.9353,0.03172}, + {424,1,77.9719,0.03172}, + {425,1,78.0085,0.03173}, + {426,1,78.0451,0.03174}, + {427,1,78.0817,0.03175}, + {428,1,78.1182,0.03175}, + {429,1,78.1546,0.03176}, + {430,1,78.1911,0.03177}, + {431,1,78.2275,0.03177}, + {432,1,78.2638,0.03178}, + {433,1,78.3001,0.03179}, + {434,1,78.3364,0.0318}, + {435,1,78.3727,0.0318}, + {436,1,78.4089,0.03181}, + {437,1,78.4451,0.03182}, + {438,1,78.4812,0.03183}, + {439,1,78.5173,0.03183}, + {440,1,78.5534,0.03184}, + {441,1,78.5894,0.03185}, + {442,1,78.6254,0.03186}, + {443,1,78.6614,0.03186}, + {444,1,78.6973,0.03187}, + {445,1,78.7332,0.03188}, + {446,1,78.7691,0.03189}, + {447,1,78.8049,0.03189}, + {448,1,78.8407,0.0319}, + {449,1,78.8764,0.03191}, + {450,1,78.9122,0.03192}, + {451,1,78.9479,0.03192}, + {452,1,78.9835,0.03193}, + {453,1,79.0191,0.03194}, + {454,1,79.0547,0.03195}, + {455,1,79.0903,0.03196}, + {456,1,79.1258,0.03196}, + {457,1,79.1613,0.03197}, + {458,1,79.1968,0.03198}, + {459,1,79.2322,0.03199}, + {460,1,79.2676,0.032}, + {461,1,79.303,0.032}, + {462,1,79.3383,0.03201}, + {463,1,79.3736,0.03202}, + {464,1,79.4089,0.03203}, + {465,1,79.4441,0.03204}, + {466,1,79.4793,0.03204}, + {467,1,79.5145,0.03205}, + {468,1,79.5496,0.03206}, + {469,1,79.5847,0.03207}, + {470,1,79.6198,0.03208}, + {471,1,79.6548,0.03209}, + {472,1,79.6898,0.03209}, + {473,1,79.7248,0.0321}, + {474,1,79.7598,0.03211}, + {475,1,79.7947,0.03212}, + {476,1,79.8296,0.03213}, + {477,1,79.8644,0.03214}, + {478,1,79.8993,0.03214}, + {479,1,79.9341,0.03215}, + {480,1,79.9688,0.03216}, + {481,1,80.0036,0.03217}, + {482,1,80.0383,0.03218}, + {483,1,80.0729,0.03219}, + {484,1,80.1076,0.0322}, + {485,1,80.1422,0.0322}, + {486,1,80.1768,0.03221}, + {487,1,80.2113,0.03222}, + {488,1,80.2459,0.03223}, + {489,1,80.2804,0.03224}, + {490,1,80.3148,0.03225}, + {491,1,80.3493,0.03226}, + {492,1,80.3837,0.03226}, + {493,1,80.4181,0.03227}, + {494,1,80.4524,0.03228}, + {495,1,80.4867,0.03229}, + {496,1,80.521,0.0323}, + {497,1,80.5553,0.03231}, + {498,1,80.5895,0.03232}, + {499,1,80.6237,0.03233}, + {500,1,80.6578,0.03234}, + {501,1,80.692,0.03234}, + {502,1,80.7261,0.03235}, + {503,1,80.7602,0.03236}, + {504,1,80.7942,0.03237}, + {505,1,80.8282,0.03238}, + {506,1,80.8622,0.03239}, + {507,1,80.8961,0.0324}, + {508,1,80.9301,0.03241}, + {509,1,80.964,0.03242}, + {510,1,80.9978,0.03243}, + {511,1,81.0317,0.03244}, + {512,1,81.0655,0.03245}, + {513,1,81.0992,0.03245}, + {514,1,81.133,0.03246}, + {515,1,81.1667,0.03247}, + {516,1,81.2004,0.03248}, + {517,1,81.234,0.03249}, + {518,1,81.2677,0.0325}, + {519,1,81.3013,0.03251}, + {520,1,81.3348,0.03252}, + {521,1,81.3684,0.03253}, + {522,1,81.4019,0.03254}, + {523,1,81.4353,0.03255}, + {524,1,81.4688,0.03256}, + {525,1,81.5022,0.03257}, + {526,1,81.5356,0.03258}, + {527,1,81.569,0.03259}, + {528,1,81.6023,0.0326}, + {529,1,81.6356,0.03261}, + {530,1,81.6689,0.03261}, + {531,1,81.7021,0.03262}, + {532,1,81.7353,0.03263}, + {533,1,81.7685,0.03264}, + {534,1,81.8017,0.03265}, + {535,1,81.8348,0.03266}, + {536,1,81.8679,0.03267}, + {537,1,81.9009,0.03268}, + {538,1,81.934,0.03269}, + {539,1,81.967,0.0327}, + {540,1,82,0.03271}, + {541,1,82.0329,0.03272}, + {542,1,82.0659,0.03273}, + {543,1,82.0987,0.03274}, + {544,1,82.1316,0.03275}, + {545,1,82.1644,0.03276}, + {546,1,82.1973,0.03277}, + {547,1,82.23,0.03278}, + {548,1,82.2628,0.03279}, + {549,1,82.2955,0.0328}, + {550,1,82.3282,0.03281}, + {551,1,82.3609,0.03282}, + {552,1,82.3935,0.03283}, + {553,1,82.4261,0.03284}, + {554,1,82.4587,0.03285}, + {555,1,82.4912,0.03286}, + {556,1,82.5237,0.03287}, + {557,1,82.5562,0.03288}, + {558,1,82.5887,0.03289}, + {559,1,82.6211,0.0329}, + {560,1,82.6535,0.03291}, + {561,1,82.6859,0.03292}, + {562,1,82.7182,0.03293}, + {563,1,82.7505,0.03294}, + {564,1,82.7828,0.03295}, + {565,1,82.8151,0.03296}, + {566,1,82.8473,0.03297}, + {567,1,82.8795,0.03298}, + {568,1,82.9117,0.03299}, + {569,1,82.9438,0.033}, + {570,1,82.9759,0.03301}, + {571,1,83.008,0.03302}, + {572,1,83.04,0.03303}, + {573,1,83.0721,0.03304}, + {574,1,83.1041,0.03305}, + {575,1,83.136,0.03306}, + {576,1,83.168,0.03308}, + {577,1,83.1999,0.03309}, + {578,1,83.2318,0.0331}, + {579,1,83.2637,0.03311}, + {580,1,83.2955,0.03312}, + {581,1,83.3273,0.03313}, + {582,1,83.3591,0.03314}, + {583,1,83.3908,0.03315}, + {584,1,83.4226,0.03316}, + {585,1,83.4543,0.03317}, + {586,1,83.4859,0.03318}, + {587,1,83.5176,0.03319}, + {588,1,83.5492,0.0332}, + {589,1,83.5808,0.03321}, + {590,1,83.6124,0.03322}, + {591,1,83.6439,0.03323}, + {592,1,83.6754,0.03324}, + {593,1,83.7069,0.03325}, + {594,1,83.7384,0.03326}, + {595,1,83.7698,0.03327}, + {596,1,83.8012,0.03329}, + {597,1,83.8326,0.0333}, + {598,1,83.864,0.03331}, + {599,1,83.8953,0.03332}, + {600,1,83.9267,0.03333}, + {601,1,83.9579,0.03334}, + {602,1,83.9892,0.03335}, + {603,1,84.0205,0.03336}, + {604,1,84.0517,0.03337}, + {605,1,84.0829,0.03338}, + {606,1,84.114,0.03339}, + {607,1,84.1452,0.0334}, + {608,1,84.1763,0.03341}, + {609,1,84.2074,0.03342}, + {610,1,84.2385,0.03344}, + {611,1,84.2695,0.03345}, + {612,1,84.3006,0.03346}, + {613,1,84.3316,0.03347}, + {614,1,84.3626,0.03348}, + {615,1,84.3935,0.03349}, + {616,1,84.4245,0.0335}, + {617,1,84.4554,0.03351}, + {618,1,84.4862,0.03352}, + {619,1,84.5171,0.03353}, + {620,1,84.5479,0.03354}, + {621,1,84.5787,0.03356}, + {622,1,84.6095,0.03357}, + {623,1,84.6403,0.03358}, + {624,1,84.671,0.03359}, + {625,1,84.7017,0.0336}, + {626,1,84.7324,0.03361}, + {627,1,84.7631,0.03362}, + {628,1,84.7937,0.03363}, + {629,1,84.8243,0.03364}, + {630,1,84.8549,0.03365}, + {631,1,84.8855,0.03367}, + {632,1,84.916,0.03368}, + {633,1,84.9465,0.03369}, + {634,1,84.977,0.0337}, + {635,1,85.0075,0.03371}, + {636,1,85.0379,0.03372}, + {637,1,85.0683,0.03373}, + {638,1,85.0987,0.03374}, + {639,1,85.1291,0.03375}, + {640,1,85.1594,0.03377}, + {641,1,85.1897,0.03378}, + {642,1,85.22,0.03379}, + {643,1,85.2503,0.0338}, + {644,1,85.2805,0.03381}, + {645,1,85.3108,0.03382}, + {646,1,85.341,0.03383}, + {647,1,85.3711,0.03384}, + {648,1,85.4013,0.03385}, + {649,1,85.4314,0.03387}, + {650,1,85.4615,0.03388}, + {651,1,85.4916,0.03389}, + {652,1,85.5217,0.0339}, + {653,1,85.5517,0.03391}, + {654,1,85.5817,0.03392}, + {655,1,85.6117,0.03393}, + {656,1,85.6417,0.03394}, + {657,1,85.6716,0.03396}, + {658,1,85.7015,0.03397}, + {659,1,85.7314,0.03398}, + {660,1,85.7613,0.03399}, + {661,1,85.7912,0.034}, + {662,1,85.821,0.03401}, + {663,1,85.8508,0.03402}, + {664,1,85.8806,0.03404}, + {665,1,85.9104,0.03405}, + {666,1,85.9401,0.03406}, + {667,1,85.9698,0.03407}, + {668,1,85.9995,0.03408}, + {669,1,86.0292,0.03409}, + {670,1,86.0589,0.0341}, + {671,1,86.0885,0.03411}, + {672,1,86.1181,0.03413}, + {673,1,86.1477,0.03414}, + {674,1,86.1773,0.03415}, + {675,1,86.2068,0.03416}, + {676,1,86.2363,0.03417}, + {677,1,86.2659,0.03418}, + {678,1,86.2954,0.03419}, + {679,1,86.3248,0.03421}, + {680,1,86.3543,0.03422}, + {681,1,86.3837,0.03423}, + {682,1,86.4131,0.03424}, + {683,1,86.4425,0.03425}, + {684,1,86.4719,0.03426}, + {685,1,86.5012,0.03427}, + {686,1,86.5306,0.03429}, + {687,1,86.5599,0.0343}, + {688,1,86.5892,0.03431}, + {689,1,86.6184,0.03432}, + {690,1,86.6477,0.03433}, + {691,1,86.6769,0.03434}, + {692,1,86.7061,0.03435}, + {693,1,86.7353,0.03437}, + {694,1,86.7645,0.03438}, + {695,1,86.7937,0.03439}, + {696,1,86.8228,0.0344}, + {697,1,86.8519,0.03441}, + {698,1,86.881,0.03442}, + {699,1,86.9101,0.03443}, + {700,1,86.9392,0.03445}, + {701,1,86.9682,0.03446}, + {702,1,86.9972,0.03447}, + {703,1,87.0262,0.03448}, + {704,1,87.0552,0.03449}, + {705,1,87.0842,0.0345}, + {706,1,87.1131,0.03451}, + {707,1,87.142,0.03453}, + {708,1,87.1709,0.03454}, + {709,1,87.1998,0.03455}, + {710,1,87.2287,0.03456}, + {711,1,87.2575,0.03457}, + {712,1,87.2863,0.03458}, + {713,1,87.3151,0.03459}, + {714,1,87.3439,0.03461}, + {715,1,87.3727,0.03462}, + {716,1,87.4014,0.03463}, + {717,1,87.4302,0.03464}, + {718,1,87.4589,0.03465}, + {719,1,87.4876,0.03466}, + {720,1,87.5162,0.03467}, + {721,1,87.5449,0.03469}, + {722,1,87.5735,0.0347}, + {723,1,87.6021,0.03471}, + {724,1,87.6307,0.03472}, + {725,1,87.6593,0.03473}, + {726,1,87.6878,0.03474}, + {727,1,87.7164,0.03475}, + {728,1,87.7449,0.03477}, + {729,1,87.7734,0.03478}, + {730,1,87.8018,0.03479}, + {731,1,87.1303,0.03508}, + {732,1,87.1587,0.03509}, + {733,1,87.1871,0.0351}, + {734,1,87.2155,0.03511}, + {735,1,87.2439,0.03513}, + {736,1,87.2722,0.03514}, + {737,1,87.3006,0.03515}, + {738,1,87.3289,0.03516}, + {739,1,87.3571,0.03517}, + {740,1,87.3854,0.03518}, + {741,1,87.4136,0.03519}, + {742,1,87.4419,0.03521}, + {743,1,87.4701,0.03522}, + {744,1,87.4982,0.03523}, + {745,1,87.5264,0.03524}, + {746,1,87.5545,0.03525}, + {747,1,87.5826,0.03526}, + {748,1,87.6107,0.03527}, + {749,1,87.6388,0.03528}, + {750,1,87.6668,0.0353}, + {751,1,87.6948,0.03531}, + {752,1,87.7228,0.03532}, + {753,1,87.7508,0.03533}, + {754,1,87.7788,0.03534}, + {755,1,87.8067,0.03535}, + {756,1,87.8346,0.03536}, + {757,1,87.8625,0.03538}, + {758,1,87.8903,0.03539}, + {759,1,87.9181,0.0354}, + {760,1,87.946,0.03541}, + {761,1,87.9737,0.03542}, + {762,1,88.0015,0.03543}, + {763,1,88.0292,0.03544}, + {764,1,88.057,0.03545}, + {765,1,88.0846,0.03547}, + {766,1,88.1123,0.03548}, + {767,1,88.14,0.03549}, + {768,1,88.1676,0.0355}, + {769,1,88.1952,0.03551}, + {770,1,88.2228,0.03552}, + {771,1,88.2503,0.03553}, + {772,1,88.2778,0.03555}, + {773,1,88.3053,0.03556}, + {774,1,88.3328,0.03557}, + {775,1,88.3603,0.03558}, + {776,1,88.3877,0.03559}, + {777,1,88.4151,0.0356}, + {778,1,88.4425,0.03561}, + {779,1,88.4699,0.03562}, + {780,1,88.4972,0.03564}, + {781,1,88.5245,0.03565}, + {782,1,88.5518,0.03566}, + {783,1,88.5791,0.03567}, + {784,1,88.6063,0.03568}, + {785,1,88.6335,0.03569}, + {786,1,88.6607,0.0357}, + {787,1,88.6879,0.03571}, + {788,1,88.715,0.03572}, + {789,1,88.7422,0.03574}, + {790,1,88.7693,0.03575}, + {791,1,88.7964,0.03576}, + {792,1,88.8234,0.03577}, + {793,1,88.8504,0.03578}, + {794,1,88.8775,0.03579}, + {795,1,88.9044,0.0358}, + {796,1,88.9314,0.03581}, + {797,1,88.9584,0.03582}, + {798,1,88.9853,0.03584}, + {799,1,89.0122,0.03585}, + {800,1,89.0391,0.03586}, + {801,1,89.0659,0.03587}, + {802,1,89.0927,0.03588}, + {803,1,89.1195,0.03589}, + {804,1,89.1463,0.0359}, + {805,1,89.1731,0.03591}, + {806,1,89.1998,0.03592}, + {807,1,89.2266,0.03593}, + {808,1,89.2533,0.03595}, + {809,1,89.2799,0.03596}, + {810,1,89.3066,0.03597}, + {811,1,89.3332,0.03598}, + {812,1,89.3598,0.03599}, + {813,1,89.3864,0.036}, + {814,1,89.413,0.03601}, + {815,1,89.4395,0.03602}, + {816,1,89.466,0.03603}, + {817,1,89.4925,0.03604}, + {818,1,89.519,0.03605}, + {819,1,89.5455,0.03607}, + {820,1,89.5719,0.03608}, + {821,1,89.5983,0.03609}, + {822,1,89.6247,0.0361}, + {823,1,89.651,0.03611}, + {824,1,89.6774,0.03612}, + {825,1,89.7037,0.03613}, + {826,1,89.73,0.03614}, + {827,1,89.7563,0.03615}, + {828,1,89.7825,0.03616}, + {829,1,89.8087,0.03617}, + {830,1,89.8349,0.03618}, + {831,1,89.8611,0.0362}, + {832,1,89.8873,0.03621}, + {833,1,89.9134,0.03622}, + {834,1,89.9395,0.03623}, + {835,1,89.9656,0.03624}, + {836,1,89.9917,0.03625}, + {837,1,90.0177,0.03626}, + {838,1,90.0437,0.03627}, + {839,1,90.0697,0.03628}, + {840,1,90.0957,0.03629}, + {841,1,90.1216,0.0363}, + {842,1,90.1476,0.03631}, + {843,1,90.1735,0.03632}, + {844,1,90.1994,0.03633}, + {845,1,90.2252,0.03634}, + {846,1,90.251,0.03636}, + {847,1,90.2769,0.03637}, + {848,1,90.3026,0.03638}, + {849,1,90.3284,0.03639}, + {850,1,90.3541,0.0364}, + {851,1,90.3799,0.03641}, + {852,1,90.4056,0.03642}, + {853,1,90.4312,0.03643}, + {854,1,90.4569,0.03644}, + {855,1,90.4825,0.03645}, + {856,1,90.5081,0.03646}, + {857,1,90.5337,0.03647}, + {858,1,90.5592,0.03648}, + {859,1,90.5848,0.03649}, + {860,1,90.6103,0.0365}, + {861,1,90.6358,0.03651}, + {862,1,90.6612,0.03652}, + {863,1,90.6867,0.03653}, + {864,1,90.7121,0.03654}, + {865,1,90.7375,0.03655}, + {866,1,90.7628,0.03656}, + {867,1,90.7882,0.03657}, + {868,1,90.8135,0.03659}, + {869,1,90.8388,0.0366}, + {870,1,90.8641,0.03661}, + {871,1,90.8893,0.03662}, + {872,1,90.9146,0.03663}, + {873,1,90.9398,0.03664}, + {874,1,90.965,0.03665}, + {875,1,90.9901,0.03666}, + {876,1,91.0153,0.03667}, + {877,1,91.0404,0.03668}, + {878,1,91.0655,0.03669}, + {879,1,91.0905,0.0367}, + {880,1,91.1156,0.03671}, + {881,1,91.1406,0.03672}, + {882,1,91.1656,0.03673}, + {883,1,91.1906,0.03674}, + {884,1,91.2155,0.03675}, + {885,1,91.2405,0.03676}, + {886,1,91.2654,0.03677}, + {887,1,91.2903,0.03678}, + {888,1,91.3151,0.03679}, + {889,1,91.34,0.0368}, + {890,1,91.3648,0.03681}, + {891,1,91.3896,0.03682}, + {892,1,91.4144,0.03683}, + {893,1,91.4391,0.03684}, + {894,1,91.4639,0.03685}, + {895,1,91.4886,0.03686}, + {896,1,91.5133,0.03687}, + {897,1,91.5379,0.03688}, + {898,1,91.5626,0.03689}, + {899,1,91.5872,0.0369}, + {900,1,91.6118,0.03691}, + {901,1,91.6364,0.03692}, + {902,1,91.6609,0.03693}, + {903,1,91.6855,0.03694}, + {904,1,91.71,0.03695}, + {905,1,91.7345,0.03696}, + {906,1,91.759,0.03697}, + {907,1,91.7834,0.03698}, + {908,1,91.8078,0.03699}, + {909,1,91.8323,0.037}, + {910,1,91.8566,0.03701}, + {911,1,91.881,0.03702}, + {912,1,91.9053,0.03703}, + {913,1,91.9297,0.03704}, + {914,1,91.954,0.03705}, + {915,1,91.9783,0.03706}, + {916,1,92.0025,0.03707}, + {917,1,92.0268,0.03708}, + {918,1,92.051,0.03709}, + {919,1,92.0752,0.0371}, + {920,1,92.0993,0.03711}, + {921,1,92.1235,0.03711}, + {922,1,92.1476,0.03712}, + {923,1,92.1717,0.03713}, + {924,1,92.1958,0.03714}, + {925,1,92.2199,0.03715}, + {926,1,92.244,0.03716}, + {927,1,92.268,0.03717}, + {928,1,92.292,0.03718}, + {929,1,92.316,0.03719}, + {930,1,92.34,0.0372}, + {931,1,92.3639,0.03721}, + {932,1,92.3879,0.03722}, + {933,1,92.4118,0.03723}, + {934,1,92.4357,0.03724}, + {935,1,92.4595,0.03725}, + {936,1,92.4834,0.03726}, + {937,1,92.5072,0.03727}, + {938,1,92.531,0.03728}, + {939,1,92.5548,0.03729}, + {940,1,92.5786,0.0373}, + {941,1,92.6023,0.0373}, + {942,1,92.6261,0.03731}, + {943,1,92.6498,0.03732}, + {944,1,92.6735,0.03733}, + {945,1,92.6971,0.03734}, + {946,1,92.7208,0.03735}, + {947,1,92.7444,0.03736}, + {948,1,92.768,0.03737}, + {949,1,92.7916,0.03738}, + {950,1,92.8152,0.03739}, + {951,1,92.8388,0.0374}, + {952,1,92.8623,0.03741}, + {953,1,92.8858,0.03742}, + {954,1,92.9093,0.03743}, + {955,1,92.9328,0.03743}, + {956,1,92.9562,0.03744}, + {957,1,92.9797,0.03745}, + {958,1,93.0031,0.03746}, + {959,1,93.0265,0.03747}, + {960,1,93.0499,0.03748}, + {961,1,93.0732,0.03749}, + {962,1,93.0966,0.0375}, + {963,1,93.1199,0.03751}, + {964,1,93.1432,0.03752}, + {965,1,93.1665,0.03753}, + {966,1,93.1898,0.03753}, + {967,1,93.213,0.03754}, + {968,1,93.2363,0.03755}, + {969,1,93.2595,0.03756}, + {970,1,93.2827,0.03757}, + {971,1,93.3059,0.03758}, + {972,1,93.329,0.03759}, + {973,1,93.3522,0.0376}, + {974,1,93.3753,0.03761}, + {975,1,93.3984,0.03762}, + {976,1,93.4215,0.03762}, + {977,1,93.4446,0.03763}, + {978,1,93.4676,0.03764}, + {979,1,93.4906,0.03765}, + {980,1,93.5137,0.03766}, + {981,1,93.5367,0.03767}, + {982,1,93.5596,0.03768}, + {983,1,93.5826,0.03769}, + {984,1,93.6056,0.03769}, + {985,1,93.6285,0.0377}, + {986,1,93.6514,0.03771}, + {987,1,93.6743,0.03772}, + {988,1,93.6972,0.03773}, + {989,1,93.7201,0.03774}, + {990,1,93.7429,0.03775}, + {991,1,93.7658,0.03776}, + {992,1,93.7886,0.03776}, + {993,1,93.8114,0.03777}, + {994,1,93.8342,0.03778}, + {995,1,93.8569,0.03779}, + {996,1,93.8797,0.0378}, + {997,1,93.9024,0.03781}, + {998,1,93.9252,0.03782}, + {999,1,93.9479,0.03782}, + {1000,1,93.9706,0.03783}, + {1001,1,93.9932,0.03784}, + {1002,1,94.0159,0.03785}, + {1003,1,94.0385,0.03786}, + {1004,1,94.0612,0.03787}, + {1005,1,94.0838,0.03788}, + {1006,1,94.1064,0.03788}, + {1007,1,94.129,0.03789}, + {1008,1,94.1516,0.0379}, + {1009,1,94.1741,0.03791}, + {1010,1,94.1967,0.03792}, + {1011,1,94.2192,0.03793}, + {1012,1,94.2417,0.03793}, + {1013,1,94.2642,0.03794}, + {1014,1,94.2867,0.03795}, + {1015,1,94.3092,0.03796}, + {1016,1,94.3317,0.03797}, + {1017,1,94.3541,0.03798}, + {1018,1,94.3765,0.03798}, + {1019,1,94.399,0.03799}, + {1020,1,94.4214,0.038}, + {1021,1,94.4438,0.03801}, + {1022,1,94.4662,0.03802}, + {1023,1,94.4885,0.03802}, + {1024,1,94.5109,0.03803}, + {1025,1,94.5332,0.03804}, + {1026,1,94.5556,0.03805}, + {1027,1,94.5779,0.03806}, + {1028,1,94.6002,0.03807}, + {1029,1,94.6225,0.03807}, + {1030,1,94.6447,0.03808}, + {1031,1,94.667,0.03809}, + {1032,1,94.6893,0.0381}, + {1033,1,94.7115,0.03811}, + {1034,1,94.7337,0.03811}, + {1035,1,94.7559,0.03812}, + {1036,1,94.7782,0.03813}, + {1037,1,94.8003,0.03814}, + {1038,1,94.8225,0.03815}, + {1039,1,94.8447,0.03815}, + {1040,1,94.8668,0.03816}, + {1041,1,94.889,0.03817}, + {1042,1,94.9111,0.03818}, + {1043,1,94.9332,0.03819}, + {1044,1,94.9553,0.03819}, + {1045,1,94.9774,0.0382}, + {1046,1,94.9995,0.03821}, + {1047,1,95.0216,0.03822}, + {1048,1,95.0436,0.03822}, + {1049,1,95.0657,0.03823}, + {1050,1,95.0877,0.03824}, + {1051,1,95.1097,0.03825}, + {1052,1,95.1317,0.03826}, + {1053,1,95.1537,0.03826}, + {1054,1,95.1757,0.03827}, + {1055,1,95.1977,0.03828}, + {1056,1,95.2197,0.03829}, + {1057,1,95.2416,0.03829}, + {1058,1,95.2636,0.0383}, + {1059,1,95.2855,0.03831}, + {1060,1,95.3074,0.03832}, + {1061,1,95.3293,0.03833}, + {1062,1,95.3512,0.03833}, + {1063,1,95.3731,0.03834}, + {1064,1,95.3949,0.03835}, + {1065,1,95.4168,0.03836}, + {1066,1,95.4386,0.03836}, + {1067,1,95.4605,0.03837}, + {1068,1,95.4823,0.03838}, + {1069,1,95.5041,0.03839}, + {1070,1,95.5259,0.03839}, + {1071,1,95.5477,0.0384}, + {1072,1,95.5695,0.03841}, + {1073,1,95.5913,0.03842}, + {1074,1,95.613,0.03842}, + {1075,1,95.6348,0.03843}, + {1076,1,95.6565,0.03844}, + {1077,1,95.6782,0.03845}, + {1078,1,95.6999,0.03845}, + {1079,1,95.7216,0.03846}, + {1080,1,95.7433,0.03847}, + {1081,1,95.765,0.03848}, + {1082,1,95.7867,0.03848}, + {1083,1,95.8083,0.03849}, + {1084,1,95.83,0.0385}, + {1085,1,95.8516,0.0385}, + {1086,1,95.8732,0.03851}, + {1087,1,95.8948,0.03852}, + {1088,1,95.9165,0.03853}, + {1089,1,95.938,0.03853}, + {1090,1,95.9596,0.03854}, + {1091,1,95.9812,0.03855}, + {1092,1,96.0028,0.03856}, + {1093,1,96.0243,0.03856}, + {1094,1,96.0459,0.03857}, + {1095,1,96.0674,0.03858}, + {1096,1,96.0889,0.03858}, + {1097,1,96.1104,0.03859}, + {1098,1,96.1319,0.0386}, + {1099,1,96.1534,0.03861}, + {1100,1,96.1749,0.03861}, + {1101,1,96.1964,0.03862}, + {1102,1,96.2178,0.03863}, + {1103,1,96.2393,0.03863}, + {1104,1,96.2607,0.03864}, + {1105,1,96.2821,0.03865}, + {1106,1,96.3035,0.03866}, + {1107,1,96.325,0.03866}, + {1108,1,96.3464,0.03867}, + {1109,1,96.3677,0.03868}, + {1110,1,96.3891,0.03868}, + {1111,1,96.4105,0.03869}, + {1112,1,96.4318,0.0387}, + {1113,1,96.4532,0.0387}, + {1114,1,96.4745,0.03871}, + {1115,1,96.4958,0.03872}, + {1116,1,96.5172,0.03873}, + {1117,1,96.5385,0.03873}, + {1118,1,96.5598,0.03874}, + {1119,1,96.581,0.03875}, + {1120,1,96.6023,0.03875}, + {1121,1,96.6236,0.03876}, + {1122,1,96.6448,0.03877}, + {1123,1,96.6661,0.03877}, + {1124,1,96.6873,0.03878}, + {1125,1,96.7085,0.03879}, + {1126,1,96.7298,0.03879}, + {1127,1,96.751,0.0388}, + {1128,1,96.7722,0.03881}, + {1129,1,96.7933,0.03881}, + {1130,1,96.8145,0.03882}, + {1131,1,96.8357,0.03883}, + {1132,1,96.8568,0.03883}, + {1133,1,96.878,0.03884}, + {1134,1,96.8991,0.03885}, + {1135,1,96.9203,0.03885}, + {1136,1,96.9414,0.03886}, + {1137,1,96.9625,0.03887}, + {1138,1,96.9836,0.03887}, + {1139,1,97.0047,0.03888}, + {1140,1,97.0258,0.03889}, + {1141,1,97.0468,0.03889}, + {1142,1,97.0679,0.0389}, + {1143,1,97.0889,0.03891}, + {1144,1,97.11,0.03891}, + {1145,1,97.131,0.03892}, + {1146,1,97.1521,0.03893}, + {1147,1,97.1731,0.03893}, + {1148,1,97.1941,0.03894}, + {1149,1,97.2151,0.03895}, + {1150,1,97.2361,0.03895}, + {1151,1,97.257,0.03896}, + {1152,1,97.278,0.03897}, + {1153,1,97.299,0.03897}, + {1154,1,97.3199,0.03898}, + {1155,1,97.3409,0.03899}, + {1156,1,97.3618,0.03899}, + {1157,1,97.3827,0.039}, + {1158,1,97.4036,0.03901}, + {1159,1,97.4245,0.03901}, + {1160,1,97.4454,0.03902}, + {1161,1,97.4663,0.03902}, + {1162,1,97.4872,0.03903}, + {1163,1,97.5081,0.03904}, + {1164,1,97.5289,0.03904}, + {1165,1,97.5498,0.03905}, + {1166,1,97.5706,0.03906}, + {1167,1,97.5914,0.03906}, + {1168,1,97.6123,0.03907}, + {1169,1,97.6331,0.03908}, + {1170,1,97.6539,0.03908}, + {1171,1,97.6747,0.03909}, + {1172,1,97.6954,0.03909}, + {1173,1,97.7162,0.0391}, + {1174,1,97.737,0.03911}, + {1175,1,97.7577,0.03911}, + {1176,1,97.7785,0.03912}, + {1177,1,97.7992,0.03913}, + {1178,1,97.8199,0.03913}, + {1179,1,97.8406,0.03914}, + {1180,1,97.8614,0.03914}, + {1181,1,97.8821,0.03915}, + {1182,1,97.9027,0.03916}, + {1183,1,97.9234,0.03916}, + {1184,1,97.9441,0.03917}, + {1185,1,97.9647,0.03917}, + {1186,1,97.9854,0.03918}, + {1187,1,98.006,0.03919}, + {1188,1,98.0267,0.03919}, + {1189,1,98.0473,0.0392}, + {1190,1,98.0679,0.0392}, + {1191,1,98.0885,0.03921}, + {1192,1,98.1091,0.03922}, + {1193,1,98.1297,0.03922}, + {1194,1,98.1503,0.03923}, + {1195,1,98.1708,0.03924}, + {1196,1,98.1914,0.03924}, + {1197,1,98.2119,0.03925}, + {1198,1,98.2325,0.03925}, + {1199,1,98.253,0.03926}, + {1200,1,98.2735,0.03927}, + {1201,1,98.294,0.03927}, + {1202,1,98.3145,0.03928}, + {1203,1,98.335,0.03928}, + {1204,1,98.3555,0.03929}, + {1205,1,98.3759,0.03929}, + {1206,1,98.3964,0.0393}, + {1207,1,98.4169,0.03931}, + {1208,1,98.4373,0.03931}, + {1209,1,98.4577,0.03932}, + {1210,1,98.4782,0.03932}, + {1211,1,98.4986,0.03933}, + {1212,1,98.519,0.03934}, + {1213,1,98.5394,0.03934}, + {1214,1,98.5598,0.03935}, + {1215,1,98.5801,0.03935}, + {1216,1,98.6005,0.03936}, + {1217,1,98.6209,0.03937}, + {1218,1,98.6412,0.03937}, + {1219,1,98.6615,0.03938}, + {1220,1,98.6819,0.03938}, + {1221,1,98.7022,0.03939}, + {1222,1,98.7225,0.03939}, + {1223,1,98.7428,0.0394}, + {1224,1,98.7631,0.03941}, + {1225,1,98.7834,0.03941}, + {1226,1,98.8036,0.03942}, + {1227,1,98.8239,0.03942}, + {1228,1,98.8442,0.03943}, + {1229,1,98.8644,0.03943}, + {1230,1,98.8846,0.03944}, + {1231,1,98.9049,0.03945}, + {1232,1,98.9251,0.03945}, + {1233,1,98.9453,0.03946}, + {1234,1,98.9655,0.03946}, + {1235,1,98.9857,0.03947}, + {1236,1,99.0058,0.03947}, + {1237,1,99.026,0.03948}, + {1238,1,99.0461,0.03949}, + {1239,1,99.0663,0.03949}, + {1240,1,99.0864,0.0395}, + {1241,1,99.1065,0.0395}, + {1242,1,99.1267,0.03951}, + {1243,1,99.1468,0.03951}, + {1244,1,99.1669,0.03952}, + {1245,1,99.1869,0.03952}, + {1246,1,99.207,0.03953}, + {1247,1,99.2271,0.03954}, + {1248,1,99.2471,0.03954}, + {1249,1,99.2672,0.03955}, + {1250,1,99.2872,0.03955}, + {1251,1,99.3072,0.03956}, + {1252,1,99.3272,0.03956}, + {1253,1,99.3472,0.03957}, + {1254,1,99.3672,0.03957}, + {1255,1,99.3872,0.03958}, + {1256,1,99.4072,0.03958}, + {1257,1,99.4272,0.03959}, + {1258,1,99.4471,0.0396}, + {1259,1,99.4671,0.0396}, + {1260,1,99.487,0.03961}, + {1261,1,99.5069,0.03961}, + {1262,1,99.5268,0.03962}, + {1263,1,99.5467,0.03962}, + {1264,1,99.5666,0.03963}, + {1265,1,99.5865,0.03963}, + {1266,1,99.6064,0.03964}, + {1267,1,99.6262,0.03964}, + {1268,1,99.6461,0.03965}, + {1269,1,99.666,0.03966}, + {1270,1,99.6858,0.03966}, + {1271,1,99.7056,0.03967}, + {1272,1,99.7254,0.03967}, + {1273,1,99.7452,0.03968}, + {1274,1,99.765,0.03968}, + {1275,1,99.7848,0.03969}, + {1276,1,99.8046,0.03969}, + {1277,1,99.8244,0.0397}, + {1278,1,99.8441,0.0397}, + {1279,1,99.8639,0.03971}, + {1280,1,99.8836,0.03971}, + {1281,1,99.9034,0.03972}, + {1282,1,99.9231,0.03972}, + {1283,1,99.9428,0.03973}, + {1284,1,99.9625,0.03973}, + {1285,1,99.9822,0.03974}, + {1286,1,100.0019,0.03975}, + {1287,1,100.0216,0.03975}, + {1288,1,100.0412,0.03976}, + {1289,1,100.0609,0.03976}, + {1290,1,100.0805,0.03977}, + {1291,1,100.1002,0.03977}, + {1292,1,100.1198,0.03978}, + {1293,1,100.1394,0.03978}, + {1294,1,100.1591,0.03979}, + {1295,1,100.1787,0.03979}, + {1296,1,100.1983,0.0398}, + {1297,1,100.2178,0.0398}, + {1298,1,100.2374,0.03981}, + {1299,1,100.257,0.03981}, + {1300,1,100.2765,0.03982}, + {1301,1,100.2961,0.03982}, + {1302,1,100.3156,0.03983}, + {1303,1,100.3352,0.03983}, + {1304,1,100.3547,0.03984}, + {1305,1,100.3742,0.03984}, + {1306,1,100.3937,0.03985}, + {1307,1,100.4132,0.03985}, + {1308,1,100.4327,0.03986}, + {1309,1,100.4522,0.03986}, + {1310,1,100.4717,0.03987}, + {1311,1,100.4911,0.03987}, + {1312,1,100.5106,0.03988}, + {1313,1,100.53,0.03988}, + {1314,1,100.5495,0.03989}, + {1315,1,100.5689,0.0399}, + {1316,1,100.5883,0.0399}, + {1317,1,100.6077,0.03991}, + {1318,1,100.6271,0.03991}, + {1319,1,100.6465,0.03992}, + {1320,1,100.6659,0.03992}, + {1321,1,100.6853,0.03993}, + {1322,1,100.7046,0.03993}, + {1323,1,100.724,0.03994}, + {1324,1,100.7434,0.03994}, + {1325,1,100.7627,0.03995}, + {1326,1,100.782,0.03995}, + {1327,1,100.8013,0.03996}, + {1328,1,100.8207,0.03996}, + {1329,1,100.84,0.03997}, + {1330,1,100.8593,0.03997}, + {1331,1,100.8786,0.03998}, + {1332,1,100.8978,0.03998}, + {1333,1,100.9171,0.03999}, + {1334,1,100.9364,0.03999}, + {1335,1,100.9556,0.04}, + {1336,1,100.9749,0.04}, + {1337,1,100.9941,0.04001}, + {1338,1,101.0134,0.04001}, + {1339,1,101.0326,0.04002}, + {1340,1,101.0518,0.04002}, + {1341,1,101.071,0.04003}, + {1342,1,101.0902,0.04003}, + {1343,1,101.1094,0.04004}, + {1344,1,101.1286,0.04004}, + {1345,1,101.1477,0.04004}, + {1346,1,101.1669,0.04005}, + {1347,1,101.1861,0.04005}, + {1348,1,101.2052,0.04006}, + {1349,1,101.2244,0.04006}, + {1350,1,101.2435,0.04007}, + {1351,1,101.2626,0.04007}, + {1352,1,101.2817,0.04008}, + {1353,1,101.3008,0.04008}, + {1354,1,101.32,0.04009}, + {1355,1,101.339,0.04009}, + {1356,1,101.3581,0.0401}, + {1357,1,101.3772,0.0401}, + {1358,1,101.3963,0.04011}, + {1359,1,101.4153,0.04011}, + {1360,1,101.4344,0.04012}, + {1361,1,101.4535,0.04012}, + {1362,1,101.4725,0.04013}, + {1363,1,101.4915,0.04013}, + {1364,1,101.5106,0.04014}, + {1365,1,101.5296,0.04014}, + {1366,1,101.5486,0.04015}, + {1367,1,101.5676,0.04015}, + {1368,1,101.5866,0.04016}, + {1369,1,101.6056,0.04016}, + {1370,1,101.6246,0.04017}, + {1371,1,101.6435,0.04017}, + {1372,1,101.6625,0.04018}, + {1373,1,101.6815,0.04018}, + {1374,1,101.7004,0.04019}, + {1375,1,101.7194,0.04019}, + {1376,1,101.7383,0.0402}, + {1377,1,101.7572,0.0402}, + {1378,1,101.7762,0.0402}, + {1379,1,101.7951,0.04021}, + {1380,1,101.814,0.04021}, + {1381,1,101.8329,0.04022}, + {1382,1,101.8518,0.04022}, + {1383,1,101.8707,0.04023}, + {1384,1,101.8896,0.04023}, + {1385,1,101.9085,0.04024}, + {1386,1,101.9274,0.04024}, + {1387,1,101.9462,0.04025}, + {1388,1,101.9651,0.04025}, + {1389,1,101.9839,0.04026}, + {1390,1,102.0028,0.04026}, + {1391,1,102.0216,0.04027}, + {1392,1,102.0405,0.04027}, + {1393,1,102.0593,0.04028}, + {1394,1,102.0781,0.04028}, + {1395,1,102.097,0.04029}, + {1396,1,102.1158,0.04029}, + {1397,1,102.1346,0.0403}, + {1398,1,102.1534,0.0403}, + {1399,1,102.1722,0.0403}, + {1400,1,102.191,0.04031}, + {1401,1,102.2097,0.04031}, + {1402,1,102.2285,0.04032}, + {1403,1,102.2473,0.04032}, + {1404,1,102.2661,0.04033}, + {1405,1,102.2848,0.04033}, + {1406,1,102.3036,0.04034}, + {1407,1,102.3223,0.04034}, + {1408,1,102.3411,0.04035}, + {1409,1,102.3598,0.04035}, + {1410,1,102.3785,0.04036}, + {1411,1,102.3972,0.04036}, + {1412,1,102.416,0.04037}, + {1413,1,102.4347,0.04037}, + {1414,1,102.4534,0.04037}, + {1415,1,102.4721,0.04038}, + {1416,1,102.4908,0.04038}, + {1417,1,102.5095,0.04039}, + {1418,1,102.5282,0.04039}, + {1419,1,102.5469,0.0404}, + {1420,1,102.5655,0.0404}, + {1421,1,102.5842,0.04041}, + {1422,1,102.6029,0.04041}, + {1423,1,102.6215,0.04042}, + {1424,1,102.6402,0.04042}, + {1425,1,102.6588,0.04043}, + {1426,1,102.6775,0.04043}, + {1427,1,102.6961,0.04044}, + {1428,1,102.7148,0.04044}, + {1429,1,102.7334,0.04044}, + {1430,1,102.752,0.04045}, + {1431,1,102.7706,0.04045}, + {1432,1,102.7893,0.04046}, + {1433,1,102.8079,0.04046}, + {1434,1,102.8265,0.04047}, + {1435,1,102.8451,0.04047}, + {1436,1,102.8637,0.04048}, + {1437,1,102.8823,0.04048}, + {1438,1,102.9009,0.04049}, + {1439,1,102.9195,0.04049}, + {1440,1,102.938,0.0405}, + {1441,1,102.9566,0.0405}, + {1442,1,102.9752,0.0405}, + {1443,1,102.9938,0.04051}, + {1444,1,103.0123,0.04051}, + {1445,1,103.0309,0.04052}, + {1446,1,103.0494,0.04052}, + {1447,1,103.068,0.04053}, + {1448,1,103.0865,0.04053}, + {1449,1,103.1051,0.04054}, + {1450,1,103.1236,0.04054}, + {1451,1,103.1421,0.04055}, + {1452,1,103.1607,0.04055}, + {1453,1,103.1792,0.04055}, + {1454,1,103.1977,0.04056}, + {1455,1,103.2162,0.04056}, + {1456,1,103.2348,0.04057}, + {1457,1,103.2533,0.04057}, + {1458,1,103.2718,0.04058}, + {1459,1,103.2903,0.04058}, + {1460,1,103.3088,0.04059}, + {1461,1,103.3273,0.04059}, + {1462,1,103.3458,0.0406}, + {1463,1,103.3643,0.0406}, + {1464,1,103.3827,0.0406}, + {1465,1,103.4012,0.04061}, + {1466,1,103.4197,0.04061}, + {1467,1,103.4382,0.04062}, + {1468,1,103.4566,0.04062}, + {1469,1,103.4751,0.04063}, + {1470,1,103.4936,0.04063}, + {1471,1,103.512,0.04064}, + {1472,1,103.5305,0.04064}, + {1473,1,103.5489,0.04065}, + {1474,1,103.5674,0.04065}, + {1475,1,103.5858,0.04065}, + {1476,1,103.6043,0.04066}, + {1477,1,103.6227,0.04066}, + {1478,1,103.6412,0.04067}, + {1479,1,103.6596,0.04067}, + {1480,1,103.678,0.04068}, + {1481,1,103.6965,0.04068}, + {1482,1,103.7149,0.04069}, + {1483,1,103.7333,0.04069}, + {1484,1,103.7517,0.04069}, + {1485,1,103.7701,0.0407}, + {1486,1,103.7885,0.0407}, + {1487,1,103.807,0.04071}, + {1488,1,103.8254,0.04071}, + {1489,1,103.8438,0.04072}, + {1490,1,103.8622,0.04072}, + {1491,1,103.8806,0.04073}, + {1492,1,103.899,0.04073}, + {1493,1,103.9174,0.04073}, + {1494,1,103.9357,0.04074}, + {1495,1,103.9541,0.04074}, + {1496,1,103.9725,0.04075}, + {1497,1,103.9909,0.04075}, + {1498,1,104.0093,0.04076}, + {1499,1,104.0277,0.04076}, + {1500,1,104.046,0.04077}, + {1501,1,104.0644,0.04077}, + {1502,1,104.0828,0.04078}, + {1503,1,104.1011,0.04078}, + {1504,1,104.1195,0.04078}, + {1505,1,104.1379,0.04079}, + {1506,1,104.1562,0.04079}, + {1507,1,104.1746,0.0408}, + {1508,1,104.1929,0.0408}, + {1509,1,104.2113,0.04081}, + {1510,1,104.2296,0.04081}, + {1511,1,104.248,0.04082}, + {1512,1,104.2663,0.04082}, + {1513,1,104.2847,0.04082}, + {1514,1,104.303,0.04083}, + {1515,1,104.3213,0.04083}, + {1516,1,104.3397,0.04084}, + {1517,1,104.358,0.04084}, + {1518,1,104.3763,0.04085}, + {1519,1,104.3947,0.04085}, + {1520,1,104.413,0.04086}, + {1521,1,104.4313,0.04086}, + {1522,1,104.4496,0.04086}, + {1523,1,104.4679,0.04087}, + {1524,1,104.4863,0.04087}, + {1525,1,104.5046,0.04088}, + {1526,1,104.5229,0.04088}, + {1527,1,104.5412,0.04089}, + {1528,1,104.5595,0.04089}, + {1529,1,104.5778,0.04089}, + {1530,1,104.5961,0.0409}, + {1531,1,104.6144,0.0409}, + {1532,1,104.6327,0.04091}, + {1533,1,104.651,0.04091}, + {1534,1,104.6693,0.04092}, + {1535,1,104.6876,0.04092}, + {1536,1,104.7059,0.04093}, + {1537,1,104.7242,0.04093}, + {1538,1,104.7425,0.04093}, + {1539,1,104.7608,0.04094}, + {1540,1,104.7791,0.04094}, + {1541,1,104.7974,0.04095}, + {1542,1,104.8157,0.04095}, + {1543,1,104.8339,0.04096}, + {1544,1,104.8522,0.04096}, + {1545,1,104.8705,0.04097}, + {1546,1,104.8888,0.04097}, + {1547,1,104.9071,0.04097}, + {1548,1,104.9253,0.04098}, + {1549,1,104.9436,0.04098}, + {1550,1,104.9619,0.04099}, + {1551,1,104.9802,0.04099}, + {1552,1,104.9984,0.041}, + {1553,1,105.0167,0.041}, + {1554,1,105.035,0.041}, + {1555,1,105.0532,0.04101}, + {1556,1,105.0715,0.04101}, + {1557,1,105.0898,0.04102}, + {1558,1,105.108,0.04102}, + {1559,1,105.1263,0.04103}, + {1560,1,105.1445,0.04103}, + {1561,1,105.1628,0.04104}, + {1562,1,105.1811,0.04104}, + {1563,1,105.1993,0.04104}, + {1564,1,105.2176,0.04105}, + {1565,1,105.2358,0.04105}, + {1566,1,105.2541,0.04106}, + {1567,1,105.2723,0.04106}, + {1568,1,105.2906,0.04107}, + {1569,1,105.3088,0.04107}, + {1570,1,105.3271,0.04107}, + {1571,1,105.3453,0.04108}, + {1572,1,105.3635,0.04108}, + {1573,1,105.3818,0.04109}, + {1574,1,105.4,0.04109}, + {1575,1,105.4183,0.0411}, + {1576,1,105.4365,0.0411}, + {1577,1,105.4547,0.04111}, + {1578,1,105.473,0.04111}, + {1579,1,105.4912,0.04111}, + {1580,1,105.5094,0.04112}, + {1581,1,105.5277,0.04112}, + {1582,1,105.5459,0.04113}, + {1583,1,105.5641,0.04113}, + {1584,1,105.5824,0.04114}, + {1585,1,105.6006,0.04114}, + {1586,1,105.6188,0.04114}, + {1587,1,105.637,0.04115}, + {1588,1,105.6553,0.04115}, + {1589,1,105.6735,0.04116}, + {1590,1,105.6917,0.04116}, + {1591,1,105.7099,0.04117}, + {1592,1,105.7281,0.04117}, + {1593,1,105.7463,0.04117}, + {1594,1,105.7646,0.04118}, + {1595,1,105.7828,0.04118}, + {1596,1,105.801,0.04119}, + {1597,1,105.8192,0.04119}, + {1598,1,105.8374,0.0412}, + {1599,1,105.8556,0.0412}, + {1600,1,105.8738,0.0412}, + {1601,1,105.892,0.04121}, + {1602,1,105.9102,0.04121}, + {1603,1,105.9284,0.04122}, + {1604,1,105.9466,0.04122}, + {1605,1,105.9648,0.04123}, + {1606,1,105.983,0.04123}, + {1607,1,106.0012,0.04123}, + {1608,1,106.0194,0.04124}, + {1609,1,106.0376,0.04124}, + {1610,1,106.0558,0.04125}, + {1611,1,106.074,0.04125}, + {1612,1,106.0922,0.04126}, + {1613,1,106.1104,0.04126}, + {1614,1,106.1286,0.04127}, + {1615,1,106.1467,0.04127}, + {1616,1,106.1649,0.04127}, + {1617,1,106.1831,0.04128}, + {1618,1,106.2013,0.04128}, + {1619,1,106.2195,0.04129}, + {1620,1,106.2377,0.04129}, + {1621,1,106.2558,0.0413}, + {1622,1,106.274,0.0413}, + {1623,1,106.2922,0.0413}, + {1624,1,106.3104,0.04131}, + {1625,1,106.3285,0.04131}, + {1626,1,106.3467,0.04132}, + {1627,1,106.3649,0.04132}, + {1628,1,106.3831,0.04132}, + {1629,1,106.4012,0.04133}, + {1630,1,106.4194,0.04133}, + {1631,1,106.4376,0.04134}, + {1632,1,106.4557,0.04134}, + {1633,1,106.4739,0.04135}, + {1634,1,106.4921,0.04135}, + {1635,1,106.5102,0.04135}, + {1636,1,106.5284,0.04136}, + {1637,1,106.5465,0.04136}, + {1638,1,106.5647,0.04137}, + {1639,1,106.5829,0.04137}, + {1640,1,106.601,0.04138}, + {1641,1,106.6192,0.04138}, + {1642,1,106.6373,0.04138}, + {1643,1,106.6555,0.04139}, + {1644,1,106.6736,0.04139}, + {1645,1,106.6918,0.0414}, + {1646,1,106.7099,0.0414}, + {1647,1,106.7281,0.04141}, + {1648,1,106.7462,0.04141}, + {1649,1,106.7644,0.04141}, + {1650,1,106.7825,0.04142}, + {1651,1,106.8006,0.04142}, + {1652,1,106.8188,0.04143}, + {1653,1,106.8369,0.04143}, + {1654,1,106.8551,0.04144}, + {1655,1,106.8732,0.04144}, + {1656,1,106.8913,0.04144}, + {1657,1,106.9095,0.04145}, + {1658,1,106.9276,0.04145}, + {1659,1,106.9457,0.04146}, + {1660,1,106.9639,0.04146}, + {1661,1,106.982,0.04147}, + {1662,1,107.0001,0.04147}, + {1663,1,107.0183,0.04147}, + {1664,1,107.0364,0.04148}, + {1665,1,107.0545,0.04148}, + {1666,1,107.0727,0.04149}, + {1667,1,107.0908,0.04149}, + {1668,1,107.1089,0.04149}, + {1669,1,107.127,0.0415}, + {1670,1,107.1452,0.0415}, + {1671,1,107.1633,0.04151}, + {1672,1,107.1814,0.04151}, + {1673,1,107.1995,0.04152}, + {1674,1,107.2176,0.04152}, + {1675,1,107.2358,0.04152}, + {1676,1,107.2539,0.04153}, + {1677,1,107.272,0.04153}, + {1678,1,107.2901,0.04154}, + {1679,1,107.3082,0.04154}, + {1680,1,107.3263,0.04154}, + {1681,1,107.3444,0.04155}, + {1682,1,107.3625,0.04155}, + {1683,1,107.3806,0.04156}, + {1684,1,107.3988,0.04156}, + {1685,1,107.4169,0.04157}, + {1686,1,107.435,0.04157}, + {1687,1,107.4531,0.04157}, + {1688,1,107.4712,0.04158}, + {1689,1,107.4893,0.04158}, + {1690,1,107.5074,0.04159}, + {1691,1,107.5255,0.04159}, + {1692,1,107.5436,0.0416}, + {1693,1,107.5617,0.0416}, + {1694,1,107.5798,0.0416}, + {1695,1,107.5979,0.04161}, + {1696,1,107.616,0.04161}, + {1697,1,107.6341,0.04162}, + {1698,1,107.6522,0.04162}, + {1699,1,107.6702,0.04162}, + {1700,1,107.6883,0.04163}, + {1701,1,107.7064,0.04163}, + {1702,1,107.7245,0.04164}, + {1703,1,107.7426,0.04164}, + {1704,1,107.7607,0.04165}, + {1705,1,107.7788,0.04165}, + {1706,1,107.7969,0.04165}, + {1707,1,107.8149,0.04166}, + {1708,1,107.833,0.04166}, + {1709,1,107.8511,0.04167}, + {1710,1,107.8692,0.04167}, + {1711,1,107.8873,0.04167}, + {1712,1,107.9053,0.04168}, + {1713,1,107.9234,0.04168}, + {1714,1,107.9415,0.04169}, + {1715,1,107.9596,0.04169}, + {1716,1,107.9777,0.04169}, + {1717,1,107.9957,0.0417}, + {1718,1,108.0138,0.0417}, + {1719,1,108.0319,0.04171}, + {1720,1,108.0499,0.04171}, + {1721,1,108.068,0.04172}, + {1722,1,108.0861,0.04172}, + {1723,1,108.1041,0.04172}, + {1724,1,108.1222,0.04173}, + {1725,1,108.1403,0.04173}, + {1726,1,108.1583,0.04174}, + {1727,1,108.1764,0.04174}, + {1728,1,108.1945,0.04174}, + {1729,1,108.2125,0.04175}, + {1730,1,108.2306,0.04175}, + {1731,1,108.2487,0.04176}, + {1732,1,108.2667,0.04176}, + {1733,1,108.2848,0.04176}, + {1734,1,108.3028,0.04177}, + {1735,1,108.3209,0.04177}, + {1736,1,108.3389,0.04178}, + {1737,1,108.357,0.04178}, + {1738,1,108.375,0.04179}, + {1739,1,108.3931,0.04179}, + {1740,1,108.4112,0.04179}, + {1741,1,108.4292,0.0418}, + {1742,1,108.4473,0.0418}, + {1743,1,108.4653,0.04181}, + {1744,1,108.4833,0.04181}, + {1745,1,108.5014,0.04181}, + {1746,1,108.5194,0.04182}, + {1747,1,108.5375,0.04182}, + {1748,1,108.5555,0.04183}, + {1749,1,108.5736,0.04183}, + {1750,1,108.5916,0.04183}, + {1751,1,108.6097,0.04184}, + {1752,1,108.6277,0.04184}, + {1753,1,108.6457,0.04185}, + {1754,1,108.6638,0.04185}, + {1755,1,108.6818,0.04185}, + {1756,1,108.6998,0.04186}, + {1757,1,108.7179,0.04186}, + {1758,1,108.7359,0.04187}, + {1759,1,108.7539,0.04187}, + {1760,1,108.772,0.04188}, + {1761,1,108.79,0.04188}, + {1762,1,108.808,0.04188}, + {1763,1,108.8261,0.04189}, + {1764,1,108.8441,0.04189}, + {1765,1,108.8621,0.0419}, + {1766,1,108.8801,0.0419}, + {1767,1,108.8982,0.0419}, + {1768,1,108.9162,0.04191}, + {1769,1,108.9342,0.04191}, + {1770,1,108.9522,0.04192}, + {1771,1,108.9702,0.04192}, + {1772,1,108.9883,0.04192}, + {1773,1,109.0063,0.04193}, + {1774,1,109.0243,0.04193}, + {1775,1,109.0423,0.04194}, + {1776,1,109.0603,0.04194}, + {1777,1,109.0783,0.04194}, + {1778,1,109.0963,0.04195}, + {1779,1,109.1144,0.04195}, + {1780,1,109.1324,0.04196}, + {1781,1,109.1504,0.04196}, + {1782,1,109.1684,0.04196}, + {1783,1,109.1864,0.04197}, + {1784,1,109.2044,0.04197}, + {1785,1,109.2224,0.04198}, + {1786,1,109.2404,0.04198}, + {1787,1,109.2584,0.04198}, + {1788,1,109.2764,0.04199}, + {1789,1,109.2944,0.04199}, + {1790,1,109.3124,0.042}, + {1791,1,109.3304,0.042}, + {1792,1,109.3484,0.042}, + {1793,1,109.3664,0.04201}, + {1794,1,109.3843,0.04201}, + {1795,1,109.4023,0.04202}, + {1796,1,109.4203,0.04202}, + {1797,1,109.4383,0.04202}, + {1798,1,109.4563,0.04203}, + {1799,1,109.4743,0.04203}, + {1800,1,109.4923,0.04204}, + {1801,1,109.5102,0.04204}, + {1802,1,109.5282,0.04204}, + {1803,1,109.5462,0.04205}, + {1804,1,109.5642,0.04205}, + {1805,1,109.5822,0.04206}, + {1806,1,109.6001,0.04206}, + {1807,1,109.6181,0.04206}, + {1808,1,109.6361,0.04207}, + {1809,1,109.654,0.04207}, + {1810,1,109.672,0.04208}, + {1811,1,109.69,0.04208}, + {1812,1,109.7079,0.04208}, + {1813,1,109.7259,0.04209}, + {1814,1,109.7439,0.04209}, + {1815,1,109.7618,0.0421}, + {1816,1,109.7798,0.0421}, + {1817,1,109.7978,0.0421}, + {1818,1,109.8157,0.04211}, + {1819,1,109.8337,0.04211}, + {1820,1,109.8516,0.04212}, + {1821,1,109.8696,0.04212}, + {1822,1,109.8875,0.04212}, + {1823,1,109.9055,0.04213}, + {1824,1,109.9234,0.04213}, + {1825,1,109.9414,0.04214}, + {1826,1,109.9593,0.04214}, + {1827,1,109.9773,0.04214}, + {1828,1,109.9952,0.04215}, + {1829,1,110.0131,0.04215}, + {1830,1,110.0311,0.04216}, + {1831,1,110.049,0.04216}, + {1832,1,110.0669,0.04216}, + {1833,1,110.0849,0.04217}, + {1834,1,110.1028,0.04217}, + {1835,1,110.1207,0.04218}, + {1836,1,110.1387,0.04218}, + {1837,1,110.1566,0.04218}, + {1838,1,110.1745,0.04219}, + {1839,1,110.1924,0.04219}, + {1840,1,110.2104,0.0422}, + {1841,1,110.2283,0.0422}, + {1842,1,110.2462,0.0422}, + {1843,1,110.2641,0.04221}, + {1844,1,110.282,0.04221}, + {1845,1,110.3,0.04222}, + {1846,1,110.3179,0.04222}, + {1847,1,110.3358,0.04222}, + {1848,1,110.3537,0.04223}, + {1849,1,110.3716,0.04223}, + {1850,1,110.3895,0.04223}, + {1851,1,110.4074,0.04224}, + {1852,1,110.4253,0.04224}, + {1853,1,110.4432,0.04225}, + {1854,1,110.4611,0.04225}, + {1855,1,110.479,0.04225}, + {1856,1,110.4969,0.04226} + }; + return boysLengthForAge[index < boysLengthForAge.length ? index : boysLengthForAge.length]; + } + + public double[]getGirlsLengthForAge(int index){ + double[][]girlsLengthForAge = { + {0,1,49.1477,0.0379}, + {1,1,49.3166,0.03783}, + {2,1,49.4854,0.03776}, + {3,1,49.6543,0.0377}, + {4,1,49.8232,0.03763}, + {5,1,49.9921,0.03756}, + {6,1,50.1609,0.03749}, + {7,1,50.3298,0.03742}, + {8,1,50.4987,0.03735}, + {9,1,50.6676,0.03728}, + {10,1,50.8365,0.03722}, + {11,1,51.0053,0.03715}, + {12,1,51.1742,0.03708}, + {13,1,51.3431,0.03701}, + {14,1,51.512,0.03694}, + {15,1,51.651,0.0369}, + {16,1,51.7895,0.03687}, + {17,1,51.9272,0.03683}, + {18,1,52.0641,0.0368}, + {19,1,52.2002,0.03676}, + {20,1,52.3353,0.03673}, + {21,1,52.4695,0.03669}, + {22,1,52.6027,0.03666}, + {23,1,52.7349,0.03663}, + {24,1,52.8661,0.0366}, + {25,1,52.9963,0.03656}, + {26,1,53.1255,0.03653}, + {27,1,53.2537,0.0365}, + {28,1,53.3809,0.03647}, + {29,1,53.5072,0.03644}, + {30,1,53.6326,0.03641}, + {31,1,53.7571,0.03638}, + {32,1,53.8806,0.03636}, + {33,1,54.0031,0.03633}, + {34,1,54.1247,0.0363}, + {35,1,54.2454,0.03627}, + {36,1,54.3651,0.03625}, + {37,1,54.4839,0.03622}, + {38,1,54.6018,0.03619}, + {39,1,54.7187,0.03617}, + {40,1,54.8348,0.03614}, + {41,1,54.9499,0.03612}, + {42,1,55.0642,0.03609}, + {43,1,55.1777,0.03607}, + {44,1,55.2903,0.03604}, + {45,1,55.4021,0.03602}, + {46,1,55.513,0.036}, + {47,1,55.623,0.03597}, + {48,1,55.7322,0.03595}, + {49,1,55.8406,0.03593}, + {50,1,55.9482,0.03591}, + {51,1,56.0549,0.03588}, + {52,1,56.1609,0.03586}, + {53,1,56.266,0.03584}, + {54,1,56.3704,0.03582}, + {55,1,56.4739,0.0358}, + {56,1,56.5767,0.03578}, + {57,1,56.6788,0.03576}, + {58,1,56.78,0.03574}, + {59,1,56.8806,0.03572}, + {60,1,56.9805,0.0357}, + {61,1,57.0796,0.03568}, + {62,1,57.1782,0.03566}, + {63,1,57.2761,0.03564}, + {64,1,57.3733,0.03562}, + {65,1,57.4699,0.03561}, + {66,1,57.5659,0.03559}, + {67,1,57.6613,0.03557}, + {68,1,57.756,0.03555}, + {69,1,57.8501,0.03553}, + {70,1,57.9436,0.03552}, + {71,1,58.0365,0.0355}, + {72,1,58.1288,0.03548}, + {73,1,58.2206,0.03547}, + {74,1,58.3117,0.03545}, + {75,1,58.4022,0.03543}, + {76,1,58.4922,0.03542}, + {77,1,58.5816,0.0354}, + {78,1,58.6705,0.03539}, + {79,1,58.7588,0.03537}, + {80,1,58.8465,0.03536}, + {81,1,58.9337,0.03534}, + {82,1,59.0204,0.03533}, + {83,1,59.1066,0.03531}, + {84,1,59.1922,0.0353}, + {85,1,59.2773,0.03528}, + {86,1,59.3619,0.03527}, + {87,1,59.4459,0.03526}, + {88,1,59.5295,0.03524}, + {89,1,59.6126,0.03523}, + {90,1,59.6952,0.03521}, + {91,1,59.7773,0.0352}, + {92,1,59.8589,0.03519}, + {93,1,59.9401,0.03517}, + {94,1,60.0209,0.03516}, + {95,1,60.1011,0.03515}, + {96,1,60.181,0.03514}, + {97,1,60.2603,0.03512}, + {98,1,60.3393,0.03511}, + {99,1,60.4178,0.0351}, + {100,1,60.4958,0.03509}, + {101,1,60.5734,0.03508}, + {102,1,60.6506,0.03506}, + {103,1,60.7273,0.03505}, + {104,1,60.8036,0.03504}, + {105,1,60.8795,0.03503}, + {106,1,60.955,0.03502}, + {107,1,61.0301,0.03501}, + {108,1,61.1047,0.035}, + {109,1,61.1789,0.03499}, + {110,1,61.2527,0.03497}, + {111,1,61.3261,0.03496}, + {112,1,61.3991,0.03495}, + {113,1,61.4717,0.03494}, + {114,1,61.5439,0.03493}, + {115,1,61.6156,0.03492}, + {116,1,61.687,0.03491}, + {117,1,61.758,0.0349}, + {118,1,61.8286,0.03489}, + {119,1,61.8988,0.03488}, + {120,1,61.9686,0.03487}, + {121,1,62.0381,0.03487}, + {122,1,62.1071,0.03486}, + {123,1,62.1758,0.03485}, + {124,1,62.2441,0.03484}, + {125,1,62.312,0.03483}, + {126,1,62.3795,0.03482}, + {127,1,62.4467,0.03481}, + {128,1,62.5135,0.0348}, + {129,1,62.58,0.03479}, + {130,1,62.6461,0.03479}, + {131,1,62.7118,0.03478}, + {132,1,62.7772,0.03477}, + {133,1,62.8423,0.03476}, + {134,1,62.907,0.03475}, + {135,1,62.9714,0.03475}, + {136,1,63.0354,0.03474}, + {137,1,63.0991,0.03473}, + {138,1,63.1626,0.03472}, + {139,1,63.2257,0.03471}, + {140,1,63.2884,0.03471}, + {141,1,63.3509,0.0347}, + {142,1,63.4131,0.03469}, + {143,1,63.475,0.03469}, + {144,1,63.5365,0.03468}, + {145,1,63.5978,0.03467}, + {146,1,63.6588,0.03467}, + {147,1,63.7196,0.03466}, + {148,1,63.78,0.03465}, + {149,1,63.8402,0.03465}, + {150,1,63.9,0.03464}, + {151,1,63.9597,0.03463}, + {152,1,64.019,0.03463}, + {153,1,64.0781,0.03462}, + {154,1,64.137,0.03461}, + {155,1,64.1956,0.03461}, + {156,1,64.2539,0.0346}, + {157,1,64.312,0.0346}, + {158,1,64.3699,0.03459}, + {159,1,64.4276,0.03459}, + {160,1,64.485,0.03458}, + {161,1,64.5422,0.03457}, + {162,1,64.5991,0.03457}, + {163,1,64.6559,0.03456}, + {164,1,64.7124,0.03456}, + {165,1,64.7688,0.03455}, + {166,1,64.8249,0.03455}, + {167,1,64.8808,0.03454}, + {168,1,64.9366,0.03454}, + {169,1,64.9921,0.03453}, + {170,1,65.0474,0.03453}, + {171,1,65.1026,0.03453}, + {172,1,65.1576,0.03452}, + {173,1,65.2123,0.03452}, + {174,1,65.267,0.03451}, + {175,1,65.3214,0.03451}, + {176,1,65.3757,0.0345}, + {177,1,65.4298,0.0345}, + {178,1,65.4837,0.0345}, + {179,1,65.5375,0.03449}, + {180,1,65.5911,0.03449}, + {181,1,65.6445,0.03449}, + {182,1,65.6978,0.03448}, + {183,1,65.751,0.03448}, + {184,1,65.804,0.03447}, + {185,1,65.8568,0.03447}, + {186,1,65.9095,0.03447}, + {187,1,65.9621,0.03447}, + {188,1,66.0145,0.03446}, + {189,1,66.0668,0.03446}, + {190,1,66.1189,0.03446}, + {191,1,66.1709,0.03445}, + {192,1,66.2228,0.03445}, + {193,1,66.2745,0.03445}, + {194,1,66.3261,0.03444}, + {195,1,66.3776,0.03444}, + {196,1,66.429,0.03444}, + {197,1,66.4802,0.03444}, + {198,1,66.5313,0.03444}, + {199,1,66.5823,0.03443}, + {200,1,66.6331,0.03443}, + {201,1,66.6839,0.03443}, + {202,1,66.7345,0.03443}, + {203,1,66.785,0.03442}, + {204,1,66.8354,0.03442}, + {205,1,66.8857,0.03442}, + {206,1,66.9359,0.03442}, + {207,1,66.9859,0.03442}, + {208,1,67.0359,0.03442}, + {209,1,67.0858,0.03441}, + {210,1,67.1355,0.03441}, + {211,1,67.1852,0.03441}, + {212,1,67.2347,0.03441}, + {213,1,67.2842,0.03441}, + {214,1,67.3335,0.03441}, + {215,1,67.3828,0.03441}, + {216,1,67.432,0.03441}, + {217,1,67.481,0.0344}, + {218,1,67.53,0.0344}, + {219,1,67.5789,0.0344}, + {220,1,67.6277,0.0344}, + {221,1,67.6764,0.0344}, + {222,1,67.725,0.0344}, + {223,1,67.7735,0.0344}, + {224,1,67.8219,0.0344}, + {225,1,67.8703,0.0344}, + {226,1,67.9185,0.0344}, + {227,1,67.9667,0.0344}, + {228,1,68.0148,0.0344}, + {229,1,68.0628,0.0344}, + {230,1,68.1107,0.0344}, + {231,1,68.1585,0.0344}, + {232,1,68.2063,0.0344}, + {233,1,68.254,0.0344}, + {234,1,68.3016,0.0344}, + {235,1,68.3491,0.0344}, + {236,1,68.3965,0.0344}, + {237,1,68.4439,0.0344}, + {238,1,68.4911,0.0344}, + {239,1,68.5383,0.0344}, + {240,1,68.5855,0.0344}, + {241,1,68.6325,0.0344}, + {242,1,68.6795,0.0344}, + {243,1,68.7264,0.0344}, + {244,1,68.7732,0.0344}, + {245,1,68.82,0.0344}, + {246,1,68.8666,0.0344}, + {247,1,68.9133,0.0344}, + {248,1,68.9598,0.0344}, + {249,1,69.0063,0.0344}, + {250,1,69.0527,0.0344}, + {251,1,69.099,0.03441}, + {252,1,69.1452,0.03441}, + {253,1,69.1914,0.03441}, + {254,1,69.2376,0.03441}, + {255,1,69.2836,0.03441}, + {256,1,69.3296,0.03441}, + {257,1,69.3755,0.03441}, + {258,1,69.4214,0.03441}, + {259,1,69.4672,0.03441}, + {260,1,69.5129,0.03442}, + {261,1,69.5585,0.03442}, + {262,1,69.6041,0.03442}, + {263,1,69.6496,0.03442}, + {264,1,69.6951,0.03442}, + {265,1,69.7405,0.03442}, + {266,1,69.7858,0.03443}, + {267,1,69.8311,0.03443}, + {268,1,69.8763,0.03443}, + {269,1,69.9215,0.03443}, + {270,1,69.9666,0.03443}, + {271,1,70.0116,0.03444}, + {272,1,70.0566,0.03444}, + {273,1,70.1015,0.03444}, + {274,1,70.1463,0.03444}, + {275,1,70.1911,0.03444}, + {276,1,70.2358,0.03445}, + {277,1,70.2805,0.03445}, + {278,1,70.3251,0.03445}, + {279,1,70.3697,0.03445}, + {280,1,70.4142,0.03445}, + {281,1,70.4586,0.03446}, + {282,1,70.503,0.03446}, + {283,1,70.5474,0.03446}, + {284,1,70.5917,0.03446}, + {285,1,70.6359,0.03447}, + {286,1,70.68,0.03447}, + {287,1,70.7241,0.03447}, + {288,1,70.7682,0.03448}, + {289,1,70.8122,0.03448}, + {290,1,70.8561,0.03448}, + {291,1,70.9,0.03448}, + {292,1,70.9439,0.03449}, + {293,1,70.9876,0.03449}, + {294,1,71.0314,0.03449}, + {295,1,71.075,0.0345}, + {296,1,71.1187,0.0345}, + {297,1,71.1622,0.0345}, + {298,1,71.2057,0.0345}, + {299,1,71.2492,0.03451}, + {300,1,71.2926,0.03451}, + {301,1,71.3359,0.03451}, + {302,1,71.3792,0.03452}, + {303,1,71.4224,0.03452}, + {304,1,71.4656,0.03452}, + {305,1,71.5088,0.03453}, + {306,1,71.5518,0.03453}, + {307,1,71.5949,0.03453}, + {308,1,71.6378,0.03454}, + {309,1,71.6808,0.03454}, + {310,1,71.7236,0.03454}, + {311,1,71.7664,0.03455}, + {312,1,71.8092,0.03455}, + {313,1,71.8519,0.03456}, + {314,1,71.8946,0.03456}, + {315,1,71.9372,0.03456}, + {316,1,71.9798,0.03457}, + {317,1,72.0223,0.03457}, + {318,1,72.0647,0.03457}, + {319,1,72.1071,0.03458}, + {320,1,72.1495,0.03458}, + {321,1,72.1918,0.03459}, + {322,1,72.234,0.03459}, + {323,1,72.2762,0.03459}, + {324,1,72.3184,0.0346}, + {325,1,72.3605,0.0346}, + {326,1,72.4025,0.03461}, + {327,1,72.4445,0.03461}, + {328,1,72.4865,0.03461}, + {329,1,72.5284,0.03462}, + {330,1,72.5702,0.03462}, + {331,1,72.612,0.03463}, + {332,1,72.6538,0.03463}, + {333,1,72.6955,0.03464}, + {334,1,72.7372,0.03464}, + {335,1,72.7788,0.03464}, + {336,1,72.8203,0.03465}, + {337,1,72.8618,0.03465}, + {338,1,72.9033,0.03466}, + {339,1,72.9447,0.03466}, + {340,1,72.9861,0.03467}, + {341,1,73.0274,0.03467}, + {342,1,73.0686,0.03468}, + {343,1,73.1099,0.03468}, + {344,1,73.151,0.03469}, + {345,1,73.1922,0.03469}, + {346,1,73.2332,0.03469}, + {347,1,73.2743,0.0347}, + {348,1,73.3152,0.0347}, + {349,1,73.3562,0.03471}, + {350,1,73.3971,0.03471}, + {351,1,73.4379,0.03472}, + {352,1,73.4787,0.03472}, + {353,1,73.5195,0.03473}, + {354,1,73.5602,0.03473}, + {355,1,73.6008,0.03474}, + {356,1,73.6414,0.03474}, + {357,1,73.682,0.03475}, + {358,1,73.7225,0.03475}, + {359,1,73.763,0.03476}, + {360,1,73.8034,0.03476}, + {361,1,73.8438,0.03477}, + {362,1,73.8842,0.03477}, + {363,1,73.9245,0.03478}, + {364,1,73.9647,0.03478}, + {365,1,74.0049,0.03479}, + {366,1,74.0451,0.03479}, + {367,1,74.0852,0.0348}, + {368,1,74.1253,0.0348}, + {369,1,74.1653,0.03481}, + {370,1,74.2053,0.03482}, + {371,1,74.2452,0.03482}, + {372,1,74.2851,0.03483}, + {373,1,74.325,0.03483}, + {374,1,74.3648,0.03484}, + {375,1,74.4045,0.03484}, + {376,1,74.4443,0.03485}, + {377,1,74.4839,0.03485}, + {378,1,74.5236,0.03486}, + {379,1,74.5632,0.03486}, + {380,1,74.6027,0.03487}, + {381,1,74.6422,0.03488}, + {382,1,74.6817,0.03488}, + {383,1,74.7211,0.03489}, + {384,1,74.7605,0.03489}, + {385,1,74.7998,0.0349}, + {386,1,74.8391,0.0349}, + {387,1,74.8784,0.03491}, + {388,1,74.9176,0.03491}, + {389,1,74.9567,0.03492}, + {390,1,74.9959,0.03493}, + {391,1,75.0349,0.03493}, + {392,1,75.074,0.03494}, + {393,1,75.113,0.03494}, + {394,1,75.1519,0.03495}, + {395,1,75.1908,0.03495}, + {396,1,75.2297,0.03496}, + {397,1,75.2686,0.03497}, + {398,1,75.3073,0.03497}, + {399,1,75.3461,0.03498}, + {400,1,75.3848,0.03498}, + {401,1,75.4235,0.03499}, + {402,1,75.4621,0.035}, + {403,1,75.5007,0.035}, + {404,1,75.5392,0.03501}, + {405,1,75.5777,0.03501}, + {406,1,75.6162,0.03502}, + {407,1,75.6546,0.03503}, + {408,1,75.693,0.03503}, + {409,1,75.7313,0.03504}, + {410,1,75.7696,0.03504}, + {411,1,75.8079,0.03505}, + {412,1,75.8461,0.03506}, + {413,1,75.8843,0.03506}, + {414,1,75.9224,0.03507}, + {415,1,75.9605,0.03507}, + {416,1,75.9986,0.03508}, + {417,1,76.0366,0.03509}, + {418,1,76.0746,0.03509}, + {419,1,76.1125,0.0351}, + {420,1,76.1504,0.03511}, + {421,1,76.1883,0.03511}, + {422,1,76.2261,0.03512}, + {423,1,76.2639,0.03512}, + {424,1,76.3016,0.03513}, + {425,1,76.3393,0.03514}, + {426,1,76.377,0.03514}, + {427,1,76.4146,0.03515}, + {428,1,76.4522,0.03516}, + {429,1,76.4897,0.03516}, + {430,1,76.5272,0.03517}, + {431,1,76.5647,0.03518}, + {432,1,76.6021,0.03518}, + {433,1,76.6395,0.03519}, + {434,1,76.6769,0.03519}, + {435,1,76.7142,0.0352}, + {436,1,76.7515,0.03521}, + {437,1,76.7887,0.03521}, + {438,1,76.8259,0.03522}, + {439,1,76.8631,0.03523}, + {440,1,76.9002,0.03523}, + {441,1,76.9373,0.03524}, + {442,1,76.9744,0.03525}, + {443,1,77.0114,0.03525}, + {444,1,77.0484,0.03526}, + {445,1,77.0853,0.03527}, + {446,1,77.1222,0.03527}, + {447,1,77.1591,0.03528}, + {448,1,77.1959,0.03529}, + {449,1,77.2327,0.03529}, + {450,1,77.2695,0.0353}, + {451,1,77.3062,0.0353}, + {452,1,77.3429,0.03531}, + {453,1,77.3796,0.03532}, + {454,1,77.4162,0.03532}, + {455,1,77.4528,0.03533}, + {456,1,77.4893,0.03534}, + {457,1,77.5258,0.03534}, + {458,1,77.5623,0.03535}, + {459,1,77.5988,0.03536}, + {460,1,77.6352,0.03536}, + {461,1,77.6716,0.03537}, + {462,1,77.7079,0.03538}, + {463,1,77.7442,0.03538}, + {464,1,77.7805,0.03539}, + {465,1,77.8167,0.0354}, + {466,1,77.8529,0.0354}, + {467,1,77.8891,0.03541}, + {468,1,77.9252,0.03542}, + {469,1,77.9613,0.03543}, + {470,1,77.9974,0.03543}, + {471,1,78.0334,0.03544}, + {472,1,78.0694,0.03545}, + {473,1,78.1054,0.03545}, + {474,1,78.1413,0.03546}, + {475,1,78.1772,0.03547}, + {476,1,78.2131,0.03547}, + {477,1,78.249,0.03548}, + {478,1,78.2848,0.03549}, + {479,1,78.3205,0.03549}, + {480,1,78.3563,0.0355}, + {481,1,78.392,0.03551}, + {482,1,78.4276,0.03551}, + {483,1,78.4633,0.03552}, + {484,1,78.4989,0.03553}, + {485,1,78.5345,0.03553}, + {486,1,78.57,0.03554}, + {487,1,78.6055,0.03555}, + {488,1,78.641,0.03556}, + {489,1,78.6764,0.03556}, + {490,1,78.7118,0.03557}, + {491,1,78.7472,0.03558}, + {492,1,78.7826,0.03558}, + {493,1,78.8179,0.03559}, + {494,1,78.8532,0.0356}, + {495,1,78.8884,0.0356}, + {496,1,78.9236,0.03561}, + {497,1,78.9588,0.03562}, + {498,1,78.994,0.03562}, + {499,1,79.0291,0.03563}, + {500,1,79.0642,0.03564}, + {501,1,79.0993,0.03565}, + {502,1,79.1343,0.03565}, + {503,1,79.1693,0.03566}, + {504,1,79.2042,0.03567}, + {505,1,79.2392,0.03567}, + {506,1,79.2741,0.03568}, + {507,1,79.3089,0.03569}, + {508,1,79.3438,0.03569}, + {509,1,79.3786,0.0357}, + {510,1,79.4134,0.03571}, + {511,1,79.4481,0.03572}, + {512,1,79.4828,0.03572}, + {513,1,79.5175,0.03573}, + {514,1,79.5521,0.03574}, + {515,1,79.5868,0.03574}, + {516,1,79.6213,0.03575}, + {517,1,79.6559,0.03576}, + {518,1,79.6904,0.03577}, + {519,1,79.7249,0.03577}, + {520,1,79.7594,0.03578}, + {521,1,79.7938,0.03579}, + {522,1,79.8282,0.03579}, + {523,1,79.8626,0.0358}, + {524,1,79.8969,0.03581}, + {525,1,79.9312,0.03582}, + {526,1,79.9655,0.03582}, + {527,1,79.9998,0.03583}, + {528,1,80.034,0.03584}, + {529,1,80.0682,0.03584}, + {530,1,80.1023,0.03585}, + {531,1,80.1365,0.03586}, + {532,1,80.1706,0.03587}, + {533,1,80.2046,0.03587}, + {534,1,80.2387,0.03588}, + {535,1,80.2727,0.03589}, + {536,1,80.3067,0.03589}, + {537,1,80.3406,0.0359}, + {538,1,80.3745,0.03591}, + {539,1,80.4084,0.03592}, + {540,1,80.4423,0.03592}, + {541,1,80.4761,0.03593}, + {542,1,80.5099,0.03594}, + {543,1,80.5437,0.03594}, + {544,1,80.5774,0.03595}, + {545,1,80.6112,0.03596}, + {546,1,80.6448,0.03597}, + {547,1,80.6785,0.03597}, + {548,1,80.7121,0.03598}, + {549,1,80.7457,0.03599}, + {550,1,80.7793,0.036}, + {551,1,80.8128,0.036}, + {552,1,80.8464,0.03601}, + {553,1,80.8798,0.03602}, + {554,1,80.9133,0.03602}, + {555,1,80.9467,0.03603}, + {556,1,80.9801,0.03604}, + {557,1,81.0135,0.03605}, + {558,1,81.0468,0.03605}, + {559,1,81.0802,0.03606}, + {560,1,81.1134,0.03607}, + {561,1,81.1467,0.03608}, + {562,1,81.1799,0.03608}, + {563,1,81.2131,0.03609}, + {564,1,81.2463,0.0361}, + {565,1,81.2795,0.03611}, + {566,1,81.3126,0.03611}, + {567,1,81.3457,0.03612}, + {568,1,81.3788,0.03613}, + {569,1,81.4118,0.03613}, + {570,1,81.4448,0.03614}, + {571,1,81.4778,0.03615}, + {572,1,81.5108,0.03616}, + {573,1,81.5437,0.03616}, + {574,1,81.5766,0.03617}, + {575,1,81.6095,0.03618}, + {576,1,81.6423,0.03619}, + {577,1,81.6752,0.03619}, + {578,1,81.708,0.0362}, + {579,1,81.7407,0.03621}, + {580,1,81.7735,0.03622}, + {581,1,81.8062,0.03622}, + {582,1,81.8389,0.03623}, + {583,1,81.8715,0.03624}, + {584,1,81.9042,0.03624}, + {585,1,81.9368,0.03625}, + {586,1,81.9694,0.03626}, + {587,1,82.0019,0.03627}, + {588,1,82.0345,0.03627}, + {589,1,82.067,0.03628}, + {590,1,82.0994,0.03629}, + {591,1,82.1319,0.0363}, + {592,1,82.1643,0.0363}, + {593,1,82.1967,0.03631}, + {594,1,82.2291,0.03632}, + {595,1,82.2614,0.03633}, + {596,1,82.2938,0.03633}, + {597,1,82.3261,0.03634}, + {598,1,82.3583,0.03635}, + {599,1,82.3906,0.03636}, + {600,1,82.4228,0.03636}, + {601,1,82.455,0.03637}, + {602,1,82.4872,0.03638}, + {603,1,82.5193,0.03639}, + {604,1,82.5514,0.03639}, + {605,1,82.5835,0.0364}, + {606,1,82.6156,0.03641}, + {607,1,82.6476,0.03642}, + {608,1,82.6796,0.03642}, + {609,1,82.7116,0.03643}, + {610,1,82.7436,0.03644}, + {611,1,82.7755,0.03645}, + {612,1,82.8074,0.03645}, + {613,1,82.8393,0.03646}, + {614,1,82.8712,0.03647}, + {615,1,82.903,0.03648}, + {616,1,82.9348,0.03648}, + {617,1,82.9666,0.03649}, + {618,1,82.9984,0.0365}, + {619,1,83.0301,0.0365}, + {620,1,83.0618,0.03651}, + {621,1,83.0935,0.03652}, + {622,1,83.1251,0.03653}, + {623,1,83.1568,0.03653}, + {624,1,83.1884,0.03654}, + {625,1,83.22,0.03655}, + {626,1,83.2515,0.03656}, + {627,1,83.2831,0.03656}, + {628,1,83.3146,0.03657}, + {629,1,83.3461,0.03658}, + {630,1,83.3775,0.03659}, + {631,1,83.4089,0.03659}, + {632,1,83.4403,0.0366}, + {633,1,83.4717,0.03661}, + {634,1,83.5031,0.03662}, + {635,1,83.5344,0.03662}, + {636,1,83.5657,0.03663}, + {637,1,83.597,0.03664}, + {638,1,83.6283,0.03665}, + {639,1,83.6595,0.03665}, + {640,1,83.6907,0.03666}, + {641,1,83.7219,0.03667}, + {642,1,83.753,0.03668}, + {643,1,83.7842,0.03668}, + {644,1,83.8153,0.03669}, + {645,1,83.8464,0.0367}, + {646,1,83.8774,0.03671}, + {647,1,83.9085,0.03671}, + {648,1,83.9395,0.03672}, + {649,1,83.9705,0.03673}, + {650,1,84.0014,0.03674}, + {651,1,84.0324,0.03674}, + {652,1,84.0633,0.03675}, + {653,1,84.0941,0.03676}, + {654,1,84.125,0.03677}, + {655,1,84.1558,0.03677}, + {656,1,84.1867,0.03678}, + {657,1,84.2174,0.03679}, + {658,1,84.2482,0.0368}, + {659,1,84.2789,0.0368}, + {660,1,84.3096,0.03681}, + {661,1,84.3403,0.03682}, + {662,1,84.371,0.03683}, + {663,1,84.4016,0.03683}, + {664,1,84.4323,0.03684}, + {665,1,84.4628,0.03685}, + {666,1,84.4934,0.03686}, + {667,1,84.5239,0.03686}, + {668,1,84.5545,0.03687}, + {669,1,84.585,0.03688}, + {670,1,84.6154,0.03689}, + {671,1,84.6459,0.03689}, + {672,1,84.6763,0.0369}, + {673,1,84.7067,0.03691}, + {674,1,84.737,0.03692}, + {675,1,84.7674,0.03692}, + {676,1,84.7977,0.03693}, + {677,1,84.828,0.03694}, + {678,1,84.8583,0.03695}, + {679,1,84.8885,0.03695}, + {680,1,84.9188,0.03696}, + {681,1,84.949,0.03697}, + {682,1,84.9791,0.03698}, + {683,1,85.0093,0.03698}, + {684,1,85.0394,0.03699}, + {685,1,85.0695,0.037}, + {686,1,85.0996,0.03701}, + {687,1,85.1297,0.03701}, + {688,1,85.1597,0.03702}, + {689,1,85.1897,0.03703}, + {690,1,85.2197,0.03704}, + {691,1,85.2497,0.03704}, + {692,1,85.2796,0.03705}, + {693,1,85.3096,0.03706}, + {694,1,85.3395,0.03706}, + {695,1,85.3693,0.03707}, + {696,1,85.3992,0.03708}, + {697,1,85.429,0.03709}, + {698,1,85.4588,0.03709}, + {699,1,85.4886,0.0371}, + {700,1,85.5184,0.03711}, + {701,1,85.5481,0.03712}, + {702,1,85.5778,0.03712}, + {703,1,85.6075,0.03713}, + {704,1,85.6372,0.03714}, + {705,1,85.6668,0.03715}, + {706,1,85.6964,0.03715}, + {707,1,85.726,0.03716}, + {708,1,85.7556,0.03717}, + {709,1,85.7852,0.03718}, + {710,1,85.8147,0.03718}, + {711,1,85.8442,0.03719}, + {712,1,85.8737,0.0372}, + {713,1,85.9032,0.03721}, + {714,1,85.9326,0.03721}, + {715,1,85.9621,0.03722}, + {716,1,85.9915,0.03723}, + {717,1,86.0208,0.03724}, + {718,1,86.0502,0.03724}, + {719,1,86.0795,0.03725}, + {720,1,86.1089,0.03726}, + {721,1,86.1381,0.03727}, + {722,1,86.1674,0.03727}, + {723,1,86.1967,0.03728}, + {724,1,86.2259,0.03729}, + {725,1,86.2551,0.03729}, + {726,1,86.2843,0.0373}, + {727,1,86.3134,0.03731}, + {728,1,86.3426,0.03732}, + {729,1,86.3717,0.03732}, + {730,1,86.4008,0.03733}, + {731,1,85.7299,0.03764}, + {732,1,85.7589,0.03765}, + {733,1,85.788,0.03766}, + {734,1,85.817,0.03767}, + {735,1,85.846,0.03767}, + {736,1,85.8749,0.03768}, + {737,1,85.9039,0.03769}, + {738,1,85.9328,0.0377}, + {739,1,85.9617,0.0377}, + {740,1,85.9906,0.03771}, + {741,1,86.0194,0.03772}, + {742,1,86.0483,0.03772}, + {743,1,86.0771,0.03773}, + {744,1,86.1059,0.03774}, + {745,1,86.1347,0.03775}, + {746,1,86.1634,0.03775}, + {747,1,86.1921,0.03776}, + {748,1,86.2209,0.03777}, + {749,1,86.2495,0.03778}, + {750,1,86.2782,0.03778}, + {751,1,86.3069,0.03779}, + {752,1,86.3355,0.0378}, + {753,1,86.3641,0.0378}, + {754,1,86.3927,0.03781}, + {755,1,86.4212,0.03782}, + {756,1,86.4498,0.03783}, + {757,1,86.4783,0.03783}, + {758,1,86.5068,0.03784}, + {759,1,86.5353,0.03785}, + {760,1,86.5638,0.03786}, + {761,1,86.5922,0.03786}, + {762,1,86.6206,0.03787}, + {763,1,86.649,0.03788}, + {764,1,86.6774,0.03788}, + {765,1,86.7057,0.03789}, + {766,1,86.7341,0.0379}, + {767,1,86.7624,0.03791}, + {768,1,86.7907,0.03791}, + {769,1,86.819,0.03792}, + {770,1,86.8472,0.03793}, + {771,1,86.8754,0.03794}, + {772,1,86.9037,0.03794}, + {773,1,86.9319,0.03795}, + {774,1,86.96,0.03796}, + {775,1,86.9882,0.03796}, + {776,1,87.0163,0.03797}, + {777,1,87.0444,0.03798}, + {778,1,87.0725,0.03799}, + {779,1,87.1006,0.03799}, + {780,1,87.1286,0.038}, + {781,1,87.1567,0.03801}, + {782,1,87.1847,0.03801}, + {783,1,87.2126,0.03802}, + {784,1,87.2406,0.03803}, + {785,1,87.2686,0.03804}, + {786,1,87.2965,0.03804}, + {787,1,87.3244,0.03805}, + {788,1,87.3523,0.03806}, + {789,1,87.3801,0.03806}, + {790,1,87.408,0.03807}, + {791,1,87.4358,0.03808}, + {792,1,87.4636,0.03809}, + {793,1,87.4914,0.03809}, + {794,1,87.5192,0.0381}, + {795,1,87.5469,0.03811}, + {796,1,87.5746,0.03812}, + {797,1,87.6023,0.03812}, + {798,1,87.63,0.03813}, + {799,1,87.6577,0.03814}, + {800,1,87.6853,0.03814}, + {801,1,87.7129,0.03815}, + {802,1,87.7405,0.03816}, + {803,1,87.7681,0.03817}, + {804,1,87.7956,0.03817}, + {805,1,87.8232,0.03818}, + {806,1,87.8507,0.03819}, + {807,1,87.8782,0.03819}, + {808,1,87.9056,0.0382}, + {809,1,87.9331,0.03821}, + {810,1,87.9605,0.03821}, + {811,1,87.9879,0.03822}, + {812,1,88.0153,0.03823}, + {813,1,88.0427,0.03824}, + {814,1,88.07,0.03824}, + {815,1,88.0974,0.03825}, + {816,1,88.1247,0.03826}, + {817,1,88.1519,0.03826}, + {818,1,88.1792,0.03827}, + {819,1,88.2065,0.03828}, + {820,1,88.2337,0.03829}, + {821,1,88.2609,0.03829}, + {822,1,88.2881,0.0383}, + {823,1,88.3152,0.03831}, + {824,1,88.3423,0.03831}, + {825,1,88.3695,0.03832}, + {826,1,88.3966,0.03833}, + {827,1,88.4236,0.03834}, + {828,1,88.4507,0.03834}, + {829,1,88.4777,0.03835}, + {830,1,88.5047,0.03836}, + {831,1,88.5317,0.03836}, + {832,1,88.5587,0.03837}, + {833,1,88.5856,0.03838}, + {834,1,88.6126,0.03838}, + {835,1,88.6395,0.03839}, + {836,1,88.6664,0.0384}, + {837,1,88.6932,0.03841}, + {838,1,88.7201,0.03841}, + {839,1,88.7469,0.03842}, + {840,1,88.7737,0.03843}, + {841,1,88.8005,0.03843}, + {842,1,88.8273,0.03844}, + {843,1,88.854,0.03845}, + {844,1,88.8807,0.03845}, + {845,1,88.9074,0.03846}, + {846,1,88.9341,0.03847}, + {847,1,88.9608,0.03848}, + {848,1,88.9874,0.03848}, + {849,1,89.014,0.03849}, + {850,1,89.0406,0.0385}, + {851,1,89.0672,0.0385}, + {852,1,89.0938,0.03851}, + {853,1,89.1203,0.03852}, + {854,1,89.1468,0.03852}, + {855,1,89.1733,0.03853}, + {856,1,89.1998,0.03854}, + {857,1,89.2263,0.03855}, + {858,1,89.2527,0.03855}, + {859,1,89.2791,0.03856}, + {860,1,89.3055,0.03857}, + {861,1,89.3319,0.03857}, + {862,1,89.3583,0.03858}, + {863,1,89.3846,0.03859}, + {864,1,89.4109,0.03859}, + {865,1,89.4372,0.0386}, + {866,1,89.4635,0.03861}, + {867,1,89.4898,0.03861}, + {868,1,89.516,0.03862}, + {869,1,89.5422,0.03863}, + {870,1,89.5684,0.03864}, + {871,1,89.5946,0.03864}, + {872,1,89.6208,0.03865}, + {873,1,89.6469,0.03866}, + {874,1,89.673,0.03866}, + {875,1,89.6991,0.03867}, + {876,1,89.7252,0.03868}, + {877,1,89.7513,0.03868}, + {878,1,89.7773,0.03869}, + {879,1,89.8033,0.0387}, + {880,1,89.8293,0.0387}, + {881,1,89.8553,0.03871}, + {882,1,89.8813,0.03872}, + {883,1,89.9072,0.03872}, + {884,1,89.9331,0.03873}, + {885,1,89.9591,0.03874}, + {886,1,89.9849,0.03874}, + {887,1,90.0108,0.03875}, + {888,1,90.0366,0.03876}, + {889,1,90.0625,0.03877}, + {890,1,90.0883,0.03877}, + {891,1,90.1141,0.03878}, + {892,1,90.1398,0.03879}, + {893,1,90.1656,0.03879}, + {894,1,90.1913,0.0388}, + {895,1,90.217,0.03881}, + {896,1,90.2427,0.03881}, + {897,1,90.2684,0.03882}, + {898,1,90.294,0.03883}, + {899,1,90.3197,0.03883}, + {900,1,90.3453,0.03884}, + {901,1,90.3709,0.03885}, + {902,1,90.3965,0.03885}, + {903,1,90.422,0.03886}, + {904,1,90.4476,0.03887}, + {905,1,90.4731,0.03887}, + {906,1,90.4986,0.03888}, + {907,1,90.524,0.03889}, + {908,1,90.5495,0.03889}, + {909,1,90.575,0.0389}, + {910,1,90.6004,0.03891}, + {911,1,90.6258,0.03891}, + {912,1,90.6512,0.03892}, + {913,1,90.6765,0.03893}, + {914,1,90.7019,0.03893}, + {915,1,90.7272,0.03894}, + {916,1,90.7525,0.03895}, + {917,1,90.7778,0.03895}, + {918,1,90.8031,0.03896}, + {919,1,90.8283,0.03897}, + {920,1,90.8536,0.03897}, + {921,1,90.8788,0.03898}, + {922,1,90.904,0.03899}, + {923,1,90.9292,0.03899}, + {924,1,90.9544,0.039}, + {925,1,90.9795,0.03901}, + {926,1,91.0046,0.03901}, + {927,1,91.0297,0.03902}, + {928,1,91.0548,0.03903}, + {929,1,91.0799,0.03903}, + {930,1,91.105,0.03904}, + {931,1,91.13,0.03905}, + {932,1,91.155,0.03905}, + {933,1,91.18,0.03906}, + {934,1,91.205,0.03907}, + {935,1,91.23,0.03907}, + {936,1,91.2549,0.03908}, + {937,1,91.2799,0.03909}, + {938,1,91.3048,0.03909}, + {939,1,91.3297,0.0391}, + {940,1,91.3545,0.03911}, + {941,1,91.3794,0.03911}, + {942,1,91.4043,0.03912}, + {943,1,91.4291,0.03913}, + {944,1,91.4539,0.03913}, + {945,1,91.4787,0.03914}, + {946,1,91.5035,0.03915}, + {947,1,91.5282,0.03915}, + {948,1,91.553,0.03916}, + {949,1,91.5777,0.03917}, + {950,1,91.6024,0.03917}, + {951,1,91.6271,0.03918}, + {952,1,91.6518,0.03918}, + {953,1,91.6764,0.03919}, + {954,1,91.7011,0.0392}, + {955,1,91.7257,0.0392}, + {956,1,91.7503,0.03921}, + {957,1,91.7749,0.03922}, + {958,1,91.7995,0.03922}, + {959,1,91.8241,0.03923}, + {960,1,91.8486,0.03924}, + {961,1,91.8731,0.03924}, + {962,1,91.8976,0.03925}, + {963,1,91.9221,0.03926}, + {964,1,91.9466,0.03926}, + {965,1,91.9711,0.03927}, + {966,1,91.9955,0.03928}, + {967,1,92.02,0.03928}, + {968,1,92.0444,0.03929}, + {969,1,92.0688,0.03929}, + {970,1,92.0932,0.0393}, + {971,1,92.1175,0.03931}, + {972,1,92.1419,0.03931}, + {973,1,92.1662,0.03932}, + {974,1,92.1906,0.03933}, + {975,1,92.2149,0.03933}, + {976,1,92.2392,0.03934}, + {977,1,92.2635,0.03935}, + {978,1,92.2877,0.03935}, + {979,1,92.312,0.03936}, + {980,1,92.3362,0.03936}, + {981,1,92.3604,0.03937}, + {982,1,92.3846,0.03938}, + {983,1,92.4088,0.03938}, + {984,1,92.433,0.03939}, + {985,1,92.4572,0.0394}, + {986,1,92.4813,0.0394}, + {987,1,92.5054,0.03941}, + {988,1,92.5295,0.03942}, + {989,1,92.5536,0.03942}, + {990,1,92.5777,0.03943}, + {991,1,92.6018,0.03943}, + {992,1,92.6259,0.03944}, + {993,1,92.6499,0.03945}, + {994,1,92.6739,0.03945}, + {995,1,92.698,0.03946}, + {996,1,92.722,0.03947}, + {997,1,92.7459,0.03947}, + {998,1,92.7699,0.03948}, + {999,1,92.7939,0.03948}, + {1000,1,92.8178,0.03949}, + {1001,1,92.8418,0.0395}, + {1002,1,92.8657,0.0395}, + {1003,1,92.8896,0.03951}, + {1004,1,92.9135,0.03952}, + {1005,1,92.9373,0.03952}, + {1006,1,92.9612,0.03953}, + {1007,1,92.985,0.03953}, + {1008,1,93.0089,0.03954}, + {1009,1,93.0327,0.03955}, + {1010,1,93.0565,0.03955}, + {1011,1,93.0803,0.03956}, + {1012,1,93.1041,0.03957}, + {1013,1,93.1278,0.03957}, + {1014,1,93.1516,0.03958}, + {1015,1,93.1753,0.03958}, + {1016,1,93.1991,0.03959}, + {1017,1,93.2228,0.0396}, + {1018,1,93.2465,0.0396}, + {1019,1,93.2702,0.03961}, + {1020,1,93.2938,0.03961}, + {1021,1,93.3175,0.03962}, + {1022,1,93.3411,0.03963}, + {1023,1,93.3648,0.03963}, + {1024,1,93.3884,0.03964}, + {1025,1,93.412,0.03964}, + {1026,1,93.4356,0.03965}, + {1027,1,93.4592,0.03966}, + {1028,1,93.4827,0.03966}, + {1029,1,93.5063,0.03967}, + {1030,1,93.5298,0.03968}, + {1031,1,93.5534,0.03968}, + {1032,1,93.5769,0.03969}, + {1033,1,93.6004,0.03969}, + {1034,1,93.6239,0.0397}, + {1035,1,93.6473,0.03971}, + {1036,1,93.6708,0.03971}, + {1037,1,93.6943,0.03972}, + {1038,1,93.7177,0.03972}, + {1039,1,93.7411,0.03973}, + {1040,1,93.7646,0.03974}, + {1041,1,93.788,0.03974}, + {1042,1,93.8113,0.03975}, + {1043,1,93.8347,0.03975}, + {1044,1,93.8581,0.03976}, + {1045,1,93.8814,0.03977}, + {1046,1,93.9048,0.03977}, + {1047,1,93.9281,0.03978}, + {1048,1,93.9514,0.03978}, + {1049,1,93.9747,0.03979}, + {1050,1,93.998,0.0398}, + {1051,1,94.0213,0.0398}, + {1052,1,94.0446,0.03981}, + {1053,1,94.0678,0.03981}, + {1054,1,94.0911,0.03982}, + {1055,1,94.1143,0.03983}, + {1056,1,94.1376,0.03983}, + {1057,1,94.1608,0.03984}, + {1058,1,94.184,0.03984}, + {1059,1,94.2071,0.03985}, + {1060,1,94.2303,0.03986}, + {1061,1,94.2535,0.03986}, + {1062,1,94.2766,0.03987}, + {1063,1,94.2998,0.03987}, + {1064,1,94.3229,0.03988}, + {1065,1,94.346,0.03989}, + {1066,1,94.3691,0.03989}, + {1067,1,94.3922,0.0399}, + {1068,1,94.4153,0.0399}, + {1069,1,94.4384,0.03991}, + {1070,1,94.4615,0.03991}, + {1071,1,94.4845,0.03992}, + {1072,1,94.5075,0.03993}, + {1073,1,94.5306,0.03993}, + {1074,1,94.5536,0.03994}, + {1075,1,94.5766,0.03994}, + {1076,1,94.5996,0.03995}, + {1077,1,94.6226,0.03996}, + {1078,1,94.6455,0.03996}, + {1079,1,94.6685,0.03997}, + {1080,1,94.6914,0.03997}, + {1081,1,94.7144,0.03998}, + {1082,1,94.7373,0.03999}, + {1083,1,94.7602,0.03999}, + {1084,1,94.7831,0.04}, + {1085,1,94.806,0.04}, + {1086,1,94.8289,0.04001}, + {1087,1,94.8518,0.04001}, + {1088,1,94.8747,0.04002}, + {1089,1,94.8975,0.04003}, + {1090,1,94.9203,0.04003}, + {1091,1,94.9432,0.04004}, + {1092,1,94.966,0.04004}, + {1093,1,94.9888,0.04005}, + {1094,1,95.0116,0.04005}, + {1095,1,95.0344,0.04006}, + {1096,1,95.0572,0.04007}, + {1097,1,95.0799,0.04007}, + {1098,1,95.1027,0.04008}, + {1099,1,95.1254,0.04008}, + {1100,1,95.1482,0.04009}, + {1101,1,95.1709,0.04009}, + {1102,1,95.1936,0.0401}, + {1103,1,95.2163,0.04011}, + {1104,1,95.239,0.04011}, + {1105,1,95.2617,0.04012}, + {1106,1,95.2844,0.04012}, + {1107,1,95.307,0.04013}, + {1108,1,95.3297,0.04013}, + {1109,1,95.3523,0.04014}, + {1110,1,95.375,0.04015}, + {1111,1,95.3976,0.04015}, + {1112,1,95.4202,0.04016}, + {1113,1,95.4428,0.04016}, + {1114,1,95.4654,0.04017}, + {1115,1,95.488,0.04017}, + {1116,1,95.5105,0.04018}, + {1117,1,95.5331,0.04019}, + {1118,1,95.5556,0.04019}, + {1119,1,95.5782,0.0402}, + {1120,1,95.6007,0.0402}, + {1121,1,95.6232,0.04021}, + {1122,1,95.6457,0.04021}, + {1123,1,95.6682,0.04022}, + {1124,1,95.6907,0.04023}, + {1125,1,95.7132,0.04023}, + {1126,1,95.7356,0.04024}, + {1127,1,95.7581,0.04024}, + {1128,1,95.7805,0.04025}, + {1129,1,95.803,0.04025}, + {1130,1,95.8254,0.04026}, + {1131,1,95.8478,0.04026}, + {1132,1,95.8702,0.04027}, + {1133,1,95.8926,0.04028}, + {1134,1,95.915,0.04028}, + {1135,1,95.9374,0.04029}, + {1136,1,95.9597,0.04029}, + {1137,1,95.9821,0.0403}, + {1138,1,96.0044,0.0403}, + {1139,1,96.0268,0.04031}, + {1140,1,96.0491,0.04032}, + {1141,1,96.0714,0.04032}, + {1142,1,96.0937,0.04033}, + {1143,1,96.116,0.04033}, + {1144,1,96.1383,0.04034}, + {1145,1,96.1606,0.04034}, + {1146,1,96.1828,0.04035}, + {1147,1,96.2051,0.04035}, + {1148,1,96.2273,0.04036}, + {1149,1,96.2495,0.04036}, + {1150,1,96.2718,0.04037}, + {1151,1,96.294,0.04038}, + {1152,1,96.3162,0.04038}, + {1153,1,96.3384,0.04039}, + {1154,1,96.3606,0.04039}, + {1155,1,96.3827,0.0404}, + {1156,1,96.4049,0.0404}, + {1157,1,96.427,0.04041}, + {1158,1,96.4492,0.04041}, + {1159,1,96.4713,0.04042}, + {1160,1,96.4934,0.04043}, + {1161,1,96.5156,0.04043}, + {1162,1,96.5377,0.04044}, + {1163,1,96.5598,0.04044}, + {1164,1,96.5818,0.04045}, + {1165,1,96.6039,0.04045}, + {1166,1,96.626,0.04046}, + {1167,1,96.648,0.04046}, + {1168,1,96.6701,0.04047}, + {1169,1,96.6921,0.04047}, + {1170,1,96.7141,0.04048}, + {1171,1,96.7362,0.04049}, + {1172,1,96.7582,0.04049}, + {1173,1,96.7802,0.0405}, + {1174,1,96.8021,0.0405}, + {1175,1,96.8241,0.04051}, + {1176,1,96.8461,0.04051}, + {1177,1,96.868,0.04052}, + {1178,1,96.89,0.04052}, + {1179,1,96.9119,0.04053}, + {1180,1,96.9339,0.04053}, + {1181,1,96.9558,0.04054}, + {1182,1,96.9777,0.04054}, + {1183,1,96.9996,0.04055}, + {1184,1,97.0215,0.04056}, + {1185,1,97.0434,0.04056}, + {1186,1,97.0652,0.04057}, + {1187,1,97.0871,0.04057}, + {1188,1,97.1089,0.04058}, + {1189,1,97.1308,0.04058}, + {1190,1,97.1526,0.04059}, + {1191,1,97.1744,0.04059}, + {1192,1,97.1963,0.0406}, + {1193,1,97.2181,0.0406}, + {1194,1,97.2399,0.04061}, + {1195,1,97.2616,0.04061}, + {1196,1,97.2834,0.04062}, + {1197,1,97.3052,0.04063}, + {1198,1,97.3269,0.04063}, + {1199,1,97.3487,0.04064}, + {1200,1,97.3704,0.04064}, + {1201,1,97.3922,0.04065}, + {1202,1,97.4139,0.04065}, + {1203,1,97.4356,0.04066}, + {1204,1,97.4573,0.04066}, + {1205,1,97.479,0.04067}, + {1206,1,97.5007,0.04067}, + {1207,1,97.5223,0.04068}, + {1208,1,97.544,0.04068}, + {1209,1,97.5657,0.04069}, + {1210,1,97.5873,0.04069}, + {1211,1,97.6089,0.0407}, + {1212,1,97.6306,0.0407}, + {1213,1,97.6522,0.04071}, + {1214,1,97.6738,0.04072}, + {1215,1,97.6954,0.04072}, + {1216,1,97.717,0.04073}, + {1217,1,97.7385,0.04073}, + {1218,1,97.7601,0.04074}, + {1219,1,97.7817,0.04074}, + {1220,1,97.8032,0.04075}, + {1221,1,97.8248,0.04075}, + {1222,1,97.8463,0.04076}, + {1223,1,97.8678,0.04076}, + {1224,1,97.8893,0.04077}, + {1225,1,97.9108,0.04077}, + {1226,1,97.9323,0.04078}, + {1227,1,97.9538,0.04078}, + {1228,1,97.9753,0.04079}, + {1229,1,97.9968,0.04079}, + {1230,1,98.0182,0.0408}, + {1231,1,98.0397,0.0408}, + {1232,1,98.0611,0.04081}, + {1233,1,98.0825,0.04081}, + {1234,1,98.1039,0.04082}, + {1235,1,98.1253,0.04082}, + {1236,1,98.1467,0.04083}, + {1237,1,98.1681,0.04084}, + {1238,1,98.1895,0.04084}, + {1239,1,98.2109,0.04085}, + {1240,1,98.2322,0.04085}, + {1241,1,98.2536,0.04086}, + {1242,1,98.2749,0.04086}, + {1243,1,98.2963,0.04087}, + {1244,1,98.3176,0.04087}, + {1245,1,98.3389,0.04088}, + {1246,1,98.3602,0.04088}, + {1247,1,98.3815,0.04089}, + {1248,1,98.4028,0.04089}, + {1249,1,98.4241,0.0409}, + {1250,1,98.4453,0.0409}, + {1251,1,98.4666,0.04091}, + {1252,1,98.4878,0.04091}, + {1253,1,98.5091,0.04092}, + {1254,1,98.5303,0.04092}, + {1255,1,98.5515,0.04093}, + {1256,1,98.5727,0.04093}, + {1257,1,98.5939,0.04094}, + {1258,1,98.6151,0.04094}, + {1259,1,98.6363,0.04095}, + {1260,1,98.6575,0.04095}, + {1261,1,98.6786,0.04096}, + {1262,1,98.6998,0.04096}, + {1263,1,98.7209,0.04097}, + {1264,1,98.7421,0.04097}, + {1265,1,98.7632,0.04098}, + {1266,1,98.7843,0.04098}, + {1267,1,98.8054,0.04099}, + {1268,1,98.8265,0.04099}, + {1269,1,98.8476,0.041}, + {1270,1,98.8687,0.041}, + {1271,1,98.8897,0.04101}, + {1272,1,98.9108,0.04101}, + {1273,1,98.9318,0.04102}, + {1274,1,98.9529,0.04103}, + {1275,1,98.9739,0.04103}, + {1276,1,98.9949,0.04104}, + {1277,1,99.0159,0.04104}, + {1278,1,99.0369,0.04105}, + {1279,1,99.0579,0.04105}, + {1280,1,99.0789,0.04106}, + {1281,1,99.0999,0.04106}, + {1282,1,99.1208,0.04107}, + {1283,1,99.1418,0.04107}, + {1284,1,99.1628,0.04108}, + {1285,1,99.1837,0.04108}, + {1286,1,99.2046,0.04109}, + {1287,1,99.2255,0.04109}, + {1288,1,99.2464,0.0411}, + {1289,1,99.2673,0.0411}, + {1290,1,99.2882,0.04111}, + {1291,1,99.3091,0.04111}, + {1292,1,99.33,0.04112}, + {1293,1,99.3509,0.04112}, + {1294,1,99.3717,0.04113}, + {1295,1,99.3926,0.04113}, + {1296,1,99.4134,0.04114}, + {1297,1,99.4342,0.04114}, + {1298,1,99.455,0.04115}, + {1299,1,99.4758,0.04115}, + {1300,1,99.4966,0.04116}, + {1301,1,99.5174,0.04116}, + {1302,1,99.5382,0.04117}, + {1303,1,99.559,0.04117}, + {1304,1,99.5798,0.04118}, + {1305,1,99.6005,0.04118}, + {1306,1,99.6212,0.04119}, + {1307,1,99.642,0.04119}, + {1308,1,99.6627,0.0412}, + {1309,1,99.6834,0.0412}, + {1310,1,99.7041,0.04121}, + {1311,1,99.7248,0.04121}, + {1312,1,99.7455,0.04122}, + {1313,1,99.7662,0.04122}, + {1314,1,99.7869,0.04123}, + {1315,1,99.8075,0.04123}, + {1316,1,99.8282,0.04124}, + {1317,1,99.8488,0.04124}, + {1318,1,99.8695,0.04125}, + {1319,1,99.8901,0.04125}, + {1320,1,99.9107,0.04126}, + {1321,1,99.9313,0.04126}, + {1322,1,99.9519,0.04126}, + {1323,1,99.9725,0.04127}, + {1324,1,99.9931,0.04127}, + {1325,1,100.0137,0.04128}, + {1326,1,100.0342,0.04128}, + {1327,1,100.0548,0.04129}, + {1328,1,100.0753,0.04129}, + {1329,1,100.0959,0.0413}, + {1330,1,100.1164,0.0413}, + {1331,1,100.1369,0.04131}, + {1332,1,100.1574,0.04131}, + {1333,1,100.1779,0.04132}, + {1334,1,100.1984,0.04132}, + {1335,1,100.2189,0.04133}, + {1336,1,100.2394,0.04133}, + {1337,1,100.2598,0.04134}, + {1338,1,100.2803,0.04134}, + {1339,1,100.3007,0.04135}, + {1340,1,100.3212,0.04135}, + {1341,1,100.3416,0.04136}, + {1342,1,100.362,0.04136}, + {1343,1,100.3824,0.04137}, + {1344,1,100.4028,0.04137}, + {1345,1,100.4232,0.04138}, + {1346,1,100.4436,0.04138}, + {1347,1,100.464,0.04139}, + {1348,1,100.4843,0.04139}, + {1349,1,100.5047,0.0414}, + {1350,1,100.525,0.0414}, + {1351,1,100.5454,0.04141}, + {1352,1,100.5657,0.04141}, + {1353,1,100.586,0.04142}, + {1354,1,100.6063,0.04142}, + {1355,1,100.6266,0.04143}, + {1356,1,100.6469,0.04143}, + {1357,1,100.6672,0.04144}, + {1358,1,100.6875,0.04144}, + {1359,1,100.7077,0.04145}, + {1360,1,100.728,0.04145}, + {1361,1,100.7482,0.04146}, + {1362,1,100.7685,0.04146}, + {1363,1,100.7887,0.04146}, + {1364,1,100.8089,0.04147}, + {1365,1,100.8291,0.04147}, + {1366,1,100.8493,0.04148}, + {1367,1,100.8695,0.04148}, + {1368,1,100.8897,0.04149}, + {1369,1,100.9099,0.04149}, + {1370,1,100.9301,0.0415}, + {1371,1,100.9502,0.0415}, + {1372,1,100.9704,0.04151}, + {1373,1,100.9905,0.04151}, + {1374,1,101.0107,0.04152}, + {1375,1,101.0308,0.04152}, + {1376,1,101.0509,0.04153}, + {1377,1,101.071,0.04153}, + {1378,1,101.0911,0.04154}, + {1379,1,101.1112,0.04154}, + {1380,1,101.1313,0.04155}, + {1381,1,101.1514,0.04155}, + {1382,1,101.1714,0.04156}, + {1383,1,101.1915,0.04156}, + {1384,1,101.2115,0.04157}, + {1385,1,101.2316,0.04157}, + {1386,1,101.2516,0.04158}, + {1387,1,101.2716,0.04158}, + {1388,1,101.2917,0.04158}, + {1389,1,101.3117,0.04159}, + {1390,1,101.3317,0.04159}, + {1391,1,101.3517,0.0416}, + {1392,1,101.3716,0.0416}, + {1393,1,101.3916,0.04161}, + {1394,1,101.4116,0.04161}, + {1395,1,101.4315,0.04162}, + {1396,1,101.4515,0.04162}, + {1397,1,101.4714,0.04163}, + {1398,1,101.4914,0.04163}, + {1399,1,101.5113,0.04164}, + {1400,1,101.5312,0.04164}, + {1401,1,101.5511,0.04165}, + {1402,1,101.571,0.04165}, + {1403,1,101.5909,0.04166}, + {1404,1,101.6108,0.04166}, + {1405,1,101.6306,0.04167}, + {1406,1,101.6505,0.04167}, + {1407,1,101.6704,0.04167}, + {1408,1,101.6902,0.04168}, + {1409,1,101.7101,0.04168}, + {1410,1,101.7299,0.04169}, + {1411,1,101.7497,0.04169}, + {1412,1,101.7695,0.0417}, + {1413,1,101.7893,0.0417}, + {1414,1,101.8091,0.04171}, + {1415,1,101.8289,0.04171}, + {1416,1,101.8487,0.04172}, + {1417,1,101.8685,0.04172}, + {1418,1,101.8883,0.04173}, + {1419,1,101.908,0.04173}, + {1420,1,101.9278,0.04174}, + {1421,1,101.9475,0.04174}, + {1422,1,101.9673,0.04175}, + {1423,1,101.987,0.04175}, + {1424,1,102.0067,0.04175}, + {1425,1,102.0264,0.04176}, + {1426,1,102.0461,0.04176}, + {1427,1,102.0658,0.04177}, + {1428,1,102.0855,0.04177}, + {1429,1,102.1052,0.04178}, + {1430,1,102.1249,0.04178}, + {1431,1,102.1446,0.04179}, + {1432,1,102.1642,0.04179}, + {1433,1,102.1839,0.0418}, + {1434,1,102.2035,0.0418}, + {1435,1,102.2232,0.04181}, + {1436,1,102.2428,0.04181}, + {1437,1,102.2624,0.04181}, + {1438,1,102.282,0.04182}, + {1439,1,102.3016,0.04182}, + {1440,1,102.3212,0.04183}, + {1441,1,102.3408,0.04183}, + {1442,1,102.3604,0.04184}, + {1443,1,102.38,0.04184}, + {1444,1,102.3996,0.04185}, + {1445,1,102.4191,0.04185}, + {1446,1,102.4387,0.04186}, + {1447,1,102.4582,0.04186}, + {1448,1,102.4778,0.04187}, + {1449,1,102.4973,0.04187}, + {1450,1,102.5168,0.04187}, + {1451,1,102.5364,0.04188}, + {1452,1,102.5559,0.04188}, + {1453,1,102.5754,0.04189}, + {1454,1,102.5949,0.04189}, + {1455,1,102.6144,0.0419}, + {1456,1,102.6338,0.0419}, + {1457,1,102.6533,0.04191}, + {1458,1,102.6728,0.04191}, + {1459,1,102.6923,0.04192}, + {1460,1,102.7117,0.04192}, + {1461,1,102.7312,0.04193}, + {1462,1,102.7506,0.04193}, + {1463,1,102.77,0.04193}, + {1464,1,102.7895,0.04194}, + {1465,1,102.8089,0.04194}, + {1466,1,102.8283,0.04195}, + {1467,1,102.8477,0.04195}, + {1468,1,102.8671,0.04196}, + {1469,1,102.8865,0.04196}, + {1470,1,102.9059,0.04197}, + {1471,1,102.9252,0.04197}, + {1472,1,102.9446,0.04198}, + {1473,1,102.964,0.04198}, + {1474,1,102.9833,0.04198}, + {1475,1,103.0027,0.04199}, + {1476,1,103.022,0.04199}, + {1477,1,103.0414,0.042}, + {1478,1,103.0607,0.042}, + {1479,1,103.08,0.04201}, + {1480,1,103.0993,0.04201}, + {1481,1,103.1186,0.04202}, + {1482,1,103.1379,0.04202}, + {1483,1,103.1572,0.04203}, + {1484,1,103.1765,0.04203}, + {1485,1,103.1958,0.04203}, + {1486,1,103.2151,0.04204}, + {1487,1,103.2343,0.04204}, + {1488,1,103.2536,0.04205}, + {1489,1,103.2728,0.04205}, + {1490,1,103.2921,0.04206}, + {1491,1,103.3113,0.04206}, + {1492,1,103.3306,0.04207}, + {1493,1,103.3498,0.04207}, + {1494,1,103.369,0.04208}, + {1495,1,103.3882,0.04208}, + {1496,1,103.4074,0.04208}, + {1497,1,103.4266,0.04209}, + {1498,1,103.4458,0.04209}, + {1499,1,103.465,0.0421}, + {1500,1,103.4842,0.0421}, + {1501,1,103.5034,0.04211}, + {1502,1,103.5225,0.04211}, + {1503,1,103.5417,0.04212}, + {1504,1,103.5608,0.04212}, + {1505,1,103.58,0.04212}, + {1506,1,103.5991,0.04213}, + {1507,1,103.6183,0.04213}, + {1508,1,103.6374,0.04214}, + {1509,1,103.6565,0.04214}, + {1510,1,103.6756,0.04215}, + {1511,1,103.6947,0.04215}, + {1512,1,103.7138,0.04216}, + {1513,1,103.7329,0.04216}, + {1514,1,103.752,0.04216}, + {1515,1,103.7711,0.04217}, + {1516,1,103.7902,0.04217}, + {1517,1,103.8092,0.04218}, + {1518,1,103.8283,0.04218}, + {1519,1,103.8473,0.04219}, + {1520,1,103.8664,0.04219}, + {1521,1,103.8854,0.0422}, + {1522,1,103.9045,0.0422}, + {1523,1,103.9235,0.0422}, + {1524,1,103.9425,0.04221}, + {1525,1,103.9616,0.04221}, + {1526,1,103.9806,0.04222}, + {1527,1,103.9996,0.04222}, + {1528,1,104.0186,0.04223}, + {1529,1,104.0376,0.04223}, + {1530,1,104.0565,0.04224}, + {1531,1,104.0755,0.04224}, + {1532,1,104.0945,0.04224}, + {1533,1,104.1135,0.04225}, + {1534,1,104.1324,0.04225}, + {1535,1,104.1514,0.04226}, + {1536,1,104.1703,0.04226}, + {1537,1,104.1893,0.04227}, + {1538,1,104.2082,0.04227}, + {1539,1,104.2271,0.04227}, + {1540,1,104.2461,0.04228}, + {1541,1,104.265,0.04228}, + {1542,1,104.2839,0.04229}, + {1543,1,104.3028,0.04229}, + {1544,1,104.3217,0.0423}, + {1545,1,104.3406,0.0423}, + {1546,1,104.3595,0.04231}, + {1547,1,104.3784,0.04231}, + {1548,1,104.3972,0.04231}, + {1549,1,104.4161,0.04232}, + {1550,1,104.435,0.04232}, + {1551,1,104.4538,0.04233}, + {1552,1,104.4727,0.04233}, + {1553,1,104.4915,0.04234}, + {1554,1,104.5104,0.04234}, + {1555,1,104.5292,0.04234}, + {1556,1,104.548,0.04235}, + {1557,1,104.5668,0.04235}, + {1558,1,104.5856,0.04236}, + {1559,1,104.6045,0.04236}, + {1560,1,104.6233,0.04237}, + {1561,1,104.6421,0.04237}, + {1562,1,104.6608,0.04238}, + {1563,1,104.6796,0.04238}, + {1564,1,104.6984,0.04238}, + {1565,1,104.7172,0.04239}, + {1566,1,104.736,0.04239}, + {1567,1,104.7547,0.0424}, + {1568,1,104.7735,0.0424}, + {1569,1,104.7922,0.04241}, + {1570,1,104.811,0.04241}, + {1571,1,104.8297,0.04241}, + {1572,1,104.8484,0.04242}, + {1573,1,104.8672,0.04242}, + {1574,1,104.8859,0.04243}, + {1575,1,104.9046,0.04243}, + {1576,1,104.9233,0.04244}, + {1577,1,104.942,0.04244}, + {1578,1,104.9607,0.04244}, + {1579,1,104.9794,0.04245}, + {1580,1,104.9981,0.04245}, + {1581,1,105.0167,0.04246}, + {1582,1,105.0354,0.04246}, + {1583,1,105.0541,0.04247}, + {1584,1,105.0727,0.04247}, + {1585,1,105.0914,0.04247}, + {1586,1,105.11,0.04248}, + {1587,1,105.1287,0.04248}, + {1588,1,105.1473,0.04249}, + {1589,1,105.166,0.04249}, + {1590,1,105.1846,0.0425}, + {1591,1,105.2032,0.0425}, + {1592,1,105.2218,0.0425}, + {1593,1,105.2404,0.04251}, + {1594,1,105.259,0.04251}, + {1595,1,105.2776,0.04252}, + {1596,1,105.2962,0.04252}, + {1597,1,105.3148,0.04253}, + {1598,1,105.3334,0.04253}, + {1599,1,105.352,0.04253}, + {1600,1,105.3705,0.04254}, + {1601,1,105.3891,0.04254}, + {1602,1,105.4076,0.04255}, + {1603,1,105.4262,0.04255}, + {1604,1,105.4447,0.04256}, + {1605,1,105.4633,0.04256}, + {1606,1,105.4818,0.04256}, + {1607,1,105.5003,0.04257}, + {1608,1,105.5189,0.04257}, + {1609,1,105.5374,0.04258}, + {1610,1,105.5559,0.04258}, + {1611,1,105.5744,0.04259}, + {1612,1,105.5929,0.04259}, + {1613,1,105.6114,0.04259}, + {1614,1,105.6299,0.0426}, + {1615,1,105.6483,0.0426}, + {1616,1,105.6668,0.04261}, + {1617,1,105.6853,0.04261}, + {1618,1,105.7037,0.04262}, + {1619,1,105.7222,0.04262}, + {1620,1,105.7406,0.04262}, + {1621,1,105.7591,0.04263}, + {1622,1,105.7775,0.04263}, + {1623,1,105.796,0.04264}, + {1624,1,105.8144,0.04264}, + {1625,1,105.8328,0.04264}, + {1626,1,105.8512,0.04265}, + {1627,1,105.8696,0.04265}, + {1628,1,105.888,0.04266}, + {1629,1,105.9064,0.04266}, + {1630,1,105.9248,0.04267}, + {1631,1,105.9432,0.04267}, + {1632,1,105.9616,0.04267}, + {1633,1,105.98,0.04268}, + {1634,1,105.9983,0.04268}, + {1635,1,106.0167,0.04269}, + {1636,1,106.0351,0.04269}, + {1637,1,106.0534,0.0427}, + {1638,1,106.0718,0.0427}, + {1639,1,106.0901,0.0427}, + {1640,1,106.1084,0.04271}, + {1641,1,106.1268,0.04271}, + {1642,1,106.1451,0.04272}, + {1643,1,106.1634,0.04272}, + {1644,1,106.1817,0.04272}, + {1645,1,106.2,0.04273}, + {1646,1,106.2183,0.04273}, + {1647,1,106.2366,0.04274}, + {1648,1,106.2549,0.04274}, + {1649,1,106.2732,0.04275}, + {1650,1,106.2915,0.04275}, + {1651,1,106.3097,0.04275}, + {1652,1,106.328,0.04276}, + {1653,1,106.3463,0.04276}, + {1654,1,106.3645,0.04277}, + {1655,1,106.3828,0.04277}, + {1656,1,106.401,0.04277}, + {1657,1,106.4192,0.04278}, + {1658,1,106.4375,0.04278}, + {1659,1,106.4557,0.04279}, + {1660,1,106.4739,0.04279}, + {1661,1,106.4921,0.0428}, + {1662,1,106.5103,0.0428}, + {1663,1,106.5285,0.0428}, + {1664,1,106.5467,0.04281}, + {1665,1,106.5649,0.04281}, + {1666,1,106.5831,0.04282}, + {1667,1,106.6013,0.04282}, + {1668,1,106.6195,0.04282}, + {1669,1,106.6376,0.04283}, + {1670,1,106.6558,0.04283}, + {1671,1,106.6739,0.04284}, + {1672,1,106.6921,0.04284}, + {1673,1,106.7102,0.04285}, + {1674,1,106.7284,0.04285}, + {1675,1,106.7465,0.04285}, + {1676,1,106.7646,0.04286}, + {1677,1,106.7828,0.04286}, + {1678,1,106.8009,0.04287}, + {1679,1,106.819,0.04287}, + {1680,1,106.8371,0.04287}, + {1681,1,106.8552,0.04288}, + {1682,1,106.8733,0.04288}, + {1683,1,106.8914,0.04289}, + {1684,1,106.9094,0.04289}, + {1685,1,106.9275,0.04289}, + {1686,1,106.9456,0.0429}, + {1687,1,106.9636,0.0429}, + {1688,1,106.9817,0.04291}, + {1689,1,106.9998,0.04291}, + {1690,1,107.0178,0.04292}, + {1691,1,107.0358,0.04292}, + {1692,1,107.0539,0.04292}, + {1693,1,107.0719,0.04293}, + {1694,1,107.0899,0.04293}, + {1695,1,107.1079,0.04294}, + {1696,1,107.126,0.04294}, + {1697,1,107.144,0.04294}, + {1698,1,107.162,0.04295}, + {1699,1,107.1799,0.04295}, + {1700,1,107.1979,0.04296}, + {1701,1,107.2159,0.04296}, + {1702,1,107.2339,0.04296}, + {1703,1,107.2519,0.04297}, + {1704,1,107.2698,0.04297}, + {1705,1,107.2878,0.04298}, + {1706,1,107.3057,0.04298}, + {1707,1,107.3237,0.04299}, + {1708,1,107.3416,0.04299}, + {1709,1,107.3596,0.04299}, + {1710,1,107.3775,0.043}, + {1711,1,107.3954,0.043}, + {1712,1,107.4133,0.04301}, + {1713,1,107.4312,0.04301}, + {1714,1,107.4492,0.04301}, + {1715,1,107.4671,0.04302}, + {1716,1,107.4849,0.04302}, + {1717,1,107.5028,0.04303}, + {1718,1,107.5207,0.04303}, + {1719,1,107.5386,0.04303}, + {1720,1,107.5565,0.04304}, + {1721,1,107.5743,0.04304}, + {1722,1,107.5922,0.04305}, + {1723,1,107.61,0.04305}, + {1724,1,107.6279,0.04305}, + {1725,1,107.6457,0.04306}, + {1726,1,107.6636,0.04306}, + {1727,1,107.6814,0.04307}, + {1728,1,107.6992,0.04307}, + {1729,1,107.717,0.04308}, + {1730,1,107.7349,0.04308}, + {1731,1,107.7527,0.04308}, + {1732,1,107.7705,0.04309}, + {1733,1,107.7883,0.04309}, + {1734,1,107.806,0.0431}, + {1735,1,107.8238,0.0431}, + {1736,1,107.8416,0.0431}, + {1737,1,107.8594,0.04311}, + {1738,1,107.8772,0.04311}, + {1739,1,107.8949,0.04312}, + {1740,1,107.9127,0.04312}, + {1741,1,107.9304,0.04312}, + {1742,1,107.9482,0.04313}, + {1743,1,107.9659,0.04313}, + {1744,1,107.9836,0.04314}, + {1745,1,108.0014,0.04314}, + {1746,1,108.0191,0.04314}, + {1747,1,108.0368,0.04315}, + {1748,1,108.0545,0.04315}, + {1749,1,108.0722,0.04316}, + {1750,1,108.0899,0.04316}, + {1751,1,108.1076,0.04316}, + {1752,1,108.1253,0.04317}, + {1753,1,108.143,0.04317}, + {1754,1,108.1607,0.04318}, + {1755,1,108.1783,0.04318}, + {1756,1,108.196,0.04318}, + {1757,1,108.2137,0.04319}, + {1758,1,108.2313,0.04319}, + {1759,1,108.249,0.0432}, + {1760,1,108.2666,0.0432}, + {1761,1,108.2842,0.04321}, + {1762,1,108.3019,0.04321}, + {1763,1,108.3195,0.04321}, + {1764,1,108.3371,0.04322}, + {1765,1,108.3547,0.04322}, + {1766,1,108.3723,0.04323}, + {1767,1,108.3899,0.04323}, + {1768,1,108.4075,0.04323}, + {1769,1,108.4251,0.04324}, + {1770,1,108.4427,0.04324}, + {1771,1,108.4603,0.04325}, + {1772,1,108.4779,0.04325}, + {1773,1,108.4954,0.04325}, + {1774,1,108.513,0.04326}, + {1775,1,108.5306,0.04326}, + {1776,1,108.5481,0.04327}, + {1777,1,108.5657,0.04327}, + {1778,1,108.5832,0.04327}, + {1779,1,108.6008,0.04328}, + {1780,1,108.6183,0.04328}, + {1781,1,108.6358,0.04329}, + {1782,1,108.6533,0.04329}, + {1783,1,108.6709,0.04329}, + {1784,1,108.6884,0.0433}, + {1785,1,108.7059,0.0433}, + {1786,1,108.7234,0.04331}, + {1787,1,108.7409,0.04331}, + {1788,1,108.7583,0.04331}, + {1789,1,108.7758,0.04332}, + {1790,1,108.7933,0.04332}, + {1791,1,108.8108,0.04333}, + {1792,1,108.8282,0.04333}, + {1793,1,108.8457,0.04333}, + {1794,1,108.8632,0.04334}, + {1795,1,108.8806,0.04334}, + {1796,1,108.8981,0.04335}, + {1797,1,108.9155,0.04335}, + {1798,1,108.9329,0.04335}, + {1799,1,108.9504,0.04336}, + {1800,1,108.9678,0.04336}, + {1801,1,108.9852,0.04337}, + {1802,1,109.0026,0.04337}, + {1803,1,109.02,0.04337}, + {1804,1,109.0374,0.04338}, + {1805,1,109.0548,0.04338}, + {1806,1,109.0722,0.04339}, + {1807,1,109.0896,0.04339}, + {1808,1,109.107,0.04339}, + {1809,1,109.1244,0.0434}, + {1810,1,109.1417,0.0434}, + {1811,1,109.1591,0.04341}, + {1812,1,109.1764,0.04341}, + {1813,1,109.1938,0.04341}, + {1814,1,109.2112,0.04342}, + {1815,1,109.2285,0.04342}, + {1816,1,109.2458,0.04343}, + {1817,1,109.2632,0.04343}, + {1818,1,109.2805,0.04343}, + {1819,1,109.2978,0.04344}, + {1820,1,109.3151,0.04344}, + {1821,1,109.3324,0.04345}, + {1822,1,109.3498,0.04345}, + {1823,1,109.3671,0.04345}, + {1824,1,109.3844,0.04346}, + {1825,1,109.4016,0.04346}, + {1826,1,109.4189,0.04346}, + {1827,1,109.4362,0.04347}, + {1828,1,109.4535,0.04347}, + {1829,1,109.4708,0.04348}, + {1830,1,109.488,0.04348}, + {1831,1,109.5053,0.04348}, + {1832,1,109.5225,0.04349}, + {1833,1,109.5398,0.04349}, + {1834,1,109.557,0.0435}, + {1835,1,109.5743,0.0435}, + {1836,1,109.5915,0.0435}, + {1837,1,109.6088,0.04351}, + {1838,1,109.626,0.04351}, + {1839,1,109.6432,0.04352}, + {1840,1,109.6604,0.04352}, + {1841,1,109.6776,0.04352}, + {1842,1,109.6948,0.04353}, + {1843,1,109.712,0.04353}, + {1844,1,109.7292,0.04354}, + {1845,1,109.7464,0.04354}, + {1846,1,109.7636,0.04354}, + {1847,1,109.7808,0.04355}, + {1848,1,109.798,0.04355}, + {1849,1,109.8151,0.04356}, + {1850,1,109.8323,0.04356}, + {1851,1,109.8494,0.04356}, + {1852,1,109.8666,0.04357}, + {1853,1,109.8837,0.04357}, + {1854,1,109.9009,0.04358}, + {1855,1,109.918,0.04358}, + {1856,1,109.9352,0.04358} + }; + return girlsLengthForAge[index < girlsLengthForAge.length ? index : girlsLengthForAge.length]; + } + + public double[]getBoysWeightForLength(int index){ + double[][]boysWeightForLength = { + {45,-0.3521,2.441,0.09182}, + {45.1,-0.3521,2.4577,0.09176}, + {45.2,-0.3521,2.4744,0.0917}, + {45.3,-0.3521,2.4911,0.09164}, + {45.4,-0.3521,2.5078,0.09159}, + {45.5,-0.3521,2.5244,0.09153}, + {45.6,-0.3521,2.5411,0.09147}, + {45.7,-0.3521,2.5578,0.09141}, + {45.8,-0.3521,2.5744,0.09135}, + {45.9,-0.3521,2.5911,0.09129}, + {46,-0.3521,2.6077,0.09124}, + {46.1,-0.3521,2.6244,0.09118}, + {46.2,-0.3521,2.6411,0.09112}, + {46.3,-0.3521,2.6578,0.09106}, + {46.4,-0.3521,2.6745,0.091}, + {46.5,-0.3521,2.6913,0.09094}, + {46.6,-0.3521,2.7081,0.09088}, + {46.7,-0.3521,2.7249,0.09083}, + {46.8,-0.3521,2.7417,0.09077}, + {46.9,-0.3521,2.7586,0.09071}, + {47,-0.3521,2.7755,0.09065}, + {47.1,-0.3521,2.7925,0.09059}, + {47.2,-0.3521,2.8095,0.09053}, + {47.3,-0.3521,2.8266,0.09047}, + {47.4,-0.3521,2.8437,0.09042}, + {47.5,-0.3521,2.8609,0.09036}, + {47.6,-0.3521,2.8782,0.0903}, + {47.7,-0.3521,2.8955,0.09024}, + {47.8,-0.3521,2.9129,0.09018}, + {47.9,-0.3521,2.9304,0.09012}, + {48,-0.3521,2.948,0.09007}, + {48.1,-0.3521,2.9657,0.09001}, + {48.2,-0.3521,2.9835,0.08995}, + {48.3,-0.3521,3.0014,0.08989}, + {48.4,-0.3521,3.0195,0.08983}, + {48.5,-0.3521,3.0377,0.08977}, + {48.6,-0.3521,3.056,0.08972}, + {48.7,-0.3521,3.0745,0.08966}, + {48.8,-0.3521,3.0931,0.0896}, + {48.9,-0.3521,3.1119,0.08954}, + {49,-0.3521,3.1308,0.08948}, + {49.1,-0.3521,3.1499,0.08943}, + {49.2,-0.3521,3.1691,0.08937}, + {49.3,-0.3521,3.1884,0.08931}, + {49.4,-0.3521,3.2079,0.08925}, + {49.5,-0.3521,3.2276,0.08919}, + {49.6,-0.3521,3.2473,0.08913}, + {49.7,-0.3521,3.2672,0.08908}, + {49.8,-0.3521,3.2873,0.08902}, + {49.9,-0.3521,3.3075,0.08896}, + {50,-0.3521,3.3278,0.0889}, + {50.1,-0.3521,3.3482,0.08884}, + {50.2,-0.3521,3.3688,0.08878}, + {50.3,-0.3521,3.3894,0.08872}, + {50.4,-0.3521,3.4102,0.08867}, + {50.5,-0.3521,3.4311,0.08861}, + {50.6,-0.3521,3.4522,0.08855}, + {50.7,-0.3521,3.4733,0.08849}, + {50.8,-0.3521,3.4946,0.08843}, + {50.9,-0.3521,3.5161,0.08837}, + {51,-0.3521,3.5376,0.08831}, + {51.1,-0.3521,3.5593,0.08825}, + {51.2,-0.3521,3.5812,0.08819}, + {51.3,-0.3521,3.6032,0.08813}, + {51.4,-0.3521,3.6254,0.08807}, + {51.5,-0.3521,3.6477,0.08801}, + {51.6,-0.3521,3.6702,0.08795}, + {51.7,-0.3521,3.6929,0.08789}, + {51.8,-0.3521,3.7157,0.08783}, + {51.9,-0.3521,3.7388,0.08777}, + {52,-0.3521,3.762,0.08771}, + {52.1,-0.3521,3.7855,0.08765}, + {52.2,-0.3521,3.8092,0.08759}, + {52.3,-0.3521,3.833,0.08753}, + {52.4,-0.3521,3.8571,0.08747}, + {52.5,-0.3521,3.8814,0.08741}, + {52.6,-0.3521,3.9059,0.08735}, + {52.7,-0.3521,3.9306,0.08729}, + {52.8,-0.3521,3.9555,0.08723}, + {52.9,-0.3521,3.9806,0.08717}, + {53,-0.3521,4.006,0.08711}, + {53.1,-0.3521,4.0315,0.08705}, + {53.2,-0.3521,4.0572,0.08699}, + {53.3,-0.3521,4.0831,0.08693}, + {53.4,-0.3521,4.1092,0.08687}, + {53.5,-0.3521,4.1354,0.08681}, + {53.6,-0.3521,4.1619,0.08675}, + {53.7,-0.3521,4.1885,0.08669}, + {53.8,-0.3521,4.2153,0.08663}, + {53.9,-0.3521,4.2422,0.08657}, + {54,-0.3521,4.2693,0.08651}, + {54.1,-0.3521,4.2965,0.08645}, + {54.2,-0.3521,4.3239,0.08639}, + {54.3,-0.3521,4.3513,0.08633}, + {54.4,-0.3521,4.3789,0.08627}, + {54.5,-0.3521,4.4066,0.08621}, + {54.6,-0.3521,4.4344,0.08615}, + {54.7,-0.3521,4.4623,0.0861}, + {54.8,-0.3521,4.4903,0.08604}, + {54.9,-0.3521,4.5185,0.08598}, + {55,-0.3521,4.5467,0.08592}, + {55.1,-0.3521,4.575,0.08586}, + {55.2,-0.3521,4.6034,0.0858}, + {55.3,-0.3521,4.6319,0.08575}, + {55.4,-0.3521,4.6605,0.08569}, + {55.5,-0.3521,4.6892,0.08563}, + {55.6,-0.3521,4.718,0.08558}, + {55.7,-0.3521,4.7469,0.08552}, + {55.8,-0.3521,4.7758,0.08546}, + {55.9,-0.3521,4.8048,0.08541}, + {56,-0.3521,4.8338,0.08535}, + {56.1,-0.3521,4.8629,0.08529}, + {56.2,-0.3521,4.892,0.08524}, + {56.3,-0.3521,4.9212,0.08518}, + {56.4,-0.3521,4.9504,0.08513}, + {56.5,-0.3521,4.9796,0.08507}, + {56.6,-0.3521,5.0088,0.08502}, + {56.7,-0.3521,5.0381,0.08497}, + {56.8,-0.3521,5.0673,0.08491}, + {56.9,-0.3521,5.0966,0.08486}, + {57,-0.3521,5.1259,0.08481}, + {57.1,-0.3521,5.1551,0.08475}, + {57.2,-0.3521,5.1844,0.0847}, + {57.3,-0.3521,5.2137,0.08465}, + {57.4,-0.3521,5.2429,0.0846}, + {57.5,-0.3521,5.2721,0.08455}, + {57.6,-0.3521,5.3014,0.08449}, + {57.7,-0.3521,5.3306,0.08444}, + {57.8,-0.3521,5.3598,0.08439}, + {57.9,-0.3521,5.3889,0.08434}, + {58,-0.3521,5.418,0.0843}, + {58.1,-0.3521,5.4471,0.08425}, + {58.2,-0.3521,5.4762,0.0842}, + {58.3,-0.3521,5.5053,0.08415}, + {58.4,-0.3521,5.5343,0.0841}, + {58.5,-0.3521,5.5632,0.08406}, + {58.6,-0.3521,5.5922,0.08401}, + {58.7,-0.3521,5.621,0.08397}, + {58.8,-0.3521,5.6499,0.08392}, + {58.9,-0.3521,5.6787,0.08388}, + {59,-0.3521,5.7074,0.08383}, + {59.1,-0.3521,5.7361,0.08379}, + {59.2,-0.3521,5.7647,0.08375}, + {59.3,-0.3521,5.7933,0.0837}, + {59.4,-0.3521,5.8217,0.08366}, + {59.5,-0.3521,5.8501,0.08362}, + {59.6,-0.3521,5.8784,0.08358}, + {59.7,-0.3521,5.9067,0.08354}, + {59.8,-0.3521,5.9348,0.0835}, + {59.9,-0.3521,5.9628,0.08346}, + {60,-0.3521,5.9907,0.08342}, + {60.1,-0.3521,6.0185,0.08339}, + {60.2,-0.3521,6.0461,0.08335}, + {60.3,-0.3521,6.0737,0.08331}, + {60.4,-0.3521,6.1011,0.08328}, + {60.5,-0.3521,6.1284,0.08324}, + {60.6,-0.3521,6.1556,0.08321}, + {60.7,-0.3521,6.1827,0.08317}, + {60.8,-0.3521,6.2096,0.08314}, + {60.9,-0.3521,6.2365,0.08311}, + {61,-0.3521,6.2632,0.08308}, + {61.1,-0.3521,6.2899,0.08304}, + {61.2,-0.3521,6.3164,0.08301}, + {61.3,-0.3521,6.3428,0.08298}, + {61.4,-0.3521,6.3692,0.08295}, + {61.5,-0.3521,6.3954,0.08292}, + {61.6,-0.3521,6.4215,0.0829}, + {61.7,-0.3521,6.4475,0.08287}, + {61.8,-0.3521,6.4735,0.08284}, + {61.9,-0.3521,6.4993,0.08281}, + {62,-0.3521,6.5251,0.08279}, + {62.1,-0.3521,6.5508,0.08276}, + {62.2,-0.3521,6.5764,0.08273}, + {62.3,-0.3521,6.6019,0.08271}, + {62.4,-0.3521,6.6273,0.08268}, + {62.5,-0.3521,6.6527,0.08266}, + {62.6,-0.3521,6.678,0.08264}, + {62.7,-0.3521,6.7033,0.08261}, + {62.8,-0.3521,6.7284,0.08259}, + {62.9,-0.3521,6.7535,0.08257}, + {63,-0.3521,6.7786,0.08255}, + {63.1,-0.3521,6.8035,0.08253}, + {63.2,-0.3521,6.8285,0.08251}, + {63.3,-0.3521,6.8533,0.08249}, + {63.4,-0.3521,6.8781,0.08247}, + {63.5,-0.3521,6.9028,0.08245}, + {63.6,-0.3521,6.9275,0.08243}, + {63.7,-0.3521,6.9521,0.08241}, + {63.8,-0.3521,6.9766,0.0824}, + {63.9,-0.3521,7.0011,0.08238}, + {64,-0.3521,7.0255,0.08236}, + {64.1,-0.3521,7.0499,0.08235}, + {64.2,-0.3521,7.0742,0.08233}, + {64.3,-0.3521,7.0984,0.08232}, + {64.4,-0.3521,7.1226,0.0823}, + {64.5,-0.3521,7.1467,0.08229}, + {64.6,-0.3521,7.1708,0.08228}, + {64.7,-0.3521,7.1948,0.08227}, + {64.8,-0.3521,7.2188,0.08225}, + {64.9,-0.3521,7.2427,0.08224}, + {65,-0.3521,7.2666,0.08223}, + {65.1,-0.3521,7.2905,0.08222}, + {65.2,-0.3521,7.3143,0.08221}, + {65.3,-0.3521,7.338,0.0822}, + {65.4,-0.3521,7.3617,0.08219}, + {65.5,-0.3521,7.3854,0.08218}, + {65.6,-0.3521,7.4091,0.08218}, + {65.7,-0.3521,7.4327,0.08217}, + {65.8,-0.3521,7.4563,0.08216}, + {65.9,-0.3521,7.4799,0.08216}, + {66,-0.3521,7.5034,0.08215}, + {66.1,-0.3521,7.5269,0.08214}, + {66.2,-0.3521,7.5504,0.08214}, + {66.3,-0.3521,7.5738,0.08214}, + {66.4,-0.3521,7.5973,0.08213}, + {66.5,-0.3521,7.6206,0.08213}, + {66.6,-0.3521,7.644,0.08213}, + {66.7,-0.3521,7.6673,0.08212}, + {66.8,-0.3521,7.6906,0.08212}, + {66.9,-0.3521,7.7138,0.08212}, + {67,-0.3521,7.737,0.08212}, + {67.1,-0.3521,7.7602,0.08212}, + {67.2,-0.3521,7.7834,0.08212}, + {67.3,-0.3521,7.8065,0.08212}, + {67.4,-0.3521,7.8296,0.08212}, + {67.5,-0.3521,7.8526,0.08212}, + {67.6,-0.3521,7.8757,0.08212}, + {67.7,-0.3521,7.8986,0.08213}, + {67.8,-0.3521,7.9216,0.08213}, + {67.9,-0.3521,7.9445,0.08213}, + {68,-0.3521,7.9674,0.08214}, + {68.1,-0.3521,7.9903,0.08214}, + {68.2,-0.3521,8.0132,0.08214}, + {68.3,-0.3521,8.036,0.08215}, + {68.4,-0.3521,8.0588,0.08215}, + {68.5,-0.3521,8.0816,0.08216}, + {68.6,-0.3521,8.1044,0.08217}, + {68.7,-0.3521,8.1272,0.08217}, + {68.8,-0.3521,8.15,0.08218}, + {68.9,-0.3521,8.1727,0.08219}, + {69,-0.3521,8.1955,0.08219}, + {69.1,-0.3521,8.2183,0.0822}, + {69.2,-0.3521,8.241,0.08221}, + {69.3,-0.3521,8.2638,0.08222}, + {69.4,-0.3521,8.2865,0.08223}, + {69.5,-0.3521,8.3092,0.08224}, + {69.6,-0.3521,8.332,0.08225}, + {69.7,-0.3521,8.3547,0.08226}, + {69.8,-0.3521,8.3774,0.08227}, + {69.9,-0.3521,8.4001,0.08228}, + {70,-0.3521,8.4227,0.08229}, + {70.1,-0.3521,8.4454,0.0823}, + {70.2,-0.3521,8.468,0.08231}, + {70.3,-0.3521,8.4906,0.08232}, + {70.4,-0.3521,8.5132,0.08233}, + {70.5,-0.3521,8.5358,0.08235}, + {70.6,-0.3521,8.5583,0.08236}, + {70.7,-0.3521,8.5808,0.08237}, + {70.8,-0.3521,8.6032,0.08238}, + {70.9,-0.3521,8.6257,0.0824}, + {71,-0.3521,8.648,0.08241}, + {71.1,-0.3521,8.6704,0.08242}, + {71.2,-0.3521,8.6927,0.08243}, + {71.3,-0.3521,8.715,0.08245}, + {71.4,-0.3521,8.7372,0.08246}, + {71.5,-0.3521,8.7594,0.08248}, + {71.6,-0.3521,8.7815,0.08249}, + {71.7,-0.3521,8.8036,0.0825}, + {71.8,-0.3521,8.8257,0.08252}, + {71.9,-0.3521,8.8477,0.08253}, + {72,-0.3521,8.8697,0.08254}, + {72.1,-0.3521,8.8916,0.08256}, + {72.2,-0.3521,8.9135,0.08257}, + {72.3,-0.3521,8.9353,0.08259}, + {72.4,-0.3521,8.9571,0.0826}, + {72.5,-0.3521,8.9788,0.08262}, + {72.6,-0.3521,9.0005,0.08263}, + {72.7,-0.3521,9.0221,0.08264}, + {72.8,-0.3521,9.0436,0.08266}, + {72.9,-0.3521,9.0651,0.08267}, + {73,-0.3521,9.0865,0.08269}, + {73.1,-0.3521,9.1079,0.0827}, + {73.2,-0.3521,9.1292,0.08272}, + {73.3,-0.3521,9.1504,0.08273}, + {73.4,-0.3521,9.1716,0.08274}, + {73.5,-0.3521,9.1927,0.08276}, + {73.6,-0.3521,9.2137,0.08277}, + {73.7,-0.3521,9.2347,0.08278}, + {73.8,-0.3521,9.2557,0.0828}, + {73.9,-0.3521,9.2766,0.08281}, + {74,-0.3521,9.2974,0.08283}, + {74.1,-0.3521,9.3182,0.08284}, + {74.2,-0.3521,9.339,0.08285}, + {74.3,-0.3521,9.3597,0.08287}, + {74.4,-0.3521,9.3803,0.08288}, + {74.5,-0.3521,9.401,0.08289}, + {74.6,-0.3521,9.4215,0.0829}, + {74.7,-0.3521,9.442,0.08292}, + {74.8,-0.3521,9.4625,0.08293}, + {74.9,-0.3521,9.4829,0.08294}, + {75,-0.3521,9.5032,0.08295}, + {75.1,-0.3521,9.5235,0.08297}, + {75.2,-0.3521,9.5438,0.08298}, + {75.3,-0.3521,9.5639,0.08299}, + {75.4,-0.3521,9.5841,0.083}, + {75.5,-0.3521,9.6041,0.08301}, + {75.6,-0.3521,9.6241,0.08302}, + {75.7,-0.3521,9.644,0.08303}, + {75.8,-0.3521,9.6639,0.08305}, + {75.9,-0.3521,9.6836,0.08306}, + {76,-0.3521,9.7033,0.08307}, + {76.1,-0.3521,9.723,0.08307}, + {76.2,-0.3521,9.7425,0.08308}, + {76.3,-0.3521,9.762,0.08309}, + {76.4,-0.3521,9.7814,0.0831}, + {76.5,-0.3521,9.8007,0.08311}, + {76.6,-0.3521,9.82,0.08312}, + {76.7,-0.3521,9.8392,0.08312}, + {76.8,-0.3521,9.8583,0.08313}, + {76.9,-0.3521,9.8773,0.08314}, + {77,-0.3521,9.8963,0.08314}, + {77.1,-0.3521,9.9152,0.08315}, + {77.2,-0.3521,9.9341,0.08315}, + {77.3,-0.3521,9.9528,0.08316}, + {77.4,-0.3521,9.9716,0.08316}, + {77.5,-0.3521,9.9902,0.08317}, + {77.6,-0.3521,10.0088,0.08317}, + {77.7,-0.3521,10.0274,0.08317}, + {77.8,-0.3521,10.0459,0.08318}, + {77.9,-0.3521,10.0643,0.08318}, + {78,-0.3521,10.0827,0.08318}, + {78.1,-0.3521,10.1011,0.08318}, + {78.2,-0.3521,10.1194,0.08318}, + {78.3,-0.3521,10.1377,0.08318}, + {78.4,-0.3521,10.1559,0.08318}, + {78.5,-0.3521,10.1741,0.08318}, + {78.6,-0.3521,10.1923,0.08317}, + {78.7,-0.3521,10.2105,0.08317}, + {78.8,-0.3521,10.2286,0.08317}, + {78.9,-0.3521,10.2468,0.08316}, + {79,-0.3521,10.2649,0.08316}, + {79.1,-0.3521,10.2831,0.08315}, + {79.2,-0.3521,10.3012,0.08315}, + {79.3,-0.3521,10.3194,0.08314}, + {79.4,-0.3521,10.3376,0.08313}, + {79.5,-0.3521,10.3558,0.08313}, + {79.6,-0.3521,10.3741,0.08312}, + {79.7,-0.3521,10.3923,0.08311}, + {79.8,-0.3521,10.4107,0.0831}, + {79.9,-0.3521,10.4291,0.08309}, + {80,-0.3521,10.4475,0.08308}, + {80.1,-0.3521,10.466,0.08307}, + {80.2,-0.3521,10.4845,0.08305}, + {80.3,-0.3521,10.5031,0.08304}, + {80.4,-0.3521,10.5217,0.08303}, + {80.5,-0.3521,10.5405,0.08301}, + {80.6,-0.3521,10.5592,0.083}, + {80.7,-0.3521,10.5781,0.08298}, + {80.8,-0.3521,10.597,0.08297}, + {80.9,-0.3521,10.6161,0.08295}, + {81,-0.3521,10.6352,0.08293}, + {81.1,-0.3521,10.6544,0.08291}, + {81.2,-0.3521,10.6737,0.0829}, + {81.3,-0.3521,10.6931,0.08288}, + {81.4,-0.3521,10.7126,0.08286}, + {81.5,-0.3521,10.7322,0.08284}, + {81.6,-0.3521,10.752,0.08282}, + {81.7,-0.3521,10.7718,0.08279}, + {81.8,-0.3521,10.7918,0.08277}, + {81.9,-0.3521,10.8119,0.08275}, + {82,-0.3521,10.8321,0.08273}, + {82.1,-0.3521,10.8524,0.0827}, + {82.2,-0.3521,10.8728,0.08268}, + {82.3,-0.3521,10.8934,0.08265}, + {82.4,-0.3521,10.9142,0.08263}, + {82.5,-0.3521,10.935,0.0826}, + {82.6,-0.3521,10.956,0.08258}, + {82.7,-0.3521,10.9772,0.08255}, + {82.8,-0.3521,10.9985,0.08252}, + {82.9,-0.3521,11.0199,0.08249}, + {83,-0.3521,11.0415,0.08246}, + {83.1,-0.3521,11.0632,0.08244}, + {83.2,-0.3521,11.0851,0.08241}, + {83.3,-0.3521,11.1071,0.08238}, + {83.4,-0.3521,11.1293,0.08235}, + {83.5,-0.3521,11.1516,0.08231}, + {83.6,-0.3521,11.174,0.08228}, + {83.7,-0.3521,11.1966,0.08225}, + {83.8,-0.3521,11.2193,0.08222}, + {83.9,-0.3521,11.2422,0.08219}, + {84,-0.3521,11.2651,0.08215}, + {84.1,-0.3521,11.2882,0.08212}, + {84.2,-0.3521,11.3114,0.08209}, + {84.3,-0.3521,11.3347,0.08205}, + {84.4,-0.3521,11.3581,0.08202}, + {84.5,-0.3521,11.3817,0.08198}, + {84.6,-0.3521,11.4053,0.08195}, + {84.7,-0.3521,11.429,0.08191}, + {84.8,-0.3521,11.4529,0.08188}, + {84.9,-0.3521,11.4768,0.08184}, + {85,-0.3521,11.5007,0.08181}, + {85.1,-0.3521,11.5248,0.08177}, + {85.2,-0.3521,11.549,0.08174}, + {85.3,-0.3521,11.5732,0.0817}, + {85.4,-0.3521,11.5975,0.08166}, + {85.5,-0.3521,11.6218,0.08163}, + {85.6,-0.3521,11.6462,0.08159}, + {85.7,-0.3521,11.6707,0.08156}, + {85.8,-0.3521,11.6952,0.08152}, + {85.9,-0.3521,11.7198,0.08148}, + {86,-0.3521,11.7444,0.08145}, + {86.1,-0.3521,11.769,0.08141}, + {86.2,-0.3521,11.7937,0.08138}, + {86.3,-0.3521,11.8184,0.08134}, + {86.4,-0.3521,11.8431,0.08131}, + {86.5,-0.3521,11.8678,0.08128}, + {86.6,-0.3521,11.8926,0.08124}, + {86.7,-0.3521,11.9173,0.08121}, + {86.8,-0.3521,11.9421,0.08118}, + {86.9,-0.3521,11.9668,0.08114}, + {87,-0.3521,11.9916,0.08111}, + {87.1,-0.3521,12.0163,0.08108}, + {87.2,-0.3521,12.0411,0.08105}, + {87.3,-0.3521,12.0658,0.08102}, + {87.4,-0.3521,12.0905,0.08099}, + {87.5,-0.3521,12.1152,0.08096}, + {87.6,-0.3521,12.1398,0.08093}, + {87.7,-0.3521,12.1645,0.0809}, + {87.8,-0.3521,12.1891,0.08087}, + {87.9,-0.3521,12.2136,0.08084}, + {88,-0.3521,12.2382,0.08082}, + {88.1,-0.3521,12.2627,0.08079}, + {88.2,-0.3521,12.2871,0.08076}, + {88.3,-0.3521,12.3116,0.08074}, + {88.4,-0.3521,12.336,0.08071}, + {88.5,-0.3521,12.3603,0.08069}, + {88.6,-0.3521,12.3846,0.08067}, + {88.7,-0.3521,12.4089,0.08064}, + {88.8,-0.3521,12.4332,0.08062}, + {88.9,-0.3521,12.4574,0.0806}, + {89,-0.3521,12.4815,0.08058}, + {89.1,-0.3521,12.5057,0.08056}, + {89.2,-0.3521,12.5298,0.08054}, + {89.3,-0.3521,12.5538,0.08052}, + {89.4,-0.3521,12.5778,0.0805}, + {89.5,-0.3521,12.6017,0.08048}, + {89.6,-0.3521,12.6257,0.08047}, + {89.7,-0.3521,12.6495,0.08045}, + {89.8,-0.3521,12.6734,0.08044}, + {89.9,-0.3521,12.6972,0.08042}, + {90,-0.3521,12.7209,0.08041}, + {90.1,-0.3521,12.7446,0.08039}, + {90.2,-0.3521,12.7683,0.08038}, + {90.3,-0.3521,12.792,0.08037}, + {90.4,-0.3521,12.8156,0.08035}, + {90.5,-0.3521,12.8392,0.08034}, + {90.6,-0.3521,12.8628,0.08033}, + {90.7,-0.3521,12.8864,0.08032}, + {90.8,-0.3521,12.9099,0.08031}, + {90.9,-0.3521,12.9334,0.0803}, + {91,-0.3521,12.9569,0.0803}, + {91.1,-0.3521,12.9804,0.08029}, + {91.2,-0.3521,13.0038,0.08028}, + {91.3,-0.3521,13.0273,0.08027}, + {91.4,-0.3521,13.0507,0.08027}, + {91.5,-0.3521,13.0742,0.08026}, + {91.6,-0.3521,13.0976,0.08026}, + {91.7,-0.3521,13.1209,0.08025}, + {91.8,-0.3521,13.1443,0.08025}, + {91.9,-0.3521,13.1677,0.08025}, + {92,-0.3521,13.191,0.08025}, + {92.1,-0.3521,13.2143,0.08025}, + {92.2,-0.3521,13.2376,0.08024}, + {92.3,-0.3521,13.2609,0.08024}, + {92.4,-0.3521,13.2842,0.08024}, + {92.5,-0.3521,13.3075,0.08025}, + {92.6,-0.3521,13.3308,0.08025}, + {92.7,-0.3521,13.3541,0.08025}, + {92.8,-0.3521,13.3773,0.08025}, + {92.9,-0.3521,13.4006,0.08026}, + {93,-0.3521,13.4239,0.08026}, + {93.1,-0.3521,13.4472,0.08027}, + {93.2,-0.3521,13.4705,0.08027}, + {93.3,-0.3521,13.4937,0.08028}, + {93.4,-0.3521,13.5171,0.08028}, + {93.5,-0.3521,13.5404,0.08029}, + {93.6,-0.3521,13.5637,0.0803}, + {93.7,-0.3521,13.587,0.08031}, + {93.8,-0.3521,13.6104,0.08032}, + {93.9,-0.3521,13.6338,0.08033}, + {94,-0.3521,13.6572,0.08034}, + {94.1,-0.3521,13.6806,0.08035}, + {94.2,-0.3521,13.7041,0.08036}, + {94.3,-0.3521,13.7275,0.08037}, + {94.4,-0.3521,13.751,0.08038}, + {94.5,-0.3521,13.7746,0.0804}, + {94.6,-0.3521,13.7981,0.08041}, + {94.7,-0.3521,13.8217,0.08043}, + {94.8,-0.3521,13.8454,0.08044}, + {94.9,-0.3521,13.8691,0.08046}, + {95,-0.3521,13.8928,0.08047}, + {95.1,-0.3521,13.9165,0.08049}, + {95.2,-0.3521,13.9403,0.08051}, + {95.3,-0.3521,13.9642,0.08052}, + {95.4,-0.3521,13.9881,0.08054}, + {95.5,-0.3521,14.012,0.08056}, + {95.6,-0.3521,14.036,0.08058}, + {95.7,-0.3521,14.06,0.0806}, + {95.8,-0.3521,14.0841,0.08062}, + {95.9,-0.3521,14.1083,0.08064}, + {96,-0.3521,14.1325,0.08067}, + {96.1,-0.3521,14.1567,0.08069}, + {96.2,-0.3521,14.1811,0.08071}, + {96.3,-0.3521,14.2055,0.08073}, + {96.4,-0.3521,14.2299,0.08076}, + {96.5,-0.3521,14.2544,0.08078}, + {96.6,-0.3521,14.279,0.08081}, + {96.7,-0.3521,14.3037,0.08083}, + {96.8,-0.3521,14.3284,0.08086}, + {96.9,-0.3521,14.3533,0.08089}, + {97,-0.3521,14.3782,0.08092}, + {97.1,-0.3521,14.4031,0.08094}, + {97.2,-0.3521,14.4282,0.08097}, + {97.3,-0.3521,14.4533,0.081}, + {97.4,-0.3521,14.4785,0.08103}, + {97.5,-0.3521,14.5038,0.08106}, + {97.6,-0.3521,14.5292,0.08109}, + {97.7,-0.3521,14.5547,0.08112}, + {97.8,-0.3521,14.5802,0.08116}, + {97.9,-0.3521,14.6058,0.08119}, + {98,-0.3521,14.6316,0.08122}, + {98.1,-0.3521,14.6574,0.08125}, + {98.2,-0.3521,14.6832,0.08129}, + {98.3,-0.3521,14.7092,0.08132}, + {98.4,-0.3521,14.7353,0.08136}, + {98.5,-0.3521,14.7614,0.08139}, + {98.6,-0.3521,14.7877,0.08143}, + {98.7,-0.3521,14.814,0.08146}, + {98.8,-0.3521,14.8404,0.0815}, + {98.9,-0.3521,14.8669,0.08154}, + {99,-0.3521,14.8934,0.08157}, + {99.1,-0.3521,14.9201,0.08161}, + {99.2,-0.3521,14.9468,0.08165}, + {99.3,-0.3521,14.9736,0.08169}, + {99.4,-0.3521,15.0005,0.08173}, + {99.5,-0.3521,15.0275,0.08177}, + {99.6,-0.3521,15.0546,0.08181}, + {99.7,-0.3521,15.0818,0.08185}, + {99.8,-0.3521,15.109,0.08189}, + {99.9,-0.3521,15.1363,0.08194}, + {100,-0.3521,15.1637,0.08198}, + {100.1,-0.3521,15.1912,0.08202}, + {100.2,-0.3521,15.2187,0.08206}, + {100.3,-0.3521,15.2463,0.08211}, + {100.4,-0.3521,15.274,0.08215}, + {100.5,-0.3521,15.3018,0.0822}, + {100.6,-0.3521,15.3297,0.08224}, + {100.7,-0.3521,15.3576,0.08229}, + {100.8,-0.3521,15.3856,0.08233}, + {100.9,-0.3521,15.4137,0.08238}, + {101,-0.3521,15.4419,0.08243}, + {101.1,-0.3521,15.4701,0.08247}, + {101.2,-0.3521,15.4985,0.08252}, + {101.3,-0.3521,15.5268,0.08257}, + {101.4,-0.3521,15.5553,0.08262}, + {101.5,-0.3521,15.5838,0.08267}, + {101.6,-0.3521,15.6125,0.08272}, + {101.7,-0.3521,15.6412,0.08277}, + {101.8,-0.3521,15.6699,0.08281}, + {101.9,-0.3521,15.6987,0.08287}, + {102,-0.3521,15.7276,0.08292}, + {102.1,-0.3521,15.7566,0.08297}, + {102.2,-0.3521,15.7857,0.08302}, + {102.3,-0.3521,15.8148,0.08307}, + {102.4,-0.3521,15.844,0.08312}, + {102.5,-0.3521,15.8732,0.08317}, + {102.6,-0.3521,15.9026,0.08322}, + {102.7,-0.3521,15.932,0.08328}, + {102.8,-0.3521,15.9615,0.08333}, + {102.9,-0.3521,15.991,0.08338}, + {103,-0.3521,16.0206,0.08343}, + {103.1,-0.3521,16.0503,0.08349}, + {103.2,-0.3521,16.0801,0.08354}, + {103.3,-0.3521,16.1099,0.08359}, + {103.4,-0.3521,16.1398,0.08365}, + {103.5,-0.3521,16.1697,0.0837}, + {103.6,-0.3521,16.1997,0.08376}, + {103.7,-0.3521,16.2298,0.08381}, + {103.8,-0.3521,16.26,0.08386}, + {103.9,-0.3521,16.2902,0.08392}, + {104,-0.3521,16.3204,0.08397}, + {104.1,-0.3521,16.3508,0.08403}, + {104.2,-0.3521,16.3812,0.08408}, + {104.3,-0.3521,16.4117,0.08414}, + {104.4,-0.3521,16.4422,0.08419}, + {104.5,-0.3521,16.4728,0.08425}, + {104.6,-0.3521,16.5035,0.08431}, + {104.7,-0.3521,16.5342,0.08436}, + {104.8,-0.3521,16.565,0.08442}, + {104.9,-0.3521,16.5959,0.08447}, + {105,-0.3521,16.6268,0.08453}, + {105.1,-0.3521,16.6579,0.08458}, + {105.2,-0.3521,16.6889,0.08464}, + {105.3,-0.3521,16.7201,0.0847}, + {105.4,-0.3521,16.7513,0.08475}, + {105.5,-0.3521,16.7826,0.08481}, + {105.6,-0.3521,16.8139,0.08487}, + {105.7,-0.3521,16.8454,0.08493}, + {105.8,-0.3521,16.8769,0.08498}, + {105.9,-0.3521,16.9084,0.08504}, + {106,-0.3521,16.9401,0.0851}, + {106.1,-0.3521,16.9718,0.08516}, + {106.2,-0.3521,17.0036,0.08521}, + {106.3,-0.3521,17.0355,0.08527}, + {106.4,-0.3521,17.0674,0.08533}, + {106.5,-0.3521,17.0995,0.08539}, + {106.6,-0.3521,17.1316,0.08545}, + {106.7,-0.3521,17.1637,0.08551}, + {106.8,-0.3521,17.196,0.08557}, + {106.9,-0.3521,17.2283,0.08562}, + {107,-0.3521,17.2607,0.08568}, + {107.1,-0.3521,17.2931,0.08574}, + {107.2,-0.3521,17.3256,0.0858}, + {107.3,-0.3521,17.3582,0.08586}, + {107.4,-0.3521,17.3909,0.08592}, + {107.5,-0.3521,17.4237,0.08599}, + {107.6,-0.3521,17.4565,0.08605}, + {107.7,-0.3521,17.4894,0.08611}, + {107.8,-0.3521,17.5224,0.08617}, + {107.9,-0.3521,17.5554,0.08623}, + {108,-0.3521,17.5885,0.08629}, + {108.1,-0.3521,17.6217,0.08635}, + {108.2,-0.3521,17.655,0.08641}, + {108.3,-0.3521,17.6884,0.08648}, + {108.4,-0.3521,17.7218,0.08654}, + {108.5,-0.3521,17.7553,0.0866}, + {108.6,-0.3521,17.7889,0.08666}, + {108.7,-0.3521,17.8226,0.08673}, + {108.8,-0.3521,17.8564,0.08679}, + {108.9,-0.3521,17.8903,0.08685}, + {109,-0.3521,17.9242,0.08691}, + {109.1,-0.3521,17.9583,0.08698}, + {109.2,-0.3521,17.9924,0.08704}, + {109.3,-0.3521,18.0267,0.0871}, + {109.4,-0.3521,18.061,0.08717}, + {109.5,-0.3521,18.0954,0.08723}, + {109.6,-0.3521,18.1299,0.0873}, + {109.7,-0.3521,18.1645,0.08736}, + {109.8,-0.3521,18.1992,0.08742}, + {109.9,-0.3521,18.234,0.08749}, + {110,-0.3521,18.2689,0.08755} + }; + return boysWeightForLength[index < boysWeightForLength.length ? index : boysWeightForLength.length-1]; + } + + public double[]getGirlsWeightForLength(int index){ + double[][]girlsWeightForLength = { + {45,-0.3833,2.4607,0.09029}, + {45.1,-0.3833,2.4777,0.0903}, + {45.2,-0.3833,2.4947,0.0903}, + {45.3,-0.3833,2.5117,0.09031}, + {45.4,-0.3833,2.5287,0.09032}, + {45.5,-0.3833,2.5457,0.09033}, + {45.6,-0.3833,2.5627,0.09033}, + {45.7,-0.3833,2.5797,0.09034}, + {45.8,-0.3833,2.5967,0.09035}, + {45.9,-0.3833,2.6137,0.09036}, + {46,-0.3833,2.6306,0.09037}, + {46.1,-0.3833,2.6476,0.09037}, + {46.2,-0.3833,2.6646,0.09038}, + {46.3,-0.3833,2.6816,0.09039}, + {46.4,-0.3833,2.6986,0.0904}, + {46.5,-0.3833,2.7155,0.0904}, + {46.6,-0.3833,2.7326,0.09041}, + {46.7,-0.3833,2.7496,0.09042}, + {46.8,-0.3833,2.7666,0.09043}, + {46.9,-0.3833,2.7837,0.09044}, + {47,-0.3833,2.8007,0.09044}, + {47.1,-0.3833,2.8179,0.09045}, + {47.2,-0.3833,2.835,0.09046}, + {47.3,-0.3833,2.8522,0.09047}, + {47.4,-0.3833,2.8694,0.09047}, + {47.5,-0.3833,2.8867,0.09048}, + {47.6,-0.3833,2.9041,0.09049}, + {47.7,-0.3833,2.9215,0.0905}, + {47.8,-0.3833,2.939,0.0905}, + {47.9,-0.3833,2.9565,0.09051}, + {48,-0.3833,2.9741,0.09052}, + {48.1,-0.3833,2.9918,0.09053}, + {48.2,-0.3833,3.0096,0.09054}, + {48.3,-0.3833,3.0275,0.09054}, + {48.4,-0.3833,3.0455,0.09055}, + {48.5,-0.3833,3.0636,0.09056}, + {48.6,-0.3833,3.0818,0.09057}, + {48.7,-0.3833,3.1001,0.09057}, + {48.8,-0.3833,3.1186,0.09058}, + {48.9,-0.3833,3.1372,0.09059}, + {49,-0.3833,3.156,0.0906}, + {49.1,-0.3833,3.1749,0.09061}, + {49.2,-0.3833,3.1939,0.09061}, + {49.3,-0.3833,3.2131,0.09062}, + {49.4,-0.3833,3.2325,0.09063}, + {49.5,-0.3833,3.252,0.09064}, + {49.6,-0.3833,3.2717,0.09065}, + {49.7,-0.3833,3.2915,0.09065}, + {49.8,-0.3833,3.3114,0.09066}, + {49.9,-0.3833,3.3316,0.09067}, + {50,-0.3833,3.3518,0.09068}, + {50.1,-0.3833,3.3723,0.09069}, + {50.2,-0.3833,3.3929,0.09069}, + {50.3,-0.3833,3.4136,0.0907}, + {50.4,-0.3833,3.4346,0.09071}, + {50.5,-0.3833,3.4557,0.09072}, + {50.6,-0.3833,3.4769,0.09073}, + {50.7,-0.3833,3.4983,0.09074}, + {50.8,-0.3833,3.5199,0.09074}, + {50.9,-0.3833,3.5417,0.09075}, + {51,-0.3833,3.5636,0.09076}, + {51.1,-0.3833,3.5856,0.09077}, + {51.2,-0.3833,3.6078,0.09078}, + {51.3,-0.3833,3.6302,0.09079}, + {51.4,-0.3833,3.6527,0.0908}, + {51.5,-0.3833,3.6754,0.0908}, + {51.6,-0.3833,3.6982,0.09081}, + {51.7,-0.3833,3.7212,0.09082}, + {51.8,-0.3833,3.7444,0.09083}, + {51.9,-0.3833,3.7677,0.09084}, + {52,-0.3833,3.7911,0.09085}, + {52.1,-0.3833,3.8147,0.09086}, + {52.2,-0.3833,3.8385,0.09086}, + {52.3,-0.3833,3.8623,0.09087}, + {52.4,-0.3833,3.8863,0.09088}, + {52.5,-0.3833,3.9105,0.09089}, + {52.6,-0.3833,3.9348,0.0909}, + {52.7,-0.3833,3.9592,0.09091}, + {52.8,-0.3833,3.9837,0.09092}, + {52.9,-0.3833,4.0084,0.09093}, + {53,-0.3833,4.0332,0.09093}, + {53.1,-0.3833,4.0581,0.09094}, + {53.2,-0.3833,4.0832,0.09095}, + {53.3,-0.3833,4.1084,0.09096}, + {53.4,-0.3833,4.1337,0.09097}, + {53.5,-0.3833,4.1591,0.09098}, + {53.6,-0.3833,4.1846,0.09099}, + {53.7,-0.3833,4.2102,0.09099}, + {53.8,-0.3833,4.2359,0.091}, + {53.9,-0.3833,4.2617,0.09101}, + {54,-0.3833,4.2875,0.09102}, + {54.1,-0.3833,4.3135,0.09103}, + {54.2,-0.3833,4.3395,0.09104}, + {54.3,-0.3833,4.3655,0.09105}, + {54.4,-0.3833,4.3917,0.09105}, + {54.5,-0.3833,4.4179,0.09106}, + {54.6,-0.3833,4.4442,0.09107}, + {54.7,-0.3833,4.4705,0.09108}, + {54.8,-0.3833,4.4969,0.09109}, + {54.9,-0.3833,4.5233,0.09109}, + {55,-0.3833,4.5498,0.0911}, + {55.1,-0.3833,4.5763,0.09111}, + {55.2,-0.3833,4.6029,0.09112}, + {55.3,-0.3833,4.6295,0.09113}, + {55.4,-0.3833,4.6561,0.09113}, + {55.5,-0.3833,4.6827,0.09114}, + {55.6,-0.3833,4.7094,0.09115}, + {55.7,-0.3833,4.7361,0.09116}, + {55.8,-0.3833,4.7628,0.09116}, + {55.9,-0.3833,4.7895,0.09117}, + {56,-0.3833,4.8162,0.09118}, + {56.1,-0.3833,4.843,0.09119}, + {56.2,-0.3833,4.8697,0.09119}, + {56.3,-0.3833,4.8964,0.0912}, + {56.4,-0.3833,4.9232,0.09121}, + {56.5,-0.3833,4.95,0.09121}, + {56.6,-0.3833,4.9767,0.09122}, + {56.7,-0.3833,5.0034,0.09123}, + {56.8,-0.3833,5.0302,0.09123}, + {56.9,-0.3833,5.0569,0.09124}, + {57,-0.3833,5.0837,0.09125}, + {57.1,-0.3833,5.1104,0.09125}, + {57.2,-0.3833,5.1371,0.09126}, + {57.3,-0.3833,5.1639,0.09126}, + {57.4,-0.3833,5.1906,0.09127}, + {57.5,-0.3833,5.2173,0.09128}, + {57.6,-0.3833,5.244,0.09128}, + {57.7,-0.3833,5.2707,0.09129}, + {57.8,-0.3833,5.2974,0.09129}, + {57.9,-0.3833,5.324,0.0913}, + {58,-0.3833,5.3507,0.0913}, + {58.1,-0.3833,5.3773,0.09131}, + {58.2,-0.3833,5.4039,0.09131}, + {58.3,-0.3833,5.4304,0.09131}, + {58.4,-0.3833,5.4569,0.09132}, + {58.5,-0.3833,5.4834,0.09132}, + {58.6,-0.3833,5.5098,0.09133}, + {58.7,-0.3833,5.5362,0.09133}, + {58.8,-0.3833,5.5625,0.09133}, + {58.9,-0.3833,5.5888,0.09134}, + {59,-0.3833,5.6151,0.09134}, + {59.1,-0.3833,5.6413,0.09134}, + {59.2,-0.3833,5.6674,0.09135}, + {59.3,-0.3833,5.6935,0.09135}, + {59.4,-0.3833,5.7195,0.09135}, + {59.5,-0.3833,5.7454,0.09135}, + {59.6,-0.3833,5.7713,0.09136}, + {59.7,-0.3833,5.7971,0.09136}, + {59.8,-0.3833,5.8229,0.09136}, + {59.9,-0.3833,5.8485,0.09136}, + {60,-0.3833,5.8742,0.09136}, + {60.1,-0.3833,5.8997,0.09136}, + {60.2,-0.3833,5.9252,0.09137}, + {60.3,-0.3833,5.9507,0.09137}, + {60.4,-0.3833,5.9761,0.09137}, + {60.5,-0.3833,6.0014,0.09137}, + {60.6,-0.3833,6.0266,0.09137}, + {60.7,-0.3833,6.0518,0.09137}, + {60.8,-0.3833,6.0769,0.09137}, + {60.9,-0.3833,6.102,0.09137}, + {61,-0.3833,6.127,0.09137}, + {61.1,-0.3833,6.1519,0.09137}, + {61.2,-0.3833,6.1768,0.09136}, + {61.3,-0.3833,6.2017,0.09136}, + {61.4,-0.3833,6.2264,0.09136}, + {61.5,-0.3833,6.2511,0.09136}, + {61.6,-0.3833,6.2758,0.09136}, + {61.7,-0.3833,6.3004,0.09136}, + {61.8,-0.3833,6.3249,0.09135}, + {61.9,-0.3833,6.3494,0.09135}, + {62,-0.3833,6.3738,0.09135}, + {62.1,-0.3833,6.3981,0.09135}, + {62.2,-0.3833,6.4224,0.09134}, + {62.3,-0.3833,6.4466,0.09134}, + {62.4,-0.3833,6.4708,0.09134}, + {62.5,-0.3833,6.4948,0.09133}, + {62.6,-0.3833,6.5189,0.09133}, + {62.7,-0.3833,6.5429,0.09133}, + {62.8,-0.3833,6.5668,0.09132}, + {62.9,-0.3833,6.5906,0.09132}, + {63,-0.3833,6.6144,0.09131}, + {63.1,-0.3833,6.6382,0.09131}, + {63.2,-0.3833,6.6619,0.0913}, + {63.3,-0.3833,6.6856,0.0913}, + {63.4,-0.3833,6.7092,0.09129}, + {63.5,-0.3833,6.7328,0.09129}, + {63.6,-0.3833,6.7563,0.09128}, + {63.7,-0.3833,6.7798,0.09128}, + {63.8,-0.3833,6.8033,0.09127}, + {63.9,-0.3833,6.8267,0.09127}, + {64,-0.3833,6.8501,0.09126}, + {64.1,-0.3833,6.8734,0.09125}, + {64.2,-0.3833,6.8967,0.09125}, + {64.3,-0.3833,6.9199,0.09124}, + {64.4,-0.3833,6.9431,0.09123}, + {64.5,-0.3833,6.9662,0.09123}, + {64.6,-0.3833,6.9893,0.09122}, + {64.7,-0.3833,7.0124,0.09121}, + {64.8,-0.3833,7.0354,0.0912}, + {64.9,-0.3833,7.0583,0.0912}, + {65,-0.3833,7.0812,0.09119}, + {65.1,-0.3833,7.1041,0.09118}, + {65.2,-0.3833,7.1269,0.09117}, + {65.3,-0.3833,7.1497,0.09116}, + {65.4,-0.3833,7.1724,0.09116}, + {65.5,-0.3833,7.195,0.09115}, + {65.6,-0.3833,7.2177,0.09114}, + {65.7,-0.3833,7.2402,0.09113}, + {65.8,-0.3833,7.2627,0.09112}, + {65.9,-0.3833,7.2852,0.09111}, + {66,-0.3833,7.3076,0.0911}, + {66.1,-0.3833,7.33,0.09109}, + {66.2,-0.3833,7.3523,0.09109}, + {66.3,-0.3833,7.3745,0.09108}, + {66.4,-0.3833,7.3967,0.09107}, + {66.5,-0.3833,7.4189,0.09106}, + {66.6,-0.3833,7.441,0.09105}, + {66.7,-0.3833,7.463,0.09104}, + {66.8,-0.3833,7.485,0.09103}, + {66.9,-0.3833,7.5069,0.09102}, + {67,-0.3833,7.5288,0.09101}, + {67.1,-0.3833,7.5507,0.091}, + {67.2,-0.3833,7.5724,0.09099}, + {67.3,-0.3833,7.5942,0.09098}, + {67.4,-0.3833,7.6158,0.09097}, + {67.5,-0.3833,7.6375,0.09096}, + {67.6,-0.3833,7.659,0.09095}, + {67.7,-0.3833,7.6806,0.09094}, + {67.8,-0.3833,7.702,0.09093}, + {67.9,-0.3833,7.7234,0.09091}, + {68,-0.3833,7.7448,0.0909}, + {68.1,-0.3833,7.7661,0.09089}, + {68.2,-0.3833,7.7874,0.09088}, + {68.3,-0.3833,7.8086,0.09087}, + {68.4,-0.3833,7.8298,0.09086}, + {68.5,-0.3833,7.8509,0.09085}, + {68.6,-0.3833,7.872,0.09084}, + {68.7,-0.3833,7.893,0.09083}, + {68.8,-0.3833,7.914,0.09082}, + {68.9,-0.3833,7.935,0.0908}, + {69,-0.3833,7.9559,0.09079}, + {69.1,-0.3833,7.9768,0.09078}, + {69.2,-0.3833,7.9976,0.09077}, + {69.3,-0.3833,8.0184,0.09076}, + {69.4,-0.3833,8.0392,0.09075}, + {69.5,-0.3833,8.0599,0.09074}, + {69.6,-0.3833,8.0806,0.09072}, + {69.7,-0.3833,8.1012,0.09071}, + {69.8,-0.3833,8.1218,0.0907}, + {69.9,-0.3833,8.1424,0.09069}, + {70,-0.3833,8.163,0.09068}, + {70.1,-0.3833,8.1835,0.09067}, + {70.2,-0.3833,8.2039,0.09065}, + {70.3,-0.3833,8.2244,0.09064}, + {70.4,-0.3833,8.2448,0.09063}, + {70.5,-0.3833,8.2651,0.09062}, + {70.6,-0.3833,8.2855,0.09061}, + {70.7,-0.3833,8.3058,0.09059}, + {70.8,-0.3833,8.3261,0.09058}, + {70.9,-0.3833,8.3464,0.09057}, + {71,-0.3833,8.3666,0.09056}, + {71.1,-0.3833,8.3869,0.09055}, + {71.2,-0.3833,8.4071,0.09053}, + {71.3,-0.3833,8.4273,0.09052}, + {71.4,-0.3833,8.4474,0.09051}, + {71.5,-0.3833,8.4676,0.0905}, + {71.6,-0.3833,8.4877,0.09048}, + {71.7,-0.3833,8.5078,0.09047}, + {71.8,-0.3833,8.5278,0.09046}, + {71.9,-0.3833,8.5479,0.09045}, + {72,-0.3833,8.5679,0.09043}, + {72.1,-0.3833,8.5879,0.09042}, + {72.2,-0.3833,8.6078,0.09041}, + {72.3,-0.3833,8.6277,0.0904}, + {72.4,-0.3833,8.6476,0.09039}, + {72.5,-0.3833,8.6674,0.09037}, + {72.6,-0.3833,8.6872,0.09036}, + {72.7,-0.3833,8.707,0.09035}, + {72.8,-0.3833,8.7267,0.09034}, + {72.9,-0.3833,8.7464,0.09032}, + {73,-0.3833,8.7661,0.09031}, + {73.1,-0.3833,8.7857,0.0903}, + {73.2,-0.3833,8.8053,0.09028}, + {73.3,-0.3833,8.8248,0.09027}, + {73.4,-0.3833,8.8443,0.09026}, + {73.5,-0.3833,8.8638,0.09025}, + {73.6,-0.3833,8.8831,0.09023}, + {73.7,-0.3833,8.9025,0.09022}, + {73.8,-0.3833,8.9217,0.09021}, + {73.9,-0.3833,8.941,0.0902}, + {74,-0.3833,8.9601,0.09018}, + {74.1,-0.3833,8.9792,0.09017}, + {74.2,-0.3833,8.9983,0.09016}, + {74.3,-0.3833,9.0173,0.09014}, + {74.4,-0.3833,9.0363,0.09013}, + {74.5,-0.3833,9.0552,0.09012}, + {74.6,-0.3833,9.074,0.09011}, + {74.7,-0.3833,9.0928,0.09009}, + {74.8,-0.3833,9.1116,0.09008}, + {74.9,-0.3833,9.1303,0.09007}, + {75,-0.3833,9.149,0.09005}, + {75.1,-0.3833,9.1676,0.09004}, + {75.2,-0.3833,9.1862,0.09003}, + {75.3,-0.3833,9.2048,0.09001}, + {75.4,-0.3833,9.2233,0.09}, + {75.5,-0.3833,9.2418,0.08999}, + {75.6,-0.3833,9.2602,0.08997}, + {75.7,-0.3833,9.2786,0.08996}, + {75.8,-0.3833,9.297,0.08995}, + {75.9,-0.3833,9.3154,0.08993}, + {76,-0.3833,9.3337,0.08992}, + {76.1,-0.3833,9.352,0.08991}, + {76.2,-0.3833,9.3703,0.08989}, + {76.3,-0.3833,9.3886,0.08988}, + {76.4,-0.3833,9.4069,0.08987}, + {76.5,-0.3833,9.4252,0.08985}, + {76.6,-0.3833,9.4435,0.08984}, + {76.7,-0.3833,9.4617,0.08983}, + {76.8,-0.3833,9.48,0.08981}, + {76.9,-0.3833,9.4983,0.0898}, + {77,-0.3833,9.5166,0.08979}, + {77.1,-0.3833,9.535,0.08977}, + {77.2,-0.3833,9.5533,0.08976}, + {77.3,-0.3833,9.5717,0.08975}, + {77.4,-0.3833,9.5901,0.08973}, + {77.5,-0.3833,9.6086,0.08972}, + {77.6,-0.3833,9.6271,0.08971}, + {77.7,-0.3833,9.6456,0.08969}, + {77.8,-0.3833,9.6642,0.08968}, + {77.9,-0.3833,9.6828,0.08966}, + {78,-0.3833,9.7015,0.08965}, + {78.1,-0.3833,9.7202,0.08964}, + {78.2,-0.3833,9.739,0.08963}, + {78.3,-0.3833,9.7578,0.08961}, + {78.4,-0.3833,9.7767,0.0896}, + {78.5,-0.3833,9.7957,0.08959}, + {78.6,-0.3833,9.8147,0.08957}, + {78.7,-0.3833,9.8338,0.08956}, + {78.8,-0.3833,9.853,0.08955}, + {78.9,-0.3833,9.8722,0.08953}, + {79,-0.3833,9.8915,0.08952}, + {79.1,-0.3833,9.9109,0.08951}, + {79.2,-0.3833,9.9303,0.0895}, + {79.3,-0.3833,9.9499,0.08948}, + {79.4,-0.3833,9.9695,0.08947}, + {79.5,-0.3833,9.9892,0.08946}, + {79.6,-0.3833,10.009,0.08945}, + {79.7,-0.3833,10.0289,0.08943}, + {79.8,-0.3833,10.0489,0.08942}, + {79.9,-0.3833,10.069,0.08941}, + {80,-0.3833,10.0891,0.0894}, + {80.1,-0.3833,10.1094,0.08939}, + {80.2,-0.3833,10.1298,0.08937}, + {80.3,-0.3833,10.1503,0.08936}, + {80.4,-0.3833,10.1709,0.08935}, + {80.5,-0.3833,10.1916,0.08934}, + {80.6,-0.3833,10.2123,0.08933}, + {80.7,-0.3833,10.2332,0.08932}, + {80.8,-0.3833,10.2542,0.0893}, + {80.9,-0.3833,10.2753,0.08929}, + {81,-0.3833,10.2965,0.08928}, + {81.1,-0.3833,10.3178,0.08927}, + {81.2,-0.3833,10.3393,0.08926}, + {81.3,-0.3833,10.3608,0.08925}, + {81.4,-0.3833,10.3824,0.08924}, + {81.5,-0.3833,10.4041,0.08923}, + {81.6,-0.3833,10.4258,0.08922}, + {81.7,-0.3833,10.4477,0.08921}, + {81.8,-0.3833,10.4697,0.0892}, + {81.9,-0.3833,10.4918,0.08919}, + {82,-0.3833,10.514,0.08918}, + {82.1,-0.3833,10.5363,0.08917}, + {82.2,-0.3833,10.5586,0.08916}, + {82.3,-0.3833,10.5811,0.08915}, + {82.4,-0.3833,10.6037,0.08915}, + {82.5,-0.3833,10.6263,0.08914}, + {82.6,-0.3833,10.6491,0.08913}, + {82.7,-0.3833,10.6719,0.08912}, + {82.8,-0.3833,10.6948,0.08911}, + {82.9,-0.3833,10.7178,0.0891}, + {83,-0.3833,10.741,0.0891}, + {83.1,-0.3833,10.7641,0.08909}, + {83.2,-0.3833,10.7874,0.08908}, + {83.3,-0.3833,10.8108,0.08907}, + {83.4,-0.3833,10.8343,0.08907}, + {83.5,-0.3833,10.8578,0.08906}, + {83.6,-0.3833,10.8814,0.08905}, + {83.7,-0.3833,10.9051,0.08905}, + {83.8,-0.3833,10.9289,0.08904}, + {83.9,-0.3833,10.9527,0.08903}, + {84,-0.3833,10.9767,0.08903}, + {84.1,-0.3833,11.0007,0.08902}, + {84.2,-0.3833,11.0248,0.08902}, + {84.3,-0.3833,11.0489,0.08901}, + {84.4,-0.3833,11.0731,0.08901}, + {84.5,-0.3833,11.0974,0.089}, + {84.6,-0.3833,11.1218,0.089}, + {84.7,-0.3833,11.1462,0.08899}, + {84.8,-0.3833,11.1707,0.08899}, + {84.9,-0.3833,11.1952,0.08899}, + {85,-0.3833,11.2198,0.08898}, + {85.1,-0.3833,11.2444,0.08898}, + {85.2,-0.3833,11.2691,0.08897}, + {85.3,-0.3833,11.2939,0.08897}, + {85.4,-0.3833,11.3187,0.08897}, + {85.5,-0.3833,11.3435,0.08897}, + {85.6,-0.3833,11.3684,0.08896}, + {85.7,-0.3833,11.3934,0.08896}, + {85.8,-0.3833,11.4183,0.08896}, + {85.9,-0.3833,11.4434,0.08896}, + {86,-0.3833,11.4684,0.08895}, + {86.1,-0.3833,11.4935,0.08895}, + {86.2,-0.3833,11.5186,0.08895}, + {86.3,-0.3833,11.5437,0.08895}, + {86.4,-0.3833,11.5689,0.08895}, + {86.5,-0.3833,11.594,0.08895}, + {86.6,-0.3833,11.6192,0.08895}, + {86.7,-0.3833,11.6444,0.08895}, + {86.8,-0.3833,11.6696,0.08895}, + {86.9,-0.3833,11.6948,0.08895}, + {87,-0.3833,11.7201,0.08895}, + {87.1,-0.3833,11.7453,0.08895}, + {87.2,-0.3833,11.7705,0.08895}, + {87.3,-0.3833,11.7957,0.08895}, + {87.4,-0.3833,11.8209,0.08895}, + {87.5,-0.3833,11.8461,0.08895}, + {87.6,-0.3833,11.8713,0.08896}, + {87.7,-0.3833,11.8965,0.08896}, + {87.8,-0.3833,11.9217,0.08896}, + {87.9,-0.3833,11.9468,0.08896}, + {88,-0.3833,11.972,0.08896}, + {88.1,-0.3833,11.9971,0.08897}, + {88.2,-0.3833,12.0223,0.08897}, + {88.3,-0.3833,12.0474,0.08897}, + {88.4,-0.3833,12.0725,0.08898}, + {88.5,-0.3833,12.0976,0.08898}, + {88.6,-0.3833,12.1227,0.08898}, + {88.7,-0.3833,12.1478,0.08899}, + {88.8,-0.3833,12.1728,0.08899}, + {88.9,-0.3833,12.1978,0.089}, + {89,-0.3833,12.2229,0.089}, + {89.1,-0.3833,12.2479,0.08901}, + {89.2,-0.3833,12.2729,0.08901}, + {89.3,-0.3833,12.2978,0.08902}, + {89.4,-0.3833,12.3228,0.08902}, + {89.5,-0.3833,12.3477,0.08903}, + {89.6,-0.3833,12.3727,0.08903}, + {89.7,-0.3833,12.3976,0.08904}, + {89.8,-0.3833,12.4225,0.08904}, + {89.9,-0.3833,12.4474,0.08905}, + {90,-0.3833,12.4723,0.08906}, + {90.1,-0.3833,12.4971,0.08906}, + {90.2,-0.3833,12.522,0.08907}, + {90.3,-0.3833,12.5468,0.08908}, + {90.4,-0.3833,12.5717,0.08909}, + {90.5,-0.3833,12.5965,0.08909}, + {90.6,-0.3833,12.6213,0.0891}, + {90.7,-0.3833,12.6461,0.08911}, + {90.8,-0.3833,12.6709,0.08912}, + {90.9,-0.3833,12.6957,0.08912}, + {91,-0.3833,12.7205,0.08913}, + {91.1,-0.3833,12.7453,0.08914}, + {91.2,-0.3833,12.77,0.08915}, + {91.3,-0.3833,12.7948,0.08916}, + {91.4,-0.3833,12.8196,0.08917}, + {91.5,-0.3833,12.8443,0.08918}, + {91.6,-0.3833,12.8691,0.08919}, + {91.7,-0.3833,12.8939,0.0892}, + {91.8,-0.3833,12.9186,0.08921}, + {91.9,-0.3833,12.9434,0.08922}, + {92,-0.3833,12.9681,0.08923}, + {92.1,-0.3833,12.9929,0.08924}, + {92.2,-0.3833,13.0177,0.08925}, + {92.3,-0.3833,13.0424,0.08926}, + {92.4,-0.3833,13.0672,0.08927}, + {92.5,-0.3833,13.092,0.08928}, + {92.6,-0.3833,13.1167,0.0893}, + {92.7,-0.3833,13.1415,0.08931}, + {92.8,-0.3833,13.1663,0.08932}, + {92.9,-0.3833,13.1911,0.08933}, + {93,-0.3833,13.2158,0.08934}, + {93.1,-0.3833,13.2406,0.08936}, + {93.2,-0.3833,13.2654,0.08937}, + {93.3,-0.3833,13.2902,0.08938}, + {93.4,-0.3833,13.3151,0.0894}, + {93.5,-0.3833,13.3399,0.08941}, + {93.6,-0.3833,13.3647,0.08942}, + {93.7,-0.3833,13.3896,0.08944}, + {93.8,-0.3833,13.4145,0.08945}, + {93.9,-0.3833,13.4394,0.08947}, + {94,-0.3833,13.4643,0.08948}, + {94.1,-0.3833,13.4892,0.08949}, + {94.2,-0.3833,13.5142,0.08951}, + {94.3,-0.3833,13.5391,0.08952}, + {94.4,-0.3833,13.5641,0.08954}, + {94.5,-0.3833,13.5892,0.08955}, + {94.6,-0.3833,13.6142,0.08957}, + {94.7,-0.3833,13.6393,0.08959}, + {94.8,-0.3833,13.6644,0.0896}, + {94.9,-0.3833,13.6895,0.08962}, + {95,-0.3833,13.7146,0.08963}, + {95.1,-0.3833,13.7398,0.08965}, + {95.2,-0.3833,13.765,0.08967}, + {95.3,-0.3833,13.7902,0.08968}, + {95.4,-0.3833,13.8155,0.0897}, + {95.5,-0.3833,13.8408,0.08972}, + {95.6,-0.3833,13.8661,0.08974}, + {95.7,-0.3833,13.8914,0.08975}, + {95.8,-0.3833,13.9168,0.08977}, + {95.9,-0.3833,13.9422,0.08979}, + {96,-0.3833,13.9676,0.08981}, + {96.1,-0.3833,13.9931,0.08983}, + {96.2,-0.3833,14.0186,0.08984}, + {96.3,-0.3833,14.0441,0.08986}, + {96.4,-0.3833,14.0697,0.08988}, + {96.5,-0.3833,14.0953,0.0899}, + {96.6,-0.3833,14.1209,0.08992}, + {96.7,-0.3833,14.1466,0.08994}, + {96.8,-0.3833,14.1724,0.08996}, + {96.9,-0.3833,14.1981,0.08998}, + {97,-0.3833,14.2239,0.09}, + {97.1,-0.3833,14.2498,0.09002}, + {97.2,-0.3833,14.2757,0.09004}, + {97.3,-0.3833,14.3016,0.09006}, + {97.4,-0.3833,14.3276,0.09008}, + {97.5,-0.3833,14.3537,0.0901}, + {97.6,-0.3833,14.3798,0.09012}, + {97.7,-0.3833,14.4059,0.09015}, + {97.8,-0.3833,14.4321,0.09017}, + {97.9,-0.3833,14.4584,0.09019}, + {98,-0.3833,14.4848,0.09021}, + {98.1,-0.3833,14.5112,0.09023}, + {98.2,-0.3833,14.5376,0.09026}, + {98.3,-0.3833,14.5642,0.09028}, + {98.4,-0.3833,14.5908,0.0903}, + {98.5,-0.3833,14.6174,0.09033}, + {98.6,-0.3833,14.6442,0.09035}, + {98.7,-0.3833,14.671,0.09037}, + {98.8,-0.3833,14.6979,0.0904}, + {98.9,-0.3833,14.7248,0.09042}, + {99,-0.3833,14.7519,0.09044}, + {99.1,-0.3833,14.779,0.09047}, + {99.2,-0.3833,14.8062,0.09049}, + {99.3,-0.3833,14.8334,0.09052}, + {99.4,-0.3833,14.8608,0.09054}, + {99.5,-0.3833,14.8882,0.09057}, + {99.6,-0.3833,14.9157,0.09059}, + {99.7,-0.3833,14.9434,0.09062}, + {99.8,-0.3833,14.9711,0.09064}, + {99.9,-0.3833,14.9989,0.09067}, + {100,-0.3833,15.0267,0.09069}, + {100.1,-0.3833,15.0547,0.09072}, + {100.2,-0.3833,15.0828,0.09075}, + {100.3,-0.3833,15.1109,0.09077}, + {100.4,-0.3833,15.1392,0.0908}, + {100.5,-0.3833,15.1676,0.09083}, + {100.6,-0.3833,15.196,0.09085}, + {100.7,-0.3833,15.2246,0.09088}, + {100.8,-0.3833,15.2532,0.09091}, + {100.9,-0.3833,15.2819,0.09093}, + {101,-0.3833,15.3108,0.09096}, + {101.1,-0.3833,15.3397,0.09099}, + {101.2,-0.3833,15.3687,0.09102}, + {101.3,-0.3833,15.3979,0.09105}, + {101.4,-0.3833,15.4271,0.09107}, + {101.5,-0.3833,15.4564,0.0911}, + {101.6,-0.3833,15.4858,0.09113}, + {101.7,-0.3833,15.5154,0.09116}, + {101.8,-0.3833,15.545,0.09119}, + {101.9,-0.3833,15.5747,0.09122}, + {102,-0.3833,15.6046,0.09125}, + {102.1,-0.3833,15.6345,0.09128}, + {102.2,-0.3833,15.6646,0.09131}, + {102.3,-0.3833,15.6947,0.09133}, + {102.4,-0.3833,15.725,0.09136}, + {102.5,-0.3833,15.7553,0.09139}, + {102.6,-0.3833,15.7858,0.09142}, + {102.7,-0.3833,15.8164,0.09146}, + {102.8,-0.3833,15.847,0.09149}, + {102.9,-0.3833,15.8778,0.09152}, + {103,-0.3833,15.9087,0.09155}, + {103.1,-0.3833,15.9396,0.09158}, + {103.2,-0.3833,15.9707,0.09161}, + {103.3,-0.3833,16.0019,0.09164}, + {103.4,-0.3833,16.0332,0.09167}, + {103.5,-0.3833,16.0645,0.0917}, + {103.6,-0.3833,16.096,0.09173}, + {103.7,-0.3833,16.1276,0.09177}, + {103.8,-0.3833,16.1593,0.0918}, + {103.9,-0.3833,16.191,0.09183}, + {104,-0.3833,16.2229,0.09186}, + {104.1,-0.3833,16.2549,0.0919}, + {104.2,-0.3833,16.287,0.09193}, + {104.3,-0.3833,16.3191,0.09196}, + {104.4,-0.3833,16.3514,0.09199}, + {104.5,-0.3833,16.3837,0.09203}, + {104.6,-0.3833,16.4162,0.09206}, + {104.7,-0.3833,16.4488,0.09209}, + {104.8,-0.3833,16.4814,0.09213}, + {104.9,-0.3833,16.5142,0.09216}, + {105,-0.3833,16.547,0.09219}, + {105.1,-0.3833,16.58,0.09223}, + {105.2,-0.3833,16.6131,0.09226}, + {105.3,-0.3833,16.6462,0.09229}, + {105.4,-0.3833,16.6795,0.09233}, + {105.5,-0.3833,16.7129,0.09236}, + {105.6,-0.3833,16.7464,0.0924}, + {105.7,-0.3833,16.78,0.09243}, + {105.8,-0.3833,16.8137,0.09247}, + {105.9,-0.3833,16.8475,0.0925}, + {106,-0.3833,16.8814,0.09254}, + {106.1,-0.3833,16.9154,0.09257}, + {106.2,-0.3833,16.9496,0.09261}, + {106.3,-0.3833,16.9838,0.09264}, + {106.4,-0.3833,17.0182,0.09268}, + {106.5,-0.3833,17.0527,0.09271}, + {106.6,-0.3833,17.0873,0.09275}, + {106.7,-0.3833,17.122,0.09278}, + {106.8,-0.3833,17.1569,0.09282}, + {106.9,-0.3833,17.1918,0.09286}, + {107,-0.3833,17.2269,0.09289}, + {107.1,-0.3833,17.262,0.09293}, + {107.2,-0.3833,17.2973,0.09296}, + {107.3,-0.3833,17.3327,0.093}, + {107.4,-0.3833,17.3683,0.09304}, + {107.5,-0.3833,17.4039,0.09307}, + {107.6,-0.3833,17.4397,0.09311}, + {107.7,-0.3833,17.4755,0.09315}, + {107.8,-0.3833,17.5115,0.09318}, + {107.9,-0.3833,17.5476,0.09322}, + {108,-0.3833,17.5839,0.09326}, + {108.1,-0.3833,17.6202,0.09329}, + {108.2,-0.3833,17.6567,0.09333}, + {108.3,-0.3833,17.6932,0.09337}, + {108.4,-0.3833,17.7299,0.09341}, + {108.5,-0.3833,17.7668,0.09344}, + {108.6,-0.3833,17.8037,0.09348}, + {108.7,-0.3833,17.8407,0.09352}, + {108.8,-0.3833,17.8779,0.09356}, + {108.9,-0.3833,17.9152,0.09359}, + {109,-0.3833,17.9526,0.09363}, + {109.1,-0.3833,17.9901,0.09367}, + {109.2,-0.3833,18.0277,0.09371}, + {109.3,-0.3833,18.0654,0.09375}, + {109.4,-0.3833,18.1033,0.09378}, + {109.5,-0.3833,18.1412,0.09382}, + {109.6,-0.3833,18.1792,0.09386}, + {109.7,-0.3833,18.2174,0.0939}, + {109.8,-0.3833,18.2556,0.09394}, + {109.9,-0.3833,18.294,0.09397}, + {110,-0.3833,18.3324,0.09401}, + }; + return girlsWeightForLength[index < girlsWeightForLength.length ? index : girlsWeightForLength.length-1]; + } + + public double[]getBoysWeightForHeight(int index){ + double[][]boysWeightForHeight = { + {65,-0.3521,7.4327,0.08217}, + {65.1,-0.3521,7.4563,0.08216}, + {65.2,-0.3521,7.4799,0.08216}, + {65.3,-0.3521,7.5034,0.08215}, + {65.4,-0.3521,7.5269,0.08214}, + {65.5,-0.3521,7.5504,0.08214}, + {65.6,-0.3521,7.5738,0.08214}, + {65.7,-0.3521,7.5973,0.08213}, + {65.8,-0.3521,7.6206,0.08213}, + {65.9,-0.3521,7.644,0.08213}, + {66,-0.3521,7.6673,0.08212}, + {66.1,-0.3521,7.6906,0.08212}, + {66.2,-0.3521,7.7138,0.08212}, + {66.3,-0.3521,7.737,0.08212}, + {66.4,-0.3521,7.7602,0.08212}, + {66.5,-0.3521,7.7834,0.08212}, + {66.6,-0.3521,7.8065,0.08212}, + {66.7,-0.3521,7.8296,0.08212}, + {66.8,-0.3521,7.8526,0.08212}, + {66.9,-0.3521,7.8757,0.08212}, + {67,-0.3521,7.8986,0.08213}, + {67.1,-0.3521,7.9216,0.08213}, + {67.2,-0.3521,7.9445,0.08213}, + {67.3,-0.3521,7.9674,0.08214}, + {67.4,-0.3521,7.9903,0.08214}, + {67.5,-0.3521,8.0132,0.08214}, + {67.6,-0.3521,8.036,0.08215}, + {67.7,-0.3521,8.0588,0.08215}, + {67.8,-0.3521,8.0816,0.08216}, + {67.9,-0.3521,8.1044,0.08217}, + {68,-0.3521,8.1272,0.08217}, + {68.1,-0.3521,8.15,0.08218}, + {68.2,-0.3521,8.1727,0.08219}, + {68.3,-0.3521,8.1955,0.08219}, + {68.4,-0.3521,8.2183,0.0822}, + {68.5,-0.3521,8.241,0.08221}, + {68.6,-0.3521,8.2638,0.08222}, + {68.7,-0.3521,8.2865,0.08223}, + {68.8,-0.3521,8.3092,0.08224}, + {68.9,-0.3521,8.332,0.08225}, + {69,-0.3521,8.3547,0.08226}, + {69.1,-0.3521,8.3774,0.08227}, + {69.2,-0.3521,8.4001,0.08228}, + {69.3,-0.3521,8.4227,0.08229}, + {69.4,-0.3521,8.4454,0.0823}, + {69.5,-0.3521,8.468,0.08231}, + {69.6,-0.3521,8.4906,0.08232}, + {69.7,-0.3521,8.5132,0.08233}, + {69.8,-0.3521,8.5358,0.08235}, + {69.9,-0.3521,8.5583,0.08236}, + {70,-0.3521,8.5808,0.08237}, + {70.1,-0.3521,8.6032,0.08238}, + {70.2,-0.3521,8.6257,0.0824}, + {70.3,-0.3521,8.648,0.08241}, + {70.4,-0.3521,8.6704,0.08242}, + {70.5,-0.3521,8.6927,0.08243}, + {70.6,-0.3521,8.715,0.08245}, + {70.7,-0.3521,8.7372,0.08246}, + {70.8,-0.3521,8.7594,0.08248}, + {70.9,-0.3521,8.7815,0.08249}, + {71,-0.3521,8.8036,0.0825}, + {71.1,-0.3521,8.8257,0.08252}, + {71.2,-0.3521,8.8477,0.08253}, + {71.3,-0.3521,8.8697,0.08254}, + {71.4,-0.3521,8.8916,0.08256}, + {71.5,-0.3521,8.9135,0.08257}, + {71.6,-0.3521,8.9353,0.08259}, + {71.7,-0.3521,8.9571,0.0826}, + {71.8,-0.3521,8.9788,0.08262}, + {71.9,-0.3521,9.0005,0.08263}, + {72,-0.3521,9.0221,0.08264}, + {72.1,-0.3521,9.0436,0.08266}, + {72.2,-0.3521,9.0651,0.08267}, + {72.3,-0.3521,9.0865,0.08269}, + {72.4,-0.3521,9.1079,0.0827}, + {72.5,-0.3521,9.1292,0.08272}, + {72.6,-0.3521,9.1504,0.08273}, + {72.7,-0.3521,9.1716,0.08274}, + {72.8,-0.3521,9.1927,0.08276}, + {72.9,-0.3521,9.2137,0.08277}, + {73,-0.3521,9.2347,0.08278}, + {73.1,-0.3521,9.2557,0.0828}, + {73.2,-0.3521,9.2766,0.08281}, + {73.3,-0.3521,9.2974,0.08283}, + {73.4,-0.3521,9.3182,0.08284}, + {73.5,-0.3521,9.339,0.08285}, + {73.6,-0.3521,9.3597,0.08287}, + {73.7,-0.3521,9.3803,0.08288}, + {73.8,-0.3521,9.401,0.08289}, + {73.9,-0.3521,9.4215,0.0829}, + {74,-0.3521,9.442,0.08292}, + {74.1,-0.3521,9.4625,0.08293}, + {74.2,-0.3521,9.4829,0.08294}, + {74.3,-0.3521,9.5032,0.08295}, + {74.4,-0.3521,9.5235,0.08297}, + {74.5,-0.3521,9.5438,0.08298}, + {74.6,-0.3521,9.5639,0.08299}, + {74.7,-0.3521,9.5841,0.083}, + {74.8,-0.3521,9.6041,0.08301}, + {74.9,-0.3521,9.6241,0.08302}, + {75,-0.3521,9.644,0.08303}, + {75.1,-0.3521,9.6639,0.08305}, + {75.2,-0.3521,9.6836,0.08306}, + {75.3,-0.3521,9.7033,0.08307}, + {75.4,-0.3521,9.723,0.08307}, + {75.5,-0.3521,9.7425,0.08308}, + {75.6,-0.3521,9.762,0.08309}, + {75.7,-0.3521,9.7814,0.0831}, + {75.8,-0.3521,9.8007,0.08311}, + {75.9,-0.3521,9.82,0.08312}, + {76,-0.3521,9.8392,0.08312}, + {76.1,-0.3521,9.8583,0.08313}, + {76.2,-0.3521,9.8773,0.08314}, + {76.3,-0.3521,9.8963,0.08314}, + {76.4,-0.3521,9.9152,0.08315}, + {76.5,-0.3521,9.9341,0.08315}, + {76.6,-0.3521,9.9528,0.08316}, + {76.7,-0.3521,9.9716,0.08316}, + {76.8,-0.3521,9.9902,0.08317}, + {76.9,-0.3521,10.0088,0.08317}, + {77,-0.3521,10.0274,0.08317}, + {77.1,-0.3521,10.0459,0.08318}, + {77.2,-0.3521,10.0643,0.08318}, + {77.3,-0.3521,10.0827,0.08318}, + {77.4,-0.3521,10.1011,0.08318}, + {77.5,-0.3521,10.1194,0.08318}, + {77.6,-0.3521,10.1377,0.08318}, + {77.7,-0.3521,10.1559,0.08318}, + {77.8,-0.3521,10.1741,0.08318}, + {77.9,-0.3521,10.1923,0.08317}, + {78,-0.3521,10.2105,0.08317}, + {78.1,-0.3521,10.2286,0.08317}, + {78.2,-0.3521,10.2468,0.08316}, + {78.3,-0.3521,10.2649,0.08316}, + {78.4,-0.3521,10.2831,0.08315}, + {78.5,-0.3521,10.3012,0.08315}, + {78.6,-0.3521,10.3194,0.08314}, + {78.7,-0.3521,10.3376,0.08313}, + {78.8,-0.3521,10.3558,0.08313}, + {78.9,-0.3521,10.3741,0.08312}, + {79,-0.3521,10.3923,0.08311}, + {79.1,-0.3521,10.4107,0.0831}, + {79.2,-0.3521,10.4291,0.08309}, + {79.3,-0.3521,10.4475,0.08308}, + {79.4,-0.3521,10.466,0.08307}, + {79.5,-0.3521,10.4845,0.08305}, + {79.6,-0.3521,10.5031,0.08304}, + {79.7,-0.3521,10.5217,0.08303}, + {79.8,-0.3521,10.5405,0.08301}, + {79.9,-0.3521,10.5592,0.083}, + {80,-0.3521,10.5781,0.08298}, + {80.1,-0.3521,10.597,0.08297}, + {80.2,-0.3521,10.6161,0.08295}, + {80.3,-0.3521,10.6352,0.08293}, + {80.4,-0.3521,10.6544,0.08291}, + {80.5,-0.3521,10.6737,0.0829}, + {80.6,-0.3521,10.6931,0.08288}, + {80.7,-0.3521,10.7126,0.08286}, + {80.8,-0.3521,10.7322,0.08284}, + {80.9,-0.3521,10.752,0.08282}, + {81,-0.3521,10.7718,0.08279}, + {81.1,-0.3521,10.7918,0.08277}, + {81.2,-0.3521,10.8119,0.08275}, + {81.3,-0.3521,10.8321,0.08273}, + {81.4,-0.3521,10.8524,0.0827}, + {81.5,-0.3521,10.8728,0.08268}, + {81.6,-0.3521,10.8934,0.08265}, + {81.7,-0.3521,10.9142,0.08263}, + {81.8,-0.3521,10.935,0.0826}, + {81.9,-0.3521,10.956,0.08258}, + {82,-0.3521,10.9772,0.08255}, + {82.1,-0.3521,10.9985,0.08252}, + {82.2,-0.3521,11.0199,0.08249}, + {82.3,-0.3521,11.0415,0.08246}, + {82.4,-0.3521,11.0632,0.08244}, + {82.5,-0.3521,11.0851,0.08241}, + {82.6,-0.3521,11.1071,0.08238}, + {82.7,-0.3521,11.1293,0.08235}, + {82.8,-0.3521,11.1516,0.08231}, + {82.9,-0.3521,11.174,0.08228}, + {83,-0.3521,11.1966,0.08225}, + {83.1,-0.3521,11.2193,0.08222}, + {83.2,-0.3521,11.2422,0.08219}, + {83.3,-0.3521,11.2651,0.08215}, + {83.4,-0.3521,11.2882,0.08212}, + {83.5,-0.3521,11.3114,0.08209}, + {83.6,-0.3521,11.3347,0.08205}, + {83.7,-0.3521,11.3581,0.08202}, + {83.8,-0.3521,11.3817,0.08198}, + {83.9,-0.3521,11.4053,0.08195}, + {84,-0.3521,11.429,0.08191}, + {84.1,-0.3521,11.4529,0.08188}, + {84.2,-0.3521,11.4768,0.08184}, + {84.3,-0.3521,11.5007,0.08181}, + {84.4,-0.3521,11.5248,0.08177}, + {84.5,-0.3521,11.549,0.08174}, + {84.6,-0.3521,11.5732,0.0817}, + {84.7,-0.3521,11.5975,0.08166}, + {84.8,-0.3521,11.6218,0.08163}, + {84.9,-0.3521,11.6462,0.08159}, + {85,-0.3521,11.6707,0.08156}, + {85.1,-0.3521,11.6952,0.08152}, + {85.2,-0.3521,11.7198,0.08148}, + {85.3,-0.3521,11.7444,0.08145}, + {85.4,-0.3521,11.769,0.08141}, + {85.5,-0.3521,11.7937,0.08138}, + {85.6,-0.3521,11.8184,0.08134}, + {85.7,-0.3521,11.8431,0.08131}, + {85.8,-0.3521,11.8678,0.08128}, + {85.9,-0.3521,11.8926,0.08124}, + {86,-0.3521,11.9173,0.08121}, + {86.1,-0.3521,11.9421,0.08118}, + {86.2,-0.3521,11.9668,0.08114}, + {86.3,-0.3521,11.9916,0.08111}, + {86.4,-0.3521,12.0163,0.08108}, + {86.5,-0.3521,12.0411,0.08105}, + {86.6,-0.3521,12.0658,0.08102}, + {86.7,-0.3521,12.0905,0.08099}, + {86.8,-0.3521,12.1152,0.08096}, + {86.9,-0.3521,12.1398,0.08093}, + {87,-0.3521,12.1645,0.0809}, + {87.1,-0.3521,12.1891,0.08087}, + {87.2,-0.3521,12.2136,0.08084}, + {87.3,-0.3521,12.2382,0.08082}, + {87.4,-0.3521,12.2627,0.08079}, + {87.5,-0.3521,12.2871,0.08076}, + {87.6,-0.3521,12.3116,0.08074}, + {87.7,-0.3521,12.336,0.08071}, + {87.8,-0.3521,12.3603,0.08069}, + {87.9,-0.3521,12.3846,0.08067}, + {88,-0.3521,12.4089,0.08064}, + {88.1,-0.3521,12.4332,0.08062}, + {88.2,-0.3521,12.4574,0.0806}, + {88.3,-0.3521,12.4815,0.08058}, + {88.4,-0.3521,12.5057,0.08056}, + {88.5,-0.3521,12.5298,0.08054}, + {88.6,-0.3521,12.5538,0.08052}, + {88.7,-0.3521,12.5778,0.0805}, + {88.8,-0.3521,12.6017,0.08048}, + {88.9,-0.3521,12.6257,0.08047}, + {89,-0.3521,12.6495,0.08045}, + {89.1,-0.3521,12.6734,0.08044}, + {89.2,-0.3521,12.6972,0.08042}, + {89.3,-0.3521,12.7209,0.08041}, + {89.4,-0.3521,12.7446,0.08039}, + {89.5,-0.3521,12.7683,0.08038}, + {89.6,-0.3521,12.792,0.08037}, + {89.7,-0.3521,12.8156,0.08035}, + {89.8,-0.3521,12.8392,0.08034}, + {89.9,-0.3521,12.8628,0.08033}, + {90,-0.3521,12.8864,0.08032}, + {90.1,-0.3521,12.9099,0.08031}, + {90.2,-0.3521,12.9334,0.0803}, + {90.3,-0.3521,12.9569,0.0803}, + {90.4,-0.3521,12.9804,0.08029}, + {90.5,-0.3521,13.0038,0.08028}, + {90.6,-0.3521,13.0273,0.08027}, + {90.7,-0.3521,13.0507,0.08027}, + {90.8,-0.3521,13.0742,0.08026}, + {90.9,-0.3521,13.0976,0.08026}, + {91,-0.3521,13.1209,0.08025}, + {91.1,-0.3521,13.1443,0.08025}, + {91.2,-0.3521,13.1677,0.08025}, + {91.3,-0.3521,13.191,0.08025}, + {91.4,-0.3521,13.2143,0.08025}, + {91.5,-0.3521,13.2376,0.08024}, + {91.6,-0.3521,13.2609,0.08024}, + {91.7,-0.3521,13.2842,0.08024}, + {91.8,-0.3521,13.3075,0.08025}, + {91.9,-0.3521,13.3308,0.08025}, + {92,-0.3521,13.3541,0.08025}, + {92.1,-0.3521,13.3773,0.08025}, + {92.2,-0.3521,13.4006,0.08026}, + {92.3,-0.3521,13.4239,0.08026}, + {92.4,-0.3521,13.4472,0.08027}, + {92.5,-0.3521,13.4705,0.08027}, + {92.6,-0.3521,13.4937,0.08028}, + {92.7,-0.3521,13.5171,0.08028}, + {92.8,-0.3521,13.5404,0.08029}, + {92.9,-0.3521,13.5637,0.0803}, + {93,-0.3521,13.587,0.08031}, + {93.1,-0.3521,13.6104,0.08032}, + {93.2,-0.3521,13.6338,0.08033}, + {93.3,-0.3521,13.6572,0.08034}, + {93.4,-0.3521,13.6806,0.08035}, + {93.5,-0.3521,13.7041,0.08036}, + {93.6,-0.3521,13.7275,0.08037}, + {93.7,-0.3521,13.751,0.08038}, + {93.8,-0.3521,13.7746,0.0804}, + {93.9,-0.3521,13.7981,0.08041}, + {94,-0.3521,13.8217,0.08043}, + {94.1,-0.3521,13.8454,0.08044}, + {94.2,-0.3521,13.8691,0.08046}, + {94.3,-0.3521,13.8928,0.08047}, + {94.4,-0.3521,13.9165,0.08049}, + {94.5,-0.3521,13.9403,0.08051}, + {94.6,-0.3521,13.9642,0.08052}, + {94.7,-0.3521,13.9881,0.08054}, + {94.8,-0.3521,14.012,0.08056}, + {94.9,-0.3521,14.036,0.08058}, + {95,-0.3521,14.06,0.0806}, + {95.1,-0.3521,14.0841,0.08062}, + {95.2,-0.3521,14.1083,0.08064}, + {95.3,-0.3521,14.1325,0.08067}, + {95.4,-0.3521,14.1567,0.08069}, + {95.5,-0.3521,14.1811,0.08071}, + {95.6,-0.3521,14.2055,0.08073}, + {95.7,-0.3521,14.2299,0.08076}, + {95.8,-0.3521,14.2544,0.08078}, + {95.9,-0.3521,14.279,0.08081}, + {96,-0.3521,14.3037,0.08083}, + {96.1,-0.3521,14.3284,0.08086}, + {96.2,-0.3521,14.3533,0.08089}, + {96.3,-0.3521,14.3782,0.08092}, + {96.4,-0.3521,14.4031,0.08094}, + {96.5,-0.3521,14.4282,0.08097}, + {96.6,-0.3521,14.4533,0.081}, + {96.7,-0.3521,14.4785,0.08103}, + {96.8,-0.3521,14.5038,0.08106}, + {96.9,-0.3521,14.5292,0.08109}, + {97,-0.3521,14.5547,0.08112}, + {97.1,-0.3521,14.5802,0.08116}, + {97.2,-0.3521,14.6058,0.08119}, + {97.3,-0.3521,14.6316,0.08122}, + {97.4,-0.3521,14.6574,0.08125}, + {97.5,-0.3521,14.6832,0.08129}, + {97.6,-0.3521,14.7092,0.08132}, + {97.7,-0.3521,14.7353,0.08136}, + {97.8,-0.3521,14.7614,0.08139}, + {97.9,-0.3521,14.7877,0.08143}, + {98,-0.3521,14.814,0.08146}, + {98.1,-0.3521,14.8404,0.0815}, + {98.2,-0.3521,14.8669,0.08154}, + {98.3,-0.3521,14.8934,0.08157}, + {98.4,-0.3521,14.9201,0.08161}, + {98.5,-0.3521,14.9468,0.08165}, + {98.6,-0.3521,14.9736,0.08169}, + {98.7,-0.3521,15.0005,0.08173}, + {98.8,-0.3521,15.0275,0.08177}, + {98.9,-0.3521,15.0546,0.08181}, + {99,-0.3521,15.0818,0.08185}, + {99.1,-0.3521,15.109,0.08189}, + {99.2,-0.3521,15.1363,0.08194}, + {99.3,-0.3521,15.1637,0.08198}, + {99.4,-0.3521,15.1912,0.08202}, + {99.5,-0.3521,15.2187,0.08206}, + {99.6,-0.3521,15.2463,0.08211}, + {99.7,-0.3521,15.274,0.08215}, + {99.8,-0.3521,15.3018,0.0822}, + {99.9,-0.3521,15.3297,0.08224}, + {100,-0.3521,15.3576,0.08229}, + {100.1,-0.3521,15.3856,0.08233}, + {100.2,-0.3521,15.4137,0.08238}, + {100.3,-0.3521,15.4419,0.08243}, + {100.4,-0.3521,15.4701,0.08247}, + {100.5,-0.3521,15.4985,0.08252}, + {100.6,-0.3521,15.5268,0.08257}, + {100.7,-0.3521,15.5553,0.08262}, + {100.8,-0.3521,15.5838,0.08267}, + {100.9,-0.3521,15.6125,0.08272}, + {101,-0.3521,15.6412,0.08277}, + {101.1,-0.3521,15.6699,0.08281}, + {101.2,-0.3521,15.6987,0.08287}, + {101.3,-0.3521,15.7276,0.08292}, + {101.4,-0.3521,15.7566,0.08297}, + {101.5,-0.3521,15.7857,0.08302}, + {101.6,-0.3521,15.8148,0.08307}, + {101.7,-0.3521,15.844,0.08312}, + {101.8,-0.3521,15.8732,0.08317}, + {101.9,-0.3521,15.9026,0.08322}, + {102,-0.3521,15.932,0.08328}, + {102.1,-0.3521,15.9615,0.08333}, + {102.2,-0.3521,15.991,0.08338}, + {102.3,-0.3521,16.0206,0.08343}, + {102.4,-0.3521,16.0503,0.08349}, + {102.5,-0.3521,16.0801,0.08354}, + {102.6,-0.3521,16.1099,0.08359}, + {102.7,-0.3521,16.1398,0.08365}, + {102.8,-0.3521,16.1697,0.0837}, + {102.9,-0.3521,16.1997,0.08376}, + {103,-0.3521,16.2298,0.08381}, + {103.1,-0.3521,16.26,0.08386}, + {103.2,-0.3521,16.2902,0.08392}, + {103.3,-0.3521,16.3204,0.08397}, + {103.4,-0.3521,16.3508,0.08403}, + {103.5,-0.3521,16.3812,0.08408}, + {103.6,-0.3521,16.4117,0.08414}, + {103.7,-0.3521,16.4422,0.08419}, + {103.8,-0.3521,16.4728,0.08425}, + {103.9,-0.3521,16.5035,0.08431}, + {104,-0.3521,16.5342,0.08436}, + {104.1,-0.3521,16.565,0.08442}, + {104.2,-0.3521,16.5959,0.08447}, + {104.3,-0.3521,16.6268,0.08453}, + {104.4,-0.3521,16.6579,0.08458}, + {104.5,-0.3521,16.6889,0.08464}, + {104.6,-0.3521,16.7201,0.0847}, + {104.7,-0.3521,16.7513,0.08475}, + {104.8,-0.3521,16.7826,0.08481}, + {104.9,-0.3521,16.8139,0.08487}, + {105,-0.3521,16.8454,0.08493}, + {105.1,-0.3521,16.8769,0.08498}, + {105.2,-0.3521,16.9084,0.08504}, + {105.3,-0.3521,16.9401,0.0851}, + {105.4,-0.3521,16.9718,0.08516}, + {105.5,-0.3521,17.0036,0.08521}, + {105.6,-0.3521,17.0355,0.08527}, + {105.7,-0.3521,17.0674,0.08533}, + {105.8,-0.3521,17.0995,0.08539}, + {105.9,-0.3521,17.1316,0.08545}, + {106,-0.3521,17.1637,0.08551}, + {106.1,-0.3521,17.196,0.08557}, + {106.2,-0.3521,17.2283,0.08562}, + {106.3,-0.3521,17.2607,0.08568}, + {106.4,-0.3521,17.2931,0.08574}, + {106.5,-0.3521,17.3256,0.0858}, + {106.6,-0.3521,17.3582,0.08586}, + {106.7,-0.3521,17.3909,0.08592}, + {106.8,-0.3521,17.4237,0.08599}, + {106.9,-0.3521,17.4565,0.08605}, + {107,-0.3521,17.4894,0.08611}, + {107.1,-0.3521,17.5224,0.08617}, + {107.2,-0.3521,17.5554,0.08623}, + {107.3,-0.3521,17.5885,0.08629}, + {107.4,-0.3521,17.6217,0.08635}, + {107.5,-0.3521,17.655,0.08641}, + {107.6,-0.3521,17.6884,0.08648}, + {107.7,-0.3521,17.7218,0.08654}, + {107.8,-0.3521,17.7553,0.0866}, + {107.9,-0.3521,17.7889,0.08666}, + {108,-0.3521,17.8226,0.08673}, + {108.1,-0.3521,17.8564,0.08679}, + {108.2,-0.3521,17.8903,0.08685}, + {108.3,-0.3521,17.9242,0.08691}, + {108.4,-0.3521,17.9583,0.08698}, + {108.5,-0.3521,17.9924,0.08704}, + {108.6,-0.3521,18.0267,0.0871}, + {108.7,-0.3521,18.061,0.08717}, + {108.8,-0.3521,18.0954,0.08723}, + {108.9,-0.3521,18.1299,0.0873}, + {109,-0.3521,18.1645,0.08736}, + {109.1,-0.3521,18.1992,0.08742}, + {109.2,-0.3521,18.234,0.08749}, + {109.3,-0.3521,18.2689,0.08755}, + {109.4,-0.3521,18.3039,0.08762}, + {109.5,-0.3521,18.339,0.08768}, + {109.6,-0.3521,18.3742,0.08774}, + {109.7,-0.3521,18.4094,0.08781}, + {109.8,-0.3521,18.4448,0.08787}, + {109.9,-0.3521,18.4802,0.08794}, + {110,-0.3521,18.5158,0.088}, + {110.1,-0.3521,18.5514,0.08806}, + {110.2,-0.3521,18.5871,0.08813}, + {110.3,-0.3521,18.6229,0.08819}, + {110.4,-0.3521,18.6588,0.08826}, + {110.5,-0.3521,18.6948,0.08832}, + {110.6,-0.3521,18.7308,0.08838}, + {110.7,-0.3521,18.767,0.08845}, + {110.8,-0.3521,18.8032,0.08851}, + {110.9,-0.3521,18.8395,0.08858}, + {111,-0.3521,18.8759,0.08864}, + {111.1,-0.3521,18.9123,0.08871}, + {111.2,-0.3521,18.9489,0.08877}, + {111.3,-0.3521,18.9855,0.08883}, + {111.4,-0.3521,19.0222,0.0889}, + {111.5,-0.3521,19.059,0.08896}, + {111.6,-0.3521,19.0958,0.08903}, + {111.7,-0.3521,19.1327,0.08909}, + {111.8,-0.3521,19.1697,0.08915}, + {111.9,-0.3521,19.2067,0.08922}, + {112,-0.3521,19.2439,0.08928}, + {112.1,-0.3521,19.281,0.08934}, + {112.2,-0.3521,19.3183,0.08941}, + {112.3,-0.3521,19.3556,0.08947}, + {112.4,-0.3521,19.393,0.08953}, + {112.5,-0.3521,19.4304,0.0896}, + {112.6,-0.3521,19.4679,0.08966}, + {112.7,-0.3521,19.5055,0.08972}, + {112.8,-0.3521,19.5431,0.08979}, + {112.9,-0.3521,19.5807,0.08985}, + {113,-0.3521,19.6185,0.08991}, + {113.1,-0.3521,19.6563,0.08997}, + {113.2,-0.3521,19.6941,0.09004}, + {113.3,-0.3521,19.7321,0.0901}, + {113.4,-0.3521,19.77,0.09016}, + {113.5,-0.3521,19.8081,0.09022}, + {113.6,-0.3521,19.8461,0.09029}, + {113.7,-0.3521,19.8843,0.09035}, + {113.8,-0.3521,19.9225,0.09041}, + {113.9,-0.3521,19.9607,0.09047}, + {114,-0.3521,19.999,0.09054}, + {114.1,-0.3521,20.0373,0.0906}, + {114.2,-0.3521,20.0757,0.09066}, + {114.3,-0.3521,20.1142,0.09072}, + {114.4,-0.3521,20.1527,0.09079}, + {114.5,-0.3521,20.1912,0.09085}, + {114.6,-0.3521,20.2298,0.09091}, + {114.7,-0.3521,20.2684,0.09097}, + {114.8,-0.3521,20.3071,0.09103}, + {114.9,-0.3521,20.3458,0.0911}, + {115,-0.3521,20.3846,0.09116}, + {115.1,-0.3521,20.4233,0.09122}, + {115.2,-0.3521,20.4622,0.09128}, + {115.3,-0.3521,20.501,0.09134}, + {115.4,-0.3521,20.54,0.0914}, + {115.5,-0.3521,20.5789,0.09147}, + {115.6,-0.3521,20.6179,0.09153}, + {115.7,-0.3521,20.6569,0.09159}, + {115.8,-0.3521,20.6959,0.09165}, + {115.9,-0.3521,20.735,0.09171}, + {116,-0.3521,20.7741,0.09177}, + {116.1,-0.3521,20.8132,0.09183}, + {116.2,-0.3521,20.8524,0.0919}, + {116.3,-0.3521,20.8916,0.09196}, + {116.4,-0.3521,20.9308,0.09202}, + {116.5,-0.3521,20.97,0.09208}, + {116.6,-0.3521,21.0093,0.09214}, + {116.7,-0.3521,21.0486,0.0922}, + {116.8,-0.3521,21.0879,0.09227}, + {116.9,-0.3521,21.1272,0.09233}, + {117,-0.3521,21.1666,0.09239}, + {117.1,-0.3521,21.2059,0.09245}, + {117.2,-0.3521,21.2453,0.09251}, + {117.3,-0.3521,21.2847,0.09257}, + {117.4,-0.3521,21.3242,0.09263}, + {117.5,-0.3521,21.3636,0.0927}, + {117.6,-0.3521,21.4031,0.09276}, + {117.7,-0.3521,21.4426,0.09282}, + {117.8,-0.3521,21.482,0.09288}, + {117.9,-0.3521,21.5215,0.09294}, + {118,-0.3521,21.5611,0.093}, + {118.1,-0.3521,21.6006,0.09307}, + {118.2,-0.3521,21.6401,0.09313}, + {118.3,-0.3521,21.6797,0.09319}, + {118.4,-0.3521,21.7193,0.09325}, + {118.5,-0.3521,21.7588,0.09331}, + {118.6,-0.3521,21.7984,0.09338}, + {118.7,-0.3521,21.838,0.09344}, + {118.8,-0.3521,21.8776,0.0935}, + {118.9,-0.3521,21.9172,0.09356}, + {119,-0.3521,21.9568,0.09362}, + {119.1,-0.3521,21.9964,0.09368}, + {119.2,-0.3521,22.036,0.09375}, + {119.3,-0.3521,22.0757,0.09381}, + {119.4,-0.3521,22.1153,0.09387}, + {119.5,-0.3521,22.1549,0.09393}, + {119.6,-0.3521,22.1945,0.09399}, + {119.7,-0.3521,22.2341,0.09406}, + {119.8,-0.3521,22.2738,0.09412}, + {119.9,-0.3521,22.3134,0.09418}, + {120,-0.3521,22.353,0.09424} + }; + return boysWeightForHeight[index < boysWeightForHeight.length ? index : boysWeightForHeight.length]; + } + + public double[]getGirlsWeightForHeight(int index){ + double[][]girlsWeightForHeight = { + {65,-0.3833,7.2402,0.09113}, + {65.1,-0.3833,7.2627,0.09112}, + {65.2,-0.3833,7.2852,0.09111}, + {65.3,-0.3833,7.3076,0.0911}, + {65.4,-0.3833,7.33,0.09109}, + {65.5,-0.3833,7.3523,0.09109}, + {65.6,-0.3833,7.3745,0.09108}, + {65.7,-0.3833,7.3967,0.09107}, + {65.8,-0.3833,7.4189,0.09106}, + {65.9,-0.3833,7.441,0.09105}, + {66,-0.3833,7.463,0.09104}, + {66.1,-0.3833,7.485,0.09103}, + {66.2,-0.3833,7.5069,0.09102}, + {66.3,-0.3833,7.5288,0.09101}, + {66.4,-0.3833,7.5507,0.091}, + {66.5,-0.3833,7.5724,0.09099}, + {66.6,-0.3833,7.5942,0.09098}, + {66.7,-0.3833,7.6158,0.09097}, + {66.8,-0.3833,7.6375,0.09096}, + {66.9,-0.3833,7.659,0.09095}, + {67,-0.3833,7.6806,0.09094}, + {67.1,-0.3833,7.702,0.09093}, + {67.2,-0.3833,7.7234,0.09091}, + {67.3,-0.3833,7.7448,0.0909}, + {67.4,-0.3833,7.7661,0.09089}, + {67.5,-0.3833,7.7874,0.09088}, + {67.6,-0.3833,7.8086,0.09087}, + {67.7,-0.3833,7.8298,0.09086}, + {67.8,-0.3833,7.8509,0.09085}, + {67.9,-0.3833,7.872,0.09084}, + {68,-0.3833,7.893,0.09083}, + {68.1,-0.3833,7.914,0.09082}, + {68.2,-0.3833,7.935,0.0908}, + {68.3,-0.3833,7.9559,0.09079}, + {68.4,-0.3833,7.9768,0.09078}, + {68.5,-0.3833,7.9976,0.09077}, + {68.6,-0.3833,8.0184,0.09076}, + {68.7,-0.3833,8.0392,0.09075}, + {68.8,-0.3833,8.0599,0.09074}, + {68.9,-0.3833,8.0806,0.09072}, + {69,-0.3833,8.1012,0.09071}, + {69.1,-0.3833,8.1218,0.0907}, + {69.2,-0.3833,8.1424,0.09069}, + {69.3,-0.3833,8.163,0.09068}, + {69.4,-0.3833,8.1835,0.09067}, + {69.5,-0.3833,8.2039,0.09065}, + {69.6,-0.3833,8.2244,0.09064}, + {69.7,-0.3833,8.2448,0.09063}, + {69.8,-0.3833,8.2651,0.09062}, + {69.9,-0.3833,8.2855,0.09061}, + {70,-0.3833,8.3058,0.09059}, + {70.1,-0.3833,8.3261,0.09058}, + {70.2,-0.3833,8.3464,0.09057}, + {70.3,-0.3833,8.3666,0.09056}, + {70.4,-0.3833,8.3869,0.09055}, + {70.5,-0.3833,8.4071,0.09053}, + {70.6,-0.3833,8.4273,0.09052}, + {70.7,-0.3833,8.4474,0.09051}, + {70.8,-0.3833,8.4676,0.0905}, + {70.9,-0.3833,8.4877,0.09048}, + {71,-0.3833,8.5078,0.09047}, + {71.1,-0.3833,8.5278,0.09046}, + {71.2,-0.3833,8.5479,0.09045}, + {71.3,-0.3833,8.5679,0.09043}, + {71.4,-0.3833,8.5879,0.09042}, + {71.5,-0.3833,8.6078,0.09041}, + {71.6,-0.3833,8.6277,0.0904}, + {71.7,-0.3833,8.6476,0.09039}, + {71.8,-0.3833,8.6674,0.09037}, + {71.9,-0.3833,8.6872,0.09036}, + {72,-0.3833,8.707,0.09035}, + {72.1,-0.3833,8.7267,0.09034}, + {72.2,-0.3833,8.7464,0.09032}, + {72.3,-0.3833,8.7661,0.09031}, + {72.4,-0.3833,8.7857,0.0903}, + {72.5,-0.3833,8.8053,0.09028}, + {72.6,-0.3833,8.8248,0.09027}, + {72.7,-0.3833,8.8443,0.09026}, + {72.8,-0.3833,8.8638,0.09025}, + {72.9,-0.3833,8.8831,0.09023}, + {73,-0.3833,8.9025,0.09022}, + {73.1,-0.3833,8.9217,0.09021}, + {73.2,-0.3833,8.941,0.0902}, + {73.3,-0.3833,8.9601,0.09018}, + {73.4,-0.3833,8.9792,0.09017}, + {73.5,-0.3833,8.9983,0.09016}, + {73.6,-0.3833,9.0173,0.09014}, + {73.7,-0.3833,9.0363,0.09013}, + {73.8,-0.3833,9.0552,0.09012}, + {73.9,-0.3833,9.074,0.09011}, + {74,-0.3833,9.0928,0.09009}, + {74.1,-0.3833,9.1116,0.09008}, + {74.2,-0.3833,9.1303,0.09007}, + {74.3,-0.3833,9.149,0.09005}, + {74.4,-0.3833,9.1676,0.09004}, + {74.5,-0.3833,9.1862,0.09003}, + {74.6,-0.3833,9.2048,0.09001}, + {74.7,-0.3833,9.2233,0.09}, + {74.8,-0.3833,9.2418,0.08999}, + {74.9,-0.3833,9.2602,0.08997}, + {75,-0.3833,9.2786,0.08996}, + {75.1,-0.3833,9.297,0.08995}, + {75.2,-0.3833,9.3154,0.08993}, + {75.3,-0.3833,9.3337,0.08992}, + {75.4,-0.3833,9.352,0.08991}, + {75.5,-0.3833,9.3703,0.08989}, + {75.6,-0.3833,9.3886,0.08988}, + {75.7,-0.3833,9.4069,0.08987}, + {75.8,-0.3833,9.4252,0.08985}, + {75.9,-0.3833,9.4435,0.08984}, + {76,-0.3833,9.4617,0.08983}, + {76.1,-0.3833,9.48,0.08981}, + {76.2,-0.3833,9.4983,0.0898}, + {76.3,-0.3833,9.5166,0.08979}, + {76.4,-0.3833,9.535,0.08977}, + {76.5,-0.3833,9.5533,0.08976}, + {76.6,-0.3833,9.5717,0.08975}, + {76.7,-0.3833,9.5901,0.08973}, + {76.8,-0.3833,9.6086,0.08972}, + {76.9,-0.3833,9.6271,0.08971}, + {77,-0.3833,9.6456,0.08969}, + {77.1,-0.3833,9.6642,0.08968}, + {77.2,-0.3833,9.6828,0.08966}, + {77.3,-0.3833,9.7015,0.08965}, + {77.4,-0.3833,9.7202,0.08964}, + {77.5,-0.3833,9.739,0.08963}, + {77.6,-0.3833,9.7578,0.08961}, + {77.7,-0.3833,9.7767,0.0896}, + {77.8,-0.3833,9.7957,0.08959}, + {77.9,-0.3833,9.8147,0.08957}, + {78,-0.3833,9.8338,0.08956}, + {78.1,-0.3833,9.853,0.08955}, + {78.2,-0.3833,9.8722,0.08953}, + {78.3,-0.3833,9.8915,0.08952}, + {78.4,-0.3833,9.9109,0.08951}, + {78.5,-0.3833,9.9303,0.0895}, + {78.6,-0.3833,9.9499,0.08948}, + {78.7,-0.3833,9.9695,0.08947}, + {78.8,-0.3833,9.9892,0.08946}, + {78.9,-0.3833,10.009,0.08945}, + {79,-0.3833,10.0289,0.08943}, + {79.1,-0.3833,10.0489,0.08942}, + {79.2,-0.3833,10.069,0.08941}, + {79.3,-0.3833,10.0891,0.0894}, + {79.4,-0.3833,10.1094,0.08939}, + {79.5,-0.3833,10.1298,0.08937}, + {79.6,-0.3833,10.1503,0.08936}, + {79.7,-0.3833,10.1709,0.08935}, + {79.8,-0.3833,10.1916,0.08934}, + {79.9,-0.3833,10.2123,0.08933}, + {80,-0.3833,10.2332,0.08932}, + {80.1,-0.3833,10.2542,0.0893}, + {80.2,-0.3833,10.2753,0.08929}, + {80.3,-0.3833,10.2965,0.08928}, + {80.4,-0.3833,10.3178,0.08927}, + {80.5,-0.3833,10.3393,0.08926}, + {80.6,-0.3833,10.3608,0.08925}, + {80.7,-0.3833,10.3824,0.08924}, + {80.8,-0.3833,10.4041,0.08923}, + {80.9,-0.3833,10.4258,0.08922}, + {81,-0.3833,10.4477,0.08921}, + {81.1,-0.3833,10.4697,0.0892}, + {81.2,-0.3833,10.4918,0.08919}, + {81.3,-0.3833,10.514,0.08918}, + {81.4,-0.3833,10.5363,0.08917}, + {81.5,-0.3833,10.5586,0.08916}, + {81.6,-0.3833,10.5811,0.08915}, + {81.7,-0.3833,10.6037,0.08915}, + {81.8,-0.3833,10.6263,0.08914}, + {81.9,-0.3833,10.6491,0.08913}, + {82,-0.3833,10.6719,0.08912}, + {82.1,-0.3833,10.6948,0.08911}, + {82.2,-0.3833,10.7178,0.0891}, + {82.3,-0.3833,10.741,0.0891}, + {82.4,-0.3833,10.7641,0.08909}, + {82.5,-0.3833,10.7874,0.08908}, + {82.6,-0.3833,10.8108,0.08907}, + {82.7,-0.3833,10.8343,0.08907}, + {82.8,-0.3833,10.8578,0.08906}, + {82.9,-0.3833,10.8814,0.08905}, + {83,-0.3833,10.9051,0.08905}, + {83.1,-0.3833,10.9289,0.08904}, + {83.2,-0.3833,10.9527,0.08903}, + {83.3,-0.3833,10.9767,0.08903}, + {83.4,-0.3833,11.0007,0.08902}, + {83.5,-0.3833,11.0248,0.08902}, + {83.6,-0.3833,11.0489,0.08901}, + {83.7,-0.3833,11.0731,0.08901}, + {83.8,-0.3833,11.0974,0.089}, + {83.9,-0.3833,11.1218,0.089}, + {84,-0.3833,11.1462,0.08899}, + {84.1,-0.3833,11.1707,0.08899}, + {84.2,-0.3833,11.1952,0.08899}, + {84.3,-0.3833,11.2198,0.08898}, + {84.4,-0.3833,11.2444,0.08898}, + {84.5,-0.3833,11.2691,0.08897}, + {84.6,-0.3833,11.2939,0.08897}, + {84.7,-0.3833,11.3187,0.08897}, + {84.8,-0.3833,11.3435,0.08897}, + {84.9,-0.3833,11.3684,0.08896}, + {85,-0.3833,11.3934,0.08896}, + {85.1,-0.3833,11.4183,0.08896}, + {85.2,-0.3833,11.4434,0.08896}, + {85.3,-0.3833,11.4684,0.08895}, + {85.4,-0.3833,11.4935,0.08895}, + {85.5,-0.3833,11.5186,0.08895}, + {85.6,-0.3833,11.5437,0.08895}, + {85.7,-0.3833,11.5689,0.08895}, + {85.8,-0.3833,11.594,0.08895}, + {85.9,-0.3833,11.6192,0.08895}, + {86,-0.3833,11.6444,0.08895}, + {86.1,-0.3833,11.6696,0.08895}, + {86.2,-0.3833,11.6948,0.08895}, + {86.3,-0.3833,11.7201,0.08895}, + {86.4,-0.3833,11.7453,0.08895}, + {86.5,-0.3833,11.7705,0.08895}, + {86.6,-0.3833,11.7957,0.08895}, + {86.7,-0.3833,11.8209,0.08895}, + {86.8,-0.3833,11.8461,0.08895}, + {86.9,-0.3833,11.8713,0.08896}, + {87,-0.3833,11.8965,0.08896}, + {87.1,-0.3833,11.9217,0.08896}, + {87.2,-0.3833,11.9468,0.08896}, + {87.3,-0.3833,11.972,0.08896}, + {87.4,-0.3833,11.9971,0.08897}, + {87.5,-0.3833,12.0223,0.08897}, + {87.6,-0.3833,12.0474,0.08897}, + {87.7,-0.3833,12.0725,0.08898}, + {87.8,-0.3833,12.0976,0.08898}, + {87.9,-0.3833,12.1227,0.08898}, + {88,-0.3833,12.1478,0.08899}, + {88.1,-0.3833,12.1728,0.08899}, + {88.2,-0.3833,12.1978,0.089}, + {88.3,-0.3833,12.2229,0.089}, + {88.4,-0.3833,12.2479,0.08901}, + {88.5,-0.3833,12.2729,0.08901}, + {88.6,-0.3833,12.2978,0.08902}, + {88.7,-0.3833,12.3228,0.08902}, + {88.8,-0.3833,12.3477,0.08903}, + {88.9,-0.3833,12.3727,0.08903}, + {89,-0.3833,12.3976,0.08904}, + {89.1,-0.3833,12.4225,0.08904}, + {89.2,-0.3833,12.4474,0.08905}, + {89.3,-0.3833,12.4723,0.08906}, + {89.4,-0.3833,12.4971,0.08906}, + {89.5,-0.3833,12.522,0.08907}, + {89.6,-0.3833,12.5468,0.08908}, + {89.7,-0.3833,12.5717,0.08909}, + {89.8,-0.3833,12.5965,0.08909}, + {89.9,-0.3833,12.6213,0.0891}, + {90,-0.3833,12.6461,0.08911}, + {90.1,-0.3833,12.6709,0.08912}, + {90.2,-0.3833,12.6957,0.08912}, + {90.3,-0.3833,12.7205,0.08913}, + {90.4,-0.3833,12.7453,0.08914}, + {90.5,-0.3833,12.77,0.08915}, + {90.6,-0.3833,12.7948,0.08916}, + {90.7,-0.3833,12.8196,0.08917}, + {90.8,-0.3833,12.8443,0.08918}, + {90.9,-0.3833,12.8691,0.08919}, + {91,-0.3833,12.8939,0.0892}, + {91.1,-0.3833,12.9186,0.08921}, + {91.2,-0.3833,12.9434,0.08922}, + {91.3,-0.3833,12.9681,0.08923}, + {91.4,-0.3833,12.9929,0.08924}, + {91.5,-0.3833,13.0177,0.08925}, + {91.6,-0.3833,13.0424,0.08926}, + {91.7,-0.3833,13.0672,0.08927}, + {91.8,-0.3833,13.092,0.08928}, + {91.9,-0.3833,13.1167,0.0893}, + {92,-0.3833,13.1415,0.08931}, + {92.1,-0.3833,13.1663,0.08932}, + {92.2,-0.3833,13.1911,0.08933}, + {92.3,-0.3833,13.2158,0.08934}, + {92.4,-0.3833,13.2406,0.08936}, + {92.5,-0.3833,13.2654,0.08937}, + {92.6,-0.3833,13.2902,0.08938}, + {92.7,-0.3833,13.3151,0.0894}, + {92.8,-0.3833,13.3399,0.08941}, + {92.9,-0.3833,13.3647,0.08942}, + {93,-0.3833,13.3896,0.08944}, + {93.1,-0.3833,13.4145,0.08945}, + {93.2,-0.3833,13.4394,0.08947}, + {93.3,-0.3833,13.4643,0.08948}, + {93.4,-0.3833,13.4892,0.08949}, + {93.5,-0.3833,13.5142,0.08951}, + {93.6,-0.3833,13.5391,0.08952}, + {93.7,-0.3833,13.5641,0.08954}, + {93.8,-0.3833,13.5892,0.08955}, + {93.9,-0.3833,13.6142,0.08957}, + {94,-0.3833,13.6393,0.08959}, + {94.1,-0.3833,13.6644,0.0896}, + {94.2,-0.3833,13.6895,0.08962}, + {94.3,-0.3833,13.7146,0.08963}, + {94.4,-0.3833,13.7398,0.08965}, + {94.5,-0.3833,13.765,0.08967}, + {94.6,-0.3833,13.7902,0.08968}, + {94.7,-0.3833,13.8155,0.0897}, + {94.8,-0.3833,13.8408,0.08972}, + {94.9,-0.3833,13.8661,0.08974}, + {95,-0.3833,13.8914,0.08975}, + {95.1,-0.3833,13.9168,0.08977}, + {95.2,-0.3833,13.9422,0.08979}, + {95.3,-0.3833,13.9676,0.08981}, + {95.4,-0.3833,13.9931,0.08983}, + {95.5,-0.3833,14.0186,0.08984}, + {95.6,-0.3833,14.0441,0.08986}, + {95.7,-0.3833,14.0697,0.08988}, + {95.8,-0.3833,14.0953,0.0899}, + {95.9,-0.3833,14.1209,0.08992}, + {96,-0.3833,14.1466,0.08994}, + {96.1,-0.3833,14.1724,0.08996}, + {96.2,-0.3833,14.1981,0.08998}, + {96.3,-0.3833,14.2239,0.09}, + {96.4,-0.3833,14.2498,0.09002}, + {96.5,-0.3833,14.2757,0.09004}, + {96.6,-0.3833,14.3016,0.09006}, + {96.7,-0.3833,14.3276,0.09008}, + {96.8,-0.3833,14.3537,0.0901}, + {96.9,-0.3833,14.3798,0.09012}, + {97,-0.3833,14.4059,0.09015}, + {97.1,-0.3833,14.4321,0.09017}, + {97.2,-0.3833,14.4584,0.09019}, + {97.3,-0.3833,14.4848,0.09021}, + {97.4,-0.3833,14.5112,0.09023}, + {97.5,-0.3833,14.5376,0.09026}, + {97.6,-0.3833,14.5642,0.09028}, + {97.7,-0.3833,14.5908,0.0903}, + {97.8,-0.3833,14.6174,0.09033}, + {97.9,-0.3833,14.6442,0.09035}, + {98,-0.3833,14.671,0.09037}, + {98.1,-0.3833,14.6979,0.0904}, + {98.2,-0.3833,14.7248,0.09042}, + {98.3,-0.3833,14.7519,0.09044}, + {98.4,-0.3833,14.779,0.09047}, + {98.5,-0.3833,14.8062,0.09049}, + {98.6,-0.3833,14.8334,0.09052}, + {98.7,-0.3833,14.8608,0.09054}, + {98.8,-0.3833,14.8882,0.09057}, + {98.9,-0.3833,14.9157,0.09059}, + {99,-0.3833,14.9434,0.09062}, + {99.1,-0.3833,14.9711,0.09064}, + {99.2,-0.3833,14.9989,0.09067}, + {99.3,-0.3833,15.0267,0.09069}, + {99.4,-0.3833,15.0547,0.09072}, + {99.5,-0.3833,15.0828,0.09075}, + {99.6,-0.3833,15.1109,0.09077}, + {99.7,-0.3833,15.1392,0.0908}, + {99.8,-0.3833,15.1676,0.09083}, + {99.9,-0.3833,15.196,0.09085}, + {100,-0.3833,15.2246,0.09088}, + {100.1,-0.3833,15.2532,0.09091}, + {100.2,-0.3833,15.2819,0.09093}, + {100.3,-0.3833,15.3108,0.09096}, + {100.4,-0.3833,15.3397,0.09099}, + {100.5,-0.3833,15.3687,0.09102}, + {100.6,-0.3833,15.3979,0.09105}, + {100.7,-0.3833,15.4271,0.09107}, + {100.8,-0.3833,15.4564,0.0911}, + {100.9,-0.3833,15.4858,0.09113}, + {101,-0.3833,15.5154,0.09116}, + {101.1,-0.3833,15.545,0.09119}, + {101.2,-0.3833,15.5747,0.09122}, + {101.3,-0.3833,15.6046,0.09125}, + {101.4,-0.3833,15.6345,0.09128}, + {101.5,-0.3833,15.6646,0.09131}, + {101.6,-0.3833,15.6947,0.09133}, + {101.7,-0.3833,15.725,0.09136}, + {101.8,-0.3833,15.7553,0.09139}, + {101.9,-0.3833,15.7858,0.09142}, + {102,-0.3833,15.8164,0.09146}, + {102.1,-0.3833,15.847,0.09149}, + {102.2,-0.3833,15.8778,0.09152}, + {102.3,-0.3833,15.9087,0.09155}, + {102.4,-0.3833,15.9396,0.09158}, + {102.5,-0.3833,15.9707,0.09161}, + {102.6,-0.3833,16.0019,0.09164}, + {102.7,-0.3833,16.0332,0.09167}, + {102.8,-0.3833,16.0645,0.0917}, + {102.9,-0.3833,16.096,0.09173}, + {103,-0.3833,16.1276,0.09177}, + {103.1,-0.3833,16.1593,0.0918}, + {103.2,-0.3833,16.191,0.09183}, + {103.3,-0.3833,16.2229,0.09186}, + {103.4,-0.3833,16.2549,0.0919}, + {103.5,-0.3833,16.287,0.09193}, + {103.6,-0.3833,16.3191,0.09196}, + {103.7,-0.3833,16.3514,0.09199}, + {103.8,-0.3833,16.3837,0.09203}, + {103.9,-0.3833,16.4162,0.09206}, + {104,-0.3833,16.4488,0.09209}, + {104.1,-0.3833,16.4814,0.09213}, + {104.2,-0.3833,16.5142,0.09216}, + {104.3,-0.3833,16.547,0.09219}, + {104.4,-0.3833,16.58,0.09223}, + {104.5,-0.3833,16.6131,0.09226}, + {104.6,-0.3833,16.6462,0.09229}, + {104.7,-0.3833,16.6795,0.09233}, + {104.8,-0.3833,16.7129,0.09236}, + {104.9,-0.3833,16.7464,0.0924}, + {105,-0.3833,16.78,0.09243}, + {105.1,-0.3833,16.8137,0.09247}, + {105.2,-0.3833,16.8475,0.0925}, + {105.3,-0.3833,16.8814,0.09254}, + {105.4,-0.3833,16.9154,0.09257}, + {105.5,-0.3833,16.9496,0.09261}, + {105.6,-0.3833,16.9838,0.09264}, + {105.7,-0.3833,17.0182,0.09268}, + {105.8,-0.3833,17.0527,0.09271}, + {105.9,-0.3833,17.0873,0.09275}, + {106,-0.3833,17.122,0.09278}, + {106.1,-0.3833,17.1569,0.09282}, + {106.2,-0.3833,17.1918,0.09286}, + {106.3,-0.3833,17.2269,0.09289}, + {106.4,-0.3833,17.262,0.09293}, + {106.5,-0.3833,17.2973,0.09296}, + {106.6,-0.3833,17.3327,0.093}, + {106.7,-0.3833,17.3683,0.09304}, + {106.8,-0.3833,17.4039,0.09307}, + {106.9,-0.3833,17.4397,0.09311}, + {107,-0.3833,17.4755,0.09315}, + {107.1,-0.3833,17.5115,0.09318}, + {107.2,-0.3833,17.5476,0.09322}, + {107.3,-0.3833,17.5839,0.09326}, + {107.4,-0.3833,17.6202,0.09329}, + {107.5,-0.3833,17.6567,0.09333}, + {107.6,-0.3833,17.6932,0.09337}, + {107.7,-0.3833,17.7299,0.09341}, + {107.8,-0.3833,17.7668,0.09344}, + {107.9,-0.3833,17.8037,0.09348}, + {108,-0.3833,17.8407,0.09352}, + {108.1,-0.3833,17.8779,0.09356}, + {108.2,-0.3833,17.9152,0.09359}, + {108.3,-0.3833,17.9526,0.09363}, + {108.4,-0.3833,17.9901,0.09367}, + {108.5,-0.3833,18.0277,0.09371}, + {108.6,-0.3833,18.0654,0.09375}, + {108.7,-0.3833,18.1033,0.09378}, + {108.8,-0.3833,18.1412,0.09382}, + {108.9,-0.3833,18.1792,0.09386}, + {109,-0.3833,18.2174,0.0939}, + {109.1,-0.3833,18.2556,0.09394}, + {109.2,-0.3833,18.294,0.09397}, + {109.3,-0.3833,18.3324,0.09401}, + {109.4,-0.3833,18.371,0.09405}, + {109.5,-0.3833,18.4096,0.09409}, + {109.6,-0.3833,18.4484,0.09413}, + {109.7,-0.3833,18.4872,0.09417}, + {109.8,-0.3833,18.5262,0.09421}, + {109.9,-0.3833,18.5652,0.09424}, + {110,-0.3833,18.6043,0.09428}, + {110.1,-0.3833,18.6436,0.09432}, + {110.2,-0.3833,18.6829,0.09436}, + {110.3,-0.3833,18.7223,0.0944}, + {110.4,-0.3833,18.7618,0.09444}, + {110.5,-0.3833,18.8015,0.09448}, + {110.6,-0.3833,18.8412,0.09452}, + {110.7,-0.3833,18.8809,0.09456}, + {110.8,-0.3833,18.9208,0.0946}, + {110.9,-0.3833,18.9608,0.09464}, + {111,-0.3833,19.0009,0.09467}, + {111.1,-0.3833,19.041,0.09471}, + {111.2,-0.3833,19.0812,0.09475}, + {111.3,-0.3833,19.1215,0.09479}, + {111.4,-0.3833,19.1619,0.09483}, + {111.5,-0.3833,19.2024,0.09487}, + {111.6,-0.3833,19.243,0.09491}, + {111.7,-0.3833,19.2836,0.09495}, + {111.8,-0.3833,19.3243,0.09499}, + {111.9,-0.3833,19.3651,0.09503}, + {112,-0.3833,19.406,0.09507}, + {112.1,-0.3833,19.447,0.09511}, + {112.2,-0.3833,19.488,0.09515}, + {112.3,-0.3833,19.5291,0.09519}, + {112.4,-0.3833,19.5703,0.09523}, + {112.5,-0.3833,19.6116,0.09527}, + {112.6,-0.3833,19.6529,0.09531}, + {112.7,-0.3833,19.6943,0.09534}, + {112.8,-0.3833,19.7358,0.09538}, + {112.9,-0.3833,19.7774,0.09542}, + {113,-0.3833,19.819,0.09546}, + {113.1,-0.3833,19.8607,0.0955}, + {113.2,-0.3833,19.9024,0.09554}, + {113.3,-0.3833,19.9442,0.09558}, + {113.4,-0.3833,19.9861,0.09562}, + {113.5,-0.3833,20.028,0.09566}, + {113.6,-0.3833,20.07,0.0957}, + {113.7,-0.3833,20.112,0.09574}, + {113.8,-0.3833,20.1541,0.09578}, + {113.9,-0.3833,20.1963,0.09582}, + {114,-0.3833,20.2385,0.09586}, + {114.1,-0.3833,20.2807,0.0959}, + {114.2,-0.3833,20.323,0.09594}, + {114.3,-0.3833,20.3653,0.09598}, + {114.4,-0.3833,20.4077,0.09602}, + {114.5,-0.3833,20.4502,0.09606}, + {114.6,-0.3833,20.4926,0.0961}, + {114.7,-0.3833,20.5351,0.09614}, + {114.8,-0.3833,20.5777,0.09618}, + {114.9,-0.3833,20.6203,0.09622}, + {115,-0.3833,20.6629,0.09626}, + {115.1,-0.3833,20.7056,0.0963}, + {115.2,-0.3833,20.7483,0.09634}, + {115.3,-0.3833,20.791,0.09638}, + {115.4,-0.3833,20.8338,0.09642}, + {115.5,-0.3833,20.8766,0.09646}, + {115.6,-0.3833,20.9194,0.0965}, + {115.7,-0.3833,20.9622,0.09654}, + {115.8,-0.3833,21.0051,0.09658}, + {115.9,-0.3833,21.048,0.09662}, + {116,-0.3833,21.0909,0.09666}, + {116.1,-0.3833,21.1339,0.0967}, + {116.2,-0.3833,21.1769,0.09674}, + {116.3,-0.3833,21.2199,0.09678}, + {116.4,-0.3833,21.2629,0.09682}, + {116.5,-0.3833,21.3059,0.09686}, + {116.6,-0.3833,21.3489,0.09691}, + {116.7,-0.3833,21.392,0.09695}, + {116.8,-0.3833,21.4351,0.09699}, + {116.9,-0.3833,21.4782,0.09703}, + {117,-0.3833,21.5213,0.09707}, + {117.1,-0.3833,21.5644,0.09711}, + {117.2,-0.3833,21.6075,0.09715}, + {117.3,-0.3833,21.6507,0.09719}, + {117.4,-0.3833,21.6938,0.09723}, + {117.5,-0.3833,21.737,0.09727}, + {117.6,-0.3833,21.7802,0.09731}, + {117.7,-0.3833,21.8233,0.09735}, + {117.8,-0.3833,21.8665,0.09739}, + {117.9,-0.3833,21.9097,0.09743}, + {118,-0.3833,21.9529,0.09747}, + {118.1,-0.3833,21.9961,0.09751}, + {118.2,-0.3833,22.0393,0.09755}, + {118.3,-0.3833,22.0825,0.09759}, + {118.4,-0.3833,22.1258,0.09763}, + {118.5,-0.3833,22.169,0.09767}, + {118.6,-0.3833,22.2122,0.09771}, + {118.7,-0.3833,22.2554,0.09775}, + {118.8,-0.3833,22.2986,0.0978}, + {118.9,-0.3833,22.3419,0.09784}, + {119,-0.3833,22.3851,0.09788}, + {119.1,-0.3833,22.4283,0.09792}, + {119.2,-0.3833,22.4715,0.09796}, + {119.3,-0.3833,22.5148,0.098}, + {119.4,-0.3833,22.558,0.09804}, + {119.5,-0.3833,22.6012,0.09808}, + {119.6,-0.3833,22.6444,0.09812}, + {119.7,-0.3833,22.6877,0.09816}, + {119.8,-0.3833,22.7309,0.0982}, + {119.9,-0.3833,22.7741,0.09824}, + {120,-0.3833,22.8173,0.09828} + }; + return girlsWeightForHeight[index < girlsWeightForHeight.length ? index : girlsWeightForHeight.length]; + } + + public double[]getBoysBMIForAge(int index){ + double [][]data = { + {0,-0.3053,13.4069,0.0956}, + {1,-0.1867,13.3976,0.09597}, + {2,-0.0681,13.3883,0.09634}, + {3,0.0505,13.3791,0.09672}, + {4,0.169,13.3698,0.09709}, + {5,0.2876,13.3606,0.09746}, + {6,0.4062,13.3513,0.09784}, + {7,0.5247,13.3421,0.09821}, + {8,0.5094,13.3843,0.09769}, + {9,0.4941,13.4265,0.09716}, + {10,0.4789,13.4687,0.09664}, + {11,0.4636,13.511,0.09611}, + {12,0.4483,13.5532,0.09559}, + {13,0.433,13.5954,0.09507}, + {14,0.4177,13.6377,0.09454}, + {15,0.4059,13.7174,0.09416}, + {16,0.3946,13.8006,0.0938}, + {17,0.3839,13.8854,0.09347}, + {18,0.3735,13.9707,0.09315}, + {19,0.3636,14.0558,0.09285}, + {20,0.3541,14.1404,0.09257}, + {21,0.3449,14.2241,0.0923}, + {22,0.336,14.3065,0.09204}, + {23,0.3274,14.3877,0.0918}, + {24,0.3191,14.4675,0.09156}, + {25,0.311,14.5457,0.09134}, + {26,0.3032,14.6225,0.09112}, + {27,0.2955,14.6977,0.09092}, + {28,0.2881,14.7714,0.09072}, + {29,0.2809,14.8436,0.09053}, + {30,0.2738,14.914,0.09035}, + {31,0.2669,14.9822,0.09017}, + {32,0.2602,15.0485,0.09}, + {33,0.2536,15.1127,0.08984}, + {34,0.2472,15.175,0.08968}, + {35,0.2409,15.2355,0.08953}, + {36,0.2348,15.2942,0.08938}, + {37,0.2287,15.3511,0.08924}, + {38,0.2228,15.4062,0.0891}, + {39,0.217,15.4597,0.08897}, + {40,0.2113,15.5115,0.08884}, + {41,0.2058,15.5618,0.08871}, + {42,0.2003,15.6107,0.08859}, + {43,0.1949,15.6582,0.08847}, + {44,0.1896,15.7043,0.08835}, + {45,0.1844,15.7492,0.08824}, + {46,0.1793,15.7929,0.08813}, + {47,0.1743,15.8353,0.08802}, + {48,0.1693,15.8767,0.08792}, + {49,0.1645,15.9169,0.08782}, + {50,0.1597,15.956,0.08772}, + {51,0.155,15.9941,0.08762}, + {52,0.1503,16.0311,0.08753}, + {53,0.1457,16.0672,0.08743}, + {54,0.1412,16.1023,0.08734}, + {55,0.1368,16.1365,0.08725}, + {56,0.1324,16.1698,0.08717}, + {57,0.128,16.2021,0.08708}, + {58,0.1238,16.2336,0.087}, + {59,0.1196,16.2642,0.08692}, + {60,0.1154,16.2941,0.08684}, + {61,0.1113,16.3231,0.08676}, + {62,0.1072,16.3513,0.08669}, + {63,0.1032,16.3787,0.08661}, + {64,0.0993,16.4053,0.08654}, + {65,0.0954,16.4312,0.08646}, + {66,0.0915,16.4562,0.08639}, + {67,0.0877,16.4806,0.08632}, + {68,0.084,16.5042,0.08626}, + {69,0.0803,16.5271,0.08619}, + {70,0.0766,16.5494,0.08612}, + {71,0.0729,16.571,0.08606}, + {72,0.0693,16.592,0.08599}, + {73,0.0658,16.6124,0.08593}, + {74,0.0623,16.6321,0.08587}, + {75,0.0588,16.6514,0.08581}, + {76,0.0554,16.67,0.08575}, + {77,0.052,16.6882,0.08569}, + {78,0.0486,16.7058,0.08564}, + {79,0.0452,16.7229,0.08558}, + {80,0.0419,16.7396,0.08552}, + {81,0.0387,16.7557,0.08547}, + {82,0.0354,16.7715,0.08541}, + {83,0.0322,16.7867,0.08536}, + {84,0.0291,16.8016,0.08531}, + {85,0.0259,16.8161,0.08526}, + {86,0.0228,16.8301,0.08521}, + {87,0.0197,16.8438,0.08516}, + {88,0.0167,16.8571,0.08511}, + {89,0.0137,16.8701,0.08506}, + {90,0.0107,16.8827,0.08501}, + {91,0.0077,16.895,0.08496}, + {92,0.0048,16.9069,0.08492}, + {93,0.0018,16.9186,0.08487}, + {94,-0.0011,16.9299,0.08483}, + {95,-0.0039,16.941,0.08478}, + {96,-0.0068,16.9518,0.08474}, + {97,-0.0096,16.9623,0.0847}, + {98,-0.0124,16.9725,0.08465}, + {99,-0.0151,16.9825,0.08461}, + {100,-0.0179,16.9923,0.08457}, + {101,-0.0206,17.0018,0.08453}, + {102,-0.0233,17.0111,0.08449}, + {103,-0.026,17.0201,0.08445}, + {104,-0.0287,17.029,0.08441}, + {105,-0.0313,17.0376,0.08437}, + {106,-0.0339,17.0461,0.08433}, + {107,-0.0365,17.0544,0.08429}, + {108,-0.0391,17.0624,0.08426}, + {109,-0.0416,17.0704,0.08422}, + {110,-0.0442,17.0781,0.08418}, + {111,-0.0467,17.0857,0.08415}, + {112,-0.0492,17.0931,0.08411}, + {113,-0.0517,17.1003,0.08408}, + {114,-0.0541,17.1074,0.08404}, + {115,-0.0566,17.1144,0.08401}, + {116,-0.059,17.1212,0.08397}, + {117,-0.0614,17.1279,0.08394}, + {118,-0.0638,17.1344,0.08391}, + {119,-0.0662,17.1409,0.08387}, + {120,-0.0686,17.1472,0.08384}, + {121,-0.0709,17.1533,0.08381}, + {122,-0.0732,17.1594,0.08378}, + {123,-0.0756,17.1653,0.08375}, + {124,-0.0779,17.1712,0.08371}, + {125,-0.0801,17.1769,0.08368}, + {126,-0.0824,17.1825,0.08365}, + {127,-0.0847,17.188,0.08362}, + {128,-0.0869,17.1934,0.08359}, + {129,-0.0891,17.1987,0.08356}, + {130,-0.0913,17.2038,0.08354}, + {131,-0.0935,17.2089,0.08351}, + {132,-0.0957,17.2138,0.08348}, + {133,-0.0979,17.2187,0.08345}, + {134,-0.1,17.2234,0.08342}, + {135,-0.1022,17.2281,0.0834}, + {136,-0.1043,17.2326,0.08337}, + {137,-0.1064,17.237,0.08334}, + {138,-0.1085,17.2414,0.08332}, + {139,-0.1106,17.2456,0.08329}, + {140,-0.1127,17.2497,0.08326}, + {141,-0.1147,17.2537,0.08324}, + {142,-0.1168,17.2576,0.08321}, + {143,-0.1188,17.2615,0.08319}, + {144,-0.1208,17.2652,0.08316}, + {145,-0.1229,17.2688,0.08314}, + {146,-0.1249,17.2723,0.08311}, + {147,-0.1269,17.2757,0.08309}, + {148,-0.1288,17.2791,0.08306}, + {149,-0.1308,17.2823,0.08304}, + {150,-0.1328,17.2854,0.08302}, + {151,-0.1347,17.2885,0.08299}, + {152,-0.1366,17.2914,0.08297}, + {153,-0.1386,17.2943,0.08295}, + {154,-0.1405,17.297,0.08292}, + {155,-0.1424,17.2997,0.0829}, + {156,-0.1443,17.3023,0.08288}, + {157,-0.1462,17.3048,0.08285}, + {158,-0.148,17.3072,0.08283}, + {159,-0.1499,17.3095,0.08281}, + {160,-0.1518,17.3117,0.08279}, + {161,-0.1536,17.3139,0.08277}, + {162,-0.1554,17.316,0.08275}, + {163,-0.1573,17.318,0.08272}, + {164,-0.1591,17.3199,0.0827}, + {165,-0.1609,17.3218,0.08268}, + {166,-0.1627,17.3235,0.08266}, + {167,-0.1645,17.3252,0.08264}, + {168,-0.1663,17.3268,0.08262}, + {169,-0.168,17.3284,0.0826}, + {170,-0.1698,17.3299,0.08258}, + {171,-0.1715,17.3313,0.08256}, + {172,-0.1733,17.3326,0.08254}, + {173,-0.175,17.3338,0.08252}, + {174,-0.1768,17.335,0.0825}, + {175,-0.1785,17.3361,0.08248}, + {176,-0.1802,17.3371,0.08246}, + {177,-0.1819,17.3381,0.08244}, + {178,-0.1836,17.339,0.08242}, + {179,-0.1853,17.3398,0.08241}, + {180,-0.187,17.3406,0.08239}, + {181,-0.1886,17.3412,0.08237}, + {182,-0.1903,17.3419,0.08235}, + {183,-0.1919,17.3424,0.08233}, + {184,-0.1936,17.3429,0.08231}, + {185,-0.1952,17.3433,0.0823}, + {186,-0.1969,17.3437,0.08228}, + {187,-0.1985,17.3439,0.08226}, + {188,-0.2001,17.3441,0.08224}, + {189,-0.2017,17.3443,0.08222}, + {190,-0.2033,17.3444,0.08221}, + {191,-0.2049,17.3444,0.08219}, + {192,-0.2065,17.3443,0.08217}, + {193,-0.2081,17.3442,0.08216}, + {194,-0.2097,17.344,0.08214}, + {195,-0.2112,17.3438,0.08212}, + {196,-0.2128,17.3434,0.0821}, + {197,-0.2144,17.3431,0.08209}, + {198,-0.2159,17.3426,0.08207}, + {199,-0.2174,17.3421,0.08205}, + {200,-0.219,17.3416,0.08204}, + {201,-0.2205,17.3409,0.08202}, + {202,-0.222,17.3402,0.08201}, + {203,-0.2235,17.3395,0.08199}, + {204,-0.2251,17.3387,0.08197}, + {205,-0.2266,17.3378,0.08196}, + {206,-0.2281,17.3369,0.08194}, + {207,-0.2295,17.3359,0.08193}, + {208,-0.231,17.3349,0.08191}, + {209,-0.2325,17.3338,0.08189}, + {210,-0.234,17.3326,0.08188}, + {211,-0.2354,17.3314,0.08186}, + {212,-0.2369,17.3302,0.08185}, + {213,-0.2384,17.3289,0.08183}, + {214,-0.2398,17.3275,0.08182}, + {215,-0.2413,17.3261,0.0818}, + {216,-0.2427,17.3246,0.08179}, + {217,-0.2441,17.323,0.08177}, + {218,-0.2456,17.3215,0.08176}, + {219,-0.247,17.3198,0.08174}, + {220,-0.2484,17.3181,0.08173}, + {221,-0.2498,17.3164,0.08171}, + {222,-0.2512,17.3146,0.0817}, + {223,-0.2526,17.3127,0.08168}, + {224,-0.254,17.3108,0.08167}, + {225,-0.2554,17.3089,0.08165}, + {226,-0.2568,17.3069,0.08164}, + {227,-0.2581,17.3048,0.08163}, + {228,-0.2595,17.3027,0.08161}, + {229,-0.2609,17.3006,0.0816}, + {230,-0.2622,17.2984,0.08158}, + {231,-0.2636,17.2962,0.08157}, + {232,-0.265,17.2939,0.08155}, + {233,-0.2663,17.2916,0.08154}, + {234,-0.2676,17.2892,0.08153}, + {235,-0.269,17.2868,0.08151}, + {236,-0.2703,17.2844,0.0815}, + {237,-0.2716,17.2819,0.08149}, + {238,-0.273,17.2794,0.08147}, + {239,-0.2743,17.2768,0.08146}, + {240,-0.2756,17.2742,0.08145}, + {241,-0.2769,17.2715,0.08143}, + {242,-0.2782,17.2688,0.08142}, + {243,-0.2795,17.2661,0.08141}, + {244,-0.2808,17.2633,0.08139}, + {245,-0.2821,17.2605,0.08138}, + {246,-0.2834,17.2577,0.08137}, + {247,-0.2847,17.2548,0.08135}, + {248,-0.2859,17.2519,0.08134}, + {249,-0.2872,17.249,0.08133}, + {250,-0.2885,17.246,0.08131}, + {251,-0.2898,17.243,0.0813}, + {252,-0.291,17.2399,0.08129}, + {253,-0.2923,17.2368,0.08128}, + {254,-0.2935,17.2337,0.08126}, + {255,-0.2948,17.2306,0.08125}, + {256,-0.296,17.2274,0.08124}, + {257,-0.2972,17.2242,0.08122}, + {258,-0.2985,17.221,0.08121}, + {259,-0.2997,17.2177,0.0812}, + {260,-0.3009,17.2144,0.08119}, + {261,-0.3022,17.2111,0.08117}, + {262,-0.3034,17.2078,0.08116}, + {263,-0.3046,17.2044,0.08115}, + {264,-0.3058,17.2011,0.08114}, + {265,-0.307,17.1976,0.08113}, + {266,-0.3082,17.1942,0.08111}, + {267,-0.3094,17.1908,0.0811}, + {268,-0.3106,17.1873,0.08109}, + {269,-0.3118,17.1838,0.08108}, + {270,-0.313,17.1803,0.08107}, + {271,-0.3142,17.1767,0.08105}, + {272,-0.3153,17.1731,0.08104}, + {273,-0.3165,17.1696,0.08103}, + {274,-0.3177,17.1659,0.08102}, + {275,-0.3189,17.1623,0.08101}, + {276,-0.32,17.1587,0.08099}, + {277,-0.3212,17.155,0.08098}, + {278,-0.3223,17.1513,0.08097}, + {279,-0.3235,17.1476,0.08096}, + {280,-0.3246,17.1439,0.08095}, + {281,-0.3258,17.1402,0.08094}, + {282,-0.3269,17.1364,0.08093}, + {283,-0.3281,17.1326,0.08091}, + {284,-0.3292,17.1288,0.0809}, + {285,-0.3303,17.125,0.08089}, + {286,-0.3315,17.1212,0.08088}, + {287,-0.3326,17.1174,0.08087}, + {288,-0.3337,17.1135,0.08086}, + {289,-0.3348,17.1097,0.08085}, + {290,-0.3359,17.1058,0.08084}, + {291,-0.3371,17.1019,0.08082}, + {292,-0.3382,17.098,0.08081}, + {293,-0.3393,17.0941,0.0808}, + {294,-0.3404,17.0901,0.08079}, + {295,-0.3415,17.0862,0.08078}, + {296,-0.3426,17.0823,0.08077}, + {297,-0.3437,17.0783,0.08076}, + {298,-0.3448,17.0743,0.08075}, + {299,-0.3458,17.0703,0.08074}, + {300,-0.3469,17.0663,0.08073}, + {301,-0.348,17.0623,0.08071}, + {302,-0.3491,17.0583,0.0807}, + {303,-0.3502,17.0543,0.08069}, + {304,-0.3512,17.0503,0.08068}, + {305,-0.3523,17.0463,0.08067}, + {306,-0.3534,17.0422,0.08066}, + {307,-0.3544,17.0382,0.08065}, + {308,-0.3555,17.0341,0.08064}, + {309,-0.3565,17.0301,0.08063}, + {310,-0.3576,17.026,0.08062}, + {311,-0.3586,17.0219,0.08061}, + {312,-0.3597,17.0178,0.0806}, + {313,-0.3607,17.0138,0.08059}, + {314,-0.3618,17.0097,0.08058}, + {315,-0.3628,17.0056,0.08057}, + {316,-0.3638,17.0015,0.08056}, + {317,-0.3649,16.9974,0.08055}, + {318,-0.3659,16.9933,0.08054}, + {319,-0.3669,16.9892,0.08053}, + {320,-0.3679,16.985,0.08052}, + {321,-0.369,16.9809,0.08051}, + {322,-0.37,16.9768,0.0805}, + {323,-0.371,16.9727,0.08049}, + {324,-0.372,16.9686,0.08048}, + {325,-0.373,16.9644,0.08047}, + {326,-0.374,16.9603,0.08046}, + {327,-0.375,16.9562,0.08045}, + {328,-0.376,16.9521,0.08044}, + {329,-0.377,16.9479,0.08043}, + {330,-0.378,16.9438,0.08042}, + {331,-0.379,16.9397,0.08041}, + {332,-0.38,16.9355,0.0804}, + {333,-0.381,16.9314,0.08039}, + {334,-0.382,16.9273,0.08038}, + {335,-0.383,16.9231,0.08037}, + {336,-0.3839,16.919,0.08036}, + {337,-0.3849,16.9148,0.08035}, + {338,-0.3859,16.9107,0.08034}, + {339,-0.3869,16.9066,0.08033}, + {340,-0.3878,16.9024,0.08032}, + {341,-0.3888,16.8983,0.08031}, + {342,-0.3898,16.8942,0.0803}, + {343,-0.3907,16.89,0.08029}, + {344,-0.3917,16.8859,0.08028}, + {345,-0.3926,16.8817,0.08027}, + {346,-0.3936,16.8776,0.08026}, + {347,-0.3945,16.8735,0.08025}, + {348,-0.3955,16.8693,0.08024}, + {349,-0.3964,16.8652,0.08023}, + {350,-0.3974,16.861,0.08022}, + {351,-0.3983,16.8569,0.08022}, + {352,-0.3993,16.8528,0.08021}, + {353,-0.4002,16.8486,0.0802}, + {354,-0.4011,16.8445,0.08019}, + {355,-0.4021,16.8404,0.08018}, + {356,-0.403,16.8363,0.08017}, + {357,-0.4039,16.8321,0.08016}, + {358,-0.4049,16.828,0.08015}, + {359,-0.4058,16.8239,0.08014}, + {360,-0.4067,16.8198,0.08013}, + {361,-0.4076,16.8156,0.08012}, + {362,-0.4085,16.8115,0.08011}, + {363,-0.4095,16.8074,0.08011}, + {364,-0.4104,16.8033,0.0801}, + {365,-0.4113,16.7992,0.08009}, + {366,-0.4122,16.7951,0.08008}, + {367,-0.4131,16.7909,0.08007}, + {368,-0.414,16.7868,0.08006}, + {369,-0.4149,16.7827,0.08005}, + {370,-0.4158,16.7786,0.08004}, + {371,-0.4167,16.7745,0.08003}, + {372,-0.4176,16.7704,0.08003}, + {373,-0.4185,16.7663,0.08002}, + {374,-0.4194,16.7622,0.08001}, + {375,-0.4203,16.7582,0.08}, + {376,-0.4211,16.7541,0.07999}, + {377,-0.422,16.75,0.07998}, + {378,-0.4229,16.7459,0.07997}, + {379,-0.4238,16.7418,0.07996}, + {380,-0.4247,16.7377,0.07996}, + {381,-0.4255,16.7337,0.07995}, + {382,-0.4264,16.7296,0.07994}, + {383,-0.4273,16.7255,0.07993}, + {384,-0.4282,16.7215,0.07992}, + {385,-0.429,16.7174,0.07991}, + {386,-0.4299,16.7134,0.0799}, + {387,-0.4308,16.7093,0.0799}, + {388,-0.4316,16.7053,0.07989}, + {389,-0.4325,16.7012,0.07988}, + {390,-0.4333,16.6972,0.07987}, + {391,-0.4342,16.6932,0.07986}, + {392,-0.435,16.6891,0.07985}, + {393,-0.4359,16.6851,0.07984}, + {394,-0.4367,16.6811,0.07984}, + {395,-0.4376,16.6771,0.07983}, + {396,-0.4384,16.6731,0.07982}, + {397,-0.4393,16.6691,0.07981}, + {398,-0.4401,16.6651,0.0798}, + {399,-0.441,16.6611,0.0798}, + {400,-0.4418,16.6571,0.07979}, + {401,-0.4426,16.6531,0.07978}, + {402,-0.4435,16.6491,0.07977}, + {403,-0.4443,16.6451,0.07976}, + {404,-0.4451,16.6412,0.07975}, + {405,-0.446,16.6372,0.07975}, + {406,-0.4468,16.6332,0.07974}, + {407,-0.4476,16.6293,0.07973}, + {408,-0.4484,16.6253,0.07972}, + {409,-0.4493,16.6214,0.07971}, + {410,-0.4501,16.6175,0.07971}, + {411,-0.4509,16.6135,0.0797}, + {412,-0.4517,16.6096,0.07969}, + {413,-0.4525,16.6057,0.07968}, + {414,-0.4533,16.6018,0.07967}, + {415,-0.4541,16.5979,0.07966}, + {416,-0.455,16.594,0.07966}, + {417,-0.4558,16.5901,0.07965}, + {418,-0.4566,16.5862,0.07964}, + {419,-0.4574,16.5823,0.07963}, + {420,-0.4582,16.5784,0.07963}, + {421,-0.459,16.5745,0.07962}, + {422,-0.4598,16.5707,0.07961}, + {423,-0.4606,16.5668,0.0796}, + {424,-0.4614,16.5629,0.07959}, + {425,-0.4621,16.5591,0.07959}, + {426,-0.4629,16.5553,0.07958}, + {427,-0.4637,16.5514,0.07957}, + {428,-0.4645,16.5476,0.07956}, + {429,-0.4653,16.5438,0.07955}, + {430,-0.4661,16.5399,0.07955}, + {431,-0.4669,16.5361,0.07954}, + {432,-0.4677,16.5323,0.07953}, + {433,-0.4684,16.5285,0.07952}, + {434,-0.4692,16.5247,0.07952}, + {435,-0.47,16.5209,0.07951}, + {436,-0.4708,16.5172,0.0795}, + {437,-0.4715,16.5134,0.07949}, + {438,-0.4723,16.5096,0.07949}, + {439,-0.4731,16.5059,0.07948}, + {440,-0.4738,16.5021,0.07947}, + {441,-0.4746,16.4984,0.07946}, + {442,-0.4754,16.4946,0.07946}, + {443,-0.4761,16.4909,0.07945}, + {444,-0.4769,16.4871,0.07944}, + {445,-0.4777,16.4834,0.07943}, + {446,-0.4784,16.4797,0.07943}, + {447,-0.4792,16.476,0.07942}, + {448,-0.4799,16.4723,0.07941}, + {449,-0.4807,16.4686,0.0794}, + {450,-0.4814,16.4649,0.0794}, + {451,-0.4822,16.4612,0.07939}, + {452,-0.4829,16.4576,0.07938}, + {453,-0.4837,16.4539,0.07937}, + {454,-0.4844,16.4502,0.07937}, + {455,-0.4852,16.4466,0.07936}, + {456,-0.4859,16.4429,0.07935}, + {457,-0.4867,16.4393,0.07934}, + {458,-0.4874,16.4357,0.07934}, + {459,-0.4881,16.432,0.07933}, + {460,-0.4889,16.4284,0.07932}, + {461,-0.4896,16.4248,0.07931}, + {462,-0.4903,16.4212,0.07931}, + {463,-0.4911,16.4176,0.0793}, + {464,-0.4918,16.414,0.07929}, + {465,-0.4925,16.4104,0.07929}, + {466,-0.4933,16.4069,0.07928}, + {467,-0.494,16.4033,0.07927}, + {468,-0.4947,16.3997,0.07926}, + {469,-0.4954,16.3962,0.07926}, + {470,-0.4962,16.3926,0.07925}, + {471,-0.4969,16.3891,0.07924}, + {472,-0.4976,16.3856,0.07924}, + {473,-0.4983,16.3821,0.07923}, + {474,-0.499,16.3785,0.07922}, + {475,-0.4997,16.375,0.07921}, + {476,-0.5005,16.3715,0.07921}, + {477,-0.5012,16.368,0.0792}, + {478,-0.5019,16.3646,0.07919}, + {479,-0.5026,16.3611,0.07919}, + {480,-0.5033,16.3576,0.07918}, + {481,-0.504,16.3541,0.07917}, + {482,-0.5047,16.3507,0.07916}, + {483,-0.5054,16.3472,0.07916}, + {484,-0.5061,16.3438,0.07915}, + {485,-0.5068,16.3404,0.07914}, + {486,-0.5075,16.3369,0.07914}, + {487,-0.5082,16.3335,0.07913}, + {488,-0.5089,16.3301,0.07912}, + {489,-0.5096,16.3267,0.07912}, + {490,-0.5103,16.3233,0.07911}, + {491,-0.511,16.3199,0.0791}, + {492,-0.5117,16.3165,0.07909}, + {493,-0.5124,16.3131,0.07909}, + {494,-0.5131,16.3098,0.07908}, + {495,-0.5138,16.3064,0.07907}, + {496,-0.5144,16.3031,0.07907}, + {497,-0.5151,16.2997,0.07906}, + {498,-0.5158,16.2964,0.07905}, + {499,-0.5165,16.293,0.07905}, + {500,-0.5172,16.2897,0.07904}, + {501,-0.5179,16.2864,0.07903}, + {502,-0.5185,16.2831,0.07903}, + {503,-0.5192,16.2798,0.07902}, + {504,-0.5199,16.2765,0.07901}, + {505,-0.5206,16.2732,0.07901}, + {506,-0.5212,16.2699,0.079}, + {507,-0.5219,16.2666,0.07899}, + {508,-0.5226,16.2634,0.07899}, + {509,-0.5233,16.2601,0.07898}, + {510,-0.5239,16.2568,0.07897}, + {511,-0.5246,16.2536,0.07897}, + {512,-0.5253,16.2504,0.07896}, + {513,-0.5259,16.2471,0.07895}, + {514,-0.5266,16.2439,0.07895}, + {515,-0.5273,16.2407,0.07894}, + {516,-0.5279,16.2375,0.07893}, + {517,-0.5286,16.2343,0.07893}, + {518,-0.5292,16.2311,0.07892}, + {519,-0.5299,16.2279,0.07891}, + {520,-0.5306,16.2247,0.07891}, + {521,-0.5312,16.2215,0.0789}, + {522,-0.5319,16.2184,0.07889}, + {523,-0.5325,16.2152,0.07889}, + {524,-0.5332,16.2121,0.07888}, + {525,-0.5338,16.2089,0.07887}, + {526,-0.5345,16.2058,0.07887}, + {527,-0.5351,16.2027,0.07886}, + {528,-0.5358,16.1996,0.07885}, + {529,-0.5364,16.1964,0.07885}, + {530,-0.5371,16.1933,0.07884}, + {531,-0.5377,16.1902,0.07883}, + {532,-0.5383,16.1872,0.07883}, + {533,-0.539,16.1841,0.07882}, + {534,-0.5396,16.181,0.07881}, + {535,-0.5403,16.1779,0.07881}, + {536,-0.5409,16.1749,0.0788}, + {537,-0.5415,16.1718,0.0788}, + {538,-0.5422,16.1688,0.07879}, + {539,-0.5428,16.1658,0.07878}, + {540,-0.5434,16.1627,0.07878}, + {541,-0.5441,16.1597,0.07877}, + {542,-0.5447,16.1567,0.07876}, + {543,-0.5453,16.1537,0.07876}, + {544,-0.546,16.1507,0.07875}, + {545,-0.5466,16.1477,0.07874}, + {546,-0.5472,16.1447,0.07874}, + {547,-0.5479,16.1418,0.07873}, + {548,-0.5485,16.1388,0.07873}, + {549,-0.5491,16.1359,0.07872}, + {550,-0.5497,16.1329,0.07871}, + {551,-0.5503,16.13,0.07871}, + {552,-0.551,16.127,0.0787}, + {553,-0.5516,16.1241,0.07869}, + {554,-0.5522,16.1212,0.07869}, + {555,-0.5528,16.1183,0.07868}, + {556,-0.5534,16.1154,0.07867}, + {557,-0.5541,16.1125,0.07867}, + {558,-0.5547,16.1096,0.07866}, + {559,-0.5553,16.1067,0.07866}, + {560,-0.5559,16.1039,0.07865}, + {561,-0.5565,16.101,0.07864}, + {562,-0.5571,16.0981,0.07864}, + {563,-0.5577,16.0953,0.07863}, + {564,-0.5583,16.0925,0.07863}, + {565,-0.5589,16.0896,0.07862}, + {566,-0.5595,16.0868,0.07861}, + {567,-0.5602,16.084,0.07861}, + {568,-0.5608,16.0812,0.0786}, + {569,-0.5614,16.0784,0.07859}, + {570,-0.562,16.0756,0.07859}, + {571,-0.5626,16.0728,0.07858}, + {572,-0.5632,16.0701,0.07858}, + {573,-0.5638,16.0673,0.07857}, + {574,-0.5644,16.0646,0.07856}, + {575,-0.565,16.0618,0.07856}, + {576,-0.5656,16.0591,0.07855}, + {577,-0.5662,16.0564,0.07855}, + {578,-0.5667,16.0536,0.07854}, + {579,-0.5673,16.0509,0.07853}, + {580,-0.5679,16.0482,0.07853}, + {581,-0.5685,16.0455,0.07852}, + {582,-0.5691,16.0429,0.07852}, + {583,-0.5697,16.0402,0.07851}, + {584,-0.5703,16.0375,0.0785}, + {585,-0.5709,16.0349,0.0785}, + {586,-0.5715,16.0322,0.07849}, + {587,-0.5721,16.0296,0.07849}, + {588,-0.5726,16.0269,0.07848}, + {589,-0.5732,16.0243,0.07847}, + {590,-0.5738,16.0217,0.07847}, + {591,-0.5744,16.0191,0.07846}, + {592,-0.575,16.0165,0.07846}, + {593,-0.5755,16.0139,0.07845}, + {594,-0.5761,16.0113,0.07844}, + {595,-0.5767,16.0088,0.07844}, + {596,-0.5773,16.0062,0.07843}, + {597,-0.5779,16.0036,0.07843}, + {598,-0.5784,16.0011,0.07842}, + {599,-0.579,15.9986,0.07841}, + {600,-0.5796,15.996,0.07841}, + {601,-0.5802,15.9935,0.0784}, + {602,-0.5807,15.991,0.0784}, + {603,-0.5813,15.9885,0.07839}, + {604,-0.5819,15.986,0.07838}, + {605,-0.5824,15.9835,0.07838}, + {606,-0.583,15.9811,0.07837}, + {607,-0.5836,15.9786,0.07837}, + {608,-0.5841,15.9761,0.07836}, + {609,-0.5847,15.9737,0.07836}, + {610,-0.5853,15.9713,0.07835}, + {611,-0.5858,15.9688,0.07834}, + {612,-0.5864,15.9664,0.07834}, + {613,-0.587,15.964,0.07833}, + {614,-0.5875,15.9616,0.07833}, + {615,-0.5881,15.9592,0.07832}, + {616,-0.5886,15.9568,0.07832}, + {617,-0.5892,15.9544,0.07831}, + {618,-0.5898,15.9521,0.0783}, + {619,-0.5903,15.9497,0.0783}, + {620,-0.5909,15.9473,0.07829}, + {621,-0.5914,15.945,0.07829}, + {622,-0.592,15.9427,0.07828}, + {623,-0.5925,15.9403,0.07827}, + {624,-0.5931,15.938,0.07827}, + {625,-0.5936,15.9357,0.07826}, + {626,-0.5942,15.9334,0.07826}, + {627,-0.5947,15.9311,0.07825}, + {628,-0.5953,15.9288,0.07825}, + {629,-0.5958,15.9266,0.07824}, + {630,-0.5964,15.9243,0.07824}, + {631,-0.5969,15.922,0.07823}, + {632,-0.5975,15.9198,0.07822}, + {633,-0.598,15.9176,0.07822}, + {634,-0.5986,15.9153,0.07821}, + {635,-0.5991,15.9131,0.07821}, + {636,-0.5996,15.9109,0.0782}, + {637,-0.6002,15.9087,0.0782}, + {638,-0.6007,15.9065,0.07819}, + {639,-0.6013,15.9043,0.07818}, + {640,-0.6018,15.9021,0.07818}, + {641,-0.6023,15.9,0.07817}, + {642,-0.6029,15.8978,0.07817}, + {643,-0.6034,15.8956,0.07816}, + {644,-0.604,15.8935,0.07816}, + {645,-0.6045,15.8913,0.07815}, + {646,-0.605,15.8892,0.07815}, + {647,-0.6056,15.8871,0.07814}, + {648,-0.6061,15.885,0.07813}, + {649,-0.6066,15.8829,0.07813}, + {650,-0.6072,15.8808,0.07812}, + {651,-0.6077,15.8787,0.07812}, + {652,-0.6082,15.8766,0.07811}, + {653,-0.6087,15.8745,0.07811}, + {654,-0.6093,15.8725,0.0781}, + {655,-0.6098,15.8704,0.0781}, + {656,-0.6103,15.8684,0.07809}, + {657,-0.6109,15.8663,0.07809}, + {658,-0.6114,15.8643,0.07808}, + {659,-0.6119,15.8623,0.07807}, + {660,-0.6124,15.8602,0.07807}, + {661,-0.613,15.8582,0.07806}, + {662,-0.6135,15.8562,0.07806}, + {663,-0.614,15.8542,0.07805}, + {664,-0.6145,15.8522,0.07805}, + {665,-0.615,15.8503,0.07804}, + {666,-0.6156,15.8483,0.07804}, + {667,-0.6161,15.8463,0.07803}, + {668,-0.6166,15.8444,0.07803}, + {669,-0.6171,15.8424,0.07802}, + {670,-0.6176,15.8405,0.07802}, + {671,-0.6181,15.8385,0.07801}, + {672,-0.6187,15.8366,0.078}, + {673,-0.6192,15.8347,0.078}, + {674,-0.6197,15.8328,0.07799}, + {675,-0.6202,15.8309,0.07799}, + {676,-0.6207,15.829,0.07798}, + {677,-0.6212,15.8271,0.07798}, + {678,-0.6217,15.8252,0.07797}, + {679,-0.6222,15.8233,0.07797}, + {680,-0.6227,15.8214,0.07796}, + {681,-0.6233,15.8196,0.07796}, + {682,-0.6238,15.8177,0.07795}, + {683,-0.6243,15.8158,0.07795}, + {684,-0.6248,15.814,0.07794}, + {685,-0.6253,15.8122,0.07794}, + {686,-0.6258,15.8103,0.07793}, + {687,-0.6263,15.8085,0.07792}, + {688,-0.6268,15.8067,0.07792}, + {689,-0.6273,15.8049,0.07791}, + {690,-0.6278,15.8031,0.07791}, + {691,-0.6283,15.8013,0.0779}, + {692,-0.6288,15.7995,0.0779}, + {693,-0.6293,15.7977,0.07789}, + {694,-0.6298,15.7959,0.07789}, + {695,-0.6303,15.7941,0.07788}, + {696,-0.6308,15.7924,0.07788}, + {697,-0.6313,15.7906,0.07787}, + {698,-0.6318,15.7888,0.07787}, + {699,-0.6323,15.7871,0.07786}, + {700,-0.6328,15.7853,0.07786}, + {701,-0.6333,15.7836,0.07785}, + {702,-0.6338,15.7819,0.07785}, + {703,-0.6343,15.7802,0.07784}, + {704,-0.6348,15.7784,0.07784}, + {705,-0.6352,15.7767,0.07783}, + {706,-0.6357,15.775,0.07783}, + {707,-0.6362,15.7733,0.07782}, + {708,-0.6367,15.7716,0.07782}, + {709,-0.6372,15.7699,0.07781}, + {710,-0.6377,15.7682,0.07781}, + {711,-0.6382,15.7665,0.0778}, + {712,-0.6387,15.7649,0.0778}, + {713,-0.6392,15.7632,0.07779}, + {714,-0.6396,15.7615,0.07779}, + {715,-0.6401,15.7599,0.07778}, + {716,-0.6406,15.7582,0.07778}, + {717,-0.6411,15.7566,0.07777}, + {718,-0.6416,15.7549,0.07777}, + {719,-0.6421,15.7533,0.07776}, + {720,-0.6425,15.7517,0.07776}, + {721,-0.643,15.75,0.07775}, + {722,-0.6435,15.7484,0.07775}, + {723,-0.644,15.7468,0.07774}, + {724,-0.6445,15.7452,0.07774}, + {725,-0.6449,15.7436,0.07773}, + {726,-0.6454,15.742,0.07773}, + {727,-0.6459,15.7404,0.07772}, + {728,-0.6464,15.7388,0.07772}, + {729,-0.6469,15.7372,0.07771}, + {730,-0.6473,15.7356,0.07771}, + {731,-0.6187,16.0189,0.07785}, + {732,-0.6175,16.0176,0.07785}, + {733,-0.6164,16.0163,0.07785}, + {734,-0.6152,16.015,0.07785}, + {735,-0.614,16.0136,0.07786}, + {736,-0.6129,16.0123,0.07786}, + {737,-0.6117,16.011,0.07786}, + {738,-0.6105,16.0097,0.07786}, + {739,-0.6094,16.0084,0.07787}, + {740,-0.6082,16.0071,0.07787}, + {741,-0.607,16.0058,0.07787}, + {742,-0.6059,16.0045,0.07787}, + {743,-0.6047,16.0032,0.07787}, + {744,-0.6036,16.0019,0.07788}, + {745,-0.6024,16.0006,0.07788}, + {746,-0.6012,15.9993,0.07788}, + {747,-0.6001,15.998,0.07788}, + {748,-0.5989,15.9967,0.07789}, + {749,-0.5978,15.9954,0.07789}, + {750,-0.5966,15.9941,0.07789}, + {751,-0.5955,15.9928,0.07789}, + {752,-0.5943,15.9915,0.07789}, + {753,-0.5932,15.9902,0.0779}, + {754,-0.592,15.9889,0.0779}, + {755,-0.5909,15.9876,0.0779}, + {756,-0.5897,15.9863,0.0779}, + {757,-0.5886,15.985,0.07791}, + {758,-0.5874,15.9838,0.07791}, + {759,-0.5863,15.9825,0.07791}, + {760,-0.5851,15.9812,0.07791}, + {761,-0.584,15.9799,0.07792}, + {762,-0.5828,15.9786,0.07792}, + {763,-0.5817,15.9773,0.07792}, + {764,-0.5805,15.976,0.07792}, + {765,-0.5794,15.9748,0.07793}, + {766,-0.5783,15.9735,0.07793}, + {767,-0.5771,15.9722,0.07793}, + {768,-0.576,15.9709,0.07793}, + {769,-0.5748,15.9697,0.07794}, + {770,-0.5737,15.9684,0.07794}, + {771,-0.5726,15.9671,0.07794}, + {772,-0.5714,15.9658,0.07794}, + {773,-0.5703,15.9646,0.07795}, + {774,-0.5692,15.9633,0.07795}, + {775,-0.568,15.962,0.07795}, + {776,-0.5669,15.9607,0.07795}, + {777,-0.5658,15.9595,0.07796}, + {778,-0.5647,15.9582,0.07796}, + {779,-0.5635,15.9569,0.07796}, + {780,-0.5624,15.9557,0.07796}, + {781,-0.5613,15.9544,0.07797}, + {782,-0.5602,15.9532,0.07797}, + {783,-0.559,15.9519,0.07797}, + {784,-0.5579,15.9506,0.07798}, + {785,-0.5568,15.9494,0.07798}, + {786,-0.5557,15.9481,0.07798}, + {787,-0.5546,15.9468,0.07798}, + {788,-0.5535,15.9456,0.07799}, + {789,-0.5523,15.9443,0.07799}, + {790,-0.5512,15.9431,0.07799}, + {791,-0.5501,15.9418,0.07799}, + {792,-0.549,15.9406,0.078}, + {793,-0.5479,15.9393,0.078}, + {794,-0.5468,15.9381,0.078}, + {795,-0.5457,15.9368,0.07801}, + {796,-0.5446,15.9356,0.07801}, + {797,-0.5435,15.9343,0.07801}, + {798,-0.5424,15.9331,0.07801}, + {799,-0.5413,15.9318,0.07802}, + {800,-0.5402,15.9306,0.07802}, + {801,-0.5391,15.9293,0.07802}, + {802,-0.538,15.9281,0.07803}, + {803,-0.5369,15.9268,0.07803}, + {804,-0.5358,15.9256,0.07803}, + {805,-0.5347,15.9244,0.07803}, + {806,-0.5336,15.9231,0.07804}, + {807,-0.5325,15.9219,0.07804}, + {808,-0.5315,15.9206,0.07804}, + {809,-0.5304,15.9194,0.07805}, + {810,-0.5293,15.9182,0.07805}, + {811,-0.5282,15.9169,0.07805}, + {812,-0.5271,15.9157,0.07805}, + {813,-0.526,15.9145,0.07806}, + {814,-0.525,15.9132,0.07806}, + {815,-0.5239,15.912,0.07806}, + {816,-0.5228,15.9108,0.07807}, + {817,-0.5217,15.9095,0.07807}, + {818,-0.5207,15.9083,0.07807}, + {819,-0.5196,15.9071,0.07808}, + {820,-0.5185,15.9058,0.07808}, + {821,-0.5175,15.9046,0.07808}, + {822,-0.5164,15.9034,0.07809}, + {823,-0.5153,15.9022,0.07809}, + {824,-0.5143,15.9009,0.07809}, + {825,-0.5132,15.8997,0.07809}, + {826,-0.5122,15.8985,0.0781}, + {827,-0.5111,15.8973,0.0781}, + {828,-0.5101,15.8961,0.0781}, + {829,-0.509,15.8948,0.07811}, + {830,-0.508,15.8936,0.07811}, + {831,-0.5069,15.8924,0.07811}, + {832,-0.5059,15.8912,0.07812}, + {833,-0.5048,15.89,0.07812}, + {834,-0.5038,15.8888,0.07812}, + {835,-0.5027,15.8875,0.07813}, + {836,-0.5017,15.8863,0.07813}, + {837,-0.5006,15.8851,0.07813}, + {838,-0.4996,15.8839,0.07814}, + {839,-0.4986,15.8827,0.07814}, + {840,-0.4975,15.8815,0.07814}, + {841,-0.4965,15.8803,0.07815}, + {842,-0.4955,15.8791,0.07815}, + {843,-0.4944,15.8779,0.07815}, + {844,-0.4934,15.8767,0.07816}, + {845,-0.4924,15.8755,0.07816}, + {846,-0.4914,15.8742,0.07816}, + {847,-0.4904,15.873,0.07817}, + {848,-0.4893,15.8718,0.07817}, + {849,-0.4883,15.8706,0.07817}, + {850,-0.4873,15.8694,0.07818}, + {851,-0.4863,15.8682,0.07818}, + {852,-0.4853,15.867,0.07818}, + {853,-0.4843,15.8658,0.07819}, + {854,-0.4833,15.8646,0.07819}, + {855,-0.4823,15.8634,0.07819}, + {856,-0.4813,15.8622,0.0782}, + {857,-0.4803,15.8611,0.0782}, + {858,-0.4793,15.8599,0.0782}, + {859,-0.4783,15.8587,0.07821}, + {860,-0.4773,15.8575,0.07821}, + {861,-0.4763,15.8563,0.07821}, + {862,-0.4753,15.8551,0.07822}, + {863,-0.4743,15.8539,0.07822}, + {864,-0.4733,15.8527,0.07822}, + {865,-0.4723,15.8515,0.07823}, + {866,-0.4713,15.8503,0.07823}, + {867,-0.4704,15.8491,0.07824}, + {868,-0.4694,15.848,0.07824}, + {869,-0.4684,15.8468,0.07824}, + {870,-0.4674,15.8456,0.07825}, + {871,-0.4665,15.8444,0.07825}, + {872,-0.4655,15.8432,0.07825}, + {873,-0.4645,15.842,0.07826}, + {874,-0.4636,15.8409,0.07826}, + {875,-0.4626,15.8397,0.07826}, + {876,-0.4616,15.8385,0.07827}, + {877,-0.4607,15.8373,0.07827}, + {878,-0.4597,15.8361,0.07828}, + {879,-0.4587,15.835,0.07828}, + {880,-0.4578,15.8338,0.07828}, + {881,-0.4568,15.8326,0.07829}, + {882,-0.4559,15.8314,0.07829}, + {883,-0.4549,15.8303,0.07829}, + {884,-0.454,15.8291,0.0783}, + {885,-0.4531,15.8279,0.0783}, + {886,-0.4521,15.8267,0.07831}, + {887,-0.4512,15.8256,0.07831}, + {888,-0.4502,15.8244,0.07831}, + {889,-0.4493,15.8232,0.07832}, + {890,-0.4484,15.8221,0.07832}, + {891,-0.4474,15.8209,0.07832}, + {892,-0.4465,15.8197,0.07833}, + {893,-0.4456,15.8186,0.07833}, + {894,-0.4446,15.8174,0.07834}, + {895,-0.4437,15.8162,0.07834}, + {896,-0.4428,15.8151,0.07834}, + {897,-0.4419,15.8139,0.07835}, + {898,-0.441,15.8127,0.07835}, + {899,-0.4401,15.8116,0.07835}, + {900,-0.4391,15.8104,0.07836}, + {901,-0.4382,15.8093,0.07836}, + {902,-0.4373,15.8081,0.07837}, + {903,-0.4364,15.8069,0.07837}, + {904,-0.4355,15.8058,0.07837}, + {905,-0.4346,15.8046,0.07838}, + {906,-0.4337,15.8035,0.07838}, + {907,-0.4328,15.8023,0.07839}, + {908,-0.4319,15.8012,0.07839}, + {909,-0.431,15.8,0.07839}, + {910,-0.4301,15.7989,0.0784}, + {911,-0.4293,15.7977,0.0784}, + {912,-0.4284,15.7966,0.07841}, + {913,-0.4275,15.7954,0.07841}, + {914,-0.4266,15.7943,0.07841}, + {915,-0.4257,15.7931,0.07842}, + {916,-0.4249,15.792,0.07842}, + {917,-0.424,15.7908,0.07843}, + {918,-0.4231,15.7897,0.07843}, + {919,-0.4222,15.7885,0.07843}, + {920,-0.4214,15.7874,0.07844}, + {921,-0.4205,15.7862,0.07844}, + {922,-0.4196,15.7851,0.07845}, + {923,-0.4188,15.7839,0.07845}, + {924,-0.4179,15.7828,0.07845}, + {925,-0.4171,15.7817,0.07846}, + {926,-0.4162,15.7805,0.07846}, + {927,-0.4154,15.7794,0.07847}, + {928,-0.4145,15.7782,0.07847}, + {929,-0.4137,15.7771,0.07848}, + {930,-0.4128,15.776,0.07848}, + {931,-0.412,15.7748,0.07848}, + {932,-0.4111,15.7737,0.07849}, + {933,-0.4103,15.7726,0.07849}, + {934,-0.4095,15.7714,0.0785}, + {935,-0.4086,15.7703,0.0785}, + {936,-0.4078,15.7692,0.0785}, + {937,-0.407,15.768,0.07851}, + {938,-0.4062,15.7669,0.07851}, + {939,-0.4053,15.7658,0.07852}, + {940,-0.4045,15.7646,0.07852}, + {941,-0.4037,15.7635,0.07853}, + {942,-0.4029,15.7624,0.07853}, + {943,-0.4021,15.7612,0.07853}, + {944,-0.4013,15.7601,0.07854}, + {945,-0.4005,15.759,0.07854}, + {946,-0.3997,15.7579,0.07855}, + {947,-0.3988,15.7567,0.07855}, + {948,-0.398,15.7556,0.07856}, + {949,-0.3973,15.7545,0.07856}, + {950,-0.3965,15.7534,0.07857}, + {951,-0.3957,15.7522,0.07857}, + {952,-0.3949,15.7511,0.07857}, + {953,-0.3941,15.75,0.07858}, + {954,-0.3933,15.7489,0.07858}, + {955,-0.3925,15.7478,0.07859}, + {956,-0.3917,15.7466,0.07859}, + {957,-0.391,15.7455,0.0786}, + {958,-0.3902,15.7444,0.0786}, + {959,-0.3894,15.7433,0.07861}, + {960,-0.3886,15.7422,0.07861}, + {961,-0.3879,15.7411,0.07861}, + {962,-0.3871,15.74,0.07862}, + {963,-0.3864,15.7388,0.07862}, + {964,-0.3856,15.7377,0.07863}, + {965,-0.3848,15.7366,0.07863}, + {966,-0.3841,15.7355,0.07864}, + {967,-0.3833,15.7344,0.07864}, + {968,-0.3826,15.7333,0.07865}, + {969,-0.3818,15.7322,0.07865}, + {970,-0.3811,15.7311,0.07865}, + {971,-0.3804,15.73,0.07866}, + {972,-0.3796,15.7289,0.07866}, + {973,-0.3789,15.7278,0.07867}, + {974,-0.3782,15.7267,0.07867}, + {975,-0.3774,15.7256,0.07868}, + {976,-0.3767,15.7245,0.07868}, + {977,-0.376,15.7234,0.07869}, + {978,-0.3753,15.7222,0.07869}, + {979,-0.3745,15.7211,0.0787}, + {980,-0.3738,15.72,0.0787}, + {981,-0.3731,15.719,0.07871}, + {982,-0.3724,15.7179,0.07871}, + {983,-0.3717,15.7168,0.07872}, + {984,-0.371,15.7157,0.07872}, + {985,-0.3703,15.7146,0.07872}, + {986,-0.3696,15.7135,0.07873}, + {987,-0.3689,15.7124,0.07873}, + {988,-0.3682,15.7113,0.07874}, + {989,-0.3675,15.7102,0.07874}, + {990,-0.3668,15.7091,0.07875}, + {991,-0.3661,15.708,0.07875}, + {992,-0.3655,15.7069,0.07876}, + {993,-0.3648,15.7058,0.07876}, + {994,-0.3641,15.7047,0.07877}, + {995,-0.3634,15.7037,0.07877}, + {996,-0.3628,15.7026,0.07878}, + {997,-0.3621,15.7015,0.07878}, + {998,-0.3614,15.7004,0.07879}, + {999,-0.3608,15.6993,0.07879}, + {1000,-0.3601,15.6982,0.0788}, + {1001,-0.3594,15.6971,0.0788}, + {1002,-0.3588,15.6961,0.07881}, + {1003,-0.3581,15.695,0.07881}, + {1004,-0.3575,15.6939,0.07882}, + {1005,-0.3568,15.6928,0.07882}, + {1006,-0.3562,15.6917,0.07883}, + {1007,-0.3556,15.6907,0.07883}, + {1008,-0.3549,15.6896,0.07884}, + {1009,-0.3543,15.6885,0.07884}, + {1010,-0.3536,15.6874,0.07885}, + {1011,-0.353,15.6864,0.07885}, + {1012,-0.3524,15.6853,0.07886}, + {1013,-0.3518,15.6842,0.07886}, + {1014,-0.3511,15.6832,0.07887}, + {1015,-0.3505,15.6821,0.07887}, + {1016,-0.3499,15.681,0.07888}, + {1017,-0.3493,15.6799,0.07888}, + {1018,-0.3487,15.6789,0.07889}, + {1019,-0.3481,15.6778,0.07889}, + {1020,-0.3475,15.6767,0.0789}, + {1021,-0.3469,15.6757,0.0789}, + {1022,-0.3463,15.6746,0.07891}, + {1023,-0.3457,15.6735,0.07891}, + {1024,-0.3451,15.6725,0.07892}, + {1025,-0.3445,15.6714,0.07892}, + {1026,-0.3439,15.6704,0.07893}, + {1027,-0.3433,15.6693,0.07893}, + {1028,-0.3427,15.6682,0.07894}, + {1029,-0.3422,15.6672,0.07894}, + {1030,-0.3416,15.6661,0.07895}, + {1031,-0.341,15.6651,0.07895}, + {1032,-0.3404,15.664,0.07896}, + {1033,-0.3399,15.663,0.07896}, + {1034,-0.3393,15.6619,0.07897}, + {1035,-0.3388,15.6609,0.07897}, + {1036,-0.3382,15.6598,0.07898}, + {1037,-0.3376,15.6588,0.07898}, + {1038,-0.3371,15.6577,0.07899}, + {1039,-0.3365,15.6567,0.07899}, + {1040,-0.336,15.6556,0.079}, + {1041,-0.3354,15.6546,0.079}, + {1042,-0.3349,15.6535,0.07901}, + {1043,-0.3344,15.6525,0.07901}, + {1044,-0.3338,15.6514,0.07902}, + {1045,-0.3333,15.6504,0.07903}, + {1046,-0.3328,15.6493,0.07903}, + {1047,-0.3322,15.6483,0.07904}, + {1048,-0.3317,15.6473,0.07904}, + {1049,-0.3312,15.6462,0.07905}, + {1050,-0.3307,15.6452,0.07905}, + {1051,-0.3302,15.6441,0.07906}, + {1052,-0.3296,15.6431,0.07906}, + {1053,-0.3291,15.6421,0.07907}, + {1054,-0.3286,15.641,0.07907}, + {1055,-0.3281,15.64,0.07908}, + {1056,-0.3276,15.639,0.07908}, + {1057,-0.3271,15.6379,0.07909}, + {1058,-0.3266,15.6369,0.0791}, + {1059,-0.3261,15.6359,0.0791}, + {1060,-0.3257,15.6349,0.07911}, + {1061,-0.3252,15.6338,0.07911}, + {1062,-0.3247,15.6328,0.07912}, + {1063,-0.3242,15.6318,0.07912}, + {1064,-0.3237,15.6308,0.07913}, + {1065,-0.3233,15.6297,0.07913}, + {1066,-0.3228,15.6287,0.07914}, + {1067,-0.3223,15.6277,0.07915}, + {1068,-0.3218,15.6267,0.07915}, + {1069,-0.3214,15.6256,0.07916}, + {1070,-0.3209,15.6246,0.07916}, + {1071,-0.3205,15.6236,0.07917}, + {1072,-0.32,15.6226,0.07917}, + {1073,-0.3196,15.6216,0.07918}, + {1074,-0.3191,15.6206,0.07918}, + {1075,-0.3187,15.6196,0.07919}, + {1076,-0.3182,15.6185,0.0792}, + {1077,-0.3178,15.6175,0.0792}, + {1078,-0.3174,15.6165,0.07921}, + {1079,-0.3169,15.6155,0.07921}, + {1080,-0.3165,15.6145,0.07922}, + {1081,-0.3161,15.6135,0.07922}, + {1082,-0.3156,15.6125,0.07923}, + {1083,-0.3152,15.6115,0.07924}, + {1084,-0.3148,15.6105,0.07924}, + {1085,-0.3144,15.6095,0.07925}, + {1086,-0.314,15.6085,0.07925}, + {1087,-0.3136,15.6075,0.07926}, + {1088,-0.3132,15.6065,0.07926}, + {1089,-0.3128,15.6055,0.07927}, + {1090,-0.3124,15.6045,0.07928}, + {1091,-0.312,15.6035,0.07928}, + {1092,-0.3116,15.6025,0.07929}, + {1093,-0.3112,15.6015,0.07929}, + {1094,-0.3108,15.6005,0.0793}, + {1095,-0.3104,15.5995,0.07931}, + {1096,-0.31,15.5986,0.07931}, + {1097,-0.3097,15.5976,0.07932}, + {1098,-0.3093,15.5966,0.07932}, + {1099,-0.3089,15.5956,0.07933}, + {1100,-0.3085,15.5946,0.07934}, + {1101,-0.3082,15.5936,0.07934}, + {1102,-0.3078,15.5926,0.07935}, + {1103,-0.3074,15.5917,0.07935}, + {1104,-0.3071,15.5907,0.07936}, + {1105,-0.3067,15.5897,0.07936}, + {1106,-0.3064,15.5887,0.07937}, + {1107,-0.306,15.5878,0.07938}, + {1108,-0.3057,15.5868,0.07938}, + {1109,-0.3054,15.5858,0.07939}, + {1110,-0.305,15.5848,0.0794}, + {1111,-0.3047,15.5839,0.0794}, + {1112,-0.3043,15.5829,0.07941}, + {1113,-0.304,15.5819,0.07941}, + {1114,-0.3037,15.581,0.07942}, + {1115,-0.3034,15.58,0.07943}, + {1116,-0.3031,15.579,0.07943}, + {1117,-0.3027,15.5781,0.07944}, + {1118,-0.3024,15.5771,0.07944}, + {1119,-0.3021,15.5761,0.07945}, + {1120,-0.3018,15.5752,0.07946}, + {1121,-0.3015,15.5742,0.07946}, + {1122,-0.3012,15.5733,0.07947}, + {1123,-0.3009,15.5723,0.07948}, + {1124,-0.3006,15.5714,0.07948}, + {1125,-0.3003,15.5704,0.07949}, + {1126,-0.3,15.5695,0.07949}, + {1127,-0.2997,15.5685,0.0795}, + {1128,-0.2995,15.5676,0.07951}, + {1129,-0.2992,15.5666,0.07951}, + {1130,-0.2989,15.5657,0.07952}, + {1131,-0.2986,15.5647,0.07953}, + {1132,-0.2984,15.5638,0.07953}, + {1133,-0.2981,15.5628,0.07954}, + {1134,-0.2978,15.5619,0.07954}, + {1135,-0.2976,15.5609,0.07955}, + {1136,-0.2973,15.56,0.07956}, + {1137,-0.2971,15.5591,0.07956}, + {1138,-0.2968,15.5581,0.07957}, + {1139,-0.2966,15.5572,0.07958}, + {1140,-0.2963,15.5563,0.07958}, + {1141,-0.2961,15.5553,0.07959}, + {1142,-0.2959,15.5544,0.0796}, + {1143,-0.2956,15.5535,0.0796}, + {1144,-0.2954,15.5525,0.07961}, + {1145,-0.2952,15.5516,0.07962}, + {1146,-0.2949,15.5507,0.07962}, + {1147,-0.2947,15.5498,0.07963}, + {1148,-0.2945,15.5489,0.07964}, + {1149,-0.2943,15.5479,0.07964}, + {1150,-0.2941,15.547,0.07965}, + {1151,-0.2939,15.5461,0.07966}, + {1152,-0.2937,15.5452,0.07966}, + {1153,-0.2934,15.5443,0.07967}, + {1154,-0.2932,15.5434,0.07967}, + {1155,-0.2931,15.5424,0.07968}, + {1156,-0.2929,15.5415,0.07969}, + {1157,-0.2927,15.5406,0.07969}, + {1158,-0.2925,15.5397,0.0797}, + {1159,-0.2923,15.5388,0.07971}, + {1160,-0.2921,15.5379,0.07972}, + {1161,-0.2919,15.537,0.07972}, + {1162,-0.2918,15.5361,0.07973}, + {1163,-0.2916,15.5352,0.07974}, + {1164,-0.2914,15.5343,0.07974}, + {1165,-0.2913,15.5334,0.07975}, + {1166,-0.2911,15.5325,0.07976}, + {1167,-0.2909,15.5316,0.07976}, + {1168,-0.2908,15.5307,0.07977}, + {1169,-0.2906,15.5298,0.07978}, + {1170,-0.2905,15.5289,0.07978}, + {1171,-0.2903,15.5281,0.07979}, + {1172,-0.2902,15.5272,0.0798}, + {1173,-0.2901,15.5263,0.0798}, + {1174,-0.2899,15.5254,0.07981}, + {1175,-0.2898,15.5245,0.07982}, + {1176,-0.2897,15.5236,0.07982}, + {1177,-0.2895,15.5228,0.07983}, + {1178,-0.2894,15.5219,0.07984}, + {1179,-0.2893,15.521,0.07985}, + {1180,-0.2892,15.5201,0.07985}, + {1181,-0.289,15.5193,0.07986}, + {1182,-0.2889,15.5184,0.07987}, + {1183,-0.2888,15.5175,0.07987}, + {1184,-0.2887,15.5167,0.07988}, + {1185,-0.2886,15.5158,0.07989}, + {1186,-0.2885,15.5149,0.07989}, + {1187,-0.2884,15.5141,0.0799}, + {1188,-0.2883,15.5132,0.07991}, + {1189,-0.2882,15.5123,0.07992}, + {1190,-0.2881,15.5115,0.07992}, + {1191,-0.2881,15.5106,0.07993}, + {1192,-0.288,15.5098,0.07994}, + {1193,-0.2879,15.5089,0.07994}, + {1194,-0.2878,15.5081,0.07995}, + {1195,-0.2877,15.5072,0.07996}, + {1196,-0.2877,15.5064,0.07997}, + {1197,-0.2876,15.5055,0.07997}, + {1198,-0.2875,15.5047,0.07998}, + {1199,-0.2875,15.5038,0.07999}, + {1200,-0.2874,15.503,0.07999}, + {1201,-0.2874,15.5021,0.08}, + {1202,-0.2873,15.5013,0.08001}, + {1203,-0.2873,15.5005,0.08002}, + {1204,-0.2872,15.4996,0.08002}, + {1205,-0.2872,15.4988,0.08003}, + {1206,-0.2871,15.498,0.08004}, + {1207,-0.2871,15.4971,0.08005}, + {1208,-0.2871,15.4963,0.08005}, + {1209,-0.287,15.4955,0.08006}, + {1210,-0.287,15.4946,0.08007}, + {1211,-0.287,15.4938,0.08008}, + {1212,-0.287,15.493,0.08008}, + {1213,-0.2869,15.4922,0.08009}, + {1214,-0.2869,15.4914,0.0801}, + {1215,-0.2869,15.4905,0.08011}, + {1216,-0.2869,15.4897,0.08011}, + {1217,-0.2869,15.4889,0.08012}, + {1218,-0.2869,15.4881,0.08013}, + {1219,-0.2869,15.4873,0.08014}, + {1220,-0.2869,15.4865,0.08014}, + {1221,-0.2869,15.4857,0.08015}, + {1222,-0.2869,15.4848,0.08016}, + {1223,-0.2869,15.484,0.08017}, + {1224,-0.2869,15.4832,0.08017}, + {1225,-0.2869,15.4824,0.08018}, + {1226,-0.287,15.4816,0.08019}, + {1227,-0.287,15.4808,0.0802}, + {1228,-0.287,15.48,0.0802}, + {1229,-0.287,15.4792,0.08021}, + {1230,-0.2871,15.4785,0.08022}, + {1231,-0.2871,15.4777,0.08023}, + {1232,-0.2871,15.4769,0.08023}, + {1233,-0.2872,15.4761,0.08024}, + {1234,-0.2872,15.4753,0.08025}, + {1235,-0.2873,15.4745,0.08026}, + {1236,-0.2873,15.4737,0.08027}, + {1237,-0.2874,15.4729,0.08027}, + {1238,-0.2874,15.4722,0.08028}, + {1239,-0.2875,15.4714,0.08029}, + {1240,-0.2875,15.4706,0.0803}, + {1241,-0.2876,15.4698,0.08031}, + {1242,-0.2877,15.4691,0.08031}, + {1243,-0.2877,15.4683,0.08032}, + {1244,-0.2878,15.4675,0.08033}, + {1245,-0.2879,15.4667,0.08034}, + {1246,-0.288,15.466,0.08034}, + {1247,-0.288,15.4652,0.08035}, + {1248,-0.2881,15.4645,0.08036}, + {1249,-0.2882,15.4637,0.08037}, + {1250,-0.2883,15.4629,0.08038}, + {1251,-0.2884,15.4622,0.08038}, + {1252,-0.2885,15.4614,0.08039}, + {1253,-0.2886,15.4607,0.0804}, + {1254,-0.2887,15.4599,0.08041}, + {1255,-0.2888,15.4592,0.08042}, + {1256,-0.2889,15.4584,0.08042}, + {1257,-0.289,15.4577,0.08043}, + {1258,-0.2891,15.4569,0.08044}, + {1259,-0.2892,15.4562,0.08045}, + {1260,-0.2893,15.4554,0.08046}, + {1261,-0.2894,15.4547,0.08046}, + {1262,-0.2896,15.4539,0.08047}, + {1263,-0.2897,15.4532,0.08048}, + {1264,-0.2898,15.4525,0.08049}, + {1265,-0.2899,15.4517,0.0805}, + {1266,-0.2901,15.451,0.08051}, + {1267,-0.2902,15.4503,0.08051}, + {1268,-0.2903,15.4495,0.08052}, + {1269,-0.2905,15.4488,0.08053}, + {1270,-0.2906,15.4481,0.08054}, + {1271,-0.2908,15.4473,0.08055}, + {1272,-0.2909,15.4466,0.08056}, + {1273,-0.2911,15.4459,0.08056}, + {1274,-0.2912,15.4452,0.08057}, + {1275,-0.2914,15.4445,0.08058}, + {1276,-0.2915,15.4437,0.08059}, + {1277,-0.2917,15.443,0.0806}, + {1278,-0.2918,15.4423,0.08061}, + {1279,-0.292,15.4416,0.08061}, + {1280,-0.2922,15.4409,0.08062}, + {1281,-0.2924,15.4402,0.08063}, + {1282,-0.2925,15.4395,0.08064}, + {1283,-0.2927,15.4388,0.08065}, + {1284,-0.2929,15.438,0.08066}, + {1285,-0.2931,15.4373,0.08066}, + {1286,-0.2933,15.4366,0.08067}, + {1287,-0.2934,15.4359,0.08068}, + {1288,-0.2936,15.4352,0.08069}, + {1289,-0.2938,15.4345,0.0807}, + {1290,-0.294,15.4338,0.08071}, + {1291,-0.2942,15.4332,0.08072}, + {1292,-0.2944,15.4325,0.08072}, + {1293,-0.2946,15.4318,0.08073}, + {1294,-0.2948,15.4311,0.08074}, + {1295,-0.295,15.4304,0.08075}, + {1296,-0.2952,15.4297,0.08076}, + {1297,-0.2954,15.429,0.08077}, + {1298,-0.2957,15.4283,0.08078}, + {1299,-0.2959,15.4276,0.08078}, + {1300,-0.2961,15.427,0.08079}, + {1301,-0.2963,15.4263,0.0808}, + {1302,-0.2965,15.4256,0.08081}, + {1303,-0.2968,15.4249,0.08082}, + {1304,-0.297,15.4243,0.08083}, + {1305,-0.2972,15.4236,0.08084}, + {1306,-0.2975,15.4229,0.08085}, + {1307,-0.2977,15.4222,0.08085}, + {1308,-0.2979,15.4216,0.08086}, + {1309,-0.2982,15.4209,0.08087}, + {1310,-0.2984,15.4202,0.08088}, + {1311,-0.2987,15.4196,0.08089}, + {1312,-0.2989,15.4189,0.0809}, + {1313,-0.2992,15.4182,0.08091}, + {1314,-0.2994,15.4176,0.08092}, + {1315,-0.2997,15.4169,0.08093}, + {1316,-0.3,15.4162,0.08093}, + {1317,-0.3002,15.4156,0.08094}, + {1318,-0.3005,15.4149,0.08095}, + {1319,-0.3008,15.4143,0.08096}, + {1320,-0.301,15.4136,0.08097}, + {1321,-0.3013,15.413,0.08098}, + {1322,-0.3016,15.4123,0.08099}, + {1323,-0.3018,15.4117,0.081}, + {1324,-0.3021,15.411,0.08101}, + {1325,-0.3024,15.4104,0.08102}, + {1326,-0.3027,15.4097,0.08102}, + {1327,-0.303,15.4091,0.08103}, + {1328,-0.3033,15.4084,0.08104}, + {1329,-0.3036,15.4078,0.08105}, + {1330,-0.3038,15.4072,0.08106}, + {1331,-0.3041,15.4065,0.08107}, + {1332,-0.3044,15.4059,0.08108}, + {1333,-0.3047,15.4052,0.08109}, + {1334,-0.305,15.4046,0.0811}, + {1335,-0.3054,15.404,0.08111}, + {1336,-0.3057,15.4033,0.08112}, + {1337,-0.306,15.4027,0.08113}, + {1338,-0.3063,15.4021,0.08113}, + {1339,-0.3066,15.4015,0.08114}, + {1340,-0.3069,15.4008,0.08115}, + {1341,-0.3072,15.4002,0.08116}, + {1342,-0.3076,15.3996,0.08117}, + {1343,-0.3079,15.399,0.08118}, + {1344,-0.3082,15.3983,0.08119}, + {1345,-0.3085,15.3977,0.0812}, + {1346,-0.3089,15.3971,0.08121}, + {1347,-0.3092,15.3965,0.08122}, + {1348,-0.3095,15.3958,0.08123}, + {1349,-0.3099,15.3952,0.08124}, + {1350,-0.3102,15.3946,0.08125}, + {1351,-0.3106,15.394,0.08126}, + {1352,-0.3109,15.3934,0.08127}, + {1353,-0.3113,15.3928,0.08128}, + {1354,-0.3116,15.3922,0.08128}, + {1355,-0.312,15.3916,0.08129}, + {1356,-0.3123,15.3909,0.0813}, + {1357,-0.3127,15.3903,0.08131}, + {1358,-0.313,15.3897,0.08132}, + {1359,-0.3134,15.3891,0.08133}, + {1360,-0.3138,15.3885,0.08134}, + {1361,-0.3141,15.3879,0.08135}, + {1362,-0.3145,15.3873,0.08136}, + {1363,-0.3149,15.3867,0.08137}, + {1364,-0.3152,15.3861,0.08138}, + {1365,-0.3156,15.3855,0.08139}, + {1366,-0.316,15.3849,0.0814}, + {1367,-0.3164,15.3843,0.08141}, + {1368,-0.3168,15.3837,0.08142}, + {1369,-0.3171,15.3831,0.08143}, + {1370,-0.3175,15.3825,0.08144}, + {1371,-0.3179,15.382,0.08145}, + {1372,-0.3183,15.3814,0.08146}, + {1373,-0.3187,15.3808,0.08147}, + {1374,-0.3191,15.3802,0.08148}, + {1375,-0.3195,15.3796,0.08149}, + {1376,-0.3199,15.379,0.0815}, + {1377,-0.3203,15.3784,0.08151}, + {1378,-0.3207,15.3778,0.08152}, + {1379,-0.3211,15.3773,0.08153}, + {1380,-0.3215,15.3767,0.08154}, + {1381,-0.322,15.3761,0.08155}, + {1382,-0.3224,15.3755,0.08156}, + {1383,-0.3228,15.3749,0.08157}, + {1384,-0.3232,15.3744,0.08158}, + {1385,-0.3236,15.3738,0.08159}, + {1386,-0.3241,15.3732,0.0816}, + {1387,-0.3245,15.3726,0.08161}, + {1388,-0.3249,15.3721,0.08162}, + {1389,-0.3253,15.3715,0.08163}, + {1390,-0.3258,15.3709,0.08164}, + {1391,-0.3262,15.3703,0.08165}, + {1392,-0.3266,15.3698,0.08166}, + {1393,-0.3271,15.3692,0.08167}, + {1394,-0.3275,15.3686,0.08168}, + {1395,-0.328,15.3681,0.08169}, + {1396,-0.3284,15.3675,0.0817}, + {1397,-0.3289,15.3669,0.08171}, + {1398,-0.3293,15.3664,0.08172}, + {1399,-0.3298,15.3658,0.08173}, + {1400,-0.3302,15.3652,0.08174}, + {1401,-0.3307,15.3647,0.08175}, + {1402,-0.3312,15.3641,0.08176}, + {1403,-0.3316,15.3636,0.08177}, + {1404,-0.3321,15.363,0.08178}, + {1405,-0.3325,15.3624,0.08179}, + {1406,-0.333,15.3619,0.0818}, + {1407,-0.3335,15.3613,0.08181}, + {1408,-0.334,15.3608,0.08182}, + {1409,-0.3344,15.3602,0.08183}, + {1410,-0.3349,15.3597,0.08184}, + {1411,-0.3354,15.3591,0.08185}, + {1412,-0.3359,15.3586,0.08186}, + {1413,-0.3364,15.358,0.08187}, + {1414,-0.3369,15.3575,0.08188}, + {1415,-0.3373,15.3569,0.08189}, + {1416,-0.3378,15.3564,0.0819}, + {1417,-0.3383,15.3558,0.08191}, + {1418,-0.3388,15.3553,0.08192}, + {1419,-0.3393,15.3547,0.08193}, + {1420,-0.3398,15.3542,0.08194}, + {1421,-0.3403,15.3537,0.08195}, + {1422,-0.3408,15.3531,0.08196}, + {1423,-0.3413,15.3526,0.08197}, + {1424,-0.3418,15.352,0.08198}, + {1425,-0.3424,15.3515,0.082}, + {1426,-0.3429,15.351,0.08201}, + {1427,-0.3434,15.3504,0.08202}, + {1428,-0.3439,15.3499,0.08203}, + {1429,-0.3444,15.3493,0.08204}, + {1430,-0.3449,15.3488,0.08205}, + {1431,-0.3455,15.3483,0.08206}, + {1432,-0.346,15.3477,0.08207}, + {1433,-0.3465,15.3472,0.08208}, + {1434,-0.3471,15.3467,0.08209}, + {1435,-0.3476,15.3461,0.0821}, + {1436,-0.3481,15.3456,0.08211}, + {1437,-0.3487,15.3451,0.08212}, + {1438,-0.3492,15.3445,0.08213}, + {1439,-0.3497,15.344,0.08214}, + {1440,-0.3503,15.3435,0.08215}, + {1441,-0.3508,15.343,0.08216}, + {1442,-0.3514,15.3424,0.08218}, + {1443,-0.3519,15.3419,0.08219}, + {1444,-0.3525,15.3414,0.0822}, + {1445,-0.353,15.3409,0.08221}, + {1446,-0.3536,15.3403,0.08222}, + {1447,-0.3541,15.3398,0.08223}, + {1448,-0.3547,15.3393,0.08224}, + {1449,-0.3553,15.3388,0.08225}, + {1450,-0.3558,15.3383,0.08226}, + {1451,-0.3564,15.3377,0.08227}, + {1452,-0.357,15.3372,0.08228}, + {1453,-0.3575,15.3367,0.08229}, + {1454,-0.3581,15.3362,0.08231}, + {1455,-0.3587,15.3357,0.08232}, + {1456,-0.3593,15.3352,0.08233}, + {1457,-0.3598,15.3346,0.08234}, + {1458,-0.3604,15.3341,0.08235}, + {1459,-0.361,15.3336,0.08236}, + {1460,-0.3616,15.3331,0.08237}, + {1461,-0.3622,15.3326,0.08238}, + {1462,-0.3628,15.3321,0.08239}, + {1463,-0.3634,15.3316,0.0824}, + {1464,-0.364,15.3311,0.08241}, + {1465,-0.3646,15.3306,0.08243}, + {1466,-0.3652,15.3301,0.08244}, + {1467,-0.3658,15.3295,0.08245}, + {1468,-0.3664,15.329,0.08246}, + {1469,-0.367,15.3285,0.08247}, + {1470,-0.3676,15.328,0.08248}, + {1471,-0.3682,15.3275,0.08249}, + {1472,-0.3688,15.327,0.0825}, + {1473,-0.3694,15.3265,0.08251}, + {1474,-0.37,15.326,0.08253}, + {1475,-0.3706,15.3255,0.08254}, + {1476,-0.3713,15.325,0.08255}, + {1477,-0.3719,15.3245,0.08256}, + {1478,-0.3725,15.324,0.08257}, + {1479,-0.3731,15.3235,0.08258}, + {1480,-0.3738,15.323,0.08259}, + {1481,-0.3744,15.3225,0.0826}, + {1482,-0.375,15.322,0.08262}, + {1483,-0.3756,15.3215,0.08263}, + {1484,-0.3763,15.3211,0.08264}, + {1485,-0.3769,15.3206,0.08265}, + {1486,-0.3776,15.3201,0.08266}, + {1487,-0.3782,15.3196,0.08267}, + {1488,-0.3789,15.3191,0.08268}, + {1489,-0.3795,15.3186,0.08269}, + {1490,-0.3801,15.3181,0.08271}, + {1491,-0.3808,15.3176,0.08272}, + {1492,-0.3815,15.3171,0.08273}, + {1493,-0.3821,15.3166,0.08274}, + {1494,-0.3828,15.3162,0.08275}, + {1495,-0.3834,15.3157,0.08276}, + {1496,-0.3841,15.3152,0.08277}, + {1497,-0.3847,15.3147,0.08279}, + {1498,-0.3854,15.3142,0.0828}, + {1499,-0.3861,15.3137,0.08281}, + {1500,-0.3867,15.3133,0.08282}, + {1501,-0.3874,15.3128,0.08283}, + {1502,-0.3881,15.3123,0.08284}, + {1503,-0.3888,15.3118,0.08285}, + {1504,-0.3894,15.3113,0.08287}, + {1505,-0.3901,15.3109,0.08288}, + {1506,-0.3908,15.3104,0.08289}, + {1507,-0.3915,15.3099,0.0829}, + {1508,-0.3922,15.3094,0.08291}, + {1509,-0.3929,15.309,0.08292}, + {1510,-0.3936,15.3085,0.08293}, + {1511,-0.3942,15.308,0.08295}, + {1512,-0.3949,15.3075,0.08296}, + {1513,-0.3956,15.3071,0.08297}, + {1514,-0.3963,15.3066,0.08298}, + {1515,-0.397,15.3061,0.08299}, + {1516,-0.3977,15.3057,0.083}, + {1517,-0.3984,15.3052,0.08302}, + {1518,-0.3991,15.3047,0.08303}, + {1519,-0.3998,15.3043,0.08304}, + {1520,-0.4006,15.3038,0.08305}, + {1521,-0.4013,15.3033,0.08306}, + {1522,-0.402,15.3029,0.08307}, + {1523,-0.4027,15.3024,0.08309}, + {1524,-0.4034,15.3019,0.0831}, + {1525,-0.4041,15.3015,0.08311}, + {1526,-0.4049,15.301,0.08312}, + {1527,-0.4056,15.3005,0.08313}, + {1528,-0.4063,15.3001,0.08314}, + {1529,-0.407,15.2996,0.08316}, + {1530,-0.4078,15.2992,0.08317}, + {1531,-0.4085,15.2987,0.08318}, + {1532,-0.4092,15.2982,0.08319}, + {1533,-0.41,15.2978,0.0832}, + {1534,-0.4107,15.2973,0.08322}, + {1535,-0.4114,15.2969,0.08323}, + {1536,-0.4122,15.2964,0.08324}, + {1537,-0.4129,15.2959,0.08325}, + {1538,-0.4137,15.2955,0.08326}, + {1539,-0.4144,15.295,0.08327}, + {1540,-0.4151,15.2946,0.08329}, + {1541,-0.4159,15.2941,0.0833}, + {1542,-0.4166,15.2937,0.08331}, + {1543,-0.4174,15.2932,0.08332}, + {1544,-0.4182,15.2928,0.08333}, + {1545,-0.4189,15.2923,0.08335}, + {1546,-0.4197,15.2919,0.08336}, + {1547,-0.4204,15.2914,0.08337}, + {1548,-0.4212,15.291,0.08338}, + {1549,-0.422,15.2905,0.08339}, + {1550,-0.4227,15.2901,0.08341}, + {1551,-0.4235,15.2896,0.08342}, + {1552,-0.4243,15.2892,0.08343}, + {1553,-0.425,15.2888,0.08344}, + {1554,-0.4258,15.2883,0.08345}, + {1555,-0.4266,15.2879,0.08347}, + {1556,-0.4274,15.2874,0.08348}, + {1557,-0.4281,15.287,0.08349}, + {1558,-0.4289,15.2865,0.0835}, + {1559,-0.4297,15.2861,0.08351}, + {1560,-0.4305,15.2857,0.08353}, + {1561,-0.4313,15.2852,0.08354}, + {1562,-0.4321,15.2848,0.08355}, + {1563,-0.4328,15.2844,0.08356}, + {1564,-0.4336,15.2839,0.08357}, + {1565,-0.4344,15.2835,0.08359}, + {1566,-0.4352,15.283,0.0836}, + {1567,-0.436,15.2826,0.08361}, + {1568,-0.4368,15.2822,0.08362}, + {1569,-0.4376,15.2817,0.08364}, + {1570,-0.4384,15.2813,0.08365}, + {1571,-0.4392,15.2809,0.08366}, + {1572,-0.44,15.2805,0.08367}, + {1573,-0.4408,15.28,0.08368}, + {1574,-0.4417,15.2796,0.0837}, + {1575,-0.4425,15.2792,0.08371}, + {1576,-0.4433,15.2787,0.08372}, + {1577,-0.4441,15.2783,0.08373}, + {1578,-0.4449,15.2779,0.08375}, + {1579,-0.4457,15.2775,0.08376}, + {1580,-0.4465,15.277,0.08377}, + {1581,-0.4474,15.2766,0.08378}, + {1582,-0.4482,15.2762,0.08379}, + {1583,-0.449,15.2758,0.08381}, + {1584,-0.4498,15.2753,0.08382}, + {1585,-0.4507,15.2749,0.08383}, + {1586,-0.4515,15.2745,0.08384}, + {1587,-0.4523,15.2741,0.08386}, + {1588,-0.4532,15.2737,0.08387}, + {1589,-0.454,15.2732,0.08388}, + {1590,-0.4548,15.2728,0.08389}, + {1591,-0.4557,15.2724,0.08391}, + {1592,-0.4565,15.272,0.08392}, + {1593,-0.4574,15.2716,0.08393}, + {1594,-0.4582,15.2712,0.08394}, + {1595,-0.459,15.2708,0.08395}, + {1596,-0.4599,15.2703,0.08397}, + {1597,-0.4607,15.2699,0.08398}, + {1598,-0.4616,15.2695,0.08399}, + {1599,-0.4624,15.2691,0.084}, + {1600,-0.4633,15.2687,0.08402}, + {1601,-0.4641,15.2683,0.08403}, + {1602,-0.465,15.2679,0.08404}, + {1603,-0.4659,15.2675,0.08405}, + {1604,-0.4667,15.2671,0.08407}, + {1605,-0.4676,15.2667,0.08408}, + {1606,-0.4684,15.2662,0.08409}, + {1607,-0.4693,15.2658,0.0841}, + {1608,-0.4702,15.2654,0.08412}, + {1609,-0.471,15.265,0.08413}, + {1610,-0.4719,15.2646,0.08414}, + {1611,-0.4728,15.2642,0.08415}, + {1612,-0.4736,15.2638,0.08417}, + {1613,-0.4745,15.2634,0.08418}, + {1614,-0.4754,15.263,0.08419}, + {1615,-0.4762,15.2626,0.0842}, + {1616,-0.4771,15.2622,0.08422}, + {1617,-0.478,15.2618,0.08423}, + {1618,-0.4789,15.2614,0.08424}, + {1619,-0.4798,15.261,0.08425}, + {1620,-0.4806,15.2606,0.08427}, + {1621,-0.4815,15.2602,0.08428}, + {1622,-0.4824,15.2598,0.08429}, + {1623,-0.4833,15.2594,0.08431}, + {1624,-0.4842,15.259,0.08432}, + {1625,-0.4851,15.2586,0.08433}, + {1626,-0.486,15.2582,0.08434}, + {1627,-0.4869,15.2579,0.08436}, + {1628,-0.4877,15.2575,0.08437}, + {1629,-0.4886,15.2571,0.08438}, + {1630,-0.4895,15.2567,0.08439}, + {1631,-0.4904,15.2563,0.08441}, + {1632,-0.4913,15.2559,0.08442}, + {1633,-0.4922,15.2555,0.08443}, + {1634,-0.4931,15.2551,0.08444}, + {1635,-0.494,15.2547,0.08446}, + {1636,-0.4949,15.2543,0.08447}, + {1637,-0.4958,15.254,0.08448}, + {1638,-0.4968,15.2536,0.0845}, + {1639,-0.4977,15.2532,0.08451}, + {1640,-0.4986,15.2528,0.08452}, + {1641,-0.4995,15.2524,0.08453}, + {1642,-0.5004,15.252,0.08455}, + {1643,-0.5013,15.2516,0.08456}, + {1644,-0.5022,15.2513,0.08457}, + {1645,-0.5031,15.2509,0.08459}, + {1646,-0.504,15.2505,0.0846}, + {1647,-0.505,15.2501,0.08461}, + {1648,-0.5059,15.2497,0.08462}, + {1649,-0.5068,15.2494,0.08464}, + {1650,-0.5077,15.249,0.08465}, + {1651,-0.5087,15.2486,0.08466}, + {1652,-0.5096,15.2482,0.08468}, + {1653,-0.5105,15.2478,0.08469}, + {1654,-0.5114,15.2475,0.0847}, + {1655,-0.5124,15.2471,0.08471}, + {1656,-0.5133,15.2467,0.08473}, + {1657,-0.5142,15.2463,0.08474}, + {1658,-0.5151,15.246,0.08475}, + {1659,-0.5161,15.2456,0.08477}, + {1660,-0.517,15.2452,0.08478}, + {1661,-0.518,15.2448,0.08479}, + {1662,-0.5189,15.2445,0.0848}, + {1663,-0.5198,15.2441,0.08482}, + {1664,-0.5208,15.2437,0.08483}, + {1665,-0.5217,15.2433,0.08484}, + {1666,-0.5227,15.243,0.08486}, + {1667,-0.5236,15.2426,0.08487}, + {1668,-0.5245,15.2422,0.08488}, + {1669,-0.5255,15.2419,0.0849}, + {1670,-0.5264,15.2415,0.08491}, + {1671,-0.5274,15.2411,0.08492}, + {1672,-0.5283,15.2408,0.08493}, + {1673,-0.5293,15.2404,0.08495}, + {1674,-0.5302,15.24,0.08496}, + {1675,-0.5312,15.2397,0.08497}, + {1676,-0.5321,15.2393,0.08499}, + {1677,-0.5331,15.2389,0.085}, + {1678,-0.5341,15.2386,0.08501}, + {1679,-0.535,15.2382,0.08503}, + {1680,-0.536,15.2378,0.08504}, + {1681,-0.5369,15.2375,0.08505}, + {1682,-0.5379,15.2371,0.08506}, + {1683,-0.5389,15.2368,0.08508}, + {1684,-0.5398,15.2364,0.08509}, + {1685,-0.5408,15.236,0.0851}, + {1686,-0.5418,15.2357,0.08512}, + {1687,-0.5427,15.2353,0.08513}, + {1688,-0.5437,15.235,0.08514}, + {1689,-0.5447,15.2346,0.08516}, + {1690,-0.5456,15.2342,0.08517}, + {1691,-0.5466,15.2339,0.08518}, + {1692,-0.5476,15.2335,0.0852}, + {1693,-0.5486,15.2332,0.08521}, + {1694,-0.5495,15.2328,0.08522}, + {1695,-0.5505,15.2325,0.08524}, + {1696,-0.5515,15.2321,0.08525}, + {1697,-0.5525,15.2318,0.08526}, + {1698,-0.5535,15.2314,0.08527}, + {1699,-0.5544,15.2311,0.08529}, + {1700,-0.5554,15.2307,0.0853}, + {1701,-0.5564,15.2304,0.08531}, + {1702,-0.5574,15.23,0.08533}, + {1703,-0.5584,15.2297,0.08534}, + {1704,-0.5594,15.2293,0.08535}, + {1705,-0.5604,15.229,0.08537}, + {1706,-0.5614,15.2286,0.08538}, + {1707,-0.5623,15.2283,0.08539}, + {1708,-0.5633,15.2279,0.08541}, + {1709,-0.5643,15.2276,0.08542}, + {1710,-0.5653,15.2272,0.08543}, + {1711,-0.5663,15.2269,0.08545}, + {1712,-0.5673,15.2265,0.08546}, + {1713,-0.5683,15.2262,0.08547}, + {1714,-0.5693,15.2258,0.08549}, + {1715,-0.5703,15.2255,0.0855}, + {1716,-0.5713,15.2252,0.08551}, + {1717,-0.5723,15.2248,0.08553}, + {1718,-0.5733,15.2245,0.08554}, + {1719,-0.5743,15.2241,0.08555}, + {1720,-0.5754,15.2238,0.08557}, + {1721,-0.5764,15.2235,0.08558}, + {1722,-0.5774,15.2231,0.08559}, + {1723,-0.5784,15.2228,0.08561}, + {1724,-0.5794,15.2224,0.08562}, + {1725,-0.5804,15.2221,0.08563}, + {1726,-0.5814,15.2218,0.08565}, + {1727,-0.5824,15.2214,0.08566}, + {1728,-0.5835,15.2211,0.08567}, + {1729,-0.5845,15.2208,0.08569}, + {1730,-0.5855,15.2204,0.0857}, + {1731,-0.5865,15.2201,0.08571}, + {1732,-0.5875,15.2198,0.08573}, + {1733,-0.5886,15.2194,0.08574}, + {1734,-0.5896,15.2191,0.08575}, + {1735,-0.5906,15.2188,0.08577}, + {1736,-0.5916,15.2184,0.08578}, + {1737,-0.5927,15.2181,0.08579}, + {1738,-0.5937,15.2178,0.08581}, + {1739,-0.5947,15.2175,0.08582}, + {1740,-0.5958,15.2171,0.08583}, + {1741,-0.5968,15.2168,0.08585}, + {1742,-0.5978,15.2165,0.08586}, + {1743,-0.5989,15.2162,0.08587}, + {1744,-0.5999,15.2158,0.08589}, + {1745,-0.6009,15.2155,0.0859}, + {1746,-0.602,15.2152,0.08591}, + {1747,-0.603,15.2149,0.08593}, + {1748,-0.604,15.2145,0.08594}, + {1749,-0.6051,15.2142,0.08595}, + {1750,-0.6061,15.2139,0.08597}, + {1751,-0.6072,15.2136,0.08598}, + {1752,-0.6082,15.2133,0.08599}, + {1753,-0.6093,15.213,0.08601}, + {1754,-0.6103,15.2126,0.08602}, + {1755,-0.6114,15.2123,0.08603}, + {1756,-0.6124,15.212,0.08605}, + {1757,-0.6135,15.2117,0.08606}, + {1758,-0.6145,15.2114,0.08608}, + {1759,-0.6156,15.2111,0.08609}, + {1760,-0.6166,15.2108,0.0861}, + {1761,-0.6177,15.2104,0.08612}, + {1762,-0.6187,15.2101,0.08613}, + {1763,-0.6198,15.2098,0.08614}, + {1764,-0.6209,15.2095,0.08616}, + {1765,-0.6219,15.2092,0.08617}, + {1766,-0.623,15.2089,0.08618}, + {1767,-0.6241,15.2086,0.0862}, + {1768,-0.6251,15.2083,0.08621}, + {1769,-0.6262,15.208,0.08622}, + {1770,-0.6273,15.2077,0.08624}, + {1771,-0.6283,15.2074,0.08625}, + {1772,-0.6294,15.2071,0.08626}, + {1773,-0.6305,15.2068,0.08628}, + {1774,-0.6315,15.2065,0.08629}, + {1775,-0.6326,15.2061,0.0863}, + {1776,-0.6337,15.2058,0.08632}, + {1777,-0.6348,15.2055,0.08633}, + {1778,-0.6358,15.2052,0.08634}, + {1779,-0.6369,15.2049,0.08636}, + {1780,-0.638,15.2047,0.08637}, + {1781,-0.6391,15.2044,0.08639}, + {1782,-0.6402,15.2041,0.0864}, + {1783,-0.6412,15.2038,0.08641}, + {1784,-0.6423,15.2035,0.08643}, + {1785,-0.6434,15.2032,0.08644}, + {1786,-0.6445,15.2029,0.08645}, + {1787,-0.6456,15.2026,0.08647}, + {1788,-0.6467,15.2023,0.08648}, + {1789,-0.6478,15.202,0.08649}, + {1790,-0.6488,15.2017,0.08651}, + {1791,-0.6499,15.2014,0.08652}, + {1792,-0.651,15.2011,0.08653}, + {1793,-0.6521,15.2008,0.08655}, + {1794,-0.6532,15.2005,0.08656}, + {1795,-0.6543,15.2003,0.08657}, + {1796,-0.6554,15.2,0.08659}, + {1797,-0.6565,15.1997,0.0866}, + {1798,-0.6576,15.1994,0.08662}, + {1799,-0.6587,15.1991,0.08663}, + {1800,-0.6598,15.1988,0.08664}, + {1801,-0.6609,15.1985,0.08666}, + {1802,-0.662,15.1983,0.08667}, + {1803,-0.6631,15.198,0.08668}, + {1804,-0.6642,15.1977,0.0867}, + {1805,-0.6653,15.1974,0.08671}, + {1806,-0.6665,15.1971,0.08672}, + {1807,-0.6676,15.1969,0.08674}, + {1808,-0.6687,15.1966,0.08675}, + {1809,-0.6698,15.1963,0.08676}, + {1810,-0.6709,15.196,0.08678}, + {1811,-0.672,15.1958,0.08679}, + {1812,-0.6731,15.1955,0.0868}, + {1813,-0.6743,15.1952,0.08682}, + {1814,-0.6754,15.1949,0.08683}, + {1815,-0.6765,15.1947,0.08685}, + {1816,-0.6776,15.1944,0.08686}, + {1817,-0.6787,15.1941,0.08687}, + {1818,-0.6799,15.1938,0.08689}, + {1819,-0.681,15.1936,0.0869}, + {1820,-0.6821,15.1933,0.08691}, + {1821,-0.6833,15.193,0.08693}, + {1822,-0.6844,15.1928,0.08694}, + {1823,-0.6855,15.1925,0.08695}, + {1824,-0.6866,15.1922,0.08697}, + {1825,-0.6878,15.192,0.08698}, + {1826,-0.6889,15.1917,0.08699}, + {1827,-0.69,15.1914,0.08701}, + {1828,-0.6912,15.1912,0.08702}, + {1829,-0.6923,15.1909,0.08704}, + {1830,-0.6935,15.1906,0.08705}, + {1831,-0.6946,15.1904,0.08706}, + {1832,-0.6957,15.1901,0.08708}, + {1833,-0.6969,15.1899,0.08709}, + {1834,-0.698,15.1896,0.0871}, + {1835,-0.6992,15.1893,0.08712}, + {1836,-0.7003,15.1891,0.08713}, + {1837,-0.7015,15.1888,0.08714}, + {1838,-0.7026,15.1886,0.08716}, + {1839,-0.7038,15.1883,0.08717}, + {1840,-0.7049,15.188,0.08718}, + {1841,-0.7061,15.1878,0.0872}, + {1842,-0.7072,15.1875,0.08721}, + {1843,-0.7084,15.1873,0.08722}, + {1844,-0.7095,15.187,0.08724}, + {1845,-0.7107,15.1868,0.08725}, + {1846,-0.7118,15.1865,0.08727}, + {1847,-0.713,15.1863,0.08728}, + {1848,-0.7141,15.186,0.08729}, + {1849,-0.7153,15.1858,0.08731}, + {1850,-0.7165,15.1855,0.08732}, + {1851,-0.7176,15.1853,0.08733}, + {1852,-0.7188,15.185,0.08735}, + {1853,-0.72,15.1848,0.08736}, + {1854,-0.7211,15.1845,0.08737}, + {1855,-0.7223,15.1843,0.08739}, + {1856,-0.7235,15.184,0.0874} + }; + return data[index < data.length ? index : data.length]; + } + + public double[]getGirlsBMIForAge(int index){ + double[][]data = { + {0,-0.0631,13.3363,0.09272}, + {1,0.0362,13.3185,0.0936}, + {2,0.1355,13.3006,0.09448}, + {3,0.2347,13.2828,0.09535}, + {4,0.334,13.2649,0.09623}, + {5,0.4333,13.247,0.09711}, + {6,0.5326,13.2292,0.09799}, + {7,0.6319,13.2113,0.09887}, + {8,0.6142,13.2455,0.09866}, + {9,0.5965,13.2796,0.09845}, + {10,0.5789,13.3137,0.09824}, + {11,0.5612,13.3478,0.09804}, + {12,0.5435,13.3819,0.09783}, + {13,0.5258,13.416,0.09762}, + {14,0.5082,13.4501,0.09741}, + {15,0.4947,13.5169,0.09726}, + {16,0.482,13.5873,0.09711}, + {17,0.4699,13.6595,0.09697}, + {18,0.4583,13.7325,0.09684}, + {19,0.4472,13.8056,0.09671}, + {20,0.4365,13.8784,0.09659}, + {21,0.4263,13.9505,0.09647}, + {22,0.4164,14.0216,0.09636}, + {23,0.4069,14.0916,0.09625}, + {24,0.3977,14.1603,0.09615}, + {25,0.3888,14.2276,0.09605}, + {26,0.3802,14.2935,0.09595}, + {27,0.3718,14.3579,0.09586}, + {28,0.3637,14.4208,0.09577}, + {29,0.3558,14.4824,0.09568}, + {30,0.3481,14.5422,0.09559}, + {31,0.3406,14.6003,0.09551}, + {32,0.3333,14.6566,0.09543}, + {33,0.3262,14.7112,0.09535}, + {34,0.3192,14.7642,0.09527}, + {35,0.3124,14.8157,0.0952}, + {36,0.3058,14.8657,0.09513}, + {37,0.2993,14.9142,0.09506}, + {38,0.2929,14.9614,0.09499}, + {39,0.2867,15.0073,0.09492}, + {40,0.2806,15.052,0.09485}, + {41,0.2747,15.0955,0.09479}, + {42,0.2688,15.138,0.09472}, + {43,0.263,15.1794,0.09466}, + {44,0.2574,15.2198,0.0946}, + {45,0.2519,15.2591,0.09454}, + {46,0.2464,15.2974,0.09448}, + {47,0.2411,15.3347,0.09442}, + {48,0.2358,15.3709,0.09436}, + {49,0.2306,15.4063,0.09431}, + {50,0.2255,15.4408,0.09425}, + {51,0.2205,15.4744,0.0942}, + {52,0.2156,15.5072,0.09415}, + {53,0.2107,15.5393,0.0941}, + {54,0.2059,15.5706,0.09404}, + {55,0.2012,15.6012,0.09399}, + {56,0.1966,15.6311,0.09394}, + {57,0.192,15.6604,0.09389}, + {58,0.1875,15.689,0.09385}, + {59,0.183,15.717,0.0938}, + {60,0.1787,15.7444,0.09375}, + {61,0.1743,15.7713,0.09371}, + {62,0.17,15.7975,0.09366}, + {63,0.1658,15.8232,0.09361}, + {64,0.1617,15.8483,0.09357}, + {65,0.1575,15.8729,0.09353}, + {66,0.1535,15.8968,0.09348}, + {67,0.1495,15.9202,0.09344}, + {68,0.1455,15.9431,0.0934}, + {69,0.1416,15.9655,0.09336}, + {70,0.1377,15.9874,0.09332}, + {71,0.1339,16.0087,0.09328}, + {72,0.1301,16.0297,0.09324}, + {73,0.1263,16.0501,0.0932}, + {74,0.1226,16.0702,0.09316}, + {75,0.119,16.0897,0.09312}, + {76,0.1154,16.1089,0.09308}, + {77,0.1118,16.1277,0.09304}, + {78,0.1082,16.1461,0.093}, + {79,0.1047,16.164,0.09297}, + {80,0.1013,16.1817,0.09293}, + {81,0.0978,16.1989,0.09289}, + {82,0.0944,16.2158,0.09286}, + {83,0.0911,16.2323,0.09282}, + {84,0.0877,16.2485,0.09279}, + {85,0.0844,16.2644,0.09275}, + {86,0.0811,16.28,0.09272}, + {87,0.0779,16.2952,0.09268}, + {88,0.0747,16.3101,0.09265}, + {89,0.0715,16.3247,0.09262}, + {90,0.0684,16.339,0.09258}, + {91,0.0652,16.3531,0.09255}, + {92,0.0621,16.3668,0.09252}, + {93,0.0591,16.3803,0.09249}, + {94,0.056,16.3935,0.09245}, + {95,0.053,16.4065,0.09242}, + {96,0.05,16.4192,0.09239}, + {97,0.0471,16.4316,0.09236}, + {98,0.0442,16.4438,0.09233}, + {99,0.0412,16.4557,0.0923}, + {100,0.0384,16.4673,0.09227}, + {101,0.0355,16.4788,0.09224}, + {102,0.0327,16.49,0.09221}, + {103,0.0298,16.5009,0.09218}, + {104,0.027,16.5117,0.09215}, + {105,0.0243,16.5222,0.09212}, + {106,0.0215,16.5325,0.09209}, + {107,0.0188,16.5426,0.09206}, + {108,0.0161,16.5525,0.09203}, + {109,0.0134,16.5622,0.09201}, + {110,0.0107,16.5717,0.09198}, + {111,0.0081,16.581,0.09195}, + {112,0.0055,16.5901,0.09192}, + {113,0.0029,16.5991,0.09189}, + {114,0.0003,16.6078,0.09187}, + {115,-0.0023,16.6164,0.09184}, + {116,-0.0048,16.6249,0.09181}, + {117,-0.0074,16.6331,0.09179}, + {118,-0.0099,16.6412,0.09176}, + {119,-0.0124,16.6492,0.09173}, + {120,-0.0148,16.657,0.09171}, + {121,-0.0173,16.6647,0.09168}, + {122,-0.0197,16.6722,0.09166}, + {123,-0.0222,16.6795,0.09163}, + {124,-0.0246,16.6868,0.09161}, + {125,-0.027,16.6939,0.09158}, + {126,-0.0293,16.7009,0.09156}, + {127,-0.0317,16.7077,0.09153}, + {128,-0.034,16.7144,0.09151}, + {129,-0.0364,16.721,0.09148}, + {130,-0.0387,16.7274,0.09146}, + {131,-0.041,16.7337,0.09143}, + {132,-0.0433,16.7399,0.09141}, + {133,-0.0455,16.746,0.09139}, + {134,-0.0478,16.7519,0.09136}, + {135,-0.05,16.7577,0.09134}, + {136,-0.0522,16.7634,0.09131}, + {137,-0.0545,16.7689,0.09129}, + {138,-0.0566,16.7743,0.09127}, + {139,-0.0588,16.7797,0.09125}, + {140,-0.061,16.7848,0.09122}, + {141,-0.0632,16.7899,0.0912}, + {142,-0.0653,16.7948,0.09118}, + {143,-0.0674,16.7997,0.09116}, + {144,-0.0696,16.8044,0.09113}, + {145,-0.0717,16.809,0.09111}, + {146,-0.0737,16.8134,0.09109}, + {147,-0.0758,16.8178,0.09107}, + {148,-0.0779,16.822,0.09104}, + {149,-0.08,16.8262,0.09102}, + {150,-0.082,16.8302,0.091}, + {151,-0.084,16.8341,0.09098}, + {152,-0.086,16.8379,0.09096}, + {153,-0.0881,16.8416,0.09094}, + {154,-0.0901,16.8452,0.09092}, + {155,-0.092,16.8487,0.0909}, + {156,-0.094,16.8521,0.09088}, + {157,-0.096,16.8554,0.09085}, + {158,-0.0979,16.8586,0.09083}, + {159,-0.0999,16.8617,0.09081}, + {160,-0.1018,16.8648,0.09079}, + {161,-0.1037,16.8677,0.09077}, + {162,-0.1056,16.8705,0.09075}, + {163,-0.1075,16.8732,0.09073}, + {164,-0.1094,16.8759,0.09071}, + {165,-0.1113,16.8784,0.09069}, + {166,-0.1132,16.8808,0.09067}, + {167,-0.115,16.8832,0.09065}, + {168,-0.1169,16.8854,0.09063}, + {169,-0.1187,16.8876,0.09061}, + {170,-0.1206,16.8897,0.09059}, + {171,-0.1224,16.8917,0.09058}, + {172,-0.1242,16.8936,0.09056}, + {173,-0.126,16.8954,0.09054}, + {174,-0.1278,16.8971,0.09052}, + {175,-0.1296,16.8987,0.0905}, + {176,-0.1314,16.9002,0.09048}, + {177,-0.1331,16.9017,0.09046}, + {178,-0.1349,16.9031,0.09044}, + {179,-0.1366,16.9043,0.09043}, + {180,-0.1384,16.9055,0.09041}, + {181,-0.1401,16.9066,0.09039}, + {182,-0.1418,16.9077,0.09037}, + {183,-0.1436,16.9086,0.09035}, + {184,-0.1453,16.9095,0.09033}, + {185,-0.147,16.9102,0.09032}, + {186,-0.1487,16.9109,0.0903}, + {187,-0.1503,16.9116,0.09028}, + {188,-0.152,16.9121,0.09026}, + {189,-0.1537,16.9125,0.09024}, + {190,-0.1554,16.9129,0.09023}, + {191,-0.157,16.9132,0.09021}, + {192,-0.1587,16.9135,0.09019}, + {193,-0.1603,16.9136,0.09017}, + {194,-0.1619,16.9137,0.09016}, + {195,-0.1635,16.9137,0.09014}, + {196,-0.1652,16.9136,0.09012}, + {197,-0.1668,16.9135,0.09011}, + {198,-0.1684,16.9133,0.09009}, + {199,-0.17,16.913,0.09007}, + {200,-0.1715,16.9127,0.09006}, + {201,-0.1731,16.9122,0.09004}, + {202,-0.1747,16.9118,0.09002}, + {203,-0.1763,16.9112,0.09001}, + {204,-0.1778,16.9106,0.08999}, + {205,-0.1794,16.9099,0.08997}, + {206,-0.1809,16.9091,0.08996}, + {207,-0.1824,16.9083,0.08994}, + {208,-0.184,16.9074,0.08992}, + {209,-0.1855,16.9065,0.08991}, + {210,-0.187,16.9055,0.08989}, + {211,-0.1885,16.9044,0.08988}, + {212,-0.19,16.9033,0.08986}, + {213,-0.1915,16.9021,0.08984}, + {214,-0.193,16.9008,0.08983}, + {215,-0.1945,16.8995,0.08981}, + {216,-0.196,16.8981,0.0898}, + {217,-0.1975,16.8967,0.08978}, + {218,-0.1989,16.8952,0.08976}, + {219,-0.2004,16.8937,0.08975}, + {220,-0.2018,16.8921,0.08973}, + {221,-0.2033,16.8905,0.08972}, + {222,-0.2047,16.8888,0.0897}, + {223,-0.2062,16.887,0.08969}, + {224,-0.2076,16.8852,0.08967}, + {225,-0.209,16.8834,0.08966}, + {226,-0.2104,16.8814,0.08964}, + {227,-0.2119,16.8795,0.08963}, + {228,-0.2133,16.8775,0.08961}, + {229,-0.2147,16.8754,0.0896}, + {230,-0.2161,16.8733,0.08958}, + {231,-0.2175,16.8712,0.08957}, + {232,-0.2188,16.869,0.08955}, + {233,-0.2202,16.8667,0.08954}, + {234,-0.2216,16.8644,0.08952}, + {235,-0.223,16.8621,0.08951}, + {236,-0.2243,16.8597,0.08949}, + {237,-0.2257,16.8572,0.08948}, + {238,-0.227,16.8548,0.08947}, + {239,-0.2284,16.8522,0.08945}, + {240,-0.2297,16.8497,0.08944}, + {241,-0.2311,16.8471,0.08942}, + {242,-0.2324,16.8444,0.08941}, + {243,-0.2337,16.8417,0.08939}, + {244,-0.2351,16.839,0.08938}, + {245,-0.2364,16.8362,0.08937}, + {246,-0.2377,16.8334,0.08935}, + {247,-0.239,16.8305,0.08934}, + {248,-0.2403,16.8276,0.08932}, + {249,-0.2416,16.8247,0.08931}, + {250,-0.2429,16.8217,0.0893}, + {251,-0.2442,16.8187,0.08928}, + {252,-0.2455,16.8157,0.08927}, + {253,-0.2467,16.8126,0.08926}, + {254,-0.248,16.8095,0.08924}, + {255,-0.2493,16.8063,0.08923}, + {256,-0.2505,16.8031,0.08921}, + {257,-0.2518,16.7999,0.0892}, + {258,-0.2531,16.7967,0.08919}, + {259,-0.2543,16.7934,0.08917}, + {260,-0.2556,16.79,0.08916}, + {261,-0.2568,16.7867,0.08915}, + {262,-0.258,16.7833,0.08913}, + {263,-0.2593,16.7799,0.08912}, + {264,-0.2605,16.7764,0.08911}, + {265,-0.2617,16.773,0.08909}, + {266,-0.263,16.7695,0.08908}, + {267,-0.2642,16.7659,0.08907}, + {268,-0.2654,16.7624,0.08906}, + {269,-0.2666,16.7588,0.08904}, + {270,-0.2678,16.7551,0.08903}, + {271,-0.269,16.7515,0.08902}, + {272,-0.2702,16.7478,0.089}, + {273,-0.2714,16.7441,0.08899}, + {274,-0.2726,16.7404,0.08898}, + {275,-0.2737,16.7367,0.08897}, + {276,-0.2749,16.7329,0.08895}, + {277,-0.2761,16.7291,0.08894}, + {278,-0.2773,16.7253,0.08893}, + {279,-0.2784,16.7214,0.08892}, + {280,-0.2796,16.7176,0.0889}, + {281,-0.2808,16.7137,0.08889}, + {282,-0.2819,16.7098,0.08888}, + {283,-0.2831,16.7059,0.08887}, + {284,-0.2842,16.7019,0.08885}, + {285,-0.2854,16.698,0.08884}, + {286,-0.2865,16.694,0.08883}, + {287,-0.2876,16.69,0.08882}, + {288,-0.2888,16.686,0.08881}, + {289,-0.2899,16.682,0.08879}, + {290,-0.291,16.6779,0.08878}, + {291,-0.2922,16.6739,0.08877}, + {292,-0.2933,16.6698,0.08876}, + {293,-0.2944,16.6657,0.08874}, + {294,-0.2955,16.6616,0.08873}, + {295,-0.2966,16.6575,0.08872}, + {296,-0.2977,16.6534,0.08871}, + {297,-0.2988,16.6492,0.0887}, + {298,-0.2999,16.6451,0.08869}, + {299,-0.301,16.6409,0.08867}, + {300,-0.3021,16.6367,0.08866}, + {301,-0.3032,16.6326,0.08865}, + {302,-0.3043,16.6284,0.08864}, + {303,-0.3053,16.6242,0.08863}, + {304,-0.3064,16.62,0.08862}, + {305,-0.3075,16.6157,0.0886}, + {306,-0.3086,16.6115,0.08859}, + {307,-0.3096,16.6073,0.08858}, + {308,-0.3107,16.603,0.08857}, + {309,-0.3118,16.5988,0.08856}, + {310,-0.3128,16.5945,0.08855}, + {311,-0.3139,16.5903,0.08854}, + {312,-0.3149,16.586,0.08852}, + {313,-0.316,16.5817,0.08851}, + {314,-0.317,16.5774,0.0885}, + {315,-0.3181,16.5731,0.08849}, + {316,-0.3191,16.5688,0.08848}, + {317,-0.3201,16.5645,0.08847}, + {318,-0.3212,16.5602,0.08846}, + {319,-0.3222,16.5559,0.08845}, + {320,-0.3232,16.5516,0.08843}, + {321,-0.3242,16.5473,0.08842}, + {322,-0.3253,16.543,0.08841}, + {323,-0.3263,16.5387,0.0884}, + {324,-0.3273,16.5343,0.08839}, + {325,-0.3283,16.53,0.08838}, + {326,-0.3293,16.5257,0.08837}, + {327,-0.3303,16.5213,0.08836}, + {328,-0.3313,16.517,0.08835}, + {329,-0.3323,16.5127,0.08834}, + {330,-0.3333,16.5083,0.08833}, + {331,-0.3343,16.504,0.08832}, + {332,-0.3353,16.4997,0.0883}, + {333,-0.3363,16.4953,0.08829}, + {334,-0.3373,16.491,0.08828}, + {335,-0.3382,16.4867,0.08827}, + {336,-0.3392,16.4823,0.08826}, + {337,-0.3402,16.478,0.08825}, + {338,-0.3412,16.4737,0.08824}, + {339,-0.3421,16.4693,0.08823}, + {340,-0.3431,16.465,0.08822}, + {341,-0.3441,16.4607,0.08821}, + {342,-0.345,16.4563,0.0882}, + {343,-0.346,16.452,0.08819}, + {344,-0.347,16.4477,0.08818}, + {345,-0.3479,16.4434,0.08817}, + {346,-0.3489,16.4391,0.08816}, + {347,-0.3498,16.4347,0.08815}, + {348,-0.3508,16.4304,0.08814}, + {349,-0.3517,16.4261,0.08813}, + {350,-0.3526,16.4218,0.08812}, + {351,-0.3536,16.4175,0.08811}, + {352,-0.3545,16.4132,0.0881}, + {353,-0.3555,16.4089,0.08809}, + {354,-0.3564,16.4046,0.08808}, + {355,-0.3573,16.4004,0.08807}, + {356,-0.3582,16.3961,0.08806}, + {357,-0.3592,16.3918,0.08805}, + {358,-0.3601,16.3875,0.08804}, + {359,-0.361,16.3833,0.08803}, + {360,-0.3619,16.379,0.08802}, + {361,-0.3628,16.3748,0.08801}, + {362,-0.3638,16.3705,0.088}, + {363,-0.3647,16.3663,0.08799}, + {364,-0.3656,16.3621,0.08798}, + {365,-0.3665,16.3578,0.08797}, + {366,-0.3674,16.3536,0.08796}, + {367,-0.3683,16.3494,0.08795}, + {368,-0.3692,16.3452,0.08794}, + {369,-0.3701,16.341,0.08793}, + {370,-0.371,16.3368,0.08792}, + {371,-0.3719,16.3326,0.08791}, + {372,-0.3727,16.3284,0.0879}, + {373,-0.3736,16.3242,0.08789}, + {374,-0.3745,16.32,0.08788}, + {375,-0.3754,16.3158,0.08787}, + {376,-0.3763,16.3117,0.08786}, + {377,-0.3772,16.3075,0.08785}, + {378,-0.378,16.3034,0.08784}, + {379,-0.3789,16.2992,0.08783}, + {380,-0.3798,16.2951,0.08782}, + {381,-0.3806,16.291,0.08782}, + {382,-0.3815,16.2868,0.08781}, + {383,-0.3824,16.2827,0.0878}, + {384,-0.3832,16.2786,0.08779}, + {385,-0.3841,16.2745,0.08778}, + {386,-0.385,16.2704,0.08777}, + {387,-0.3858,16.2663,0.08776}, + {388,-0.3867,16.2622,0.08775}, + {389,-0.3875,16.2582,0.08774}, + {390,-0.3884,16.2541,0.08773}, + {391,-0.3892,16.25,0.08772}, + {392,-0.3901,16.246,0.08771}, + {393,-0.3909,16.2419,0.0877}, + {394,-0.3917,16.2379,0.08769}, + {395,-0.3926,16.2339,0.08769}, + {396,-0.3934,16.2298,0.08768}, + {397,-0.3943,16.2258,0.08767}, + {398,-0.3951,16.2218,0.08766}, + {399,-0.3959,16.2178,0.08765}, + {400,-0.3968,16.2138,0.08764}, + {401,-0.3976,16.2099,0.08763}, + {402,-0.3984,16.2059,0.08762}, + {403,-0.3992,16.2019,0.08761}, + {404,-0.4001,16.198,0.08761}, + {405,-0.4009,16.194,0.0876}, + {406,-0.4017,16.1901,0.08759}, + {407,-0.4025,16.1862,0.08758}, + {408,-0.4033,16.1822,0.08757}, + {409,-0.4041,16.1783,0.08756}, + {410,-0.4049,16.1744,0.08755}, + {411,-0.4057,16.1705,0.08754}, + {412,-0.4066,16.1667,0.08753}, + {413,-0.4074,16.1628,0.08753}, + {414,-0.4082,16.1589,0.08752}, + {415,-0.409,16.1551,0.08751}, + {416,-0.4098,16.1512,0.0875}, + {417,-0.4106,16.1474,0.08749}, + {418,-0.4114,16.1435,0.08748}, + {419,-0.4121,16.1397,0.08747}, + {420,-0.4129,16.1359,0.08747}, + {421,-0.4137,16.1321,0.08746}, + {422,-0.4145,16.1283,0.08745}, + {423,-0.4153,16.1245,0.08744}, + {424,-0.4161,16.1207,0.08743}, + {425,-0.4169,16.117,0.08742}, + {426,-0.4176,16.1132,0.08741}, + {427,-0.4184,16.1095,0.08741}, + {428,-0.4192,16.1057,0.0874}, + {429,-0.42,16.102,0.08739}, + {430,-0.4208,16.0983,0.08738}, + {431,-0.4215,16.0946,0.08737}, + {432,-0.4223,16.0909,0.08736}, + {433,-0.4231,16.0872,0.08736}, + {434,-0.4238,16.0835,0.08735}, + {435,-0.4246,16.0798,0.08734}, + {436,-0.4254,16.0762,0.08733}, + {437,-0.4261,16.0725,0.08732}, + {438,-0.4269,16.0689,0.08731}, + {439,-0.4276,16.0652,0.08731}, + {440,-0.4284,16.0616,0.0873}, + {441,-0.4292,16.058,0.08729}, + {442,-0.4299,16.0544,0.08728}, + {443,-0.4307,16.0508,0.08727}, + {444,-0.4314,16.0472,0.08727}, + {445,-0.4322,16.0436,0.08726}, + {446,-0.4329,16.04,0.08725}, + {447,-0.4337,16.0365,0.08724}, + {448,-0.4344,16.0329,0.08723}, + {449,-0.4351,16.0294,0.08722}, + {450,-0.4359,16.0258,0.08722}, + {451,-0.4366,16.0223,0.08721}, + {452,-0.4374,16.0188,0.0872}, + {453,-0.4381,16.0153,0.08719}, + {454,-0.4388,16.0118,0.08718}, + {455,-0.4396,16.0083,0.08718}, + {456,-0.4403,16.0048,0.08717}, + {457,-0.441,16.0013,0.08716}, + {458,-0.4418,15.9979,0.08715}, + {459,-0.4425,15.9944,0.08714}, + {460,-0.4432,15.991,0.08714}, + {461,-0.4439,15.9875,0.08713}, + {462,-0.4447,15.9841,0.08712}, + {463,-0.4454,15.9807,0.08711}, + {464,-0.4461,15.9773,0.08711}, + {465,-0.4468,15.9739,0.0871}, + {466,-0.4475,15.9705,0.08709}, + {467,-0.4482,15.9671,0.08708}, + {468,-0.449,15.9638,0.08707}, + {469,-0.4497,15.9604,0.08707}, + {470,-0.4504,15.9571,0.08706}, + {471,-0.4511,15.9537,0.08705}, + {472,-0.4518,15.9504,0.08704}, + {473,-0.4525,15.9471,0.08704}, + {474,-0.4532,15.9438,0.08703}, + {475,-0.4539,15.9405,0.08702}, + {476,-0.4546,15.9372,0.08701}, + {477,-0.4553,15.9339,0.08701}, + {478,-0.456,15.9307,0.087}, + {479,-0.4567,15.9274,0.08699}, + {480,-0.4574,15.9241,0.08698}, + {481,-0.4581,15.9209,0.08698}, + {482,-0.4588,15.9177,0.08697}, + {483,-0.4595,15.9145,0.08696}, + {484,-0.4602,15.9112,0.08695}, + {485,-0.4609,15.908,0.08695}, + {486,-0.4616,15.9049,0.08694}, + {487,-0.4623,15.9017,0.08693}, + {488,-0.4629,15.8985,0.08692}, + {489,-0.4636,15.8953,0.08692}, + {490,-0.4643,15.8922,0.08691}, + {491,-0.465,15.8891,0.0869}, + {492,-0.4657,15.8859,0.08689}, + {493,-0.4663,15.8828,0.08689}, + {494,-0.467,15.8797,0.08688}, + {495,-0.4677,15.8766,0.08687}, + {496,-0.4684,15.8735,0.08686}, + {497,-0.469,15.8704,0.08686}, + {498,-0.4697,15.8673,0.08685}, + {499,-0.4704,15.8643,0.08684}, + {500,-0.4711,15.8612,0.08683}, + {501,-0.4717,15.8582,0.08683}, + {502,-0.4724,15.8552,0.08682}, + {503,-0.4731,15.8521,0.08681}, + {504,-0.4737,15.8491,0.08681}, + {505,-0.4744,15.8461,0.0868}, + {506,-0.4751,15.8431,0.08679}, + {507,-0.4757,15.8401,0.08678}, + {508,-0.4764,15.8372,0.08678}, + {509,-0.477,15.8342,0.08677}, + {510,-0.4777,15.8313,0.08676}, + {511,-0.4783,15.8283,0.08676}, + {512,-0.479,15.8254,0.08675}, + {513,-0.4797,15.8224,0.08674}, + {514,-0.4803,15.8195,0.08673}, + {515,-0.481,15.8166,0.08673}, + {516,-0.4816,15.8137,0.08672}, + {517,-0.4823,15.8108,0.08671}, + {518,-0.4829,15.808,0.08671}, + {519,-0.4836,15.8051,0.0867}, + {520,-0.4842,15.8022,0.08669}, + {521,-0.4848,15.7994,0.08668}, + {522,-0.4855,15.7965,0.08668}, + {523,-0.4861,15.7937,0.08667}, + {524,-0.4868,15.7909,0.08666}, + {525,-0.4874,15.7881,0.08666}, + {526,-0.488,15.7853,0.08665}, + {527,-0.4887,15.7825,0.08664}, + {528,-0.4893,15.7797,0.08664}, + {529,-0.49,15.7769,0.08663}, + {530,-0.4906,15.7742,0.08662}, + {531,-0.4912,15.7714,0.08662}, + {532,-0.4919,15.7687,0.08661}, + {533,-0.4925,15.7659,0.0866}, + {534,-0.4931,15.7632,0.0866}, + {535,-0.4937,15.7605,0.08659}, + {536,-0.4944,15.7578,0.08658}, + {537,-0.495,15.7551,0.08657}, + {538,-0.4956,15.7524,0.08657}, + {539,-0.4962,15.7497,0.08656}, + {540,-0.4969,15.747,0.08655}, + {541,-0.4975,15.7444,0.08655}, + {542,-0.4981,15.7417,0.08654}, + {543,-0.4987,15.7391,0.08653}, + {544,-0.4993,15.7364,0.08653}, + {545,-0.5,15.7338,0.08652}, + {546,-0.5006,15.7312,0.08651}, + {547,-0.5012,15.7286,0.08651}, + {548,-0.5018,15.726,0.0865}, + {549,-0.5024,15.7234,0.08649}, + {550,-0.503,15.7208,0.08649}, + {551,-0.5036,15.7183,0.08648}, + {552,-0.5043,15.7157,0.08647}, + {553,-0.5049,15.7132,0.08647}, + {554,-0.5055,15.7106,0.08646}, + {555,-0.5061,15.7081,0.08645}, + {556,-0.5067,15.7056,0.08645}, + {557,-0.5073,15.703,0.08644}, + {558,-0.5079,15.7005,0.08643}, + {559,-0.5085,15.698,0.08643}, + {560,-0.5091,15.6956,0.08642}, + {561,-0.5097,15.6931,0.08642}, + {562,-0.5103,15.6906,0.08641}, + {563,-0.5109,15.6882,0.0864}, + {564,-0.5115,15.6857,0.0864}, + {565,-0.5121,15.6833,0.08639}, + {566,-0.5127,15.6808,0.08638}, + {567,-0.5133,15.6784,0.08638}, + {568,-0.5139,15.676,0.08637}, + {569,-0.5145,15.6736,0.08636}, + {570,-0.5151,15.6712,0.08636}, + {571,-0.5156,15.6688,0.08635}, + {572,-0.5162,15.6665,0.08634}, + {573,-0.5168,15.6641,0.08634}, + {574,-0.5174,15.6617,0.08633}, + {575,-0.518,15.6594,0.08632}, + {576,-0.5186,15.6571,0.08632}, + {577,-0.5192,15.6547,0.08631}, + {578,-0.5197,15.6524,0.08631}, + {579,-0.5203,15.6501,0.0863}, + {580,-0.5209,15.6478,0.08629}, + {581,-0.5215,15.6455,0.08629}, + {582,-0.5221,15.6432,0.08628}, + {583,-0.5226,15.6409,0.08627}, + {584,-0.5232,15.6387,0.08627}, + {585,-0.5238,15.6364,0.08626}, + {586,-0.5244,15.6342,0.08626}, + {587,-0.525,15.6319,0.08625}, + {588,-0.5255,15.6297,0.08624}, + {589,-0.5261,15.6275,0.08624}, + {590,-0.5267,15.6253,0.08623}, + {591,-0.5272,15.6231,0.08622}, + {592,-0.5278,15.6209,0.08622}, + {593,-0.5284,15.6187,0.08621}, + {594,-0.529,15.6165,0.08621}, + {595,-0.5295,15.6144,0.0862}, + {596,-0.5301,15.6122,0.08619}, + {597,-0.5307,15.61,0.08619}, + {598,-0.5312,15.6079,0.08618}, + {599,-0.5318,15.6058,0.08618}, + {600,-0.5323,15.6037,0.08617}, + {601,-0.5329,15.6015,0.08616}, + {602,-0.5335,15.5994,0.08616}, + {603,-0.534,15.5973,0.08615}, + {604,-0.5346,15.5953,0.08614}, + {605,-0.5351,15.5932,0.08614}, + {606,-0.5357,15.5911,0.08613}, + {607,-0.5363,15.589,0.08613}, + {608,-0.5368,15.587,0.08612}, + {609,-0.5374,15.585,0.08611}, + {610,-0.5379,15.5829,0.08611}, + {611,-0.5385,15.5809,0.0861}, + {612,-0.539,15.5789,0.0861}, + {613,-0.5396,15.5769,0.08609}, + {614,-0.5401,15.5749,0.08608}, + {615,-0.5407,15.5729,0.08608}, + {616,-0.5412,15.5709,0.08607}, + {617,-0.5418,15.569,0.08607}, + {618,-0.5423,15.567,0.08606}, + {619,-0.5429,15.5651,0.08605}, + {620,-0.5434,15.5631,0.08605}, + {621,-0.544,15.5612,0.08604}, + {622,-0.5445,15.5593,0.08604}, + {623,-0.5451,15.5574,0.08603}, + {624,-0.5456,15.5555,0.08603}, + {625,-0.5461,15.5536,0.08602}, + {626,-0.5467,15.5517,0.08601}, + {627,-0.5472,15.5498,0.08601}, + {628,-0.5478,15.548,0.086}, + {629,-0.5483,15.5461,0.086}, + {630,-0.5488,15.5443,0.08599}, + {631,-0.5494,15.5424,0.08598}, + {632,-0.5499,15.5406,0.08598}, + {633,-0.5504,15.5388,0.08597}, + {634,-0.551,15.537,0.08597}, + {635,-0.5515,15.5352,0.08596}, + {636,-0.552,15.5334,0.08596}, + {637,-0.5526,15.5316,0.08595}, + {638,-0.5531,15.5299,0.08594}, + {639,-0.5536,15.5281,0.08594}, + {640,-0.5542,15.5263,0.08593}, + {641,-0.5547,15.5246,0.08593}, + {642,-0.5552,15.5229,0.08592}, + {643,-0.5557,15.5212,0.08591}, + {644,-0.5563,15.5194,0.08591}, + {645,-0.5568,15.5177,0.0859}, + {646,-0.5573,15.5161,0.0859}, + {647,-0.5578,15.5144,0.08589}, + {648,-0.5584,15.5127,0.08589}, + {649,-0.5589,15.511,0.08588}, + {650,-0.5594,15.5094,0.08587}, + {651,-0.5599,15.5077,0.08587}, + {652,-0.5605,15.5061,0.08586}, + {653,-0.561,15.5045,0.08586}, + {654,-0.5615,15.5028,0.08585}, + {655,-0.562,15.5012,0.08585}, + {656,-0.5625,15.4996,0.08584}, + {657,-0.563,15.498,0.08584}, + {658,-0.5636,15.4965,0.08583}, + {659,-0.5641,15.4949,0.08582}, + {660,-0.5646,15.4933,0.08582}, + {661,-0.5651,15.4918,0.08581}, + {662,-0.5656,15.4902,0.08581}, + {663,-0.5661,15.4887,0.0858}, + {664,-0.5666,15.4872,0.0858}, + {665,-0.5672,15.4856,0.08579}, + {666,-0.5677,15.4841,0.08579}, + {667,-0.5682,15.4826,0.08578}, + {668,-0.5687,15.4811,0.08577}, + {669,-0.5692,15.4797,0.08577}, + {670,-0.5697,15.4782,0.08576}, + {671,-0.5702,15.4767,0.08576}, + {672,-0.5707,15.4753,0.08575}, + {673,-0.5712,15.4738,0.08575}, + {674,-0.5717,15.4724,0.08574}, + {675,-0.5722,15.471,0.08574}, + {676,-0.5727,15.4695,0.08573}, + {677,-0.5732,15.4681,0.08573}, + {678,-0.5737,15.4667,0.08572}, + {679,-0.5742,15.4653,0.08571}, + {680,-0.5747,15.4639,0.08571}, + {681,-0.5752,15.4626,0.0857}, + {682,-0.5757,15.4612,0.0857}, + {683,-0.5762,15.4598,0.08569}, + {684,-0.5767,15.4585,0.08569}, + {685,-0.5772,15.4572,0.08568}, + {686,-0.5777,15.4558,0.08568}, + {687,-0.5782,15.4545,0.08567}, + {688,-0.5787,15.4532,0.08567}, + {689,-0.5792,15.4519,0.08566}, + {690,-0.5797,15.4506,0.08565}, + {691,-0.5802,15.4493,0.08565}, + {692,-0.5807,15.448,0.08564}, + {693,-0.5812,15.4467,0.08564}, + {694,-0.5817,15.4455,0.08563}, + {695,-0.5821,15.4442,0.08563}, + {696,-0.5826,15.443,0.08562}, + {697,-0.5831,15.4417,0.08562}, + {698,-0.5836,15.4405,0.08561}, + {699,-0.5841,15.4393,0.08561}, + {700,-0.5846,15.4381,0.0856}, + {701,-0.5851,15.4368,0.0856}, + {702,-0.5855,15.4356,0.08559}, + {703,-0.586,15.4345,0.08559}, + {704,-0.5865,15.4333,0.08558}, + {705,-0.587,15.4321,0.08558}, + {706,-0.5875,15.4309,0.08557}, + {707,-0.588,15.4298,0.08556}, + {708,-0.5884,15.4286,0.08556}, + {709,-0.5889,15.4275,0.08555}, + {710,-0.5894,15.4263,0.08555}, + {711,-0.5899,15.4252,0.08554}, + {712,-0.5904,15.4241,0.08554}, + {713,-0.5908,15.423,0.08553}, + {714,-0.5913,15.4219,0.08553}, + {715,-0.5918,15.4208,0.08552}, + {716,-0.5923,15.4197,0.08552}, + {717,-0.5927,15.4186,0.08551}, + {718,-0.5932,15.4175,0.08551}, + {719,-0.5937,15.4164,0.0855}, + {720,-0.5942,15.4154,0.0855}, + {721,-0.5946,15.4143,0.08549}, + {722,-0.5951,15.4133,0.08549}, + {723,-0.5956,15.4122,0.08548}, + {724,-0.5961,15.4112,0.08548}, + {725,-0.5965,15.4102,0.08547}, + {726,-0.597,15.4092,0.08547}, + {727,-0.5975,15.4082,0.08546}, + {728,-0.5979,15.4072,0.08546}, + {729,-0.5984,15.4062,0.08545}, + {730,-0.5989,15.4052,0.08545}, + {731,-0.5684,15.6881,0.08454}, + {732,-0.5684,15.6871,0.08454}, + {733,-0.5684,15.6861,0.08454}, + {734,-0.5684,15.6851,0.08454}, + {735,-0.5684,15.6841,0.08454}, + {736,-0.5684,15.6831,0.08454}, + {737,-0.5684,15.6822,0.08454}, + {738,-0.5684,15.6812,0.08454}, + {739,-0.5684,15.6802,0.08454}, + {740,-0.5684,15.6792,0.08454}, + {741,-0.5684,15.6782,0.08454}, + {742,-0.5684,15.6772,0.08454}, + {743,-0.5684,15.6763,0.08454}, + {744,-0.5684,15.6753,0.08454}, + {745,-0.5684,15.6743,0.08453}, + {746,-0.5684,15.6733,0.08453}, + {747,-0.5684,15.6724,0.08453}, + {748,-0.5684,15.6714,0.08453}, + {749,-0.5684,15.6704,0.08453}, + {750,-0.5684,15.6695,0.08453}, + {751,-0.5684,15.6685,0.08453}, + {752,-0.5684,15.6675,0.08453}, + {753,-0.5684,15.6666,0.08453}, + {754,-0.5684,15.6656,0.08453}, + {755,-0.5684,15.6646,0.08453}, + {756,-0.5684,15.6637,0.08453}, + {757,-0.5684,15.6627,0.08452}, + {758,-0.5684,15.6618,0.08452}, + {759,-0.5684,15.6608,0.08452}, + {760,-0.5684,15.6599,0.08452}, + {761,-0.5684,15.6589,0.08452}, + {762,-0.5684,15.658,0.08452}, + {763,-0.5684,15.657,0.08452}, + {764,-0.5684,15.6561,0.08452}, + {765,-0.5684,15.6551,0.08452}, + {766,-0.5684,15.6542,0.08452}, + {767,-0.5684,15.6532,0.08451}, + {768,-0.5684,15.6523,0.08451}, + {769,-0.5684,15.6514,0.08451}, + {770,-0.5684,15.6504,0.08451}, + {771,-0.5684,15.6495,0.08451}, + {772,-0.5684,15.6486,0.08451}, + {773,-0.5684,15.6476,0.08451}, + {774,-0.5684,15.6467,0.08451}, + {775,-0.5684,15.6458,0.08451}, + {776,-0.5684,15.6448,0.08451}, + {777,-0.5684,15.6439,0.08451}, + {778,-0.5684,15.643,0.0845}, + {779,-0.5684,15.6421,0.0845}, + {780,-0.5684,15.6411,0.0845}, + {781,-0.5684,15.6402,0.0845}, + {782,-0.5684,15.6393,0.0845}, + {783,-0.5684,15.6384,0.0845}, + {784,-0.5684,15.6375,0.0845}, + {785,-0.5684,15.6366,0.0845}, + {786,-0.5684,15.6356,0.0845}, + {787,-0.5684,15.6347,0.0845}, + {788,-0.5684,15.6338,0.08449}, + {789,-0.5684,15.6329,0.08449}, + {790,-0.5684,15.632,0.08449}, + {791,-0.5684,15.6311,0.08449}, + {792,-0.5684,15.6302,0.08449}, + {793,-0.5684,15.6293,0.08449}, + {794,-0.5684,15.6284,0.08449}, + {795,-0.5684,15.6275,0.08449}, + {796,-0.5684,15.6266,0.08449}, + {797,-0.5684,15.6257,0.08449}, + {798,-0.5684,15.6248,0.08448}, + {799,-0.5684,15.6239,0.08448}, + {800,-0.5684,15.623,0.08448}, + {801,-0.5684,15.6221,0.08448}, + {802,-0.5684,15.6212,0.08448}, + {803,-0.5684,15.6203,0.08448}, + {804,-0.5684,15.6194,0.08448}, + {805,-0.5684,15.6185,0.08448}, + {806,-0.5684,15.6176,0.08448}, + {807,-0.5684,15.6168,0.08448}, + {808,-0.5684,15.6159,0.08447}, + {809,-0.5684,15.615,0.08447}, + {810,-0.5684,15.6141,0.08447}, + {811,-0.5684,15.6132,0.08447}, + {812,-0.5684,15.6123,0.08447}, + {813,-0.5684,15.6115,0.08447}, + {814,-0.5684,15.6106,0.08447}, + {815,-0.5684,15.6097,0.08447}, + {816,-0.5684,15.6088,0.08447}, + {817,-0.5684,15.6079,0.08447}, + {818,-0.5684,15.6071,0.08447}, + {819,-0.5684,15.6062,0.08447}, + {820,-0.5684,15.6053,0.08446}, + {821,-0.5684,15.6044,0.08446}, + {822,-0.5684,15.6036,0.08446}, + {823,-0.5684,15.6027,0.08446}, + {824,-0.5684,15.6018,0.08446}, + {825,-0.5684,15.601,0.08446}, + {826,-0.5684,15.6001,0.08446}, + {827,-0.5684,15.5992,0.08446}, + {828,-0.5684,15.5984,0.08446}, + {829,-0.5684,15.5975,0.08446}, + {830,-0.5684,15.5966,0.08446}, + {831,-0.5684,15.5958,0.08446}, + {832,-0.5684,15.5949,0.08445}, + {833,-0.5684,15.5941,0.08445}, + {834,-0.5684,15.5932,0.08445}, + {835,-0.5684,15.5923,0.08445}, + {836,-0.5684,15.5915,0.08445}, + {837,-0.5684,15.5906,0.08445}, + {838,-0.5684,15.5898,0.08445}, + {839,-0.5684,15.5889,0.08445}, + {840,-0.5684,15.5881,0.08445}, + {841,-0.5684,15.5872,0.08445}, + {842,-0.5684,15.5863,0.08445}, + {843,-0.5684,15.5855,0.08445}, + {844,-0.5684,15.5846,0.08445}, + {845,-0.5684,15.5838,0.08445}, + {846,-0.5684,15.5829,0.08444}, + {847,-0.5684,15.5821,0.08444}, + {848,-0.5684,15.5812,0.08444}, + {849,-0.5684,15.5804,0.08444}, + {850,-0.5684,15.5796,0.08444}, + {851,-0.5684,15.5787,0.08444}, + {852,-0.5684,15.5779,0.08444}, + {853,-0.5684,15.577,0.08444}, + {854,-0.5684,15.5762,0.08444}, + {855,-0.5684,15.5753,0.08444}, + {856,-0.5684,15.5745,0.08444}, + {857,-0.5684,15.5737,0.08444}, + {858,-0.5684,15.5728,0.08444}, + {859,-0.5684,15.572,0.08444}, + {860,-0.5684,15.5711,0.08444}, + {861,-0.5684,15.5703,0.08444}, + {862,-0.5684,15.5695,0.08444}, + {863,-0.5684,15.5686,0.08444}, + {864,-0.5684,15.5678,0.08443}, + {865,-0.5684,15.567,0.08443}, + {866,-0.5684,15.5661,0.08443}, + {867,-0.5684,15.5653,0.08443}, + {868,-0.5684,15.5645,0.08443}, + {869,-0.5684,15.5636,0.08443}, + {870,-0.5684,15.5628,0.08443}, + {871,-0.5684,15.562,0.08443}, + {872,-0.5684,15.5611,0.08443}, + {873,-0.5684,15.5603,0.08443}, + {874,-0.5684,15.5595,0.08443}, + {875,-0.5684,15.5587,0.08443}, + {876,-0.5684,15.5578,0.08443}, + {877,-0.5684,15.557,0.08443}, + {878,-0.5684,15.5562,0.08443}, + {879,-0.5684,15.5554,0.08443}, + {880,-0.5684,15.5545,0.08443}, + {881,-0.5684,15.5537,0.08443}, + {882,-0.5684,15.5529,0.08443}, + {883,-0.5684,15.5521,0.08443}, + {884,-0.5684,15.5513,0.08443}, + {885,-0.5684,15.5504,0.08443}, + {886,-0.5684,15.5496,0.08443}, + {887,-0.5684,15.5488,0.08443}, + {888,-0.5684,15.548,0.08443}, + {889,-0.5684,15.5472,0.08443}, + {890,-0.5684,15.5463,0.08443}, + {891,-0.5684,15.5455,0.08443}, + {892,-0.5684,15.5447,0.08443}, + {893,-0.5684,15.5439,0.08443}, + {894,-0.5684,15.5431,0.08443}, + {895,-0.5684,15.5423,0.08443}, + {896,-0.5684,15.5414,0.08443}, + {897,-0.5684,15.5406,0.08443}, + {898,-0.5684,15.5398,0.08443}, + {899,-0.5684,15.539,0.08443}, + {900,-0.5684,15.5382,0.08443}, + {901,-0.5684,15.5374,0.08443}, + {902,-0.5684,15.5366,0.08443}, + {903,-0.5684,15.5358,0.08443}, + {904,-0.5684,15.535,0.08443}, + {905,-0.5684,15.5341,0.08443}, + {906,-0.5684,15.5333,0.08443}, + {907,-0.5684,15.5325,0.08443}, + {908,-0.5684,15.5317,0.08444}, + {909,-0.5684,15.5309,0.08444}, + {910,-0.5684,15.5301,0.08444}, + {911,-0.5684,15.5293,0.08444}, + {912,-0.5684,15.5285,0.08444}, + {913,-0.5684,15.5277,0.08444}, + {914,-0.5684,15.5269,0.08444}, + {915,-0.5684,15.5261,0.08444}, + {916,-0.5684,15.5253,0.08444}, + {917,-0.5684,15.5245,0.08444}, + {918,-0.5684,15.5237,0.08444}, + {919,-0.5684,15.5229,0.08444}, + {920,-0.5684,15.5221,0.08444}, + {921,-0.5684,15.5213,0.08445}, + {922,-0.5684,15.5205,0.08445}, + {923,-0.5684,15.5197,0.08445}, + {924,-0.5684,15.5189,0.08445}, + {925,-0.5684,15.5181,0.08445}, + {926,-0.5684,15.5173,0.08445}, + {927,-0.5684,15.5165,0.08445}, + {928,-0.5684,15.5157,0.08445}, + {929,-0.5684,15.5149,0.08445}, + {930,-0.5684,15.5141,0.08446}, + {931,-0.5684,15.5133,0.08446}, + {932,-0.5684,15.5125,0.08446}, + {933,-0.5684,15.5117,0.08446}, + {934,-0.5684,15.5109,0.08446}, + {935,-0.5684,15.5101,0.08446}, + {936,-0.5684,15.5093,0.08446}, + {937,-0.5684,15.5086,0.08447}, + {938,-0.5684,15.5078,0.08447}, + {939,-0.5684,15.507,0.08447}, + {940,-0.5684,15.5062,0.08447}, + {941,-0.5684,15.5054,0.08447}, + {942,-0.5684,15.5046,0.08447}, + {943,-0.5684,15.5038,0.08448}, + {944,-0.5684,15.503,0.08448}, + {945,-0.5684,15.5023,0.08448}, + {946,-0.5684,15.5015,0.08448}, + {947,-0.5684,15.5007,0.08448}, + {948,-0.5684,15.4999,0.08448}, + {949,-0.5684,15.4991,0.08449}, + {950,-0.5684,15.4983,0.08449}, + {951,-0.5684,15.4976,0.08449}, + {952,-0.5684,15.4968,0.08449}, + {953,-0.5684,15.496,0.0845}, + {954,-0.5684,15.4952,0.0845}, + {955,-0.5684,15.4944,0.0845}, + {956,-0.5684,15.4937,0.0845}, + {957,-0.5684,15.4929,0.0845}, + {958,-0.5684,15.4921,0.08451}, + {959,-0.5684,15.4913,0.08451}, + {960,-0.5684,15.4906,0.08451}, + {961,-0.5684,15.4898,0.08451}, + {962,-0.5684,15.489,0.08452}, + {963,-0.5684,15.4883,0.08452}, + {964,-0.5684,15.4875,0.08452}, + {965,-0.5684,15.4867,0.08452}, + {966,-0.5684,15.4859,0.08453}, + {967,-0.5684,15.4852,0.08453}, + {968,-0.5684,15.4844,0.08453}, + {969,-0.5684,15.4836,0.08454}, + {970,-0.5684,15.4829,0.08454}, + {971,-0.5684,15.4821,0.08454}, + {972,-0.5684,15.4814,0.08455}, + {973,-0.5684,15.4806,0.08455}, + {974,-0.5684,15.4798,0.08455}, + {975,-0.5684,15.4791,0.08455}, + {976,-0.5684,15.4783,0.08456}, + {977,-0.5684,15.4776,0.08456}, + {978,-0.5684,15.4768,0.08456}, + {979,-0.5684,15.476,0.08457}, + {980,-0.5684,15.4753,0.08457}, + {981,-0.5684,15.4745,0.08457}, + {982,-0.5684,15.4738,0.08458}, + {983,-0.5684,15.473,0.08458}, + {984,-0.5684,15.4723,0.08459}, + {985,-0.5684,15.4715,0.08459}, + {986,-0.5684,15.4708,0.08459}, + {987,-0.5684,15.47,0.0846}, + {988,-0.5684,15.4693,0.0846}, + {989,-0.5684,15.4685,0.0846}, + {990,-0.5684,15.4678,0.08461}, + {991,-0.5684,15.467,0.08461}, + {992,-0.5684,15.4663,0.08462}, + {993,-0.5684,15.4656,0.08462}, + {994,-0.5684,15.4648,0.08462}, + {995,-0.5684,15.4641,0.08463}, + {996,-0.5684,15.4633,0.08463}, + {997,-0.5684,15.4626,0.08464}, + {998,-0.5684,15.4619,0.08464}, + {999,-0.5684,15.4611,0.08465}, + {1000,-0.5684,15.4604,0.08465}, + {1001,-0.5684,15.4597,0.08465}, + {1002,-0.5684,15.4589,0.08466}, + {1003,-0.5684,15.4582,0.08466}, + {1004,-0.5684,15.4575,0.08467}, + {1005,-0.5684,15.4568,0.08467}, + {1006,-0.5684,15.456,0.08468}, + {1007,-0.5684,15.4553,0.08468}, + {1008,-0.5684,15.4546,0.08469}, + {1009,-0.5684,15.4539,0.08469}, + {1010,-0.5684,15.4531,0.0847}, + {1011,-0.5684,15.4524,0.0847}, + {1012,-0.5684,15.4517,0.08471}, + {1013,-0.5684,15.451,0.08471}, + {1014,-0.5684,15.4503,0.08472}, + {1015,-0.5684,15.4495,0.08472}, + {1016,-0.5684,15.4488,0.08473}, + {1017,-0.5684,15.4481,0.08473}, + {1018,-0.5684,15.4474,0.08474}, + {1019,-0.5684,15.4467,0.08474}, + {1020,-0.5684,15.446,0.08475}, + {1021,-0.5684,15.4453,0.08476}, + {1022,-0.5684,15.4446,0.08476}, + {1023,-0.5684,15.4439,0.08477}, + {1024,-0.5684,15.4432,0.08477}, + {1025,-0.5684,15.4425,0.08478}, + {1026,-0.5684,15.4418,0.08478}, + {1027,-0.5684,15.4411,0.08479}, + {1028,-0.5684,15.4404,0.0848}, + {1029,-0.5684,15.4397,0.0848}, + {1030,-0.5684,15.439,0.08481}, + {1031,-0.5684,15.4383,0.08482}, + {1032,-0.5684,15.4376,0.08482}, + {1033,-0.5684,15.4369,0.08483}, + {1034,-0.5684,15.4362,0.08483}, + {1035,-0.5684,15.4355,0.08484}, + {1036,-0.5684,15.4349,0.08485}, + {1037,-0.5684,15.4342,0.08485}, + {1038,-0.5684,15.4335,0.08486}, + {1039,-0.5684,15.4328,0.08487}, + {1040,-0.5684,15.4321,0.08487}, + {1041,-0.5684,15.4315,0.08488}, + {1042,-0.5684,15.4308,0.08489}, + {1043,-0.5684,15.4301,0.08489}, + {1044,-0.5684,15.4294,0.0849}, + {1045,-0.5684,15.4288,0.08491}, + {1046,-0.5684,15.4281,0.08492}, + {1047,-0.5684,15.4274,0.08492}, + {1048,-0.5684,15.4268,0.08493}, + {1049,-0.5684,15.4261,0.08494}, + {1050,-0.5684,15.4254,0.08494}, + {1051,-0.5684,15.4248,0.08495}, + {1052,-0.5684,15.4241,0.08496}, + {1053,-0.5684,15.4234,0.08497}, + {1054,-0.5684,15.4228,0.08497}, + {1055,-0.5684,15.4221,0.08498}, + {1056,-0.5684,15.4215,0.08499}, + {1057,-0.5684,15.4208,0.085}, + {1058,-0.5684,15.4202,0.08501}, + {1059,-0.5684,15.4195,0.08501}, + {1060,-0.5684,15.4189,0.08502}, + {1061,-0.5684,15.4182,0.08503}, + {1062,-0.5684,15.4176,0.08504}, + {1063,-0.5684,15.4169,0.08505}, + {1064,-0.5684,15.4163,0.08505}, + {1065,-0.5684,15.4157,0.08506}, + {1066,-0.5684,15.415,0.08507}, + {1067,-0.5684,15.4144,0.08508}, + {1068,-0.5684,15.4137,0.08509}, + {1069,-0.5684,15.4131,0.0851}, + {1070,-0.5684,15.4125,0.0851}, + {1071,-0.5684,15.4119,0.08511}, + {1072,-0.5684,15.4112,0.08512}, + {1073,-0.5684,15.4106,0.08513}, + {1074,-0.5684,15.41,0.08514}, + {1075,-0.5684,15.4093,0.08515}, + {1076,-0.5684,15.4087,0.08516}, + {1077,-0.5684,15.4081,0.08517}, + {1078,-0.5684,15.4075,0.08517}, + {1079,-0.5684,15.4069,0.08518}, + {1080,-0.5684,15.4063,0.08519}, + {1081,-0.5684,15.4056,0.0852}, + {1082,-0.5684,15.405,0.08521}, + {1083,-0.5684,15.4044,0.08522}, + {1084,-0.5684,15.4038,0.08523}, + {1085,-0.5684,15.4032,0.08524}, + {1086,-0.5684,15.4026,0.08525}, + {1087,-0.5684,15.402,0.08526}, + {1088,-0.5684,15.4014,0.08527}, + {1089,-0.5684,15.4008,0.08528}, + {1090,-0.5684,15.4002,0.08529}, + {1091,-0.5684,15.3996,0.0853}, + {1092,-0.5684,15.399,0.08531}, + {1093,-0.5684,15.3984,0.08532}, + {1094,-0.5684,15.3978,0.08533}, + {1095,-0.5684,15.3972,0.08534}, + {1096,-0.5684,15.3966,0.08535}, + {1097,-0.5684,15.396,0.08536}, + {1098,-0.5684,15.3954,0.08537}, + {1099,-0.5684,15.3949,0.08538}, + {1100,-0.5684,15.3943,0.08539}, + {1101,-0.5684,15.3937,0.0854}, + {1102,-0.5684,15.3931,0.08541}, + {1103,-0.5684,15.3925,0.08542}, + {1104,-0.5684,15.392,0.08543}, + {1105,-0.5684,15.3914,0.08544}, + {1106,-0.5684,15.3908,0.08545}, + {1107,-0.5684,15.3902,0.08547}, + {1108,-0.5684,15.3897,0.08548}, + {1109,-0.5684,15.3891,0.08549}, + {1110,-0.5684,15.3885,0.0855}, + {1111,-0.5684,15.388,0.08551}, + {1112,-0.5684,15.3874,0.08552}, + {1113,-0.5684,15.3868,0.08553}, + {1114,-0.5684,15.3863,0.08554}, + {1115,-0.5684,15.3857,0.08556}, + {1116,-0.5684,15.3852,0.08557}, + {1117,-0.5684,15.3846,0.08558}, + {1118,-0.5684,15.384,0.08559}, + {1119,-0.5684,15.3835,0.0856}, + {1120,-0.5684,15.3829,0.08561}, + {1121,-0.5684,15.3824,0.08563}, + {1122,-0.5684,15.3818,0.08564}, + {1123,-0.5684,15.3813,0.08565}, + {1124,-0.5684,15.3808,0.08566}, + {1125,-0.5684,15.3802,0.08567}, + {1126,-0.5684,15.3797,0.08569}, + {1127,-0.5684,15.3791,0.0857}, + {1128,-0.5684,15.3786,0.08571}, + {1129,-0.5684,15.378,0.08572}, + {1130,-0.5684,15.3775,0.08574}, + {1131,-0.5684,15.377,0.08575}, + {1132,-0.5684,15.3764,0.08576}, + {1133,-0.5684,15.3759,0.08577}, + {1134,-0.5684,15.3754,0.08579}, + {1135,-0.5684,15.3748,0.0858}, + {1136,-0.5684,15.3743,0.08581}, + {1137,-0.5684,15.3738,0.08582}, + {1138,-0.5684,15.3733,0.08584}, + {1139,-0.5684,15.3727,0.08585}, + {1140,-0.5684,15.3722,0.08586}, + {1141,-0.5684,15.3717,0.08588}, + {1142,-0.5684,15.3712,0.08589}, + {1143,-0.5684,15.3707,0.0859}, + {1144,-0.5684,15.3702,0.08592}, + {1145,-0.5684,15.3696,0.08593}, + {1146,-0.5684,15.3691,0.08594}, + {1147,-0.5684,15.3686,0.08596}, + {1148,-0.5684,15.3681,0.08597}, + {1149,-0.5684,15.3676,0.08598}, + {1150,-0.5684,15.3671,0.086}, + {1151,-0.5684,15.3666,0.08601}, + {1152,-0.5684,15.3661,0.08602}, + {1153,-0.5684,15.3656,0.08604}, + {1154,-0.5684,15.3651,0.08605}, + {1155,-0.5684,15.3646,0.08606}, + {1156,-0.5684,15.3641,0.08608}, + {1157,-0.5684,15.3636,0.08609}, + {1158,-0.5684,15.3631,0.08611}, + {1159,-0.5684,15.3626,0.08612}, + {1160,-0.5684,15.3621,0.08614}, + {1161,-0.5684,15.3616,0.08615}, + {1162,-0.5684,15.3611,0.08616}, + {1163,-0.5684,15.3606,0.08618}, + {1164,-0.5684,15.3601,0.08619}, + {1165,-0.5684,15.3597,0.08621}, + {1166,-0.5684,15.3592,0.08622}, + {1167,-0.5684,15.3587,0.08624}, + {1168,-0.5684,15.3582,0.08625}, + {1169,-0.5684,15.3577,0.08627}, + {1170,-0.5684,15.3572,0.08628}, + {1171,-0.5684,15.3568,0.08629}, + {1172,-0.5684,15.3563,0.08631}, + {1173,-0.5684,15.3558,0.08632}, + {1174,-0.5684,15.3553,0.08634}, + {1175,-0.5684,15.3549,0.08635}, + {1176,-0.5684,15.3544,0.08637}, + {1177,-0.5684,15.3539,0.08638}, + {1178,-0.5684,15.3535,0.0864}, + {1179,-0.5684,15.353,0.08641}, + {1180,-0.5684,15.3525,0.08643}, + {1181,-0.5684,15.3521,0.08645}, + {1182,-0.5684,15.3516,0.08646}, + {1183,-0.5684,15.3511,0.08648}, + {1184,-0.5684,15.3507,0.08649}, + {1185,-0.5684,15.3502,0.08651}, + {1186,-0.5684,15.3497,0.08652}, + {1187,-0.5684,15.3493,0.08654}, + {1188,-0.5684,15.3488,0.08655}, + {1189,-0.5684,15.3484,0.08657}, + {1190,-0.5684,15.3479,0.08659}, + {1191,-0.5684,15.3475,0.0866}, + {1192,-0.5684,15.347,0.08662}, + {1193,-0.5684,15.3465,0.08663}, + {1194,-0.5684,15.3461,0.08665}, + {1195,-0.5684,15.3456,0.08666}, + {1196,-0.5684,15.3452,0.08668}, + {1197,-0.5684,15.3448,0.0867}, + {1198,-0.5684,15.3443,0.08671}, + {1199,-0.5684,15.3439,0.08673}, + {1200,-0.5684,15.3434,0.08675}, + {1201,-0.5684,15.343,0.08676}, + {1202,-0.5684,15.3425,0.08678}, + {1203,-0.5684,15.3421,0.08679}, + {1204,-0.5684,15.3416,0.08681}, + {1205,-0.5684,15.3412,0.08683}, + {1206,-0.5684,15.3408,0.08684}, + {1207,-0.5684,15.3403,0.08686}, + {1208,-0.5684,15.3399,0.08688}, + {1209,-0.5684,15.3395,0.08689}, + {1210,-0.5684,15.339,0.08691}, + {1211,-0.5684,15.3386,0.08693}, + {1212,-0.5684,15.3382,0.08694}, + {1213,-0.5684,15.3377,0.08696}, + {1214,-0.5684,15.3373,0.08698}, + {1215,-0.5684,15.3369,0.08699}, + {1216,-0.5684,15.3364,0.08701}, + {1217,-0.5684,15.336,0.08703}, + {1218,-0.5684,15.3356,0.08704}, + {1219,-0.5684,15.3352,0.08706}, + {1220,-0.5684,15.3347,0.08708}, + {1221,-0.5684,15.3343,0.0871}, + {1222,-0.5684,15.3339,0.08711}, + {1223,-0.5684,15.3335,0.08713}, + {1224,-0.5684,15.3331,0.08715}, + {1225,-0.5684,15.3326,0.08716}, + {1226,-0.5684,15.3322,0.08718}, + {1227,-0.5684,15.3318,0.0872}, + {1228,-0.5684,15.3314,0.08722}, + {1229,-0.5684,15.331,0.08723}, + {1230,-0.5684,15.3306,0.08725}, + {1231,-0.5684,15.3301,0.08727}, + {1232,-0.5684,15.3297,0.08729}, + {1233,-0.5684,15.3293,0.0873}, + {1234,-0.5684,15.3289,0.08732}, + {1235,-0.5684,15.3285,0.08734}, + {1236,-0.5684,15.3281,0.08736}, + {1237,-0.5684,15.3277,0.08737}, + {1238,-0.5684,15.3273,0.08739}, + {1239,-0.5684,15.3269,0.08741}, + {1240,-0.5684,15.3265,0.08743}, + {1241,-0.5684,15.3261,0.08745}, + {1242,-0.5684,15.3257,0.08746}, + {1243,-0.5684,15.3252,0.08748}, + {1244,-0.5684,15.3248,0.0875}, + {1245,-0.5684,15.3244,0.08752}, + {1246,-0.5684,15.324,0.08753}, + {1247,-0.5684,15.3236,0.08755}, + {1248,-0.5684,15.3233,0.08757}, + {1249,-0.5684,15.3229,0.08759}, + {1250,-0.5684,15.3225,0.08761}, + {1251,-0.5684,15.3221,0.08763}, + {1252,-0.5684,15.3217,0.08764}, + {1253,-0.5684,15.3213,0.08766}, + {1254,-0.5684,15.3209,0.08768}, + {1255,-0.5684,15.3205,0.0877}, + {1256,-0.5684,15.3201,0.08772}, + {1257,-0.5684,15.3197,0.08773}, + {1258,-0.5684,15.3193,0.08775}, + {1259,-0.5684,15.3189,0.08777}, + {1260,-0.5684,15.3185,0.08779}, + {1261,-0.5684,15.3182,0.08781}, + {1262,-0.5684,15.3178,0.08783}, + {1263,-0.5684,15.3174,0.08785}, + {1264,-0.5684,15.317,0.08786}, + {1265,-0.5684,15.3166,0.08788}, + {1266,-0.5684,15.3162,0.0879}, + {1267,-0.5684,15.3159,0.08792}, + {1268,-0.5684,15.3155,0.08794}, + {1269,-0.5684,15.3151,0.08796}, + {1270,-0.5684,15.3147,0.08798}, + {1271,-0.5684,15.3143,0.08799}, + {1272,-0.5684,15.314,0.08801}, + {1273,-0.5684,15.3136,0.08803}, + {1274,-0.5684,15.3132,0.08805}, + {1275,-0.5684,15.3128,0.08807}, + {1276,-0.5684,15.3125,0.08809}, + {1277,-0.5684,15.3121,0.08811}, + {1278,-0.5684,15.3117,0.08813}, + {1279,-0.5684,15.3114,0.08814}, + {1280,-0.5684,15.311,0.08816}, + {1281,-0.5684,15.3106,0.08818}, + {1282,-0.5684,15.3102,0.0882}, + {1283,-0.5684,15.3099,0.08822}, + {1284,-0.5684,15.3095,0.08824}, + {1285,-0.5684,15.3091,0.08826}, + {1286,-0.5684,15.3088,0.08828}, + {1287,-0.5684,15.3084,0.0883}, + {1288,-0.5684,15.308,0.08832}, + {1289,-0.5684,15.3077,0.08833}, + {1290,-0.5684,15.3073,0.08835}, + {1291,-0.5684,15.307,0.08837}, + {1292,-0.5684,15.3066,0.08839}, + {1293,-0.5684,15.3062,0.08841}, + {1294,-0.5684,15.3059,0.08843}, + {1295,-0.5684,15.3055,0.08845}, + {1296,-0.5684,15.3052,0.08847}, + {1297,-0.5684,15.3048,0.08849}, + {1298,-0.5684,15.3044,0.08851}, + {1299,-0.5684,15.3041,0.08853}, + {1300,-0.5684,15.3037,0.08855}, + {1301,-0.5684,15.3034,0.08857}, + {1302,-0.5684,15.303,0.08859}, + {1303,-0.5684,15.3027,0.0886}, + {1304,-0.5684,15.3023,0.08862}, + {1305,-0.5684,15.302,0.08864}, + {1306,-0.5684,15.3016,0.08866}, + {1307,-0.5684,15.3013,0.08868}, + {1308,-0.5684,15.3009,0.0887}, + {1309,-0.5684,15.3006,0.08872}, + {1310,-0.5684,15.3002,0.08874}, + {1311,-0.5684,15.2999,0.08876}, + {1312,-0.5684,15.2996,0.08878}, + {1313,-0.5684,15.2992,0.0888}, + {1314,-0.5684,15.2989,0.08882}, + {1315,-0.5684,15.2985,0.08884}, + {1316,-0.5684,15.2982,0.08886}, + {1317,-0.5684,15.2978,0.08888}, + {1318,-0.5684,15.2975,0.0889}, + {1319,-0.5684,15.2972,0.08892}, + {1320,-0.5684,15.2968,0.08894}, + {1321,-0.5684,15.2965,0.08896}, + {1322,-0.5684,15.2962,0.08898}, + {1323,-0.5684,15.2958,0.089}, + {1324,-0.5684,15.2955,0.08901}, + {1325,-0.5684,15.2952,0.08903}, + {1326,-0.5684,15.2948,0.08905}, + {1327,-0.5684,15.2945,0.08907}, + {1328,-0.5684,15.2942,0.08909}, + {1329,-0.5684,15.2938,0.08911}, + {1330,-0.5684,15.2935,0.08913}, + {1331,-0.5684,15.2932,0.08915}, + {1332,-0.5684,15.2929,0.08917}, + {1333,-0.5684,15.2925,0.08919}, + {1334,-0.5684,15.2922,0.08921}, + {1335,-0.5684,15.2919,0.08923}, + {1336,-0.5684,15.2916,0.08925}, + {1337,-0.5684,15.2913,0.08927}, + {1338,-0.5684,15.2909,0.08929}, + {1339,-0.5684,15.2906,0.08931}, + {1340,-0.5684,15.2903,0.08933}, + {1341,-0.5684,15.29,0.08935}, + {1342,-0.5684,15.2897,0.08937}, + {1343,-0.5684,15.2894,0.08939}, + {1344,-0.5684,15.289,0.08941}, + {1345,-0.5684,15.2887,0.08943}, + {1346,-0.5684,15.2884,0.08945}, + {1347,-0.5684,15.2881,0.08947}, + {1348,-0.5684,15.2878,0.08949}, + {1349,-0.5684,15.2875,0.08951}, + {1350,-0.5684,15.2872,0.08953}, + {1351,-0.5684,15.2869,0.08955}, + {1352,-0.5684,15.2866,0.08957}, + {1353,-0.5684,15.2863,0.08959}, + {1354,-0.5684,15.286,0.08961}, + {1355,-0.5684,15.2857,0.08963}, + {1356,-0.5684,15.2854,0.08964}, + {1357,-0.5684,15.2851,0.08966}, + {1358,-0.5684,15.2848,0.08968}, + {1359,-0.5684,15.2845,0.0897}, + {1360,-0.5684,15.2842,0.08972}, + {1361,-0.5684,15.2839,0.08974}, + {1362,-0.5684,15.2836,0.08976}, + {1363,-0.5684,15.2833,0.08978}, + {1364,-0.5684,15.283,0.0898}, + {1365,-0.5684,15.2827,0.08982}, + {1366,-0.5684,15.2824,0.08984}, + {1367,-0.5684,15.2821,0.08986}, + {1368,-0.5684,15.2818,0.08988}, + {1369,-0.5684,15.2816,0.0899}, + {1370,-0.5684,15.2813,0.08992}, + {1371,-0.5684,15.281,0.08994}, + {1372,-0.5684,15.2807,0.08996}, + {1373,-0.5684,15.2804,0.08998}, + {1374,-0.5684,15.2801,0.09}, + {1375,-0.5684,15.2799,0.09002}, + {1376,-0.5684,15.2796,0.09004}, + {1377,-0.5684,15.2793,0.09006}, + {1378,-0.5684,15.279,0.09008}, + {1379,-0.5684,15.2788,0.0901}, + {1380,-0.5684,15.2785,0.09012}, + {1381,-0.5684,15.2782,0.09013}, + {1382,-0.5684,15.2779,0.09015}, + {1383,-0.5684,15.2777,0.09017}, + {1384,-0.5684,15.2774,0.09019}, + {1385,-0.5684,15.2771,0.09021}, + {1386,-0.5684,15.2769,0.09023}, + {1387,-0.5684,15.2766,0.09025}, + {1388,-0.5684,15.2763,0.09027}, + {1389,-0.5684,15.2761,0.09029}, + {1390,-0.5684,15.2758,0.09031}, + {1391,-0.5684,15.2755,0.09033}, + {1392,-0.5684,15.2753,0.09035}, + {1393,-0.5684,15.275,0.09037}, + {1394,-0.5684,15.2748,0.09039}, + {1395,-0.5684,15.2745,0.09041}, + {1396,-0.5684,15.2742,0.09043}, + {1397,-0.5684,15.274,0.09045}, + {1398,-0.5684,15.2737,0.09047}, + {1399,-0.5684,15.2735,0.09049}, + {1400,-0.5684,15.2732,0.0905}, + {1401,-0.5684,15.273,0.09052}, + {1402,-0.5684,15.2727,0.09054}, + {1403,-0.5684,15.2725,0.09056}, + {1404,-0.5684,15.2722,0.09058}, + {1405,-0.5684,15.272,0.0906}, + {1406,-0.5684,15.2717,0.09062}, + {1407,-0.5684,15.2715,0.09064}, + {1408,-0.5684,15.2713,0.09066}, + {1409,-0.5684,15.271,0.09068}, + {1410,-0.5684,15.2708,0.0907}, + {1411,-0.5684,15.2705,0.09072}, + {1412,-0.5684,15.2703,0.09074}, + {1413,-0.5684,15.2701,0.09076}, + {1414,-0.5684,15.2698,0.09078}, + {1415,-0.5684,15.2696,0.0908}, + {1416,-0.5684,15.2694,0.09081}, + {1417,-0.5684,15.2691,0.09083}, + {1418,-0.5684,15.2689,0.09085}, + {1419,-0.5684,15.2687,0.09087}, + {1420,-0.5684,15.2685,0.09089}, + {1421,-0.5684,15.2682,0.09091}, + {1422,-0.5684,15.268,0.09093}, + {1423,-0.5684,15.2678,0.09095}, + {1424,-0.5684,15.2676,0.09097}, + {1425,-0.5684,15.2673,0.09099}, + {1426,-0.5684,15.2671,0.09101}, + {1427,-0.5684,15.2669,0.09103}, + {1428,-0.5684,15.2667,0.09105}, + {1429,-0.5684,15.2665,0.09107}, + {1430,-0.5684,15.2662,0.09109}, + {1431,-0.5684,15.266,0.0911}, + {1432,-0.5684,15.2658,0.09112}, + {1433,-0.5684,15.2656,0.09114}, + {1434,-0.5684,15.2654,0.09116}, + {1435,-0.5684,15.2652,0.09118}, + {1436,-0.5684,15.265,0.0912}, + {1437,-0.5684,15.2648,0.09122}, + {1438,-0.5684,15.2646,0.09124}, + {1439,-0.5684,15.2644,0.09126}, + {1440,-0.5684,15.2642,0.09128}, + {1441,-0.5684,15.264,0.0913}, + {1442,-0.5684,15.2638,0.09132}, + {1443,-0.5684,15.2636,0.09134}, + {1444,-0.5684,15.2634,0.09136}, + {1445,-0.5684,15.2632,0.09138}, + {1446,-0.5684,15.263,0.09139}, + {1447,-0.5684,15.2628,0.09141}, + {1448,-0.5684,15.2626,0.09143}, + {1449,-0.5684,15.2624,0.09145}, + {1450,-0.5684,15.2622,0.09147}, + {1451,-0.5684,15.262,0.09149}, + {1452,-0.5684,15.2619,0.09151}, + {1453,-0.5684,15.2617,0.09153}, + {1454,-0.5684,15.2615,0.09155}, + {1455,-0.5684,15.2613,0.09157}, + {1456,-0.5684,15.2611,0.09159}, + {1457,-0.5684,15.2609,0.09161}, + {1458,-0.5684,15.2608,0.09163}, + {1459,-0.5684,15.2606,0.09165}, + {1460,-0.5684,15.2604,0.09167}, + {1461,-0.5684,15.2602,0.09168}, + {1462,-0.5684,15.2601,0.0917}, + {1463,-0.5684,15.2599,0.09172}, + {1464,-0.5684,15.2597,0.09174}, + {1465,-0.5684,15.2596,0.09176}, + {1466,-0.5684,15.2594,0.09178}, + {1467,-0.5684,15.2592,0.0918}, + {1468,-0.5684,15.2591,0.09182}, + {1469,-0.5684,15.2589,0.09184}, + {1470,-0.5684,15.2587,0.09186}, + {1471,-0.5684,15.2586,0.09188}, + {1472,-0.5684,15.2584,0.0919}, + {1473,-0.5684,15.2583,0.09192}, + {1474,-0.5684,15.2581,0.09194}, + {1475,-0.5684,15.2579,0.09196}, + {1476,-0.5684,15.2578,0.09198}, + {1477,-0.5684,15.2576,0.092}, + {1478,-0.5684,15.2575,0.09201}, + {1479,-0.5684,15.2573,0.09203}, + {1480,-0.5684,15.2572,0.09205}, + {1481,-0.5684,15.257,0.09207}, + {1482,-0.5684,15.2569,0.09209}, + {1483,-0.5684,15.2568,0.09211}, + {1484,-0.5684,15.2566,0.09213}, + {1485,-0.5684,15.2565,0.09215}, + {1486,-0.5684,15.2563,0.09217}, + {1487,-0.5684,15.2562,0.09219}, + {1488,-0.5684,15.2561,0.09221}, + {1489,-0.5684,15.2559,0.09223}, + {1490,-0.5684,15.2558,0.09225}, + {1491,-0.5684,15.2557,0.09227}, + {1492,-0.5684,15.2555,0.09229}, + {1493,-0.5684,15.2554,0.09231}, + {1494,-0.5684,15.2553,0.09232}, + {1495,-0.5684,15.2551,0.09234}, + {1496,-0.5684,15.255,0.09236}, + {1497,-0.5684,15.2549,0.09238}, + {1498,-0.5684,15.2548,0.0924}, + {1499,-0.5684,15.2547,0.09242}, + {1500,-0.5684,15.2545,0.09244}, + {1501,-0.5684,15.2544,0.09246}, + {1502,-0.5684,15.2543,0.09248}, + {1503,-0.5684,15.2542,0.0925}, + {1504,-0.5684,15.2541,0.09252}, + {1505,-0.5684,15.254,0.09254}, + {1506,-0.5684,15.2538,0.09256}, + {1507,-0.5684,15.2537,0.09258}, + {1508,-0.5684,15.2536,0.0926}, + {1509,-0.5684,15.2535,0.09262}, + {1510,-0.5684,15.2534,0.09263}, + {1511,-0.5684,15.2533,0.09265}, + {1512,-0.5684,15.2532,0.09267}, + {1513,-0.5684,15.2531,0.09269}, + {1514,-0.5684,15.253,0.09271}, + {1515,-0.5684,15.2529,0.09273}, + {1516,-0.5684,15.2528,0.09275}, + {1517,-0.5684,15.2527,0.09277}, + {1518,-0.5684,15.2526,0.09279}, + {1519,-0.5684,15.2525,0.09281}, + {1520,-0.5684,15.2525,0.09283}, + {1521,-0.5684,15.2524,0.09285}, + {1522,-0.5684,15.2523,0.09287}, + {1523,-0.5684,15.2522,0.09289}, + {1524,-0.5684,15.2521,0.09291}, + {1525,-0.5684,15.252,0.09292}, + {1526,-0.5684,15.2519,0.09294}, + {1527,-0.5684,15.2519,0.09296}, + {1528,-0.5684,15.2518,0.09298}, + {1529,-0.5684,15.2517,0.093}, + {1530,-0.5684,15.2516,0.09302}, + {1531,-0.5684,15.2515,0.09304}, + {1532,-0.5684,15.2515,0.09306}, + {1533,-0.5684,15.2514,0.09308}, + {1534,-0.5684,15.2513,0.0931}, + {1535,-0.5684,15.2513,0.09312}, + {1536,-0.5684,15.2512,0.09314}, + {1537,-0.5684,15.2511,0.09316}, + {1538,-0.5684,15.2511,0.09318}, + {1539,-0.5684,15.251,0.0932}, + {1540,-0.5684,15.2509,0.09321}, + {1541,-0.5684,15.2509,0.09323}, + {1542,-0.5684,15.2508,0.09325}, + {1543,-0.5684,15.2508,0.09327}, + {1544,-0.5684,15.2507,0.09329}, + {1545,-0.5684,15.2507,0.09331}, + {1546,-0.5684,15.2506,0.09333}, + {1547,-0.5684,15.2506,0.09335}, + {1548,-0.5684,15.2505,0.09337}, + {1549,-0.5684,15.2505,0.09339}, + {1550,-0.5684,15.2504,0.09341}, + {1551,-0.5684,15.2504,0.09343}, + {1552,-0.5684,15.2503,0.09345}, + {1553,-0.5684,15.2503,0.09346}, + {1554,-0.5684,15.2502,0.09348}, + {1555,-0.5684,15.2502,0.0935}, + {1556,-0.5684,15.2502,0.09352}, + {1557,-0.5684,15.2501,0.09354}, + {1558,-0.5684,15.2501,0.09356}, + {1559,-0.5684,15.25,0.09358}, + {1560,-0.5684,15.25,0.0936}, + {1561,-0.5684,15.25,0.09362}, + {1562,-0.5684,15.25,0.09364}, + {1563,-0.5684,15.2499,0.09366}, + {1564,-0.5684,15.2499,0.09368}, + {1565,-0.5684,15.2499,0.09369}, + {1566,-0.5684,15.2498,0.09371}, + {1567,-0.5684,15.2498,0.09373}, + {1568,-0.5684,15.2498,0.09375}, + {1569,-0.5684,15.2498,0.09377}, + {1570,-0.5684,15.2498,0.09379}, + {1571,-0.5684,15.2497,0.09381}, + {1572,-0.5684,15.2497,0.09383}, + {1573,-0.5684,15.2497,0.09385}, + {1574,-0.5684,15.2497,0.09387}, + {1575,-0.5684,15.2497,0.09388}, + {1576,-0.5684,15.2497,0.0939}, + {1577,-0.5684,15.2497,0.09392}, + {1578,-0.5684,15.2497,0.09394}, + {1579,-0.5684,15.2497,0.09396}, + {1580,-0.5684,15.2497,0.09398}, + {1581,-0.5684,15.2496,0.094}, + {1582,-0.5684,15.2496,0.09402}, + {1583,-0.5684,15.2496,0.09404}, + {1584,-0.5684,15.2496,0.09406}, + {1585,-0.5684,15.2496,0.09407}, + {1586,-0.5684,15.2497,0.09409}, + {1587,-0.5684,15.2497,0.09411}, + {1588,-0.5684,15.2497,0.09413}, + {1589,-0.5684,15.2497,0.09415}, + {1590,-0.5684,15.2497,0.09417}, + {1591,-0.5684,15.2497,0.09419}, + {1592,-0.5684,15.2497,0.09421}, + {1593,-0.5684,15.2497,0.09422}, + {1594,-0.5684,15.2497,0.09424}, + {1595,-0.5684,15.2497,0.09426}, + {1596,-0.5684,15.2498,0.09428}, + {1597,-0.5684,15.2498,0.0943}, + {1598,-0.5684,15.2498,0.09432}, + {1599,-0.5684,15.2498,0.09434}, + {1600,-0.5684,15.2498,0.09436}, + {1601,-0.5684,15.2499,0.09437}, + {1602,-0.5684,15.2499,0.09439}, + {1603,-0.5684,15.2499,0.09441}, + {1604,-0.5684,15.2499,0.09443}, + {1605,-0.5684,15.25,0.09445}, + {1606,-0.5684,15.25,0.09447}, + {1607,-0.5684,15.25,0.09449}, + {1608,-0.5684,15.25,0.0945}, + {1609,-0.5684,15.2501,0.09452}, + {1610,-0.5684,15.2501,0.09454}, + {1611,-0.5684,15.2501,0.09456}, + {1612,-0.5684,15.2502,0.09458}, + {1613,-0.5684,15.2502,0.0946}, + {1614,-0.5684,15.2502,0.09461}, + {1615,-0.5684,15.2503,0.09463}, + {1616,-0.5684,15.2503,0.09465}, + {1617,-0.5684,15.2504,0.09467}, + {1618,-0.5684,15.2504,0.09469}, + {1619,-0.5684,15.2505,0.09471}, + {1620,-0.5684,15.2505,0.09472}, + {1621,-0.5684,15.2505,0.09474}, + {1622,-0.5684,15.2506,0.09476}, + {1623,-0.5684,15.2506,0.09478}, + {1624,-0.5684,15.2507,0.0948}, + {1625,-0.5684,15.2507,0.09481}, + {1626,-0.5684,15.2508,0.09483}, + {1627,-0.5684,15.2508,0.09485}, + {1628,-0.5684,15.2509,0.09487}, + {1629,-0.5684,15.2509,0.09489}, + {1630,-0.5684,15.251,0.09491}, + {1631,-0.5684,15.2511,0.09492}, + {1632,-0.5684,15.2511,0.09494}, + {1633,-0.5684,15.2512,0.09496}, + {1634,-0.5684,15.2512,0.09498}, + {1635,-0.5684,15.2513,0.095}, + {1636,-0.5684,15.2514,0.09501}, + {1637,-0.5684,15.2514,0.09503}, + {1638,-0.5684,15.2515,0.09505}, + {1639,-0.5684,15.2515,0.09507}, + {1640,-0.5684,15.2516,0.09508}, + {1641,-0.5684,15.2517,0.0951}, + {1642,-0.5684,15.2517,0.09512}, + {1643,-0.5684,15.2518,0.09514}, + {1644,-0.5684,15.2519,0.09516}, + {1645,-0.5684,15.2519,0.09517}, + {1646,-0.5684,15.252,0.09519}, + {1647,-0.5684,15.2521,0.09521}, + {1648,-0.5684,15.2522,0.09523}, + {1649,-0.5684,15.2522,0.09524}, + {1650,-0.5684,15.2523,0.09526}, + {1651,-0.5684,15.2524,0.09528}, + {1652,-0.5684,15.2525,0.0953}, + {1653,-0.5684,15.2525,0.09531}, + {1654,-0.5684,15.2526,0.09533}, + {1655,-0.5684,15.2527,0.09535}, + {1656,-0.5684,15.2528,0.09537}, + {1657,-0.5684,15.2529,0.09538}, + {1658,-0.5684,15.2529,0.0954}, + {1659,-0.5684,15.253,0.09542}, + {1660,-0.5684,15.2531,0.09544}, + {1661,-0.5684,15.2532,0.09545}, + {1662,-0.5684,15.2533,0.09547}, + {1663,-0.5684,15.2534,0.09549}, + {1664,-0.5684,15.2534,0.0955}, + {1665,-0.5684,15.2535,0.09552}, + {1666,-0.5684,15.2536,0.09554}, + {1667,-0.5684,15.2537,0.09556}, + {1668,-0.5684,15.2538,0.09557}, + {1669,-0.5684,15.2539,0.09559}, + {1670,-0.5684,15.254,0.09561}, + {1671,-0.5684,15.2541,0.09562}, + {1672,-0.5684,15.2542,0.09564}, + {1673,-0.5684,15.2543,0.09566}, + {1674,-0.5684,15.2543,0.09567}, + {1675,-0.5684,15.2544,0.09569}, + {1676,-0.5684,15.2545,0.09571}, + {1677,-0.5684,15.2546,0.09573}, + {1678,-0.5684,15.2547,0.09574}, + {1679,-0.5684,15.2548,0.09576}, + {1680,-0.5684,15.2549,0.09578}, + {1681,-0.5684,15.255,0.09579}, + {1682,-0.5684,15.2551,0.09581}, + {1683,-0.5684,15.2552,0.09583}, + {1684,-0.5684,15.2553,0.09584}, + {1685,-0.5684,15.2554,0.09586}, + {1686,-0.5684,15.2555,0.09588}, + {1687,-0.5684,15.2556,0.09589}, + {1688,-0.5684,15.2557,0.09591}, + {1689,-0.5684,15.2558,0.09593}, + {1690,-0.5684,15.2559,0.09594}, + {1691,-0.5684,15.256,0.09596}, + {1692,-0.5684,15.2561,0.09597}, + {1693,-0.5684,15.2563,0.09599}, + {1694,-0.5684,15.2564,0.09601}, + {1695,-0.5684,15.2565,0.09602}, + {1696,-0.5684,15.2566,0.09604}, + {1697,-0.5684,15.2567,0.09606}, + {1698,-0.5684,15.2568,0.09607}, + {1699,-0.5684,15.2569,0.09609}, + {1700,-0.5684,15.257,0.0961}, + {1701,-0.5684,15.2571,0.09612}, + {1702,-0.5684,15.2572,0.09614}, + {1703,-0.5684,15.2574,0.09615}, + {1704,-0.5684,15.2575,0.09617}, + {1705,-0.5684,15.2576,0.09618}, + {1706,-0.5684,15.2577,0.0962}, + {1707,-0.5684,15.2578,0.09622}, + {1708,-0.5684,15.2579,0.09623}, + {1709,-0.5684,15.258,0.09625}, + {1710,-0.5684,15.2582,0.09626}, + {1711,-0.5684,15.2583,0.09628}, + {1712,-0.5684,15.2584,0.0963}, + {1713,-0.5684,15.2585,0.09631}, + {1714,-0.5684,15.2586,0.09633}, + {1715,-0.5684,15.2587,0.09634}, + {1716,-0.5684,15.2589,0.09636}, + {1717,-0.5684,15.259,0.09637}, + {1718,-0.5684,15.2591,0.09639}, + {1719,-0.5684,15.2592,0.09641}, + {1720,-0.5684,15.2593,0.09642}, + {1721,-0.5684,15.2595,0.09644}, + {1722,-0.5684,15.2596,0.09645}, + {1723,-0.5684,15.2597,0.09647}, + {1724,-0.5684,15.2598,0.09648}, + {1725,-0.5684,15.2599,0.0965}, + {1726,-0.5684,15.2601,0.09651}, + {1727,-0.5684,15.2602,0.09653}, + {1728,-0.5684,15.2603,0.09654}, + {1729,-0.5684,15.2604,0.09656}, + {1730,-0.5684,15.2606,0.09657}, + {1731,-0.5684,15.2607,0.09659}, + {1732,-0.5684,15.2608,0.0966}, + {1733,-0.5684,15.261,0.09662}, + {1734,-0.5684,15.2611,0.09663}, + {1735,-0.5684,15.2612,0.09665}, + {1736,-0.5684,15.2613,0.09666}, + {1737,-0.5684,15.2615,0.09668}, + {1738,-0.5684,15.2616,0.09669}, + {1739,-0.5684,15.2617,0.09671}, + {1740,-0.5684,15.2619,0.09672}, + {1741,-0.5684,15.262,0.09674}, + {1742,-0.5684,15.2621,0.09675}, + {1743,-0.5684,15.2622,0.09677}, + {1744,-0.5684,15.2624,0.09678}, + {1745,-0.5684,15.2625,0.0968}, + {1746,-0.5684,15.2626,0.09681}, + {1747,-0.5684,15.2628,0.09683}, + {1748,-0.5684,15.2629,0.09684}, + {1749,-0.5684,15.263,0.09686}, + {1750,-0.5684,15.2632,0.09687}, + {1751,-0.5684,15.2633,0.09688}, + {1752,-0.5684,15.2635,0.0969}, + {1753,-0.5684,15.2636,0.09691}, + {1754,-0.5684,15.2637,0.09693}, + {1755,-0.5684,15.2639,0.09694}, + {1756,-0.5684,15.264,0.09696}, + {1757,-0.5684,15.2641,0.09697}, + {1758,-0.5684,15.2643,0.09699}, + {1759,-0.5684,15.2644,0.097}, + {1760,-0.5684,15.2646,0.09701}, + {1761,-0.5684,15.2647,0.09703}, + {1762,-0.5684,15.2648,0.09704}, + {1763,-0.5684,15.265,0.09706}, + {1764,-0.5684,15.2651,0.09707}, + {1765,-0.5684,15.2653,0.09708}, + {1766,-0.5684,15.2654,0.0971}, + {1767,-0.5684,15.2655,0.09711}, + {1768,-0.5684,15.2657,0.09713}, + {1769,-0.5684,15.2658,0.09714}, + {1770,-0.5684,15.266,0.09715}, + {1771,-0.5684,15.2661,0.09717}, + {1772,-0.5684,15.2663,0.09718}, + {1773,-0.5684,15.2664,0.0972}, + {1774,-0.5684,15.2665,0.09721}, + {1775,-0.5684,15.2667,0.09722}, + {1776,-0.5684,15.2668,0.09724}, + {1777,-0.5684,15.267,0.09725}, + {1778,-0.5684,15.2671,0.09726}, + {1779,-0.5684,15.2673,0.09728}, + {1780,-0.5684,15.2674,0.09729}, + {1781,-0.5684,15.2676,0.0973}, + {1782,-0.5684,15.2677,0.09732}, + {1783,-0.5684,15.2679,0.09733}, + {1784,-0.5684,15.268,0.09734}, + {1785,-0.5684,15.2682,0.09736}, + {1786,-0.5684,15.2683,0.09737}, + {1787,-0.5684,15.2685,0.09739}, + {1788,-0.5684,15.2686,0.0974}, + {1789,-0.5684,15.2688,0.09741}, + {1790,-0.5684,15.2689,0.09743}, + {1791,-0.5684,15.2691,0.09744}, + {1792,-0.5684,15.2692,0.09745}, + {1793,-0.5684,15.2694,0.09746}, + {1794,-0.5684,15.2695,0.09748}, + {1795,-0.5684,15.2697,0.09749}, + {1796,-0.5684,15.2698,0.0975}, + {1797,-0.5684,15.27,0.09752}, + {1798,-0.5684,15.2702,0.09753}, + {1799,-0.5684,15.2703,0.09754}, + {1800,-0.5684,15.2705,0.09756}, + {1801,-0.5684,15.2706,0.09757}, + {1802,-0.5684,15.2708,0.09758}, + {1803,-0.5684,15.2709,0.0976}, + {1804,-0.5684,15.2711,0.09761}, + {1805,-0.5684,15.2713,0.09762}, + {1806,-0.5684,15.2714,0.09763}, + {1807,-0.5684,15.2716,0.09765}, + {1808,-0.5684,15.2717,0.09766}, + {1809,-0.5684,15.2719,0.09767}, + {1810,-0.5684,15.272,0.09769}, + {1811,-0.5684,15.2722,0.0977}, + {1812,-0.5684,15.2724,0.09771}, + {1813,-0.5684,15.2725,0.09772}, + {1814,-0.5684,15.2727,0.09774}, + {1815,-0.5684,15.2729,0.09775}, + {1816,-0.5684,15.273,0.09776}, + {1817,-0.5684,15.2732,0.09777}, + {1818,-0.5684,15.2733,0.09779}, + {1819,-0.5684,15.2735,0.0978}, + {1820,-0.5684,15.2737,0.09781}, + {1821,-0.5684,15.2738,0.09782}, + {1822,-0.5684,15.274,0.09784}, + {1823,-0.5684,15.2742,0.09785}, + {1824,-0.5684,15.2743,0.09786}, + {1825,-0.5684,15.2745,0.09787}, + {1826,-0.5684,15.2747,0.09789}, + {1827,-0.5684,15.2748,0.0979}, + {1828,-0.5684,15.275,0.09791}, + {1829,-0.5684,15.2752,0.09792}, + {1830,-0.5684,15.2753,0.09794}, + {1831,-0.5684,15.2755,0.09795}, + {1832,-0.5684,15.2757,0.09796}, + {1833,-0.5684,15.2758,0.09797}, + {1834,-0.5684,15.276,0.09799}, + {1835,-0.5684,15.2762,0.098}, + {1836,-0.5684,15.2763,0.09801}, + {1837,-0.5684,15.2765,0.09802}, + {1838,-0.5684,15.2767,0.09803}, + {1839,-0.5684,15.2768,0.09805}, + {1840,-0.5684,15.277,0.09806}, + {1841,-0.5684,15.2772,0.09807}, + {1842,-0.5684,15.2773,0.09808}, + {1843,-0.5684,15.2775,0.0981}, + {1844,-0.5684,15.2777,0.09811}, + {1845,-0.5684,15.2779,0.09812}, + {1846,-0.5684,15.278,0.09813}, + {1847,-0.5684,15.2782,0.09814}, + {1848,-0.5684,15.2784,0.09816}, + {1849,-0.5684,15.2785,0.09817}, + {1850,-0.5684,15.2787,0.09818}, + {1851,-0.5684,15.2789,0.09819}, + {1852,-0.5684,15.2791,0.0982}, + {1853,-0.5684,15.2792,0.09822}, + {1854,-0.5684,15.2794,0.09823}, + {1855,-0.5684,15.2796,0.09824}, + {1856,-0.5684,15.2798,0.09825} + + }; + return data[index < data.length ? index : data.length]; + } + + +// public String[]WeightAgeStandardIndex = {context.getResources().getString(R.string.Underweight), +// context.getResources().getString(R.string.Underweight),context.getResources().getString(R.string.good_nutrition),context.getResources().getString(R.string.overweight)}; + public String[]WeightAgeStandardIndex = {"Severely Underweight","Underweight","Normal","Overweight"}; + + // public String[]HeightAgeStandardIndex = {context.getResources().getString(R.string.s_stunted), + // context.getResources().getString(R.string.stunted), + // context.getResources().getString(R.string.normal), + // context.getResources().getString(R.string.tall)}; + public String[]HeightAgeStandardIndex = {"Severely Stunted","Stunted","Normal","Tall"}; + + // BMI, weight length and weight height has the same standard + // public String[]WeightHeightStandardIndex = {context.getResources().getString(R.string.S_wasted), + // context.getResources().getString(R.string.wasted), + // context.getResources().getString(R.string.normal), + // context.getResources().getString(R.string.overweight)}; + public String[]WeightHeightStandardIndex = {"Severely Wasted","Wasted","Normal","Overweight"}; +} \ No newline at end of file diff --git a/opensrp-gizi/src/main/java/util/ZScore/ZScoreSystemCalculation.java b/opensrp-gizi/src/main/java/util/ZScore/ZScoreSystemCalculation.java new file mode 100644 index 0000000..8c714f8 --- /dev/null +++ b/opensrp-gizi/src/main/java/util/ZScore/ZScoreSystemCalculation.java @@ -0,0 +1,133 @@ +package util.ZScore; + +/** + * Created by Iq on 24/05/16. + */ +public class ZScoreSystemCalculation { + private double[]coefficient; + + private String zScoreClassification(String[]classificationTable, double zScore){ + return zScore < -3 ? classificationTable[0] : + zScore < -2 ? classificationTable[1] : + zScore < 2 ? classificationTable[2] : + classificationTable[3]; + } + + public String getWFAZScoreClassification(double zScore){ + return zScoreClassification(new ReferenceTableForDailyIndex().WeightAgeStandardIndex,zScore); + } + + + public String getHFAZScoreClassification(double zScore){ + return zScoreClassification(new ReferenceTableForDailyIndex().HeightAgeStandardIndex,zScore); + } + + public String getWFLZScoreClassification(double zScore){ + return zScoreClassification(new ReferenceTableForDailyIndex().WeightHeightStandardIndex,zScore); + } + + private double zScoreCalculation(double Y,double[]coefficient){ + double L = coefficient[1]; + double M = coefficient[2]; + double S = coefficient[3]; + + double result = (Math.pow((Y/M),L)-1)/(S*L); + + if(result<-3){ + double sd23 = (M*Math.pow((1+L*S*-2),1/L)) - (M*Math.pow((1+L*S*-3),1/L)); + double sd3 = (M*Math.pow((1+L*S*-3),1/L)); + result = -3+((Y-sd3)/sd23); + } + else if(result>3){ + double sd23 = (M*Math.pow((1+L*S*3),1/L)) - (M*Math.pow((1+L*S*2),1/L)); + double sd3 = (M*Math.pow((1+L*S*3),1/L)); + result = 3+((Y-sd3)/sd23); + } + return result; + } + + public double countWFA(String gender, String dateOfBirth, String lastVisitDate, double weight){ + return countWFA(!gender.contains("em"),dailyUnitCalculationOf(dateOfBirth,lastVisitDate),weight); + } + + public double countWFA(boolean isMale,int age,double weight){ + + coefficient = isMale ? new ReferenceTableForDailyIndex().getBoysWeightForAge(age): + new ReferenceTableForDailyIndex().getGirlsWeightForAge(age); + return this.zScoreCalculation(weight, coefficient); + } + + public double countHFA(String gender, String dateOfBirth, String lastVisitDate, double height){ + return countHFA(!gender.contains("em"),dailyUnitCalculationOf(dateOfBirth,lastVisitDate),height); + } + + public double countHFA(boolean isMale,int age, double height){ + + coefficient = isMale ? new ReferenceTableForDailyIndex().getBoysLengthForAge(age): + new ReferenceTableForDailyIndex().getGirlsLengthForAge(age); + return this.zScoreCalculation(height, coefficient); + } + + public double countWFL(String gender, double weight,double height){ + return countWFL(!gender.contains("em"),weight,height); + } + + public double countWFL(boolean isMale, double weight, double length){ + int index = length <=45 ? 0: (int)((length - 45.0)*10); + coefficient = isMale ? new ReferenceTableForDailyIndex().getBoysWeightForLength(index): + new ReferenceTableForDailyIndex().getGirlsWeightForLength(index); + return this.zScoreCalculation(weight, coefficient); + } + + public double countWFH(String gender, double weight,double height){ + return countWFH(gender.contains("l"),weight,height); + } + + public double countWFH(boolean isMale, double weight,double height){ + int index = height <=65 ? 0: (int)((height - 65.0)*10); + coefficient = isMale ? new ReferenceTableForDailyIndex().getBoysWeightForHeight(index): + new ReferenceTableForDailyIndex().getGirlsWeightForHeight(index); + return this.zScoreCalculation(weight, coefficient); + } + + public double countBMI(String gender, String dateOfBirth, String lastVisitDate, double weight,double height){ + return countBMI(gender.contains("l"), dailyUnitCalculationOf(dateOfBirth,lastVisitDate),weight,height); + } + + public double countBMI(boolean isMale, int age, double weight,double height){ + double param = weight/Math.pow(height/100,2); + coefficient = isMale ? new ReferenceTableForDailyIndex().getBoysBMIForAge(age): + new ReferenceTableForDailyIndex().getGirlsBMIForAge(age); + return this.zScoreCalculation(param, coefficient); + } + + public int dailyUnitCalculationOf(String dateFrom,String dateTo){ + if(dateFrom.length()<10 || dateTo.length()<10) + return -1; + String[]d1 = dateFrom.split("-"); + String[]d2 = dateTo.split("-"); + + int day1=Integer.parseInt(d1[2]),month1=Integer.parseInt(d1[1]),year1=Integer.parseInt(d1[0]); + int day2=Integer.parseInt(d2[2]),month2=Integer.parseInt(d2[1]),year2=Integer.parseInt(d2[0]); + + int[]dayLength = {31,28,31,30,31,30,31,31,30,31,30,31}; + int counter = 0; + dayLength[1] = year1%4 == 0 ? 29 :28; + + while(day1<=day2 || month1dayLength[month1-1]){ + day1 = 1; + month1++; + } + if (month1 > 12){ + month1=1; + year1++; + dayLength[1] = year1 % 4 == 0 ? 29:28; + } + } + + return counter; + } +} diff --git a/opensrp-gizi/src/main/java/util/formula/Support.java b/opensrp-gizi/src/main/java/util/formula/Support.java new file mode 100644 index 0000000..94e834c --- /dev/null +++ b/opensrp-gizi/src/main/java/util/formula/Support.java @@ -0,0 +1,162 @@ +package util.formula; + +import android.app.Activity; +import android.net.Uri; +import android.widget.ImageView; + +import org.ei.opensrp.util.Log; + +import java.io.File; + +import org.ei.opensrp.commonregistry.CommonPersonObject; +import org.ei.opensrp.commonregistry.CommonPersonObjectClient; + +/** + * Created by al on 30/05/2017. + */ +public class Support { + public static boolean ONSYNC = false; + + public static String[]replace(String[]data,String target,String replacement){ + for(int i=0;i0) + return person.getColumnmaps().get(values); + } + return "-"; + } + + public static String getColumnmaps(CommonPersonObject person, String values){ + if(person.getColumnmaps().get(values)!=null){ + if(person.getColumnmaps().get(values).length()>0) + return person.getColumnmaps().get(values); + } + return "-"; + } + + public static String getDetails(CommonPersonObjectClient person, String values){ + if(person.getDetails().get(values)!=null){ + if(person.getDetails().get(values).length()>0) + return person.getDetails().get(values); + } + return "-"; + } + + public static String getDetails(CommonPersonObject person, String values){ + if(person.getDetails().get(values)!=null){ + if(person.getDetails().get(values).length()>0) + return person.getDetails().get(values); + } + return "-"; + } + + public static String[]insertionSort(String data){ + String[]temp = data.split(","); + for(int i=0;ii;j--){ + if(getAge(temp[j])dayLength[startMonth-1]){ + dayAge = dayAge - dayLength[startMonth-1]; + startMonth++; + if(startMonth>12){ + startYear++; + startMonth = 1; + dayLength[1] = startYear % 4 == 0 ? 29 : 28; + } + } + startDay+=dayAge; + if(startDay > dayLength[startMonth-1]) { + startDay=startDay - dayLength[startMonth-1]; + startMonth++; + } + if(startMonth>12) { + startYear++; + startMonth = 1; + } + + String m = "" + (startMonth<10 ? "0"+startMonth : Integer.toString(startMonth)); + String d = "" + (startDay<10 ? "0"+startDay : Integer.toString(startDay)); + return Integer.toString(startYear)+"-"+m+"-"+d; + } + + public static void setImagetoHolderFromUri(Activity activity, String file, ImageView view, int placeholder) { + view.setImageDrawable(activity.getResources().getDrawable(placeholder)); + File externalFile = new File(file); + if (!externalFile.exists()) { + externalFile = new File(file.replace(".JPEG", ".jpg")); + } + if (externalFile.exists()) { + Uri external = Uri.fromFile(externalFile); + view.setImageURI(external); + } else { + Log.logError(Support.class.getSimpleName(), String.format("image %s doesn't exist",file)); + } + } + + public static int monthAges(String lastVisitDate,String currentDate){ + int tahun = Integer.parseInt(currentDate.substring(0,4))-Integer.parseInt(lastVisitDate.substring(0,4)); + int bulan = Integer.parseInt(currentDate.substring(5,7))-Integer.parseInt(lastVisitDate.substring(5,7)); + int hari = Integer.parseInt(currentDate.substring(8))-Integer.parseInt(lastVisitDate.substring(8)); + return(tahun*12 + bulan + (int)(hari/30)); + } +} diff --git a/opensrp-gizi/src/main/java/util/growthChart/GraphConstant.java b/opensrp-gizi/src/main/java/util/growthChart/GraphConstant.java new file mode 100644 index 0000000..f70c15d --- /dev/null +++ b/opensrp-gizi/src/main/java/util/growthChart/GraphConstant.java @@ -0,0 +1,288 @@ +package util.growthChart; + +/** + * Created by Null on 2016-10-14. + */ +public class GraphConstant { + + public static final int WFA_CHART = 0; + public static final int LFA_CHART = 1; + public static final int HFA_CHART = 2; + public static final int Z_SCORE_CHART = 3; + + public static final double boyWeightChart[][]={ + {2.1,2.5,2.9,3.3,3.9,4.4,5}, + {2.9,3.4,3.9,4.5,5.1,5.8,6.6}, + {3.8,4.3,4.9,5.6,6.3,7.1,8}, + {4.4,5,5.7,6.4,7.2,8,9}, + {4.9,5.6,6.2,7,7.8,8.7,9.7}, + {5.3,6,6.7,7.5,8.4,9.3,10.4}, + {5.7,6.4,7.1,7.9,8.8,9.8,10.9}, + {5.9,6.7,7.4,8.3,9.2,10.3,11.4}, + {6.2,6.9,7.7,8.6,9.6,10.7,11.9}, + {6.4,7.1,8,8.9,9.9,11,12.3}, + {6.6,7.4,8.2,9.2,10.2,11.4,12.7}, + {6.8,7.6,8.4,9.4,10.5,11.7,13}, + {6.9,7.7,8.6,9.6,10.8,12,13.3}, + {7.1,7.9,8.8,9.9,11,12.3,13.7}, + {7.2,8.1,9,10.1,11.3,12.6,14}, + {7.4,8.3,9.2,10.3,11.5,12.8,14.3}, + {7.5,8.4,9.4,10.5,11.7,13.1,14.6}, + {7.7,8.6,9.6,10.7,12,13.4,14.9}, + {7.8,8.8,9.8,10.9,12.2,13.7,15.3}, + {8,8.9,10,11.1,12.5,13.9,15.6}, + {8.1,9.1,10.1,11.3,12.7,14.2,15.9}, + {8.2,9.2,10.3,11.5,12.9,14.5,16.2}, + {8.4,9.4,10.5,11.8,13.2,14.7,16.5}, + {8.5,9.5,10.7,12,13.4,15,16.8}, + {8.6,9.7,10.8,12.2,13.6,15.3,17.1}, + {8.8,9.8,11,12.4,13.9,15.5,17.5}, + {8.9,10,11.2,12.5,14.1,15.8,17.8}, + {9,10.1,11.3,12.7,14.3,16.1,18.1}, + {9.1,10.2,11.5,12.9,14.5,16.3,18.4}, + {9.2,10.4,11.7,13.1,14.8,16.6,18.7}, + {9.4,10.5,11.8,13.3,15,16.9,19}, + {9.5,10.7,12,13.5,15.2,17.1,19.3}, + {9.6,10.8,12.1,13.7,15.4,17.4,19.6}, + {9.7,10.9,12.3,13.8,15.6,17.6,19.9}, + {9.8,11,12.4,14,15.8,17.8,20.2}, + {9.9,11.2,12.6,14.2,16,18.1,20.4}, + {10,11.3,12.7,14.3,16.2,18.3,20.7}, + {10.1,11.4,12.9,14.5,16.4,18.6,21}, + {10.2,11.5,13,14.7,16.6,18.8,21.3}, + {10.3,11.6,13.1,14.8,16.8,19,21.6}, + {10.4,11.8,13.3,15,17,19.3,21.9}, + {10.5,11.9,13.4,15.2,17.2,19.5,22.1}, + {10.6,12,13.6,15.3,17.4,19.7,22.4}, + {10.7,12.1,13.7,15.5,17.6,20,22.7}, + {10.8,12.2,13.8,15.7,17.8,20.2,23}, + {10.9,12.4,14,15.8,18,20.5,23.3}, + {11,12.5,14.1,16,18.2,20.7,23.6}, + {11.1,12.6,14.3,16.2,18.4,20.9,23.9}, + {11.2,12.7,14.4,16.3,18.6,21.2,24.2}, + {11.3,12.8,14.5,16.5,18.8,21.4,24.5}, + {11.4,12.9,14.7,16.7,19,21.7,24.8}, + {11.5,13.1,14.8,16.8,19.2,21.9,25.1}, + {11.6,13.2,15,17,19.4,22.2,25.4}, + {11.7,13.3,15.1,17.2,19.6,22.4,25.7}, + {11.8,13.4,15.2,17.3,19.8,22.7,26}, + {11.9,13.5,15.4,17.5,20,22.9,26.3}, + {12,13.6,15.5,17.7,20.2,23.2,26.6}, + {12.1,13.7,15.6,17.8,20.4,23.4,26.9}, + {12.2,13.8,15.8,18,20.6,23.7,27.2}, + {12.3,14,15.9,18.2,20.8,23.9,27.6}, + {12.4,14.1,16,18.3,21,24.2,27.9} + }; + + public static final double girlWeightChart[][]={ + {2,2.4,2.8,3.2,3.7,4.2,4.8}, + {2.7,3.2,3.6,4.2,4.8,5.5,6.2}, + {3.4,3.9,4.5,5.1,5.8,6.6,7.5}, + {4,4.5,5.2,5.8,6.6,7.5,8.5}, + {4.4,5,5.7,6.4,7.3,8.2,9.3}, + {4.8,5.4,6.1,6.9,7.8,8.8,10}, + {5.1,5.7,6.5,7.3,8.2,9.3,10.6}, + {5.3,6,6.8,7.6,8.6,9.8,11.1}, + {5.6,6.3,7,7.9,9,10.2,11.6}, + {5.8,6.5,7.3,8.2,9.3,10.5,12}, + {5.9,6.7,7.5,8.5,9.6,10.9,12.4}, + {6.1,6.9,7.7,8.7,9.9,11.2,12.8}, + {6.3,7,7.9,8.9,10.1,11.5,13.1}, + {6.4,7.2,8.1,9.2,10.4,11.8,13.5}, + {6.6,7.4,8.3,9.4,10.6,12.1,13.8}, + {6.7,7.6,8.5,9.6,10.9,12.4,14.1}, + {6.9,7.7,8.7,9.8,11.1,12.6,14.5}, + {7,7.9,8.9,10,11.4,12.9,14.8}, + {7.2,8.1,9.1,10.2,11.6,13.2,15.1}, + {7.3,8.2,9.2,10.4,11.8,13.5,15.4}, + {7.5,8.4,9.4,10.6,12.1,13.7,15.7}, + {7.6,8.6,9.6,10.9,12.3,14,16}, + {7.8,8.7,9.8,11.1,12.5,14.3,16.4}, + {7.9,8.9,10,11.3,12.8,14.6,16.7}, + {8.1,9,10.2,11.5,13,14.8,17}, + {8.2,9.2,10.3,11.7,13.3,15.1,17.3}, + {8.4,9.4,10.5,11.9,13.5,15.4,17.7}, + {8.5,9.5,10.7,12.1,13.7,15.7,18}, + {8.6,9.7,10.9,12.3,14,16,18.3}, + {8.8,9.8,11.1,12.5,14.2,16.2,18.7}, + {8.9,10,11.2,12.7,14.4,16.5,19}, + {9,10.1,11.4,12.9,14.7,16.8,19.3}, + {9.1,10.3,11.6,13.1,14.9,17.1,19.6}, + {9.3,10.4,11.7,13.3,15.1,17.3,20}, + {9.4,10.5,11.9,13.5,15.4,17.6,20.3}, + {9.5,10.7,12,13.7,15.6,17.9,20.6}, + {9.6,10.8,12.2,13.9,15.8,18.1,20.9}, + {9.7,10.9,12.4,14,16,18.4,21.3}, + {9.8,11.1,12.5,14.2,16.3,18.7,21.6}, + {9.9,11.2,12.7,14.4,16.5,19,22}, + {10.1,11.3,12.8,14.6,16.7,19.2,22.3}, + {10.2,11.5,13,14.8,16.9,19.5,22.7}, + {10.3,11.6,13.1,15,17.2,19.8,23}, + {10.4,11.7,13.3,15.2,17.4,20.1,23.4}, + {10.5,11.8,13.4,15.3,17.6,20.4,23.7}, + {10.6,12,13.6,15.5,17.8,20.7,24.1}, + {10.7,12.1,13.7,15.7,18.1,20.9,24.5}, + {10.8,12.2,13.9,15.9,18.3,21.2,24.8}, + {10.9,12.3,14,16.1,18.5,21.5,25.2}, + {11,12.4,14.2,16.3,18.8,21.8,25.5}, + {11.1,12.6,14.3,16.4,19,22.1,25.9}, + {11.2,12.7,14.5,16.6,19.2,22.4,26.3}, + {11.3,12.8,14.6,16.8,19.4,22.6,26.6}, + {11.4,12.9,14.8,17,19.7,22.9,27}, + {11.5,13,14.9,17.2,19.9,23.2,27.4}, + {11.6,13.2,15.1,17.3,20.1,23.5,27.7}, + {11.7,13.3,15.2,17.5,20.3,23.8,28.1}, + {11.8,13.4,15.3,17.7,20.6,24.1,28.5}, + {11.9,13.5,15.5,17.9,20.8,24.4,28.8}, + {12,13.6,15.6,18,21,24.6,29.2}, + {12.1,13.7,15.8,18.2,21.2,24.9,29.5} + }; + + public static final double boyLengthChart[][]={ + {44.2,46.1,48,49.9,51.8,53.7,55.6}, + {48.9,50.8,52.8,54.7,56.7,58.6,60.6}, + {52.4,54.4,56.4,58.4,60.4,62.4,64.4}, + {55.3,57.3,59.4,61.4,63.5,65.5,67.6}, + {57.6,59.7,61.8,63.9,66,68,70.1}, + {59.6,61.7,63.8,65.9,68,70.1,72.2}, + {61.2,63.3,65.5,67.6,69.8,71.9,74}, + {62.7,64.8,67,69.2,71.3,73.5,75.7}, + {64,66.2,68.4,70.6,72.8,75,77.2}, + {65.2,67.5,69.7,72,74.2,76.5,78.7}, + {66.4,68.7,71,73.3,75.6,77.9,80.1}, + {67.6,69.9,72.2,74.5,76.9,79.2,81.5}, + {68.6,71,73.4,75.7,78.1,80.5,82.9}, + {69.6,72.1,74.5,76.9,79.3,81.8,84.2}, + {70.6,73.1,75.6,78,80.5,83,85.5}, + {71.6,74.1,76.6,79.1,81.7,84.2,86.7}, + {72.5,75,77.6,80.2,82.8,85.4,88}, + {73.3,76,78.6,81.2,83.9,86.5,89.2}, + {74.2,76.9,79.6,82.3,85,87.7,90.4}, + {75,77.7,80.5,83.2,86,88.8,91.5}, + {75.8,78.6,81.4,84.2,87,89.8,92.6}, + {76.5,79.4,82.3,85.1,88,90.9,93.8}, + {77.2,80.2,83.1,86,89,91.9,94.9}, + {78,81,83.9,86.9,89.9,92.9,95.9}, + {78.7,81.7,84.8,87.8,90.9,93.9,97} + }; + + public static final double girlLengthChart[][]={ + {43.6,45.4,47.3,49.1,51,52.9,54.7}, + {47.8,49.8,51.7,53.7,55.6,57.6,59.5}, + {51,53,55,57.1,59.1,61.1,63.2}, + {53.5,55.6,57.7,59.8,61.9,64,66.1}, + {55.6,57.8,59.9,62.1,64.3,66.4,68.6}, + {57.4,59.6,61.8,64,66.2,68.5,70.7}, + {58.9,61.2,63.5,65.7,68,70.3,72.5}, + {60.3,62.7,65,67.3,69.6,71.9,74.2}, + {61.7,64,66.4,68.7,71.1,73.5,75.8}, + {62.9,65.3,67.7,70.1,72.6,75,77.4}, + {64.1,66.5,69,71.5,73.9,76.4,78.9}, + {65.2,67.7,70.3,72.8,75.3,77.8,80.3}, + {66.3,68.9,71.4,74,76.6,79.2,81.7}, + {67.3,70,72.6,75.2,77.8,80.5,83.1}, + {68.3,71,73.7,76.4,79.1,81.7,84.4}, + {69.3,72,74.8,77.5,80.2,83,85.7}, + {70.2,73,75.8,78.6,81.4,84.2,87}, + {71.1,74,76.8,79.7,82.5,85.4,88.2}, + {72,74.9,77.8,80.7,83.6,86.5,89.4}, + {72.8,75.8,78.8,81.7,84.7,87.6,90.6}, + {73.7,76.7,79.7,82.7,85.7,88.7,91.7}, + {74.5,77.5,80.6,83.7,86.7,89.8,92.9}, + {75.2,78.4,81.5,84.6,87.7,90.8,94}, + {76,79.2,82.3,85.5,88.7,91.9,95}, + {76.7,80,83.2,86.4,89.6,92.9,96.1} + }; + + public static final double boyHeightChart[][]={ + {78,81,84.1,87.1,90.2,93.2,96.3}, + {78.6,81.7,84.9,88,91.1,94.2,97.3}, + {79.3,82.5,85.6,88.8,92,95.2,98.3}, + {79.9,83.1,86.4,89.6,92.9,96.1,99.3}, + {80.5,83.8,87.1,90.4,93.7,97,100.3}, + {81.1,84.5,87.8,91.2,94.5,97.9,101.2}, + {81.7,85.1,88.5,91.9,95.3,98.7,102.1}, + {82.3,85.7,89.2,92.7,96.1,99.6,103}, + {82.8,86.4,89.9,93.4,96.9,100.4,103.9}, + {83.4,86.9,90.5,94.1,97.6,101.2,104.8}, + {83.9,87.5,91.1,94.8,98.4,102,105.6}, + {84.4,88.1,91.8,95.4,99.1,102.7,106.4}, + {85,88.7,92.4,96.1,99.8,103.5,107.2}, + {85.5,89.2,93,96.7,100.5,104.2,108}, + {86,89.8,93.6,97.4,101.2,105,108.8}, + {86.5,90.3,94.2,98,101.8,105.7,109.5}, + {87,90.9,94.7,98.6,102.5,106.4,110.3}, + {87.5,91.4,95.3,99.2,103.2,107.1,111}, + {88,91.9,95.9,99.9,103.8,107.8,111.7}, + {88.4,92.4,96.4,100.4,104.5,108.5,112.5}, + {88.9,93,97,101,105.1,109.1,113.2}, + {89.4,93.5,97.5,101.6,105.7,109.8,113.9}, + {89.8,94,98.1,102.2,106.3,110.4,114.6}, + {90.3,94.4,98.6,102.8,106.9,111.1,115.2}, + {90.7,94.9,99.1,103.3,107.5,111.7,115.9}, + {91.2,95.4,99.7,103.9,108.1,112.4,116.6}, + {91.6,95.9,100.2,104.4,108.7,113,117.3}, + {92.1,96.4,100.7,105,109.3,113.6,117.9}, + {92.5,96.9,101.2,105.6,109.9,114.2,118.6}, + {93,97.4,101.7,106.1,110.5,114.9,119.2}, + {93.4,97.8,102.3,106.7,111.1,115.5,119.9}, + {93.9,98.3,102.8,107.2,111.7,116.1,120.6}, + {94.3,98.8,103.3,107.8,112.3,116.7,121.2}, + {94.7,99.3,103.8,108.3,112.8,117.4,121.9}, + {95.2,99.7,104.3,108.9,113.4,118,122.6}, + {95.6,100.2,104.8,109.4,114,118.6,123.2}, + {96.1,100.7,105.3,110,114.6,119.2,123.9} + }; + + public static final double girlHeightChart[][]={ + {76,79.3,82.5,85.7,88.9,92.2,95.4}, + {76.8,80,83.3,86.6,89.9,93.1,96.4}, + {77.5,80.8,84.1,87.4,90.8,94.1,97.4}, + {78.1,81.5,84.9,88.3,91.7,95,98.4}, + {78.8,82.2,85.7,89.1,92.5,96,99.4}, + {79.5,82.9,86.4,89.9,93.4,96.9,100.3}, + {80.1,83.6,87.1,90.7,94.2,97.7,101.3}, + {80.7,84.3,87.9,91.4,95,98.6,102.2}, + {81.3,84.9,88.6,92.2,95.8,99.4,103.1}, + {81.9,85.6,89.3,92.9,96.6,100.3,103.9}, + {82.5,86.2,89.9,93.6,97.4,101.1,104.8}, + {83.1,86.8,90.6,94.4,98.1,101.9,105.6}, + {83.6,87.4,91.2,95.1,98.9,102.7,106.5}, + {84.2,88,91.9,95.7,99.6,103.4,107.3}, + {84.7,88.6,92.5,96.4,100.3,104.2,108.1}, + {85.3,89.2,93.1,97.1,101,105,108.9}, + {85.8,89.8,93.8,97.7,101.7,105.7,109.7}, + {86.3,90.4,94.4,98.4,102.4,106.4,110.5}, + {86.8,90.9,95,99,103.1,107.2,111.2}, + {87.4,91.5,95.6,99.7,103.8,107.9,112}, + {87.9,92,96.2,100.3,104.5,108.6,112.7}, + {88.4,92.5,96.7,100.9,105.1,109.3,113.5}, + {88.9,93.1,97.3,101.5,105.8,110,114.2}, + {89.3,93.6,97.9,102.1,106.4,110.7,114.9}, + {89.8,94.1,98.4,102.7,107,111.3,115.7}, + {90.3,94.6,99,103.3,107.7,112,116.4}, + {90.7,95.1,99.5,103.9,108.3,112.7,117.1}, + {91.2,95.6,100.1,104.5,108.9,113.3,117.7}, + {91.7,96.1,100.6,105,109.5,114,118.4}, + {92.1,96.6,101.1,105.6,110.1,114.6,119.1}, + {92.6,97.1,101.6,106.2,110.7,115.2,119.8}, + {93,97.6,102.2,106.7,111.3,115.9,120.4}, + {93.4,98.1,102.7,107.3,111.9,116.5,121.1}, + {93.9,98.5,103.2,107.8,112.5,117.1,121.8}, + {94.3,99,103.7,108.4,113,117.7,122.4}, + {94.7,99.5,104.2,108.9,113.6,118.3,123.1}, + {95.2,99.9,104.7,109.4,114.2,118.9,123.7} + + }; + + public static double[][] zScoreBackground(){ + double data[][]=new double[61][7]; + for(int i=0;i series, int backGround, int color, int thick,String title, boolean putStroke){ +// series.setTitle(title); +// this.initSeries(series, backGround, color, thick); +// if(putStroke){ +// series.setDrawDataPoints(true); +// series.setDataPointsRadius(5); +// } +// } + + private void initSeries(LineGraphSeries series, int backGround, int color, int thick){ + series.setDrawBackground(true); + series.setBackgroundColor(backGround); + series.setColor(color); + series.setThickness(thick); + } + + private LineGraphSeriescreateDataSeries(String []age,String []weight){ + LineGraphSeriesseries=new LineGraphSeries<>(); + series.setDrawDataPoints(true); + series.setDataPointsRadius(dataPointRadius); + series.setColor(zScoreChartColor[index]); + if(age[0]!=null) + series.appendData(new DataPoint(Double.parseDouble(age[0]), Double.parseDouble(weight[0])), false, 70); + for(int i=0;i1) + counter++; + if(series[counter]==null){ + series[counter]=weightDouble[i]; + axis[counter]=Integer.toString(dateInt[i]); + } + else{ + series[counter] = series[counter]+","+weightDouble[i]; + axis[counter]=axis[counter]+","+Integer.toString(dateInt[i]); + } + } + //System.out.println("index of line 172 = "+index); + ArrayListlist = new ArrayList<>(); + LineGraphSeriestemp = new LineGraphSeries<>(); + for(int i=0;i=date.length || i>=value.length) // prevent null data on chart + break; + createLineChart(graph, dateOfBirth, date[i], value[i]); + } + } + + private int[]calculateAgesFrom(String dateOfBirth,String []data){ + int[]result=new int[data.length]; + if(data[0].length()>5) { + for (int i = 0; i < data.length; i++) { + result[i] = getMonthAge(dateOfBirth, data[i]); + } + }else{ + for (int i=0;i1) + counter++; + } + return counter+1; + } + + public void putSeriesOfIndex(int idx){ + index = idx; + if(!chartDisplay[index] && a[index]!=null){ + for(int i=0;i series1 = new LineGraphSeries(); + LineGraphSeries series2 = new LineGraphSeries(); + LineGraphSeries series3 = new LineGraphSeries(); + LineGraphSeries series4 = new LineGraphSeries(); + LineGraphSeries series5 = new LineGraphSeries(); + LineGraphSeries series6 = new LineGraphSeries(); + LineGraphSeries series7 = new LineGraphSeries(); +// LineGraphSeries seriesMain = new LineGraphSeries(); + + private double [][]graphLine; + private String xValue; + private String yValue; + private String dateOfBirth; + private String gender; + LineGraphSeries [][]a; + + /** + * age shift used to shift X-Axis value so the axis value will start from (0 + ageShift) value, + * currently used when generating height for age chart. + */ + private int ageShift = 0; + private int index = 0; + private boolean[]chartDisplay = {true,true,true}; + + private final int red = Color.rgb(255,0,0); + private final int yellow = Color.rgb(255,255,0); + private final int green = Color.rgb(0,255,0); + private final int blue = Color.rgb(0,32,255); + private final int purple = Color.rgb(239,0,255); + private final int orange = Color.rgb(255,111,0); + private final int []zScoreChartColor = {blue,purple,orange}; + private final int dataPointRadius = 7; +} diff --git a/opensrp-gizi/src/main/java/util/uniqueIdGenerator/AllSettingsINA.java b/opensrp-gizi/src/main/java/util/uniqueIdGenerator/AllSettingsINA.java new file mode 100644 index 0000000..c4de89e --- /dev/null +++ b/opensrp-gizi/src/main/java/util/uniqueIdGenerator/AllSettingsINA.java @@ -0,0 +1,35 @@ +package util.uniqueIdGenerator; + +import org.ei.opensrp.repository.AllSettings; +import org.ei.opensrp.repository.AllSharedPreferences; +import org.ei.opensrp.repository.SettingsRepository; + +/** + * Created by Dimas on 9/17/2015. + */ +public class AllSettingsINA extends AllSettings { + + private static final String LAST_USED_UNIQUE_ID = "lastUsedId"; + private static final String CURRENT_UNIQUE_ID = "currentUniqueId"; + + public AllSettingsINA(AllSharedPreferences preferences, SettingsRepository settingsRepository) { + super(preferences, settingsRepository); + } + + public void saveLastUsedId(String lastUsedId) { + settingsRepository.updateSetting(LAST_USED_UNIQUE_ID, lastUsedId); + } + + public String fetchLastUsedId() { + return settingsRepository.querySetting(LAST_USED_UNIQUE_ID, "0"); + } + + public void saveCurrentId(String currentId) { + settingsRepository.updateSetting(CURRENT_UNIQUE_ID, currentId); + } + + public String fetchCurrentId() { + return settingsRepository.querySetting(CURRENT_UNIQUE_ID, "0"); + } + +} \ No newline at end of file diff --git a/opensrp-gizi/src/main/java/util/uniqueIdGenerator/Generator.java b/opensrp-gizi/src/main/java/util/uniqueIdGenerator/Generator.java new file mode 100644 index 0000000..b8c863f --- /dev/null +++ b/opensrp-gizi/src/main/java/util/uniqueIdGenerator/Generator.java @@ -0,0 +1,151 @@ +package util.uniqueIdGenerator; + +import android.os.AsyncTask; +import android.util.Log; + +import org.apache.http.HttpEntity; +import org.apache.http.HttpResponse; +import org.apache.http.StatusLine; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.impl.client.DefaultHttpClient; +import org.ei.opensrp.Context; +import org.ei.opensrp.gizi.LoginActivity; +import org.ei.opensrp.util.Cache; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.util.List; + +/** + * Created by Null on 2016-10-13. + */ +public class Generator { + private UniqueIdRepository uniqueIdRepository; + private Cache> uIdsCache; + private AllSettingsINA allSettingsINA; + private UniqueIdController uniqueIdController; + private UniqueIdService uniqueIdService; + private Context context; + + private String url; + private String result; + + public static final int UNIQUE_ID_LIMIT = 10; + public static final int UNIQUE_ID_LENGTH_REQUEST = 15; + + public Generator(Context context, String username, String password){ + this.context=context; + String DRISTHI_BASE_URL = context.configuration().dristhiBaseURL().replaceFirst("[^/]*$", "openmrs"); + url = DRISTHI_BASE_URL+ + "/module/idgen/exportIdentifiers.form?source=1"+ + "&numberToGenerate="+Integer.toString(UNIQUE_ID_LENGTH_REQUEST)+ + "&username="+username+ + "&password="+password; + } + + public AllSettingsINA allSettingsINA() { + context.initializeRepositoryForUniqueId(); + if(allSettingsINA == null) + allSettingsINA = new AllSettingsINA(context.allSharedPreferences(), context.getSettingsRepositoryforUniqueId()); + + return allSettingsINA; + } + public Cache> uIdsCache() { + if (uIdsCache == null) + uIdsCache = new Cache<>(); + return uIdsCache; + } + public UniqueIdRepository uniqueIdRepository() { + if(uniqueIdRepository==null) + uniqueIdRepository = new UniqueIdRepository(context.applicationContext()); + return uniqueIdRepository; + } + public UniqueIdController uniqueIdController() { + if(uniqueIdController == null) + uniqueIdController = new UniqueIdController(uniqueIdRepository(), allSettingsINA(), uIdsCache()); + return uniqueIdController; + } + public UniqueIdService uniqueIdService() { + if (uniqueIdService == null) + uniqueIdService = new UniqueIdService(context.getHttpAgent(), context.configuration(), uniqueIdController(), allSettingsINA(), context.allSharedPreferences()); + return uniqueIdService; + } + + public void requestUniqueId(){ + try { + IdgenModuleAccessor module = new IdgenModuleAccessor(); + module.execute(); +// return new Response<>(module.getResult().equals("")?ResponseStatus.failure:ResponseStatus.success,module.getResult()); + }catch(Exception ex){ + ex.printStackTrace(); +// return new Response<>(ResponseStatus.failure,""); + } + } + + private String connectToOpenMRS() { + try { + StringBuilder builder = new StringBuilder(); + HttpClient client = new DefaultHttpClient(); + HttpGet httpGet = new HttpGet(url); + + httpGet.setHeader("Content-Type", "application/json"); + try { + HttpResponse response = client.execute(httpGet); + StatusLine statusLine = response.getStatusLine(); + int statusCode = statusLine.getStatusCode(); + if (statusCode == 200) { + HttpEntity entity = response.getEntity(); + InputStream content = entity.getContent(); + BufferedReader reader = new BufferedReader(new InputStreamReader(content)); + String line; + while ((line = reader.readLine()) != null) { + builder.append(line); + } + //System.out.println("builder string = "+builder.toString()); + return builder.toString(); + } else { + Log.e("", "Failed to download file"); + } + } catch (ClientProtocolException e) { + //System.out.println("failed !!! ClientProtocolException "); + e.printStackTrace(); + } catch (IOException e) { + //System.out.println("Failed !!! IOException"); + e.printStackTrace(); + } + } catch (Exception e) { + Log.e("", e.getMessage()); + //System.out.println("Failed !!!, Exception"); + } + return ""; + } + + private class IdgenModuleAccessor extends AsyncTask { + + @Override + protected String doInBackground(String... params) { + result = connectToOpenMRS(); + if(result.length()>1) + LoginActivity.generator.uniqueIdService().saveJsonResponseToUniqueId(result); + + return "Executed"; + } + + @Override + protected void onPostExecute(String result) { + + // might want to change "executed" for the returned string passed + // into onPostExecute() but that is upto you + } + + @Override + protected void onPreExecute() {} + + @Override + protected void onProgressUpdate(Void... values) {} + } +} diff --git a/opensrp-gizi/src/main/java/util/uniqueIdGenerator/UniqueIdController.java b/opensrp-gizi/src/main/java/util/uniqueIdGenerator/UniqueIdController.java new file mode 100644 index 0000000..d1326ca --- /dev/null +++ b/opensrp-gizi/src/main/java/util/uniqueIdGenerator/UniqueIdController.java @@ -0,0 +1,120 @@ +package util.uniqueIdGenerator; + +import android.support.annotation.Nullable; + +import org.ei.opensrp.util.Cache; +import org.json.JSONException; +import org.json.JSONObject; + +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + + * Created by Dimas on 9/8/2015. + + */ +public class UniqueIdController { + + private AllSettingsINA allSettings; + private UniqueIdRepository uniqueIdRepository; + private Cache> cache; + + public UniqueIdController(UniqueIdRepository uniqueIdRepository, AllSettingsINA allSettings, Cache> cache) { + this.uniqueIdRepository = uniqueIdRepository; + this.allSettings = allSettings; + this.cache = cache; + } + + public String getUniqueId() { + List uids = getAllUniqueId(); + List uidstring = getAllUniqueIdString(); + return processLatestUniqueId(uids,uidstring); + } + + public String getUniqueIdJson() { + String uniqueId = getUniqueId(); + if(uniqueId == null || uniqueId.isEmpty()) { + return null; + } + JSONObject obj = new JSONObject(); + try { + obj.put("unique_id", uniqueId); + } catch (JSONException e) { + e.printStackTrace(); + } + return obj.toString(); + } + + public void updateCurrentUniqueId(String id) { + Long ids = Long.parseLong(allSettings.fetchCurrentId()); + id = id.length()>8? id.substring(0,8) : id; + if((ids > 20000000) || (ids < Long.parseLong(id))) { + allSettings.saveCurrentId(id); + } + } + + public List getAllUniqueId() { + return uniqueIdRepository.getAllUniqueId(); + } + + public List getAllUniqueIdString() { + return uniqueIdRepository.getAllUniqueIdString(); + } + + public void saveUniqueId(String uniqueId) { + uniqueIdRepository.saveUniqueId(uniqueId); + } + + public boolean needToRefillUniqueId() { + List uids = getAllUniqueId(); + int currentId = Integer.parseInt(allSettings.fetchCurrentId()); + return uids==null || uids.isEmpty() || uids.get(uids.size()-15) < currentId; + } + + public boolean needToRefillUniqueId(int limit) { + List uids = getAllUniqueId(); + int currentId = Integer.parseInt(allSettings.fetchCurrentId()); + return uids==null || uids.isEmpty() || (uids.get(uids.size()-(limit+1) < 0 ? 0 : uids.size()-(limit+1)) <= currentId); + } + + public int countRemainingUniqueId(){ + List uids = getAllUniqueId(); + int currentId = Integer.parseInt(allSettings.fetchCurrentId())>200000000 + ? 10000000 : Integer.parseInt(allSettings.fetchCurrentId()); + return (uids.size()-1)- Collections.binarySearch(uids,new Long(currentId)); + } + + // Class for testing + public boolean needToRefillUniqueIdTest() { + List uids = uniqueIdRepository.getAllUniqueId(); + long currentId = Long.parseLong(allSettings.fetchCurrentId()); + return (uids.get(uids.size()-1)/10) - currentId <= uids.size()/4; + } + + public String getUniqueIdTest() { + List uids = uniqueIdRepository.getAllUniqueId(); + return processLatestUniqueId(uids); + } + + @Nullable + private String processLatestUniqueId(List uids) { + Long currentId = Long.parseLong(allSettings.fetchCurrentId()) > 20000000 ? 10000000 : Long.parseLong(allSettings.fetchCurrentId()); + if(uids == null || uids.isEmpty() || currentId > uids.get(uids.size()-1)) { + return null; + } + int index = Arrays.binarySearch(uids.toArray(), currentId); + if(index<-1) index = -1; + return index >= uids.size()-1 ? null : "" + String.valueOf(uids.get(index+1)); + } + + @Nullable + private String processLatestUniqueId(List uids,Listuidstring) { + Long currentId = Long.parseLong(allSettings.fetchCurrentId()) > 20000000 ? 10000000 : Long.parseLong(allSettings.fetchCurrentId()); + if(uids == null || uids.isEmpty() || currentId > uids.get(uids.size() - 1)) + return null; + int index = Arrays.binarySearch(uids.toArray(), currentId); + if(index<-1) index = -1; + return index >= uidstring.size()-1 ? null : "" + String.valueOf(uidstring.get(index+1)); + } + +} diff --git a/opensrp-gizi/src/main/java/util/uniqueIdGenerator/UniqueIdRepository.java b/opensrp-gizi/src/main/java/util/uniqueIdGenerator/UniqueIdRepository.java new file mode 100644 index 0000000..54f2280 --- /dev/null +++ b/opensrp-gizi/src/main/java/util/uniqueIdGenerator/UniqueIdRepository.java @@ -0,0 +1,97 @@ +package util.uniqueIdGenerator; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; + +import java.util.ArrayList; +import java.util.List; + +/** + + * Created by Dimas on 9/7/2015, modify by Marwan on 17/11/2016 + + */ +public class UniqueIdRepository extends SQLiteOpenHelper{ + + private static final String UNIQUE_ID_SQL = "CREATE TABLE IF NOT EXISTS unique_id(id INTEGER PRIMARY KEY AUTOINCREMENT, uniqueId VARCHAR)"; + private static final String DB_NAME = "uniqueiddb"; + + private static final String UNIQUE_ID_TABLE_NAME = "unique_id"; + private static final String UNIQUE_ID_COLUMN = "uniqueId"; + + public UniqueIdRepository(Context context){ + super(context, DB_NAME, null, 1); + } + + @Override + public void onCreate(SQLiteDatabase database) { + database.execSQL(UNIQUE_ID_SQL); + } + + @Override + public void onUpgrade(SQLiteDatabase db,int oldVersion, int newVersion){ + + } + + public void saveUniqueId(String uniqueId) { + //System.out.println("uniqueId on saveUniqueId method = "+uniqueId); + if(Long.parseLong(uniqueId.substring(0,8))>Long.parseLong("20000000")) + uniqueId = "10000000"; + SQLiteDatabase database = this.getWritableDatabase(); + ContentValues values = new ContentValues(); + values.put(UNIQUE_ID_COLUMN, uniqueId); + database.insert(UNIQUE_ID_TABLE_NAME, null, values); + } + + public String getUniqueIdFromLastUsedId(String lastUsedId) { + SQLiteDatabase database = this.getReadableDatabase(); + Cursor cursor = database.rawQuery("SELECT " + UNIQUE_ID_COLUMN + + " FROM " + UNIQUE_ID_TABLE_NAME + + " WHERE " + UNIQUE_ID_COLUMN + " > ?" + + " ORDER BY " + UNIQUE_ID_COLUMN + " ASC " + + " LIMIT 1", new String[]{lastUsedId}); + String uniqueId = null; + if(cursor!=null) { + if(cursor.moveToFirst()) { + uniqueId = cursor.getString(0); + } + cursor.close(); + } + return uniqueId; + } + + public List getAllUniqueId() { + SQLiteDatabase database = this.getReadableDatabase(); + Cursor cursor = database.rawQuery("SELECT id, " + UNIQUE_ID_COLUMN + + " FROM " + UNIQUE_ID_TABLE_NAME, new String[]{}); + cursor.moveToFirst(); + List uids = new ArrayList<>(); + while(!cursor.isAfterLast()) { + uids.add(cursor.getLong(1)); + cursor.moveToNext(); + } + cursor.close(); + return uids; + } + + public List getAllUniqueIdString() { + SQLiteDatabase database = this.getReadableDatabase(); + Cursor cursor = database.rawQuery("SELECT id, " + UNIQUE_ID_COLUMN + + " FROM " + UNIQUE_ID_TABLE_NAME, new String[]{}); + cursor.moveToFirst(); + List uids = new ArrayList<>(); + while(!cursor.isAfterLast()) { + uids.add(cursor.getString(1)); + cursor.moveToNext(); + } + cursor.close(); + return uids; + } + + public void deleteUsedId(int lastUsedId){ + SQLiteDatabase database = this.getWritableDatabase(); + List allUniqueId = this.getAllUniqueId(); + database.delete(UNIQUE_ID_TABLE_NAME, UNIQUE_ID_COLUMN + " < ?", new String[]{Integer.toString(lastUsedId)}); + } +} \ No newline at end of file diff --git a/opensrp-gizi/src/main/java/util/uniqueIdGenerator/UniqueIdService.java b/opensrp-gizi/src/main/java/util/uniqueIdGenerator/UniqueIdService.java new file mode 100644 index 0000000..36c2d0d --- /dev/null +++ b/opensrp-gizi/src/main/java/util/uniqueIdGenerator/UniqueIdService.java @@ -0,0 +1,204 @@ +package util.uniqueIdGenerator; + +import org.ei.opensrp.DristhiConfiguration; +import org.ei.opensrp.domain.FetchStatus; +import org.ei.opensrp.domain.Response; +import org.ei.opensrp.domain.ResponseStatus; +import org.ei.opensrp.gizi.LoginActivity; +import org.ei.opensrp.repository.AllSharedPreferences; +import org.ei.opensrp.service.HTTPAgent; +import org.ei.opensrp.sync.AdditionalSyncService; +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import static java.text.MessageFormat.format; +import static org.ei.opensrp.domain.FetchStatus.fetched; +import static org.ei.opensrp.domain.FetchStatus.fetchedFailed; +import static org.ei.opensrp.domain.FetchStatus.nothingFetched; +import static org.ei.opensrp.domain.ResponseStatus.failure; +import static org.ei.opensrp.util.Log.logDebug; +import static org.ei.opensrp.util.Log.logError; +import static org.ei.opensrp.util.Log.logInfo; + +/** + * Created by Dimas on 9/7/2015. + */ +public class UniqueIdService implements AdditionalSyncService { + + public static final String UNIQUE_ID_PATH = "unique-id"; + public static final String LAST_USED_ID_PATH = "last-used-id"; + public static final String REFILL_UNIQUE_ID = "refill-unique-id"; + private final HTTPAgent httpAgent; + private DristhiConfiguration configuration; + private UniqueIdController uniqueIdController; + private AllSettingsINA allSettings; + private AllSharedPreferences allSharedPreferences; + + public UniqueIdService(HTTPAgent httpAgent, DristhiConfiguration configuration, + UniqueIdController uniqueIdController, AllSettingsINA allSettings, + AllSharedPreferences allSharedPreferences) { + this.httpAgent = httpAgent; + this.configuration = configuration; + this.uniqueIdController = uniqueIdController; + this.allSettings = allSettings; + this.allSharedPreferences = allSharedPreferences; + } + + public FetchStatus sync() { + FetchStatus dataStatus = nothingFetched; + int lastUsedId = Integer.parseInt(allSettings.fetchLastUsedId()); + int currentId = Integer.parseInt(allSettings.fetchCurrentId()); + + if (currentId > lastUsedId) { + lastUsedId = currentId; + pushLastUsedIdToServer(lastUsedId+ ""); + allSettings.saveLastUsedId(lastUsedId+ ""); + } else if (lastUsedId > currentId) { + currentId = lastUsedId; + allSettings.saveCurrentId(currentId+ ""); + } + + if (currentId == 0) { + ResponseStatus status = getLastUsedId(allSharedPreferences.fetchRegisteredANM(), allSettings.fetchANMPassword()); + if (status == ResponseStatus.success) { + dataStatus = fetched; + } + } + + if (uniqueIdController.needToRefillUniqueId()) { + dataStatus = refillUniqueId(); + } + + return dataStatus; + } + + public Response pullUniqueIdFromServer(String username, String password) { +// String baseURL = configuration.dristhiBaseURL(); + while (true) { + String uri = "http://118.91.130.18:8080/openmrs/module/idgen/exportIdentifiers.form?source=1&numberToGenerate="+Integer.toString(LoginActivity.generator.UNIQUE_ID_LENGTH_REQUEST)+"&username="+username+"&password="+password; + Response response = httpAgent.fetchWithCredentials(uri, username, password); + if (response.isFailure()) { + logError(format("Unique id pull failed")); + return new Response<>(failure, ""); + } + logDebug(format("Unique id fetched")); + return new Response<>(response.status(), response.payload() == null ? "" : response.payload()); + } + } + + public ResponseStatus getLastUsedId(String username, String password) { + String baseURL = configuration.dristhiBaseURL(); + while (true) { + String uri = format("{0}/{1}", + baseURL, + LAST_USED_ID_PATH); + Response response = httpAgent.fetchWithCredentials(uri, username, password); + if (response.isFailure()) { + logError(format("Last used id pull failed")); + return ResponseStatus.failure; + } else if (response.payload().isEmpty()) { + logError(format("Last used Id empty")); + return ResponseStatus.failure; + } + logDebug(format("Unique id fetched")); + + try { + JSONObject jsonObject = new JSONObject(response.payload()); + String lastUsedId = jsonObject.getString("lastUsedId"); + allSettings.saveLastUsedId(lastUsedId); + allSettings.saveCurrentId(lastUsedId); + } catch (JSONException e) { + e.printStackTrace(); + } + return ResponseStatus.success; + } + } + + public void pushLastUsedIdToServer(String lastUsedId) { + JSONObject json = new JSONObject(); + try { + json.put("lastUsedId", lastUsedId); + } catch (JSONException e) { + e.printStackTrace(); + return; + } + String jsonPayload = json.toString(); + Response response = httpAgent.post( + format("{0}/{1}", + configuration.dristhiBaseURL(), + LAST_USED_ID_PATH), + jsonPayload); + if (response.isFailure()) { + logError(format("Last used id sync failed. Unique Id: {0}", lastUsedId)); + return; + } + logInfo(format("Last used id sync successfully. Unique Id: {0}", lastUsedId)); + } + + public FetchStatus refillUniqueId() { + Response response = httpAgent.post( + format("{0}/{1}", + configuration.dristhiBaseURL(), + REFILL_UNIQUE_ID), ""); + if (response.isFailure()) { + logError(format("Refill unique id sync failed")); + return fetchedFailed; + } else { + String baseURL = configuration.dristhiBaseURL(); + while (true) { + String uri = format("{0}/{1}", + baseURL, + UNIQUE_ID_PATH); + Response refillResponse = httpAgent.fetch(uri); + //System.out.println(refillResponse.toString()); + if (refillResponse.isFailure()) { + logError(format("Unique id pull failed")); + return fetchedFailed; + } + logDebug(format("Unique id fetched")); + saveJsonResponseToUniqueId(refillResponse.payload()); + return fetched; + } + } + + } + +// public void refillUniqueId(String username, String password){ +// this.syncUniqueIdFromServer(username,password); +// } +// +// public boolean uniqueIdReachLimit(int limit){ +// return uniqueIdController.needToRefillUniqueId(); +// } + + public void saveJsonResponseToUniqueId(String payload) { + if (payload != null) { + try { + JSONObject ids = new JSONObject(payload); + JSONArray uniqueId = ids.getJSONArray("identifiers"); + for (int i = 0; i < uniqueId.length(); i++) { + //System.out.println("unique id "+i+", : "+uniqueId.getString(i)); + } + for (int i = 0; i < uniqueId.length(); i++) { + uniqueIdController.saveUniqueId(uniqueId.getString(i)); + } + } catch (JSONException e) { + e.printStackTrace(); + } + } + } + + public FetchStatus syncUniqueIdFromServer(String username, String password) { + Response uniqueIds = pullUniqueIdFromServer(username, password); + if (uniqueIds.isFailure()) { + return fetchedFailed; + } + if (uniqueIds.payload().isEmpty()) { + return nothingFetched; + } + saveJsonResponseToUniqueId(uniqueIds.payload()); + return fetched; + } + +} \ No newline at end of file diff --git a/opensrp-gizi/src/main/java/widget/CircleFlowIndicator.java b/opensrp-gizi/src/main/java/widget/CircleFlowIndicator.java new file mode 100644 index 0000000..a3e07c3 --- /dev/null +++ b/opensrp-gizi/src/main/java/widget/CircleFlowIndicator.java @@ -0,0 +1,441 @@ +/* + * Copyright (C) 2011 Patrik Ă…kerfeldt + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Paint.Style; +import android.os.AsyncTask; +import android.util.AttributeSet; +import android.view.View; +import android.view.animation.Animation; +import android.view.animation.Animation.AnimationListener; +import android.view.animation.AnimationUtils; + +import org.ei.opensrp.gizi.R; + + +/** + * A FlowIndicator which draws circles (one for each view). + *
+ * Available attributes are:
+ *

    + *
  • + * activeColor: Define the color used to draw the active circle (default to white) + *
  • + *
  • + * inactiveColor: Define the color used to draw the inactive circles (default to 0x44FFFFFF) + *
  • + *
  • + * inactiveType: Define how to draw the inactive circles, either stroke or fill (default to stroke) + *
  • + *
  • + * activeType: Define how to draw the active circle, either stroke or fill (default to fill) + *
  • + *
  • + * fadeOut: Define the time (in ms) until the indicator will fade out (default to 0 = never fade out) + *
  • + *
  • + * radius: Define the circle outer radius (default to 4.0) + *
  • + *
  • + * spacing: Define the circle spacing (default to 4.0) + *
  • + *
  • + * snap: If true, the 'active' indicator snaps from one page to the next; otherwise, it moves smoothly. + *
  • + *
+ */ +public class CircleFlowIndicator extends View implements FlowIndicator, + AnimationListener { + private static final int STYLE_STROKE = 0; + private static final int STYLE_FILL = 1; + + private float mRadius = 4; + private float mRadiusInactive = 4; + private float mRadiusActive = 4; + private float spacing = 4; + private int fadeOutTime = 0; + private final Paint mPaintInactive = new Paint(Paint.ANTI_ALIAS_FLAG); + private final Paint mPaintActive = new Paint(Paint.ANTI_ALIAS_FLAG); + private ViewFlow viewFlow; + private int currentScroll = 0; + private int currentPosition = 0; + private int flowWidth = 0; + private FadeTimer timer; + public AnimationListener animationListener = this; + private Animation animation; + private boolean mCentered = false; + private boolean mSnap = false; + + /** + * Default constructor + * + * @param context + */ + public CircleFlowIndicator(Context context) { + super(context); + initColors(0xFFFFFFFF, 0xFFFFFFFF, STYLE_FILL, STYLE_STROKE); + } + + /** + * The contructor used with an inflater + * + * @param context + * @param attrs + */ + public CircleFlowIndicator(Context context, AttributeSet attrs) { + super(context, attrs); + // Retrieve styles attributs + TypedArray a = context.obtainStyledAttributes(attrs, + R.styleable.CircleFlowIndicator); + + // Gets the active circle type, defaulting to "fill" + int activeType = a.getInt(R.styleable.CircleFlowIndicator_activeType, + STYLE_FILL); + + int activeDefaultColor = 0xFFFFFFFF; + + // Get a custom active color if there is one + int activeColor = a + .getColor(R.styleable.CircleFlowIndicator_activeColor, + activeDefaultColor); + + // Gets the inactive circle type, defaulting to "stroke" + int inactiveType = a.getInt( + R.styleable.CircleFlowIndicator_inactiveType, STYLE_STROKE); + + int inactiveDefaultColor = 0x44FFFFFF; + // Get a custom inactive color if there is one + int inactiveColor = a.getColor( + R.styleable.CircleFlowIndicator_inactiveColor, + inactiveDefaultColor); + + // Retrieve the radius + mRadius = a.getDimension(R.styleable.CircleFlowIndicator_radius, 4.0f); + mRadiusActive = mRadius; + mRadiusInactive = mRadius; + + // Retrieve the spacing + spacing = a.getDimension(R.styleable.CircleFlowIndicator_spacing, 4.0f); + // We want the spacing to be center-to-center + spacing += 2 * mRadiusActive; + + // Retrieve the fade out time + fadeOutTime = a.getInt(R.styleable.CircleFlowIndicator_fadeOut, 0); + + mCentered = a.getBoolean(R.styleable.CircleFlowIndicator_centered, false); + + mSnap = a.getBoolean(R.styleable.CircleFlowIndicator_snap, false); + + initColors(activeColor, inactiveColor, activeType, inactiveType); + } + + private void initColors(int activeColor, int inactiveColor, int activeType, + int inactiveType) { + // Select the paint type given the type attr + switch (inactiveType) { + case STYLE_FILL: + mPaintInactive.setStyle(Style.FILL); + break; + default: + mPaintInactive.setStyle(Style.STROKE); + float strokeWidth = mPaintInactive.getStrokeWidth(); + if (strokeWidth == 0.0f) { + // It draws in "hairline mode", which is 1 px wide. + strokeWidth = 1.0f / getResources().getDisplayMetrics().density; + } + mRadiusInactive -= strokeWidth / 2.0f; + } + mPaintInactive.setColor(inactiveColor); + + // Select the paint type given the type attr + switch (activeType) { + case STYLE_STROKE: + mPaintActive.setStyle(Style.STROKE); + float strokeWidth = mPaintInactive.getStrokeWidth(); + if (strokeWidth == 0.0f) { + // It draws in "hairline mode", which is 1 px wide. + strokeWidth = 1.0f / getResources().getDisplayMetrics().density; + } + mRadiusActive -= strokeWidth / 2.0f; + break; + default: + mPaintActive.setStyle(Style.FILL); + } + mPaintActive.setColor(activeColor); + } + + /* + * (non-Javadoc) + * + * @see android.view.View#onDraw(android.graphics.Canvas) + */ + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + int count = 3; + if (viewFlow != null) { + count = viewFlow.getViewsCount(); + } + + //this is the amount the first circle should be offset to make the entire thing centered + float centeringOffset = 0; + + int leftPadding = getPaddingLeft(); + + // Draw stroked circles + for (int iLoop = 0; iLoop < count; iLoop++) { + canvas.drawCircle(leftPadding + mRadius + + (iLoop * spacing) + centeringOffset, + getPaddingTop() + mRadius, mRadiusInactive, mPaintInactive); + } + float cx = 0; + if (mSnap) { + cx = currentPosition * spacing; + } else { + if (flowWidth != 0) { + // Draw the filled circle according to the current scroll + cx = (currentScroll * spacing) / flowWidth; + } + // else, the flow width hasn't been updated yet. Draw the default position. + } + canvas.drawCircle(leftPadding + mRadius + cx+centeringOffset, getPaddingTop() + + mRadius, mRadiusActive, mPaintActive); + } + + /* + * (non-Javadoc) + * + * @see + * org.taptwo.android.widget.ViewFlow.ViewSwitchListener#onSwitched(android + * .view.View, int) + */ + @Override + public void onSwitched(View view, int position) { + currentPosition = position; + if (mSnap) { + setVisibility(View.VISIBLE); + resetTimer(); + invalidate(); + } + } + + /* + * (non-Javadoc) + * + * @see + * org.taptwo.android.widget.FlowIndicator#setViewFlow(org.taptwo.android + * .widget.ViewFlow) + */ + @Override + public void setViewFlow(ViewFlow view) { + resetTimer(); + viewFlow = view; + flowWidth = viewFlow.getChildWidth(); + invalidate(); + } + + /* + * (non-Javadoc) + * + * @see org.taptwo.android.widget.FlowIndicator#onScrolled(int, int, int, + * int) + */ + @Override + public void onScrolled(int h, int v, int oldh, int oldv) { + currentScroll = h; + flowWidth = viewFlow.getChildWidth(); + if (!mSnap) { + setVisibility(View.VISIBLE); + resetTimer(); + invalidate(); + } + } + + /* + * (non-Javadoc) + * + * @see android.view.View#onMeasure(int, int) + */ + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension(measureWidth(widthMeasureSpec), + measureHeight(heightMeasureSpec)); + } + + /** + * Determines the width of this view + * + * @param measureSpec + * A measureSpec packed into an int + * @return The width of the view, honoring constraints from measureSpec + */ + private int measureWidth(int measureSpec) { + int result = 0; + int specMode = MeasureSpec.getMode(measureSpec); + int specSize = MeasureSpec.getSize(measureSpec); + + // We were told how big to be + if (specMode == MeasureSpec.EXACTLY) { + result = specSize; + } + // Calculate the width according the views count + else { + int count = 3; + if (viewFlow != null) { + count = viewFlow.getViewsCount(); + } + // Remember that spacing is centre-to-centre + result = (int) (getPaddingLeft() + getPaddingRight() + + (2 * mRadius) + (count - 1) * spacing); + // Respect AT_MOST value if that was what is called for by + // measureSpec + if (specMode == MeasureSpec.AT_MOST) { + result = Math.min(result, specSize); + } + } + return result; + } + + /** + * Determines the height of this view + * + * @param measureSpec + * A measureSpec packed into an int + * @return The height of the view, honoring constraints from measureSpec + */ + private int measureHeight(int measureSpec) { + int result = 0; + int specMode = MeasureSpec.getMode(measureSpec); + int specSize = MeasureSpec.getSize(measureSpec); + + // We were told how big to be + if (specMode == MeasureSpec.EXACTLY) { + result = specSize; + } + // Measure the height + else { + result = (int) (2 * mRadius + getPaddingTop() + getPaddingBottom() + 1); + // Respect AT_MOST value if that was what is called for by + // measureSpec + if (specMode == MeasureSpec.AT_MOST) { + result = Math.min(result, specSize); + } + } + return result; + } + + /** + * Sets the fill color + * + * @param color + * ARGB value for the text + */ + public void setFillColor(int color) { + mPaintActive.setColor(color); + invalidate(); + } + + /** + * Sets the stroke color + * + * @param color + * ARGB value for the text + */ + public void setStrokeColor(int color) { + mPaintInactive.setColor(color); + invalidate(); + } + + /** + * Resets the fade out timer to 0. Creating a new one if needed + */ + private void resetTimer() { + // Only set the timer if we have a timeout of at least 1 millisecond + if (fadeOutTime > 0) { + // Check if we need to create a new timer + if (timer == null || timer._run == false) { + // Create and start a new timer + timer = new FadeTimer(); + timer.execute(); + } else { + // Reset the current tiemr to 0 + timer.resetTimer(); + } + } + } + + /** + * Counts from 0 to the fade out time and animates the view away when + * reached + */ + private class FadeTimer extends AsyncTask { + // The current count + private int timer = 0; + // If we are inside the timing loop + private boolean _run = true; + + public void resetTimer() { + timer = 0; + } + + @Override + protected Void doInBackground(Void... arg0) { + while (_run) { + try { + // Wait for a millisecond + Thread.sleep(1); + // Increment the timer + timer++; + + // Check if we've reached the fade out time + if (timer == fadeOutTime) { + // Stop running + _run = false; + } + } catch (InterruptedException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + } + return null; + } + + @Override + protected void onPostExecute(Void result) { + animation = AnimationUtils.loadAnimation(getContext(), + android.R.anim.fade_out); + animation.setAnimationListener(animationListener); + startAnimation(animation); + } + } + + @Override + public void onAnimationEnd(Animation animation) { + setVisibility(View.GONE); + } + + @Override + public void onAnimationRepeat(Animation animation) { + } + + @Override + public void onAnimationStart(Animation animation) { + } +} diff --git a/opensrp-gizi/src/main/java/widget/FlowIndicator.java b/opensrp-gizi/src/main/java/widget/FlowIndicator.java new file mode 100644 index 0000000..08942a8 --- /dev/null +++ b/opensrp-gizi/src/main/java/widget/FlowIndicator.java @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2011 Patrik Ă…kerfeldt + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package widget; + +import widget.ViewFlow.ViewSwitchListener; + +/** + * An interface which defines the contract between a ViewFlow and a + * FlowIndicator.
+ * A FlowIndicator is responsible to show an visual indicator on the total views + * number and the current visible view.
+ * + */ +public interface FlowIndicator extends ViewSwitchListener { + + /** + * Set the current ViewFlow. This method is called by the ViewFlow when the + * FlowIndicator is attached to it. + * + * @param view + */ + public void setViewFlow(ViewFlow view); + + /** + * The scroll position has been changed. A FlowIndicator may implement this + * method to reflect the current position + * + * @param h + * @param v + * @param oldh + * @param oldv + */ + public void onScrolled(int h, int v, int oldh, int oldv); +} diff --git a/opensrp-gizi/src/main/java/widget/TitleFlowIndicator.java b/opensrp-gizi/src/main/java/widget/TitleFlowIndicator.java new file mode 100644 index 0000000..685395c --- /dev/null +++ b/opensrp-gizi/src/main/java/widget/TitleFlowIndicator.java @@ -0,0 +1,448 @@ +/* + * Copyright (C) 2011 Patrik Åkerfeldt + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package widget; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Paint; +import android.graphics.Path; +import android.graphics.Rect; +import android.graphics.Typeface; +import android.util.AttributeSet; +import android.view.View; +import android.widget.TextView; + + +import org.ei.opensrp.gizi.R; + +import java.util.ArrayList; + +/** + * A TitleFlowIndicator is a FlowIndicator which displays the title of left view + * (if exist), the title of the current select view (centered) and the title of + * the right view (if exist). When the user scrolls the ViewFlow then titles are + * also scrolled. + * + */ +public class TitleFlowIndicator extends TextView implements FlowIndicator { + + private static final float TITLE_PADDING = 10.0f; + private static final float CLIP_PADDING = 0.0f; + private static final int SELECTED_COLOR = 0xFFFFC445; + private static final boolean SELECTED_BOLD = false; + private static final int TEXT_COLOR = 0xFFAAAAAA; + private static final int TEXT_SIZE = 15; + private static final float FOOTER_LINE_HEIGHT = 4.0f; + private static final int FOOTER_COLOR = 0xFFFFC445; + private static final float FOOTER_TRIANGLE_HEIGHT = 10; + private ViewFlow viewFlow; + private int currentScroll = 0; + private TitleProvider titleProvider = null; + private int currentPosition = 0; + private Paint paintText; + private Paint paintSelected; + private Path path; + private Paint paintFooterLine; + private Paint paintFooterTriangle; + private float footerTriangleHeight; + private float titlePadding; + /** + * Left and right side padding for not active view titles. + */ + private float clipPadding; + private float footerLineHeight; + + /* These are hardcoded just like in TextView */ + private static final int SANS = 1; + private static final int SERIF = 2; + private static final int MONOSPACE = 3; + + private Typeface typeface; + + /** + * Default constructor + */ + public TitleFlowIndicator(Context context) { + super(context); + initDraw(TEXT_COLOR, TEXT_SIZE, SELECTED_COLOR, SELECTED_BOLD, TEXT_SIZE, FOOTER_LINE_HEIGHT, FOOTER_COLOR); + } + + /** + * The contructor used with an inflater + * + * @param context + * @param attrs + */ + public TitleFlowIndicator(Context context, AttributeSet attrs) { + super(context, attrs); + // Retrieve styles attributs + + int typefaceIndex = attrs.getAttributeIntValue("http://schemas.android.com/apk/res/android", "typeface", 0); + int textStyleIndex = attrs.getAttributeIntValue("http://schemas.android.com/apk/res/android", "textStyle", 0); + TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.TitleFlowIndicator); + + String customTypeface = a.getString(R.styleable.TitleFlowIndicator_customTypeface); + // Retrieve the colors to be used for this view and apply them. + int footerColor = a.getColor(R.styleable.TitleFlowIndicator_footerColor, FOOTER_COLOR); + footerLineHeight = a.getDimension(R.styleable.TitleFlowIndicator_footerLineHeight, FOOTER_LINE_HEIGHT); + footerTriangleHeight = a.getDimension(R.styleable.TitleFlowIndicator_footerTriangleHeight, FOOTER_TRIANGLE_HEIGHT); + int selectedColor = a.getColor(R.styleable.TitleFlowIndicator_selectedColor, SELECTED_COLOR); + boolean selectedBold = a.getBoolean(R.styleable.TitleFlowIndicator_selectedBold, SELECTED_BOLD); + int textColor = a.getColor(R.styleable.TitleFlowIndicator_textColor, TEXT_COLOR); + float textSize = a.getDimension(R.styleable.TitleFlowIndicator_textSize, TEXT_SIZE); + float selectedSize = a.getDimension(R.styleable.TitleFlowIndicator_selectedSize, textSize); + titlePadding = a.getDimension(R.styleable.TitleFlowIndicator_titlePadding, TITLE_PADDING); + clipPadding = a.getDimension(R.styleable.TitleFlowIndicator_clipPadding, CLIP_PADDING); + initDraw(textColor, textSize, selectedColor, selectedBold, selectedSize, footerLineHeight, footerColor); + + if (customTypeface != null) + typeface = Typeface.createFromAsset(context.getAssets(), customTypeface); + else + typeface = getTypefaceByIndex(typefaceIndex); + typeface = Typeface.create(typeface, textStyleIndex); + + } + + /** + * Initialize draw objects + */ + private void initDraw(int textColor, float textSize, int selectedColor, boolean selectedBold, float selectedSize, float footerLineHeight, int footerColor) { + paintText = new Paint(); + paintText.setColor(textColor); + paintText.setTextSize(textSize); + paintText.setAntiAlias(true); + paintSelected = new Paint(); + paintSelected.setColor(selectedColor); + paintSelected.setTextSize(selectedSize); + paintSelected.setFakeBoldText(selectedBold); + paintSelected.setAntiAlias(true); + paintFooterLine = new Paint(); + paintFooterLine.setStyle(Paint.Style.FILL_AND_STROKE); + paintFooterLine.setStrokeWidth(footerLineHeight); + paintFooterLine.setColor(footerColor); + paintFooterTriangle = new Paint(); + paintFooterTriangle.setStyle(Paint.Style.FILL_AND_STROKE); + paintFooterTriangle.setColor(footerColor); + } + + /* + * (non-Javadoc) + * + * @see android.view.View#onDraw(android.graphics.Canvas) + */ + @Override + protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + + // Calculate views bounds + ArrayList bounds = calculateAllBounds(paintText); + + // If no value then add a fake one + int count = (viewFlow != null && viewFlow.getAdapter() != null) ? viewFlow.getAdapter().getCount() : 1; + + // Verify if the current view must be clipped to the screen + Rect curViewBound = bounds.get(currentPosition); + int curViewWidth = curViewBound.right - curViewBound.left; + if (curViewBound.left < 0) { + // Try to clip to the screen (left side) + clipViewOnTheLeft(curViewBound, curViewWidth); + } + if (curViewBound.right > getLeft() + getWidth()) { + // Try to clip to the screen (right side) + clipViewOnTheRight(curViewBound, curViewWidth); + } + + // Left views starting from the current position + if (currentPosition > 0) { + for (int iLoop = currentPosition - 1; iLoop >= 0; iLoop--) { + Rect bound = bounds.get(iLoop); + int w = bound.right - bound.left; + // Si left side is outside the screen + if (bound.left < 0) { + // Try to clip to the screen (left side) + clipViewOnTheLeft(bound, w); + // Except if there's an intersection with the right view + if (iLoop < count - 1 && currentPosition != iLoop) { + Rect rightBound = bounds.get(iLoop + 1); + // Intersection + if (bound.right + TITLE_PADDING > rightBound.left) { + bound.left = rightBound.left - (w + (int) titlePadding); + } + } + } + } + } + // Right views starting from the current position + if (currentPosition < count - 1) { + for (int iLoop = currentPosition + 1; iLoop < count; iLoop++) { + Rect bound = bounds.get(iLoop); + int w = bound.right - bound.left; + // If right side is outside the screen + if (bound.right > getLeft() + getWidth()) { + // Try to clip to the screen (right side) + clipViewOnTheRight(bound, w); + // Except if there's an intersection with the left view + if (iLoop > 0 && currentPosition != iLoop) { + Rect leftBound = bounds.get(iLoop - 1); + // Intersection + if (bound.left - TITLE_PADDING < leftBound.right) { + bound.left = leftBound.right + (int) titlePadding; + } + } + } + } + } + + // Now draw views + for (int iLoop = 0; iLoop < count; iLoop++) { + // Get the title + String title = getTitle(iLoop); + Rect bound = bounds.get(iLoop); + // Only if one side is visible + if ((bound.left > getLeft() && bound.left < getLeft() + getWidth()) || (bound.right > getLeft() && bound.right < getLeft() + getWidth())) { + Paint paint = paintText; + // Change the color is the title is closed to the center + int middle = (bound.left + bound.right) / 2; + if (Math.abs(middle - (getWidth() / 2)) < 20) { + paint = paintSelected; + } + paint.setTypeface(typeface); + canvas.drawText(title, bound.left, bound.bottom, paint); + } + } + + // Draw the footer line + path = new Path(); + int coordY = getHeight() - 1; + coordY -= (footerLineHeight % 2 == 1) ? footerLineHeight / 2 : footerLineHeight / 2 - 1; + path.moveTo(0, coordY); + path.lineTo(getWidth(), coordY); + path.close(); + canvas.drawPath(path, paintFooterLine); + // Draw the footer triangle + path = new Path(); + path.moveTo(getWidth() / 2, getHeight() - footerLineHeight - footerTriangleHeight); + path.lineTo(getWidth() / 2 + footerTriangleHeight, getHeight() - footerLineHeight); + path.lineTo(getWidth() / 2 - footerTriangleHeight, getHeight() - footerLineHeight); + path.close(); + canvas.drawPath(path, paintFooterTriangle); + + } + + /** + * Set bounds for the right textView including clip padding. + * + * @param curViewBound + * current bounds. + * @param curViewWidth + * width of the view. + */ + private void clipViewOnTheRight(Rect curViewBound, int curViewWidth) { + curViewBound.right = getLeft() + getWidth() - (int) clipPadding; + curViewBound.left = curViewBound.right - curViewWidth; + } + + /** + * Set bounds for the left textView including clip padding. + * + * @param curViewBound + * current bounds. + * @param curViewWidth + * width of the view. + */ + private void clipViewOnTheLeft(Rect curViewBound, int curViewWidth) { + curViewBound.left = 0 + (int) clipPadding; + curViewBound.right = curViewWidth; + } + + /** + * Calculate views bounds and scroll them according to the current index + * + * @param paint + * @param currentIndex + * @return + */ + private ArrayList calculateAllBounds(Paint paint) { + ArrayList list = new ArrayList(); + // For each views (If no values then add a fake one) + int count = (viewFlow != null && viewFlow.getAdapter() != null) ? viewFlow.getAdapter().getCount() : 1; + for (int iLoop = 0; iLoop < count; iLoop++) { + Rect bounds = calcBounds(iLoop, paint); + int w = (bounds.right - bounds.left); + int h = (bounds.bottom - bounds.top); + bounds.left = (getWidth() / 2) - (w / 2) - currentScroll + (iLoop * getWidth()); + bounds.right = bounds.left + w; + bounds.top = 0; + bounds.bottom = h; + list.add(bounds); + } + + return list; + } + + /** + * Calculate the bounds for a view's title + * + * @param index + * @param paint + * @return + */ + private Rect calcBounds(int index, Paint paint) { + // Get the title + String title = getTitle(index); + // Calculate the text bounds + Rect bounds = new Rect(); + bounds.right = (int) paint.measureText(title); + bounds.bottom = (int) (paint.descent() - paint.ascent()); + return bounds; + } + + /** + * Returns the title + * + * @param pos + * @return + */ + private String getTitle(int pos) { + // Set the default title + String title = "title " + pos; + // If the TitleProvider exist + if (titleProvider != null) { + title = titleProvider.getTitle(pos); + } + return title; + } + + /* + * (non-Javadoc) + * + * @see org.taptwo.android.widget.FlowIndicator#onScrolled(int, int, int, + * int) + */ + @Override + public void onScrolled(int h, int v, int oldh, int oldv) { + currentScroll = h; + invalidate(); + } + + /* + * (non-Javadoc) + * + * @see + * org.taptwo.android.widget.ViewFlow.ViewSwitchListener#onSwitched(android + * .view.View, int) + */ + @Override + public void onSwitched(View view, int position) { + currentPosition = position; + invalidate(); + } + + /* + * (non-Javadoc) + * + * @see + * org.taptwo.android.widget.FlowIndicator#setViewFlow(org.taptwo.android + * .widget.ViewFlow) + */ + @Override + public void setViewFlow(ViewFlow view) { + viewFlow = view; + currentPosition = view.getSelectedItemPosition(); + invalidate(); + } + + /** + * Set the title provider + * + * @param provider + */ + public void setTitleProvider(TitleProvider provider) { + titleProvider = provider; + } + + /* + * (non-Javadoc) + * + * @see android.view.View#onMeasure(int, int) + */ + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension(measureWidth(widthMeasureSpec), measureHeight(heightMeasureSpec)); + } + + /** + * Determines the width of this view + * + * @param measureSpec + * A measureSpec packed into an int + * @return The width of the view, honoring constraints from measureSpec + */ + private int measureWidth(int measureSpec) { + int result = 0; + int specMode = MeasureSpec.getMode(measureSpec); + int specSize = MeasureSpec.getSize(measureSpec); + + if (specMode != MeasureSpec.EXACTLY) { + throw new IllegalStateException("ViewFlow can only be used in EXACTLY mode."); + } + result = specSize; + return result; + } + + /** + * Determines the height of this view + * + * @param measureSpec + * A measureSpec packed into an int + * @return The height of the view, honoring constraints from measureSpec + */ + private int measureHeight(int measureSpec) { + int result = 0; + int specMode = MeasureSpec.getMode(measureSpec); + int specSize = MeasureSpec.getSize(measureSpec); + + // We were told how big to be + if (specMode == MeasureSpec.EXACTLY) { + result = specSize; + } + // Measure the height + else { + // Calculate the text bounds + Rect bounds = new Rect(); + bounds.bottom = (int) (paintText.descent() - paintText.ascent()); + result = bounds.bottom - bounds.top + (int) footerTriangleHeight + (int) footerLineHeight + 10; + return result; + } + return result; + } + + private Typeface getTypefaceByIndex(int typefaceIndex) { + switch (typefaceIndex) { + case SANS: + return Typeface.SANS_SERIF; + + case SERIF: + return Typeface.SERIF; + + case MONOSPACE: + return Typeface.MONOSPACE; + default: + return Typeface.DEFAULT; + } + } +} diff --git a/opensrp-gizi/src/main/java/widget/TitleProvider.java b/opensrp-gizi/src/main/java/widget/TitleProvider.java new file mode 100644 index 0000000..3f13c06 --- /dev/null +++ b/opensrp-gizi/src/main/java/widget/TitleProvider.java @@ -0,0 +1,30 @@ +/* + * Copyright (C) 2011 Patrik Åkerfeldt + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package widget; + +/** + * A TitleProvider provides the title to display according to a view. + */ +public interface TitleProvider { + + /** + * Returns the title of the view at position + * @param position + * @return + */ + public String getTitle(int position); + +} diff --git a/opensrp-gizi/src/main/java/widget/ViewFlow.java b/opensrp-gizi/src/main/java/widget/ViewFlow.java new file mode 100644 index 0000000..a6e0cf7 --- /dev/null +++ b/opensrp-gizi/src/main/java/widget/ViewFlow.java @@ -0,0 +1,841 @@ +/* + * Copyright (C) 2011 Patrik Åkerfeldt + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package widget; + +import android.content.Context; +import android.content.res.Configuration; +import android.content.res.TypedArray; +import android.database.DataSetObserver; +import android.util.AttributeSet; +import android.util.Log; +import android.view.MotionEvent; +import android.view.VelocityTracker; +import android.view.View; +import android.view.ViewConfiguration; +import android.view.ViewGroup; +import android.view.ViewTreeObserver.OnGlobalLayoutListener; +import android.widget.Adapter; +import android.widget.AdapterView; +import android.widget.Scroller; + + +import org.ei.opensrp.gizi.R; + +import java.util.EnumSet; +import java.util.LinkedList; + +/** + * A horizontally scrollable {@link ViewGroup} with items populated from an + * {@link Adapter}. The ViewFlow uses a buffer to store loaded {@link View}s in. + * The default size of the buffer is 3 elements on both sides of the currently + * visible {@link View}, making up a total buffer size of 3 * 2 + 1 = 7. The + * buffer size can be changed using the {@code sidebuffer} xml attribute. + * + */ +public class ViewFlow extends AdapterView { + + private static final int SNAP_VELOCITY = 1000; + private static final int INVALID_SCREEN = -1; + private final static int TOUCH_STATE_REST = 0; + private final static int TOUCH_STATE_SCROLLING = 1; + + private LinkedList mLoadedViews; + private LinkedList mRecycledViews; + private int mCurrentBufferIndex; + private int mCurrentAdapterIndex; + private int mSideBuffer = 2; + private Scroller mScroller; + private VelocityTracker mVelocityTracker; + private int mTouchState = TOUCH_STATE_REST; + private float mLastMotionX; + private int mTouchSlop; + private int mMaximumVelocity; + private int mCurrentScreen; + private int mNextScreen = INVALID_SCREEN; + private boolean mFirstLayout = true; + private ViewSwitchListener mViewSwitchListener; + private ViewLazyInitializeListener mViewInitializeListener; + private EnumSet mLazyInit = EnumSet.allOf(LazyInit.class); + private Adapter mAdapter; + private int mLastScrollDirection; + private AdapterDataSetObserver mDataSetObserver; + private FlowIndicator mIndicator; + private int mLastOrientation = -1; + /** Extra return value from obtainView: tells you whether the item it returned on the last call was recycled rather than created by the adapter. + * This is a member because getting a second return value requires an allocation. */ + private boolean mLastObtainedViewWasRecycled = false; + + private OnGlobalLayoutListener orientationChangeListener = new OnGlobalLayoutListener() { + + @Override + public void onGlobalLayout() { + getViewTreeObserver().removeGlobalOnLayoutListener( + orientationChangeListener); + setSelection(mCurrentAdapterIndex); + } + }; + + /** + * Receives call backs when a new {@link View} has been scrolled to. + */ + public static interface ViewSwitchListener { + + /** + * This method is called when a new View has been scrolled to. + * + * @param view + * the {@link View} currently in focus. + * @param position + * The position in the adapter of the {@link View} currently in focus. + */ + void onSwitched(View view, int position); + + } + + public static interface ViewLazyInitializeListener { + void onViewLazyInitialize(View view, int position); + } + + enum LazyInit { + LEFT, RIGHT + } + + public ViewFlow(Context context) { + super(context); + mSideBuffer = 3; + init(); + } + + public ViewFlow(Context context, int sideBuffer) { + super(context); + mSideBuffer = sideBuffer; + init(); + } + + public ViewFlow(Context context, AttributeSet attrs) { + super(context, attrs); + TypedArray styledAttrs = context.obtainStyledAttributes(attrs, + R.styleable.ViewFlow); + mSideBuffer = styledAttrs.getInt(R.styleable.ViewFlow_sidebuffer, 3); + init(); + } + + private void init() { + mLoadedViews = new LinkedList(); + mRecycledViews = new LinkedList(); + mScroller = new Scroller(getContext()); + final ViewConfiguration configuration = ViewConfiguration + .get(getContext()); + mTouchSlop = configuration.getScaledTouchSlop(); + mMaximumVelocity = configuration.getScaledMaximumFlingVelocity(); + } + + public void onConfigurationChanged(Configuration newConfig) { + if (newConfig.orientation != mLastOrientation) { + mLastOrientation = newConfig.orientation; + getViewTreeObserver().addOnGlobalLayoutListener(orientationChangeListener); + } + } + + public int getViewsCount() { + return mAdapter.getCount(); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + int widthSize = MeasureSpec.getSize(widthMeasureSpec); + int heightSize = MeasureSpec.getSize(heightMeasureSpec); + final int widthMode = MeasureSpec.getMode(widthMeasureSpec); + final int heightMode = MeasureSpec.getMode(heightMeasureSpec); + + int childWidth = 0; + int childHeight = 0; + int childState = 0; + + final int widthPadding = getWidthPadding(); + final int heightPadding = getHeightPadding(); + + int count = mAdapter == null ? 0 : mAdapter.getCount(); + if (count > 0) { + final View child = obtainView(0); + measureChild(child, widthMeasureSpec, heightMeasureSpec); + childWidth = child.getMeasuredWidth(); + childHeight = child.getMeasuredHeight(); + childState = child.getMeasuredState(); + mRecycledViews.add(child); + } + + switch (widthMode) { + case MeasureSpec.UNSPECIFIED: + widthSize = childWidth + widthPadding; + break; + case MeasureSpec.AT_MOST: + widthSize = (childWidth + widthPadding) | childState; + break; + case MeasureSpec.EXACTLY: + if (widthSize < childWidth + widthPadding) + widthSize |= MEASURED_STATE_TOO_SMALL; + break; + } + switch (heightMode) { + case MeasureSpec.UNSPECIFIED: + heightSize = childHeight + heightPadding; + break; + case MeasureSpec.AT_MOST: + heightSize = (childHeight + heightPadding) | (childState >> MEASURED_HEIGHT_STATE_SHIFT); + break; + case MeasureSpec.EXACTLY: + if (heightSize < childHeight + heightPadding) + heightSize |= MEASURED_STATE_TOO_SMALL; + break; + } + + if (heightMode == MeasureSpec.UNSPECIFIED) { + heightSize = heightPadding + childHeight; + } else { + heightSize |= (childState&MEASURED_STATE_MASK); + } + + setMeasuredDimension(widthSize, heightSize); + } + + private int getWidthPadding() { + return getPaddingLeft() + getPaddingRight() + getHorizontalFadingEdgeLength() * 2; + } + + public int getChildWidth() { + return getWidth() - getWidthPadding(); + } + + private int getHeightPadding() { + return getPaddingTop() + getPaddingBottom(); + } + + public int getChildHeight() { + return getHeight() - getHeightPadding(); + } + + @Override + protected void onSizeChanged(int w, int h, int oldw, int oldh) { + super.onSizeChanged(w, h, oldw, oldh); + + final int count = getChildCount(); + for (int i = 0; i < count ; ++i) { + final View child = getChildAt(i); + child.measure(MeasureSpec.makeMeasureSpec(getChildWidth(), MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(getChildHeight(), MeasureSpec.EXACTLY)); + } + + if (mFirstLayout) { + mScroller.startScroll(0, 0, mCurrentScreen * getChildWidth(), 0, 0); + mFirstLayout = false; + } + } + + @Override + protected void onLayout(boolean changed, int l, int t, int r, int b) { + int childLeft = getPaddingLeft() + getHorizontalFadingEdgeLength(); + + final int count = getChildCount(); + for (int i = 0; i < count; i++) { + final View child = getChildAt(i); + if (child.getVisibility() != View.GONE) { + final int childWidth = child.getMeasuredWidth(); + child.layout(childLeft, getPaddingTop(), childLeft + childWidth, + getPaddingTop() + child.getMeasuredHeight()); + childLeft += childWidth; + } + } + } + + @Override + protected float getTopFadingEdgeStrength() { + return 0.0f; + } + + @Override + protected float getBottomFadingEdgeStrength() { + return 0.0f; + } + + @Override + protected float getLeftFadingEdgeStrength() { + // always do the fading edge + return 1.0f; + } + + @Override + protected float getRightFadingEdgeStrength() { + // always do the fading edge + return 1.0f; + } + + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + if (getChildCount() == 0) + return false; + + if (mVelocityTracker == null) { + mVelocityTracker = VelocityTracker.obtain(); + } + mVelocityTracker.addMovement(ev); + + final int action = ev.getAction(); + final float x = ev.getX(); + + switch (action) { + case MotionEvent.ACTION_DOWN: + /* + * If being flinged and user touches, stop the fling. isFinished + * will be false if being flinged. + */ + if (!mScroller.isFinished()) { + mScroller.abortAnimation(); + } + + // Remember where the motion event started + mLastMotionX = x; + + mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST + : TOUCH_STATE_SCROLLING; + + break; + + case MotionEvent.ACTION_MOVE: + final int deltaX = (int) (mLastMotionX - x); + + boolean xMoved = Math.abs(deltaX) > mTouchSlop; + + if (xMoved) { + // Scroll if the user moved far enough along the X axis + mTouchState = TOUCH_STATE_SCROLLING; + + if (mViewInitializeListener != null) + initializeView(deltaX); + } + + if (mTouchState == TOUCH_STATE_SCROLLING) { + // Scroll to follow the motion event + + mLastMotionX = x; + + final int scrollX = getScrollX(); + if (deltaX < 0) { + if (scrollX > 0) { + scrollBy(Math.max(-scrollX, deltaX), 0); + } + } else if (deltaX > 0) { + final int availableToScroll = getChildAt( + getChildCount() - 1).getRight() + - getPaddingRight() - getHorizontalFadingEdgeLength() + - scrollX - getWidth(); + if (availableToScroll > 0) { + scrollBy(Math.min(availableToScroll, deltaX), 0); + } + } + return true; + } + break; + + case MotionEvent.ACTION_UP: + if (mTouchState == TOUCH_STATE_SCROLLING) { + final VelocityTracker velocityTracker = mVelocityTracker; + velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); + int velocityX = (int) velocityTracker.getXVelocity(); + + if (velocityX > SNAP_VELOCITY && mCurrentScreen > 0) { + // Fling hard enough to move left + snapToScreen(mCurrentScreen - 1); + } else if (velocityX < -SNAP_VELOCITY + && mCurrentScreen < getChildCount() - 1) { + // Fling hard enough to move right + snapToScreen(mCurrentScreen + 1); + } else { + snapToDestination(); + } + + if (mVelocityTracker != null) { + mVelocityTracker.recycle(); + mVelocityTracker = null; + } + } + + mTouchState = TOUCH_STATE_REST; + + break; + case MotionEvent.ACTION_CANCEL: + mTouchState = TOUCH_STATE_REST; + } + return false; + } + + @Override + public boolean onTouchEvent(MotionEvent ev) { + if (getChildCount() == 0) + return false; + + if (mVelocityTracker == null) { + mVelocityTracker = VelocityTracker.obtain(); + } + mVelocityTracker.addMovement(ev); + + final int action = ev.getAction(); + final float x = ev.getX(); + + switch (action) { + case MotionEvent.ACTION_DOWN: + /* + * If being flinged and user touches, stop the fling. isFinished + * will be false if being flinged. + */ + if (!mScroller.isFinished()) { + mScroller.abortAnimation(); + } + + // Remember where the motion event started + mLastMotionX = x; + + mTouchState = mScroller.isFinished() ? TOUCH_STATE_REST + : TOUCH_STATE_SCROLLING; + + break; + + case MotionEvent.ACTION_MOVE: + final int deltaX = (int) (mLastMotionX - x); + + boolean xMoved = Math.abs(deltaX) > mTouchSlop; + + if (xMoved) { + // Scroll if the user moved far enough along the X axis + mTouchState = TOUCH_STATE_SCROLLING; + + if (mViewInitializeListener != null) + initializeView(deltaX); + } + + if (mTouchState == TOUCH_STATE_SCROLLING) { + // Scroll to follow the motion event + + mLastMotionX = x; + + final int scrollX = getScrollX(); + if (deltaX < 0) { + if (scrollX > 0) { + scrollBy(Math.max(-scrollX, deltaX), 0); + } + } else if (deltaX > 0) { + final int availableToScroll = getChildAt( + getChildCount() - 1).getRight() + - getPaddingRight() - getHorizontalFadingEdgeLength() + - scrollX - getChildWidth(); + if (availableToScroll > 0) { + scrollBy(Math.min(availableToScroll, deltaX), 0); + } + } + return true; + } + break; + + case MotionEvent.ACTION_UP: + if (mTouchState == TOUCH_STATE_SCROLLING) { + final VelocityTracker velocityTracker = mVelocityTracker; + velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity); + int velocityX = (int) velocityTracker.getXVelocity(); + + if (velocityX > SNAP_VELOCITY && mCurrentScreen > 0) { + // Fling hard enough to move left + snapToScreen(mCurrentScreen - 1); + } else if (velocityX < -SNAP_VELOCITY + && mCurrentScreen < getChildCount() - 1) { + // Fling hard enough to move right + snapToScreen(mCurrentScreen + 1); + } else { + snapToDestination(); + } + + if (mVelocityTracker != null) { + mVelocityTracker.recycle(); + mVelocityTracker = null; + } + } + + mTouchState = TOUCH_STATE_REST; + + break; + case MotionEvent.ACTION_CANCEL: + snapToDestination(); + mTouchState = TOUCH_STATE_REST; + } + return true; + } + + private void initializeView(final float direction) { + if (direction > 0) { + if (mLazyInit.contains(LazyInit.RIGHT)) { + mLazyInit.remove(LazyInit.RIGHT); + if (mCurrentBufferIndex+1 < mLoadedViews.size()) + mViewInitializeListener.onViewLazyInitialize(mLoadedViews.get(mCurrentBufferIndex + 1), mCurrentAdapterIndex + 1); + } + } else { + if (mLazyInit.contains(LazyInit.LEFT)) { + mLazyInit.remove(LazyInit.LEFT); + if (mCurrentBufferIndex > 0) + mViewInitializeListener.onViewLazyInitialize(mLoadedViews.get(mCurrentBufferIndex - 1), mCurrentAdapterIndex - 1); + } + } + } + + @Override + protected void onScrollChanged(int h, int v, int oldh, int oldv) { + super.onScrollChanged(h, v, oldh, oldv); + if (mIndicator != null) { + /* + * The actual horizontal scroll origin does typically not match the + * perceived one. Therefore, we need to calculate the perceived + * horizontal scroll origin here, since we use a view buffer. + */ + int hPerceived = h + (mCurrentAdapterIndex - mCurrentBufferIndex) + * getChildWidth(); + mIndicator.onScrolled(hPerceived, v, oldh, oldv); + } + } + + private void snapToDestination() { + final int screenWidth = getChildWidth(); + final int whichScreen = (getScrollX() + (screenWidth / 2)) + / screenWidth; + + snapToScreen(whichScreen); + } + + private void snapToScreen(int whichScreen) { + mLastScrollDirection = whichScreen - mCurrentScreen; + if (!mScroller.isFinished()) + return; + + whichScreen = Math.max(0, Math.min(whichScreen, getChildCount() - 1)); + + mNextScreen = whichScreen; + + final int newX = whichScreen * getChildWidth(); + final int delta = newX - getScrollX(); + mScroller.startScroll(getScrollX(), 0, delta, 0, Math.abs(delta) * 2); + invalidate(); + } + + @Override + public void computeScroll() { + if (mScroller.computeScrollOffset()) { + scrollTo(mScroller.getCurrX(), mScroller.getCurrY()); + postInvalidate(); + } else if (mNextScreen != INVALID_SCREEN) { + mCurrentScreen = Math.max(0, + Math.min(mNextScreen, getChildCount() - 1)); + mNextScreen = INVALID_SCREEN; + post(new Runnable() { + @Override + public void run() { + postViewSwitched(mLastScrollDirection); + } + }); + } + } + + /** + * Scroll to the {@link View} in the view buffer specified by the index. + * + * @param indexInBuffer + * Index of the view in the view buffer. + */ + private void setVisibleView(int indexInBuffer, boolean uiThread) { + mCurrentScreen = Math.max(0, + Math.min(indexInBuffer, getChildCount() - 1)); + int dx = (mCurrentScreen * getChildWidth()) - mScroller.getCurrX(); + mScroller.startScroll(mScroller.getCurrX(), mScroller.getCurrY(), dx, + 0, 0); + if(dx == 0) + onScrollChanged(mScroller.getCurrX() + dx, mScroller.getCurrY(), mScroller.getCurrX() + dx, mScroller.getCurrY()); + if (uiThread) + invalidate(); + else + postInvalidate(); + } + + /** + * Set the listener that will receive notifications every time the {code + * ViewFlow} scrolls. + * + * @param l + * the scroll listener + */ + public void setOnViewSwitchListener(ViewSwitchListener l) { + mViewSwitchListener = l; + } + + public void setOnViewLazyInitializeListener(ViewLazyInitializeListener l) { + mViewInitializeListener = l; + } + + @Override + public Adapter getAdapter() { + return mAdapter; + } + + @Override + public void setAdapter(Adapter adapter) { + setAdapter(adapter, 0); + } + + public void setAdapter(Adapter adapter, int initialPosition) { + if (mAdapter != null) { + mAdapter.unregisterDataSetObserver(mDataSetObserver); + } + + mAdapter = adapter; + + if (mAdapter != null) { + mDataSetObserver = new AdapterDataSetObserver(); + mAdapter.registerDataSetObserver(mDataSetObserver); + + } + if (mAdapter == null || mAdapter.getCount() == 0) + return; + + setSelection(initialPosition); + } + + @Override + public View getSelectedView() { + return (mCurrentBufferIndex < mLoadedViews.size() ? mLoadedViews + .get(mCurrentBufferIndex) : null); + } + + @Override + public int getSelectedItemPosition() { + return mCurrentAdapterIndex; + } + + /** + * Set the FlowIndicator + * + * @param flowIndicator + */ + public void setFlowIndicator(FlowIndicator flowIndicator) { + mIndicator = flowIndicator; + mIndicator.setViewFlow(this); + } + + protected void recycleViews() { + while (!mLoadedViews.isEmpty()) + recycleView(mLoadedViews.remove()); + } + + protected void recycleView(View v) { + if (v == null) + return; + mRecycledViews.addFirst(v); + detachViewFromParent(v); + } + + protected View getRecycledView() { + return (mRecycledViews.isEmpty() ? null : mRecycledViews.remove()); + } + + @Override + public void setSelection(int position) { + mNextScreen = INVALID_SCREEN; + mScroller.forceFinished(true); + if (mAdapter == null) + return; + + position = Math.max(position, 0); + position = Math.min(position, mAdapter.getCount() - 1); + + recycleViews(); + + View currentView = makeAndAddView(position, true); + mLoadedViews.addLast(currentView); + + if (mViewInitializeListener != null) + mViewInitializeListener.onViewLazyInitialize(currentView, position); + + for(int offset = 1; mSideBuffer - offset >= 0; offset++) { + int leftIndex = position - offset; + int rightIndex = position + offset; + if(leftIndex >= 0) + mLoadedViews.addFirst(makeAndAddView(leftIndex, false)); + if(rightIndex < mAdapter.getCount()) + mLoadedViews.addLast(makeAndAddView(rightIndex, true)); + } + + mCurrentBufferIndex = mLoadedViews.indexOf(currentView); + mCurrentAdapterIndex = position; + + requestLayout(); + setVisibleView(mCurrentBufferIndex, false); + if (mIndicator != null) { + mIndicator.onSwitched(currentView, mCurrentAdapterIndex); + } + if (mViewSwitchListener != null) { + mViewSwitchListener.onSwitched(currentView, mCurrentAdapterIndex); + } + } + + private void resetFocus() { + logBuffer(); + recycleViews(); + removeAllViewsInLayout(); + mLazyInit.addAll(EnumSet.allOf(LazyInit.class)); + + for (int i = Math.max(0, mCurrentAdapterIndex - mSideBuffer); i < Math + .min(mAdapter.getCount(), mCurrentAdapterIndex + mSideBuffer + + 1); i++) { + mLoadedViews.addLast(makeAndAddView(i, true)); + if (i == mCurrentAdapterIndex) { + mCurrentBufferIndex = mLoadedViews.size() - 1; + if (mViewInitializeListener != null) + mViewInitializeListener.onViewLazyInitialize(mLoadedViews.getLast(), mCurrentAdapterIndex); + } + } + logBuffer(); + requestLayout(); + } + + private void postViewSwitched(int direction) { + if (direction == 0) + return; + + if (direction > 0) { // to the right + mCurrentAdapterIndex++; + mCurrentBufferIndex++; + mLazyInit.remove(LazyInit.LEFT); + mLazyInit.add(LazyInit.RIGHT); + + // Recycle view outside buffer range + if (mCurrentAdapterIndex > mSideBuffer) { + recycleView(mLoadedViews.removeFirst()); + mCurrentBufferIndex--; + } + + // Add new view to buffer + int newBufferIndex = mCurrentAdapterIndex + mSideBuffer; + if (newBufferIndex < mAdapter.getCount()) + mLoadedViews.addLast(makeAndAddView(newBufferIndex, true)); + + } else { // to the left + mCurrentAdapterIndex--; + mCurrentBufferIndex--; + mLazyInit.add(LazyInit.LEFT); + mLazyInit.remove(LazyInit.RIGHT); + + // Recycle view outside buffer range + if (mAdapter.getCount() - 1 - mCurrentAdapterIndex > mSideBuffer) { + recycleView(mLoadedViews.removeLast()); + } + + // Add new view to buffer + int newBufferIndex = mCurrentAdapterIndex - mSideBuffer; + if (newBufferIndex > -1) { + mLoadedViews.addFirst(makeAndAddView(newBufferIndex, false)); + mCurrentBufferIndex++; + } + + } + + requestLayout(); + setVisibleView(mCurrentBufferIndex, true); + if (mIndicator != null) { + mIndicator.onSwitched(mLoadedViews.get(mCurrentBufferIndex), + mCurrentAdapterIndex); + } + if (mViewSwitchListener != null) { + mViewSwitchListener + .onSwitched(mLoadedViews.get(mCurrentBufferIndex), + mCurrentAdapterIndex); + } + logBuffer(); + } + + @Override + protected void measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) { + LayoutParams lp = child.getLayoutParams(); + final int childWidthSpec = getChildMeasureSpec(parentWidthMeasureSpec, getWidthPadding(), lp.width); + final int childHeightSpec = getChildMeasureSpec(parentHeightMeasureSpec, getHeightPadding(), lp.height); + child.measure(childWidthSpec, childHeightSpec); + } + + private View setupChild(View child, boolean addToEnd, boolean recycle) { + final LayoutParams lp = child.getLayoutParams(); + child.measure(MeasureSpec.makeMeasureSpec(getChildWidth(), MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(getChildHeight(), MeasureSpec.EXACTLY)); + if (recycle) + attachViewToParent(child, (addToEnd ? -1 : 0), lp); + else + addViewInLayout(child, (addToEnd ? -1 : 0), lp, true); + return child; + } + + private View makeAndAddView(int position, boolean addToEnd) { + View view = obtainView(position); + return setupChild(view, addToEnd, mLastObtainedViewWasRecycled); + } + + private View obtainView(int position) { + View convertView = getRecycledView(); + View view = mAdapter.getView(position, convertView, this); + if(view != convertView && convertView != null) + mRecycledViews.add(convertView); + mLastObtainedViewWasRecycled = (view == convertView); + LayoutParams p = view.getLayoutParams(); + if (p == null) { + p = new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT); + view.setLayoutParams(p); + } + return view; + } + + class AdapterDataSetObserver extends DataSetObserver { + + @Override + public void onChanged() { + View v = getChildAt(mCurrentBufferIndex); + if (v != null) { + for (int index = 0; index < mAdapter.getCount(); index++) { + if (v.equals(mAdapter.getItem(index))) { + mCurrentAdapterIndex = index; + break; + } + } + } + resetFocus(); + } + + @Override + public void onInvalidated() { + // Not yet implemented! + } + + } + + private void logBuffer() { + + Log.d("viewflow", "Size of mLoadedViews: " + mLoadedViews.size() + + ", Size of mRecycledViews: " + mRecycledViews.size() + + ", X: " + mScroller.getCurrX() + ", Y: " + mScroller.getCurrY()); + Log.d("viewflow", "IndexInAdapter: " + mCurrentAdapterIndex + + ", IndexInBuffer: " + mCurrentBufferIndex); + } +} diff --git a/opensrp-gizi/src/main/jniLibs/armeabi/libfacialproc_jni.so b/opensrp-gizi/src/main/jniLibs/armeabi/libfacialproc_jni.so new file mode 100755 index 0000000..11837ca Binary files /dev/null and b/opensrp-gizi/src/main/jniLibs/armeabi/libfacialproc_jni.so differ diff --git a/opensrp-gizi/src/main/res/anim/fadeout.xml b/opensrp-gizi/src/main/res/anim/fadeout.xml new file mode 100644 index 0000000..3321b19 --- /dev/null +++ b/opensrp-gizi/src/main/res/anim/fadeout.xml @@ -0,0 +1,11 @@ + + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/fr_face_detection.xml b/opensrp-gizi/src/main/res/drawable-mdpi/fr_face_detection.xml new file mode 100644 index 0000000..6ba85fd --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/fr_face_detection.xml @@ -0,0 +1,8 @@ + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/fr_face_detection_on.xml b/opensrp-gizi/src/main/res/drawable-mdpi/fr_face_detection_on.xml new file mode 100644 index 0000000..d7343e9 --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/fr_face_detection_on.xml @@ -0,0 +1,8 @@ + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/fr_not_found_404.png b/opensrp-gizi/src/main/res/drawable-mdpi/fr_not_found_404.png new file mode 100644 index 0000000..7a54260 Binary files /dev/null and b/opensrp-gizi/src/main/res/drawable-mdpi/fr_not_found_404.png differ diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/fr_shutter_anim_1.png b/opensrp-gizi/src/main/res/drawable-mdpi/fr_shutter_anim_1.png new file mode 100755 index 0000000..4ac4471 Binary files /dev/null and b/opensrp-gizi/src/main/res/drawable-mdpi/fr_shutter_anim_1.png differ diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/fr_shutter_anim_2.png b/opensrp-gizi/src/main/res/drawable-mdpi/fr_shutter_anim_2.png new file mode 100755 index 0000000..36da8a4 Binary files /dev/null and b/opensrp-gizi/src/main/res/drawable-mdpi/fr_shutter_anim_2.png differ diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/fr_shutter_anim_3.png b/opensrp-gizi/src/main/res/drawable-mdpi/fr_shutter_anim_3.png new file mode 100755 index 0000000..47e30f3 Binary files /dev/null and b/opensrp-gizi/src/main/res/drawable-mdpi/fr_shutter_anim_3.png differ diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/fr_shutter_anim_4.png b/opensrp-gizi/src/main/res/drawable-mdpi/fr_shutter_anim_4.png new file mode 100755 index 0000000..87a9c4e Binary files /dev/null and b/opensrp-gizi/src/main/res/drawable-mdpi/fr_shutter_anim_4.png differ diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/fr_shutter_anim_5.png b/opensrp-gizi/src/main/res/drawable-mdpi/fr_shutter_anim_5.png new file mode 100755 index 0000000..71e36cf Binary files /dev/null and b/opensrp-gizi/src/main/res/drawable-mdpi/fr_shutter_anim_5.png differ diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/fr_shutter_anim_6.png b/opensrp-gizi/src/main/res/drawable-mdpi/fr_shutter_anim_6.png new file mode 100755 index 0000000..b948462 Binary files /dev/null and b/opensrp-gizi/src/main/res/drawable-mdpi/fr_shutter_anim_6.png differ diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/fr_spin_animation.xml b/opensrp-gizi/src/main/res/drawable-mdpi/fr_spin_animation.xml new file mode 100755 index 0000000..64a67c3 --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/fr_spin_animation.xml @@ -0,0 +1,12 @@ + + + + + + + + + + + diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_camera_alt_white_24dp.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_camera_alt_white_24dp.xml new file mode 100644 index 0000000..c04127b --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_camera_alt_white_24dp.xml @@ -0,0 +1,12 @@ + + + + diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_camera_front_white_24dp.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_camera_front_white_24dp.xml new file mode 100644 index 0000000..5f5a86b --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_camera_front_white_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_camera_rear_white_24dp.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_camera_rear_white_24dp.xml new file mode 100644 index 0000000..32adce9 --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_camera_rear_white_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_checked_white.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_checked_white.xml new file mode 100644 index 0000000..c87fab0 --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_checked_white.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_collections_white_24dp.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_collections_white_24dp.xml new file mode 100644 index 0000000..cc0a3be --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_collections_white_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_confirm_highlighted_24dp.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_confirm_highlighted_24dp.xml new file mode 100644 index 0000000..22cdaf2 --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_confirm_highlighted_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_confirm_white_24dp.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_confirm_white_24dp.xml new file mode 100644 index 0000000..3b81a0a --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_confirm_white_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_cross.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_cross.xml new file mode 100644 index 0000000..a24d4b6 --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_cross.xml @@ -0,0 +1,22 @@ + + + + + + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_delete.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_delete.xml new file mode 100644 index 0000000..8156cc6 --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_delete.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_delete_highlighted_white_24dp.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_delete_highlighted_white_24dp.xml new file mode 100644 index 0000000..b827d81 --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_delete_highlighted_white_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_delete_white_24dp.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_delete_white_24dp.xml new file mode 100644 index 0000000..d5a3a5d --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_delete_white_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_faces.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_faces.xml new file mode 100644 index 0000000..a6c9833 --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_faces.xml @@ -0,0 +1,22 @@ + + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_flash_green.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_flash_green.xml new file mode 100644 index 0000000..7fbbad3 --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_flash_green.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_flash_off.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_flash_off.xml new file mode 100644 index 0000000..cbe1b58 --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_flash_off.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_home_highlighted_24dp.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_home_highlighted_24dp.xml new file mode 100644 index 0000000..89e341d --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_home_highlighted_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_home_white_24dp.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_home_white_24dp.xml new file mode 100644 index 0000000..c58a39e --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_home_white_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_perfect_mode_off.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_perfect_mode_off.xml new file mode 100644 index 0000000..b524271 --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_perfect_mode_off.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_perfect_mode_on.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_perfect_mode_on.xml new file mode 100644 index 0000000..9b9d418 --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_perfect_mode_on.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_settings_blue_24dp.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_settings_blue_24dp.xml new file mode 100644 index 0000000..f29a403 --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_settings_blue_24dp.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_settings_green_24dp.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_settings_green_24dp.xml new file mode 100644 index 0000000..da1f569 --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_settings_green_24dp.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_settings_white_24dp.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_settings_white_24dp.xml new file mode 100644 index 0000000..64616f1 --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_settings_white_24dp.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_trash_delete.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_trash_delete.xml new file mode 100644 index 0000000..2d375d5 --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_trash_delete.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/drawable-mdpi/ic_trash_delete_green.xml b/opensrp-gizi/src/main/res/drawable-mdpi/ic_trash_delete_green.xml new file mode 100644 index 0000000..1028fff --- /dev/null +++ b/opensrp-gizi/src/main/res/drawable-mdpi/ic_trash_delete_green.xml @@ -0,0 +1,7 @@ + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/layout/activity_fr_clients.xml b/opensrp-gizi/src/main/res/layout/activity_fr_clients.xml new file mode 100644 index 0000000..368a28a --- /dev/null +++ b/opensrp-gizi/src/main/res/layout/activity_fr_clients.xml @@ -0,0 +1,13 @@ + + + + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/layout/activity_fr_image_face_confirmation.xml b/opensrp-gizi/src/main/res/layout/activity_fr_image_face_confirmation.xml new file mode 100755 index 0000000..fad74a8 --- /dev/null +++ b/opensrp-gizi/src/main/res/layout/activity_fr_image_face_confirmation.xml @@ -0,0 +1,37 @@ + + + + + + + + + + diff --git a/opensrp-gizi/src/main/res/layout/activity_fr_main_face.xml b/opensrp-gizi/src/main/res/layout/activity_fr_main_face.xml new file mode 100755 index 0000000..87eb26f --- /dev/null +++ b/opensrp-gizi/src/main/res/layout/activity_fr_main_face.xml @@ -0,0 +1,138 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opensrp-gizi/src/main/res/layout/fr_base_id_clients.xml b/opensrp-gizi/src/main/res/layout/fr_base_id_clients.xml new file mode 100644 index 0000000..c28780d --- /dev/null +++ b/opensrp-gizi/src/main/res/layout/fr_base_id_clients.xml @@ -0,0 +1,27 @@ + + + + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/layout/gizi_chart_activity.xml b/opensrp-gizi/src/main/res/layout/gizi_chart_activity.xml new file mode 100644 index 0000000..a4b7333 --- /dev/null +++ b/opensrp-gizi/src/main/res/layout/gizi_chart_activity.xml @@ -0,0 +1,60 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/layout/gizi_chart_nav_bar.xml b/opensrp-gizi/src/main/res/layout/gizi_chart_nav_bar.xml new file mode 100644 index 0000000..0a50ad7 --- /dev/null +++ b/opensrp-gizi/src/main/res/layout/gizi_chart_nav_bar.xml @@ -0,0 +1,88 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opensrp-gizi/src/main/res/layout/gizi_detail_activity.xml b/opensrp-gizi/src/main/res/layout/gizi_detail_activity.xml new file mode 100644 index 0000000..63feaa0 --- /dev/null +++ b/opensrp-gizi/src/main/res/layout/gizi_detail_activity.xml @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opensrp-gizi/src/main/res/layout/gizi_detail_profile.xml b/opensrp-gizi/src/main/res/layout/gizi_detail_profile.xml new file mode 100644 index 0000000..2700195 --- /dev/null +++ b/opensrp-gizi/src/main/res/layout/gizi_detail_profile.xml @@ -0,0 +1,289 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/layout/gizi_z_score_activity.xml b/opensrp-gizi/src/main/res/layout/gizi_z_score_activity.xml new file mode 100644 index 0000000..bb30c93 --- /dev/null +++ b/opensrp-gizi/src/main/res/layout/gizi_z_score_activity.xml @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + +]]> + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/layout/gizidetail_nav_bar.xml b/opensrp-gizi/src/main/res/layout/gizidetail_nav_bar.xml new file mode 100644 index 0000000..35da0cd --- /dev/null +++ b/opensrp-gizi/src/main/res/layout/gizidetail_nav_bar.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/layout/smart_register_gizi_client.xml b/opensrp-gizi/src/main/res/layout/smart_register_gizi_client.xml new file mode 100644 index 0000000..ca564bd --- /dev/null +++ b/opensrp-gizi/src/main/res/layout/smart_register_gizi_client.xml @@ -0,0 +1,350 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/layout/smart_register_gizi_ibu_client.xml b/opensrp-gizi/src/main/res/layout/smart_register_gizi_ibu_client.xml new file mode 100644 index 0000000..a96a6e6 --- /dev/null +++ b/opensrp-gizi/src/main/res/layout/smart_register_gizi_ibu_client.xml @@ -0,0 +1,243 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/layout/smart_registers_gizi_home.xml b/opensrp-gizi/src/main/res/layout/smart_registers_gizi_home.xml new file mode 100644 index 0000000..f0362a8 --- /dev/null +++ b/opensrp-gizi/src/main/res/layout/smart_registers_gizi_home.xml @@ -0,0 +1,152 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opensrp-gizi/src/main/res/menu/client_activity.xml b/opensrp-gizi/src/main/res/menu/client_activity.xml new file mode 100644 index 0000000..4f4b568 --- /dev/null +++ b/opensrp-gizi/src/main/res/menu/client_activity.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/menu/image_confirmation.xml b/opensrp-gizi/src/main/res/menu/image_confirmation.xml new file mode 100644 index 0000000..d227c49 --- /dev/null +++ b/opensrp-gizi/src/main/res/menu/image_confirmation.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/menu/main.xml b/opensrp-gizi/src/main/res/menu/main.xml new file mode 100644 index 0000000..d227c49 --- /dev/null +++ b/opensrp-gizi/src/main/res/menu/main.xml @@ -0,0 +1,9 @@ + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/menu/menu_main.xml b/opensrp-gizi/src/main/res/menu/menu_main.xml new file mode 100644 index 0000000..508a1e4 --- /dev/null +++ b/opensrp-gizi/src/main/res/menu/menu_main.xml @@ -0,0 +1,26 @@ + + + + + + + + diff --git a/opensrp-gizi/src/main/res/mipmap-hdpi/ic_launcher.png b/opensrp-gizi/src/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000..cde69bc Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-hdpi/logo.png b/opensrp-gizi/src/main/res/mipmap-hdpi/logo.png new file mode 100644 index 0000000..ac362e9 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-hdpi/logo.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/child_boy_infant.png b/opensrp-gizi/src/main/res/mipmap-mdpi/child_boy_infant.png new file mode 100644 index 0000000..7366434 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/child_boy_infant.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/child_girl_infant.png b/opensrp-gizi/src/main/res/mipmap-mdpi/child_girl_infant.png new file mode 100644 index 0000000..75ed5a7 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/child_girl_infant.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/flag_hrp.png b/opensrp-gizi/src/main/res/mipmap-mdpi/flag_hrp.png new file mode 100644 index 0000000..b012895 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/flag_hrp.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/flag_vg.png b/opensrp-gizi/src/main/res/mipmap-mdpi/flag_vg.png new file mode 100644 index 0000000..d5180ba Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/flag_vg.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/gizilogin.png b/opensrp-gizi/src/main/res/mipmap-mdpi/gizilogin.png new file mode 100644 index 0000000..9a5cce8 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/gizilogin.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/hhreg.png b/opensrp-gizi/src/main/res/mipmap-mdpi/hhreg.png new file mode 100644 index 0000000..ceaf707 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/hhreg.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/household_profile.png b/opensrp-gizi/src/main/res/mipmap-mdpi/household_profile.png new file mode 100644 index 0000000..002ce0d Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/household_profile.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/household_profile_thumb.png b/opensrp-gizi/src/main/res/mipmap-mdpi/household_profile_thumb.png new file mode 100644 index 0000000..f920b38 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/household_profile_thumb.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/householdload.png b/opensrp-gizi/src/main/res/mipmap-mdpi/householdload.png new file mode 100644 index 0000000..c273652 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/householdload.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/ic_launcher.png b/opensrp-gizi/src/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000..c133a0c Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/icon_event_anc.png b/opensrp-gizi/src/main/res/mipmap-mdpi/icon_event_anc.png new file mode 100644 index 0000000..025516c Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/icon_event_anc.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/icon_event_edd.png b/opensrp-gizi/src/main/res/mipmap-mdpi/icon_event_edd.png new file mode 100644 index 0000000..b4618f2 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/icon_event_edd.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/login_logo.png b/opensrp-gizi/src/main/res/mipmap-mdpi/login_logo.png new file mode 100644 index 0000000..8e3de02 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/login_logo.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/logo.png b/opensrp-gizi/src/main/res/mipmap-mdpi/logo.png new file mode 100644 index 0000000..ac362e9 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/logo.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/opensrp_indonesia_gizi_logo.png b/opensrp-gizi/src/main/res/mipmap-mdpi/opensrp_indonesia_gizi_logo.png new file mode 100644 index 0000000..7a14047 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/opensrp_indonesia_gizi_logo.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/register_hh.png b/opensrp-gizi/src/main/res/mipmap-mdpi/register_hh.png new file mode 100644 index 0000000..3396346 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/register_hh.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/station_icon.png b/opensrp-gizi/src/main/res/mipmap-mdpi/station_icon.png new file mode 100644 index 0000000..a4b2856 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/station_icon.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/tutoria1.png b/opensrp-gizi/src/main/res/mipmap-mdpi/tutoria1.png new file mode 100644 index 0000000..7c4e015 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/tutoria1.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/tutorial1bangla.png b/opensrp-gizi/src/main/res/mipmap-mdpi/tutorial1bangla.png new file mode 100644 index 0000000..2dcd94a Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/tutorial1bangla.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/tutorial2.png b/opensrp-gizi/src/main/res/mipmap-mdpi/tutorial2.png new file mode 100644 index 0000000..99de387 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/tutorial2.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/tutorial2bangla.png b/opensrp-gizi/src/main/res/mipmap-mdpi/tutorial2bangla.png new file mode 100644 index 0000000..4d567e6 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/tutorial2bangla.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/tutorial3.png b/opensrp-gizi/src/main/res/mipmap-mdpi/tutorial3.png new file mode 100644 index 0000000..d35972f Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/tutorial3.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/tutorialbangla3.png b/opensrp-gizi/src/main/res/mipmap-mdpi/tutorialbangla3.png new file mode 100644 index 0000000..3e549f6 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/tutorialbangla3.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/warning.png b/opensrp-gizi/src/main/res/mipmap-mdpi/warning.png new file mode 100644 index 0000000..c6ec4a8 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/warning.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/woman_placeholder.png b/opensrp-gizi/src/main/res/mipmap-mdpi/woman_placeholder.png new file mode 100644 index 0000000..9b47b5a Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/woman_placeholder.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-mdpi/womanimageload.png b/opensrp-gizi/src/main/res/mipmap-mdpi/womanimageload.png new file mode 100644 index 0000000..0a6d9d7 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-mdpi/womanimageload.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-xhdpi/ic_launcher.png b/opensrp-gizi/src/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000..bfa42f0 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-xhdpi/info.png b/opensrp-gizi/src/main/res/mipmap-xhdpi/info.png new file mode 100644 index 0000000..d683829 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-xhdpi/info.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-xhdpi/logo.png b/opensrp-gizi/src/main/res/mipmap-xhdpi/logo.png new file mode 100644 index 0000000..ac362e9 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-xhdpi/logo.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-xxhdpi/ic_launcher.png b/opensrp-gizi/src/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..324e72c Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-xxhdpi/logo.png b/opensrp-gizi/src/main/res/mipmap-xxhdpi/logo.png new file mode 100644 index 0000000..ac362e9 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-xxhdpi/logo.png differ diff --git a/opensrp-gizi/src/main/res/mipmap-xxxhdpi/ic_launcher.png b/opensrp-gizi/src/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000..aee44e1 Binary files /dev/null and b/opensrp-gizi/src/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/opensrp-gizi/src/main/res/values-bn/strings.xml b/opensrp-gizi/src/main/res/values-bn/strings.xml new file mode 100644 index 0000000..e46d75c --- /dev/null +++ b/opensrp-gizi/src/main/res/values-bn/strings.xml @@ -0,0 +1,401 @@ + + + opensrp-gizi + Enter user name + Enter password + Log In + logo + spacer + Logging in… + Please wait + Log in failed + Please check the credentials + Are you sure you want to go back? + Confirm form close + Yes + No + Household + ELCO + FP + ANC + PNC + Child + Reporting + Register + Videos + + Cannot play video. + Please install IEC application to play the videos. + + Unable to play video due to technical error. + Confirm Log out + Are you sure you want to log out? All the data will be + cleared. + + forms unsynced + + "Next >>" + "<< Previous" + Page {0} of {1} + + NAME + EC NO. + GPLSA + FP METHOD + CHILDREN + STATUS + + + All Eligible Couples + Search EC Register + Search FP Register + Search PNC Register + Search Child Register + Sorted By: + , Village: + ({0}) + + Male\n{0} + Female\n{0} + No FP + + Delivery: + LMP: + EDD: + ANC + PNC + FP + No. strips: + No. Given: + G + P + L + S + A + + (O/A) + + Name (A to Z) + EC Number + Date of Delivery + SC + ST + High Priority (HP) + HRP + High Risk (HR) + BPL + + All + O/A + L/P + EC: + + Register ANC + Register FP + Register Child + FP Change + Change FP + Record ECP + Edit EC + Close EC + 26/03 - 25/04 + Switch Language + + ANC Visit + Hb Test + IFA + TT + Delivery Plan + PNC Registration + ANC Investigations + ANC Close + + Reporting + Videos + + Child: + Overview + Immunization 0-9 + Immunization 9+ + ID NO + DOB + SICK STATUS + LAST SERVICE + BCG + HEP B BIRTH + OPV + PENTAVALENT + MEASLES + OPV BOOSTER + DPT BOOSTER + VITAMIN A + Thayi: + Mother EC: + Age + HR + Child Immunizations + Child Illness + Child Close + Vitamin A + PNC + Pentavalent 2 + BCG + Pentavalent 3 + Pentavalent 1 + OPV 0 + OPV 1 + OPV 2 + OPV 3 + DPT Boost. 1 + DPT Boost. 2 + OPV Boost + Measles + Measles Booster + Measles B + Hep B + JE + MMR + Vitamin A + Illness Visit + + Sick Visit + Illness Report: %s + Date: + BCG + On + Hep B + OPV + TT + IFA + Pentavalent + Measles + OPV Booster + DPT Booster + Vitamin A + Pentav 1 + Pentav 2 + Pentav 3 + DPT B1 + DPT B2 + Pentav + + FP: + PNC: + METHOD + SIDE EFFECTS + FOLLOW UP/REFILL + RISKS + All Methods + Condom + DMPA/Injectable + IUCD + OCP + Female Sterilization + Male Sterilization + Others + + ECP + Traditional Methods + LAM + Centchroman + None - PS + None - SS + + All EC + High Priority (HP) + 2+ Children + 1 Child + Child: + "Due " + FP Methods + FP Prioritization + Add FP + FP Videos + + THAYI NO. + DELIVERY INFO + COMPLICATIONS + PP FP + CHILD + DAYS PP + FIRST 7 DAYS + PNC VISITS + + Overview + PNC Visits + + PNC Visit + Postpartum family planning + PNC Close + + Referred + referral + follow-up + refill + Update + Side Effects + + ANC: + Hb Test + "EDD: " + day (s) past due + LMP: + weeks + ANC: + BP + Weight : + Search ANC Register + Overview + ANC Visits + TT + Hb/IFA + Delivery Plan + " g/dl + " Tablets + ID + ANC STATUS + RISK FACTORS + ANC1 + ANC2 + ANC3 + ANC4 + Other + VISITS + TT + TT 1 + TT 2 + TT Booster + IFA + HB + DELIVERY PLAN + Delivery At + Transport: + Has companion: + Asha: + Contact: + Risks reviewed: + EDD + + Date: + Place: + Type: + PP FP + Wt: %1$s kg + DOB: + + PNC + expected + actual + done + missed + yellow + green + red + ari + sam + PNC Visit + + + + + + + + + Profile + No of ELCO + Last Visit Date + HH Visit Due Date + Other Inhabitants + HH Inhabitants Details + All Household Entries + Test Register + Test + HH + + Profile; + Unique ID + LMP + PSRF Due Date + Filtered By : + Name (A to Z) + HHID - Government + HHID - JiVitA + Due Status + Search Household + No ELCO + Has one or more ELCO + Search Eligible Couples + ELCO Woman Details + Summary + MWRA Registration Date + Last PSF Date + All Eligible Couples + HHID - Government : + HHID - JiVitA : + BRID : + Husband Name : + Age : + HHID-JiVitA : + HHID-Government : + Mauza : + Alphabetical (Woman name) + NBNF due date + ANC reminder Status + EDD and GA + ANC reminder due + Take Picture-NID/BRID + Census New Woman Registration Form + Pregnancy Surveillance And Registration Form + All Pregnant Women + History + Pregnant Woman Details + NBNF form + ANC visit 4 form + ANC visit 3 Form + ANC Visit 2 Form + ANC Visit 1 Form + ANC Register + Please check the credentials + login failed. Try later + No internet connection. Please ensure data connectivity + Please check the form for any error/missing input marked in Red box + ok + Child Profile + Anthopometry + Nutrition Status + Visit Date : + Height : + Height for Age : + Weight for length : + Weight for Age : + Weight : + Child Name : + Mother Name : + Father Name : + Posyandu : + Village : + Birth Date : + Birth Date + Gender : + Birth Weight : + Nutrition Status : + BGM : + 2T : + Under Yellow Line : + Exclusive Breastfeeding : + Parent Name + Gizi + Severely Underweight + Underweight + Good Nutrition + Overweight + Severely Stunted + Stunted + Normal + Tall + severely Wasted + Wasted + + + diff --git a/opensrp-gizi/src/main/res/values-in/strings.xml b/opensrp-gizi/src/main/res/values-in/strings.xml new file mode 100644 index 0000000..2d920f3 --- /dev/null +++ b/opensrp-gizi/src/main/res/values-in/strings.xml @@ -0,0 +1,438 @@ + + + Gizi + Enter user name + Enter password + Log In + logo + spacer + Logging in… + Please wait + Log in failed + Please check the credentials + Are you sure you want to go back? + Confirm form close + Yes + No + Household + ELCO + FP + ANC + PNC + Child + Reporting + Register + Videos + + Cannot play video. + Please install IEC application to play the videos. + + Unable to play video due to technical error. + Confirm Log out + Are you sure you want to log out? All the data will be + cleared. + + forms unsynced + + "Next >>" + "<< Previous" + Page {0} of {1} + + NAME + EC NO. + GPLSA + FP METHOD + CHILDREN + STATUS + + + All Eligible Couples + Search EC Register + Search FP Register + Search PNC Register + Cari Anak + Diurutkan berdasarkan: + , Desa: + ({0}) + kia-report.sid-indonesia.org/login/auth + + Male\n{0} + Female\n{0} + No FP + + Delivery: + LMP: + EDD: + ANC + PNC + FP + No. strips: + No. Given: + G + P + L + S + A + + (O/A) + + Nama (A ke Z) + Nama (Z ke A) + EC Number + Date of Delivery + SC + ST + High Priority (HP) + HRP + High Risk (HR) + BPL + Umur (0 ke 5) + umur (5 ke 0) + + All + O/A + L/P + EC: + + Register ANC + Register FP + Register Child + FP Change + Change FP + Record ECP + Edit EC + Close EC + 26/03 - 25/04 + Switch Language + + ANC Visit + Hb Test + IFA + TT + Delivery Plan + PNC Registration + ANC Investigations + ANC Close + + Reporting + Videos + + Child: + Overview + Immunization 0-9 + Immunization 9+ + ID NO + DOB + SICK STATUS + LAST SERVICE + BCG + HEP B BIRTH + OPV + PENTAVALENT + MEASLES + OPV BOOSTER + DPT BOOSTER + VITAMIN A + Thayi: + Mother EC: + Age + HR + Child Immunizations + Child Illness + Child Close + Vitamin A + PNC + Pentavalent 2 + BCG + Pentavalent 3 + Pentavalent 1 + OPV 0 + OPV 1 + OPV 2 + OPV 3 + DPT Boost. 1 + DPT Boost. 2 + OPV Boost + Measles + Measles Booster + Measles B + Hep B + JE + MMR + Vitamin A + Illness Visit + + Sick Visit + Illness Report: %s + Date: + BCG + On + Hep B + OPV + TT + IFA + Pentavalent + Measles + OPV Booster + DPT Booster + Vitamin A + Pentav 1 + Pentav 2 + Pentav 3 + DPT B1 + DPT B2 + Pentav + Konfirmasi nama Anak + + FP: + PNC: + METHOD + SIDE EFFECTS + FOLLOW UP/REFILL + RISKS + All Methods + Condom + DMPA/Injectable + IUCD + OCP + Female Sterilization + Male Sterilization + Others + + ECP + Traditional Methods + LAM + Centchroman + None - PS + None - SS + + All EC + High Priority (HP) + 2+ Children + 1 Child + Child: + "Due " + FP Methods + FP Prioritization + Add FP + FP Videos + + THAYI NO. + DELIVERY INFO + COMPLICATIONS + PP FP + CHILD + DAYS PP + FIRST 7 DAYS + PNC VISITS + + Overview + PNC Visits + + PNC Visit + Postpartum family planning + PNC Close + + Referred + referral + follow-up + refill + Update + Side Effects + + ANC: + Hb Test + "EDD: " + day (s) past due + LMP: + Minggu + ANC: + BP + Weight: + Search ANC Register + Overview + ANC Visits + TT + Hb/IFA + Delivery Plan + " g/dl + " Tablets + ID + ANC STATUS + RISK FACTORS + ANC1 + ANC2 + ANC3 + ANC4 + Other + VISITS + TT + TT 1 + TT 2 + TT Booster + IFA + HB + DELIVERY PLAN + Delivery At + Transport: + Has companion: + Asha: + Contact: + Risks reviewed: + EDD + + Date: + Place: + Type: + PP FP + Wt: %1$s kg + DOB: + + PNC + expected + actual + done + missed + yellow + green + red + ari + sam + PNC Visit + + + + + + + + + Profile + No of ELCO + Tanggal Kunjungan + HH Visit Due Date + Other Inhabitants + HH Inhabitants Details + All Household Entries + Test Register + Test + HH + + Ya + Tidak + Baru + Naik + Tidak Naik + Tidak Datang Bulan Lalu + Laki-laki + Perempuan + Profile; + Unique ID + LMP + PSRF Due Date + Filtered By: + Name (A to Z) + HHID - Government + HHID - JiVitA + Due Status + Search Household + No ELCO + Has one or more ELCO + Search Eligible Couples + ELCO Woman Details + Summary + MWRA Registration Date + Last PSF Date + All Eligible Couples + HHID - Government: + HHID - JiVitA: + BRID: + Husband Name: + Age: + HHID-JiVitA: + HHID-Government: + Mauza: + Alphabetical (Woman name) + NBNF due date + ANC reminder Status + EDD and GA + ANC reminder due + Take Picture-NID/BRID + Census New Woman Registration Form + Pregnancy Surveillance And Registration Form + All Pregnant Women + History + Pregnant Woman Details + NBNF form + ANC visit 4 form + ANC visit 3 Form + ANC Visit 2 Form + ANC Visit 1 Form + ANC Register + Please check the credentials + login failed. Try later + No internet connection. Please ensure data connectivity + Please check the form for any error/missing input marked in Red box + ok + Data Anak + Antropometri + Status Gizi + Unique ID: + Tanggal Kunjungan: + Tinggi: + Berat Badan + Tinggi Badan + Obat Cacing + Tinggi/Umur: + Berat/Tinggi: + Berat/Umur: + Berat: + Nama Anak: + Nama Ibu: + Nama Ayah: + Posyandu: + Desa: + Tanggal Lahir: + Tanggal Lahir + Jenis Kelamin: + Status Gizi: + Berat Lahir: + BGM: + 2T: + Gizi Kurang: + Asi Ekslusif: + MP ASI: + Nama Orang Tua + Gizi + Gizi Buruk + Gizi Kurang + Gizi Baik + Gizi Lebih + Gemuk + Sangat Pendek + Pendek + Normal + Tinggi + Sangat Kurus + Kurus + Jadwal Kunjungan + Obat Cacing: + Vitamin A terakhir diberikan: + Obat cacing terakhir diberikan: + + GIZI IBU + Detail Ibu + Hasil Tes Lab + Kadar HB + Vitamin A setelah 2 jam: + Vitamin A setelah 24 jam: + Pelayanan Post-Partum + thn + bln + Kunjungan Terakhir + Usia Kandungan + Lingkar Lengan + Sistolik + Diastolik + + diff --git a/opensrp-gizi/src/main/res/values/attrs.xml b/opensrp-gizi/src/main/res/values/attrs.xml new file mode 100644 index 0000000..d97a928 --- /dev/null +++ b/opensrp-gizi/src/main/res/values/attrs.xml @@ -0,0 +1,47 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/values/colors.xml b/opensrp-gizi/src/main/res/values/colors.xml new file mode 100644 index 0000000..5841de9 --- /dev/null +++ b/opensrp-gizi/src/main/res/values/colors.xml @@ -0,0 +1,51 @@ + + + #1a93d2 + + #d9d9d9 + #494949 + #f5f5f5 + #333333 + #389cc8 + #e6e6e6 + #389cc8 + + #44ffffff + #44389cc8 + #bb389cc8 + #1a1a1a + #494949 + + #cae2ed + #d13f3f + #389cc8 + #25aa4a + #fdd835 + + #f5f5f5 + + #EDCA00 + #d13f3f + #25aa4a + + #43ae23 + #d13f3f + #edca00 + + #2b475e + + #4fb45b + + #ff0000 + #ffff00 + #0000ff + + + #a3c639 + #85a71d + + #ccc + #e91e63 + #fff + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/values/dimens.xml b/opensrp-gizi/src/main/res/values/dimens.xml new file mode 100644 index 0000000..3d710cc --- /dev/null +++ b/opensrp-gizi/src/main/res/values/dimens.xml @@ -0,0 +1,70 @@ + + + 0dp + 0dp + 0dp + 0dp + 0dp + 0dp + 0dp + 0dp + 0dp + 0dp + 0dp + 0dp + 0dp + 0dp + 0dp + + 90dp + 1dp + 80dp + 70dp + 5dp + 5dp + 5dp + 30dp + 22dp + 5dp + 30dp + 3dp + 5dp + + 16sp + 19sp + + 24sp + 22sp + + 49dp + 30dp + + 25dp + + 50dp + 120dp + 16sp + + 150dp + 50dp + 200dp + 1dp + 10dp + 2dp + + 22sp + + 50dp + 540dp + 10dp + 3dp + 22dp + 22dp + 45dp + + 15dp + 10dp + 5dp + 25dp + 25dp + diff --git a/opensrp-gizi/src/main/res/values/ids.xml b/opensrp-gizi/src/main/res/values/ids.xml new file mode 100644 index 0000000..6aeb3c6 --- /dev/null +++ b/opensrp-gizi/src/main/res/values/ids.xml @@ -0,0 +1,9 @@ + + + + + + client + textforAncRegister + idforalertstatus + diff --git a/opensrp-gizi/src/main/res/values/integer.xml b/opensrp-gizi/src/main/res/values/integer.xml new file mode 100644 index 0000000..050b81b --- /dev/null +++ b/opensrp-gizi/src/main/res/values/integer.xml @@ -0,0 +1,93 @@ + + + 1000 + 244 + 75 + 125 + 109 + 160 + 218 + 89 + + 100 + 26 + 14 + 60 + 12 + 15 + 23 + 10 + + 15 + 15 + 15 + 15 + + 15 + 15 + 15 + 15 + + 100 + 24 + 6 + 10 + 60 + 13 + 7 + 13 + 7 + 20 + 30 + 15 + + 100 + 20 + 9 + 13 + 58 + 12 + 12 + 12 + 12 + 10 + 14 + 14 + 14 + 14 + 2 + 20 + 20 + 18 + 15 + 14 + 15 + 14 + 58 + 9 + 9 + 11 + 9 + 9 + 9 + + 100 + 24 + 8 + 17 + 15 + 9 + 16 + 22 + 12 + 12 + 7 + + 7 + 68 + 7 + + 4 + 300 + + \ No newline at end of file diff --git a/opensrp-gizi/src/main/res/values/strings.xml b/opensrp-gizi/src/main/res/values/strings.xml new file mode 100644 index 0000000..5ab75fd --- /dev/null +++ b/opensrp-gizi/src/main/res/values/strings.xml @@ -0,0 +1,488 @@ + + + Gizi + Enter user name + Enter password + Log In + logo + spacer + Logging in… + Please wait + Log in failed + Please check the credentials + Are you sure you want to go back? + Confirm form close + Yes + No + Household + ELCO + FP + ANC + PNC + Child + Reporting + Register + Videos + + Cannot play video. + Please install IEC application to play the videos. + + Unable to play video due to technical error. + Confirm Log out + Are you sure you want to log out? All the data will be + cleared. + + forms unsynced + + "Next >>" + "<< Previous" + Page {0} of {1} + + NAME + EC NO. + GPLSA + FP METHOD + CHILDREN + STATUS + + + All Eligible Couples + Search EC Register + Search FP Register + Search PNC Register + Cari Anak + Sorted By: + , Village: + ({0}) + + Male\n{0} + Female\n{0} + No FP + + Delivery: + LMP: + EDD: + ANC + PNC + FP + No. strips: + No. Given: + G + P + L + S + A + + (O/A) + + Nama (A to Z) + EC Number + Date of Delivery + SC + ST + High Priority (HP) + HRP + High Risk (HR) + BPL + + All + O/A + L/P + EC: + + Register ANC + Register FP + Register Child + FP Change + Change FP + Record ECP + Edit EC + Close EC + 26/03 - 25/04 + Switch Language + + ANC Visit + Hb Test + IFA + TT + Delivery Plan + PNC Registration + ANC Investigations + ANC Close + + Reporting + Videos + + Child: + Overview + Immunization 0-9 + Immunization 9+ + ID NO + DOB + SICK STATUS + LAST SERVICE + BCG + HEP B BIRTH + OPV + PENTAVALENT + MEASLES + OPV BOOSTER + DPT BOOSTER + VITAMIN A + Thayi: + Mother EC: + Age + HR + Child Immunizations + Child Illness + Child Close + Vitamin A + PNC + Pentavalent 2 + BCG + Pentavalent 3 + Pentavalent 1 + OPV 0 + OPV 1 + OPV 2 + OPV 3 + DPT Boost. 1 + DPT Boost. 2 + OPV Boost + Measles + Measles Booster + Measles B + Hep B + JE + MMR + Vitamin A + Illness Visit + + Sick Visit + Illness Report: %s + Date: + BCG + On + Hep B + OPV + TT + IFA + Pentavalent + Measles + OPV Booster + DPT Booster + Vitamin A + Pentav 1 + Pentav 2 + Pentav 3 + DPT B1 + DPT B2 + Pentav + + FP: + PNC: + METHOD + SIDE EFFECTS + FOLLOW UP/REFILL + RISKS + All Methods + Condom + DMPA/Injectable + IUCD + OCP + Female Sterilization + Male Sterilization + Others + + ECP + Traditional Methods + LAM + Centchroman + None - PS + None - SS + + All EC + High Priority (HP) + 2+ Children + 1 Child + Child: + "Due " + FP Methods + FP Prioritization + Add FP + FP Videos + + THAYI NO. + DELIVERY INFO + COMPLICATIONS + PP FP + CHILD + DAYS PP + FIRST 7 DAYS + PNC VISITS + + Overview + PNC Visits + + PNC Visit + Postpartum family planning + PNC Close + + Referred + referral + follow-up + refill + Update + Side Effects + + ANC: + Hb Test + "EDD: " + day (s) past due + LMP: + weeks + ANC: + BP + Weight: + Search ANC Register + Overview + ANC Visits + TT + Hb/IFA + Delivery Plan + " g/dl + " Tablets + ID + ANC STATUS + RISK FACTORS + ANC1 + ANC2 + ANC3 + ANC4 + Other + VISITS + TT + TT 1 + TT 2 + TT Booster + IFA + HB + DELIVERY PLAN + Delivery At + Transport: + Has companion: + Asha: + Contact: + Risks reviewed: + EDD + + Date: + Place: + Type: + PP FP + Wt: %1$s kg + DOB: + + PNC + expected + actual + done + missed + yellow + green + red + ari + sam + PNC Visit + Age (0y to 5 yrs) + Age (5 to 0 yrs) + + + + + + + + + Profile + No of ELCO + Visit Date + HH Visit Due Date + Other Inhabitants + HH Inhabitants Details + All Household Entries + Test Register + Test + HH + kia-report.sid-indonesia.org/login/auth + + Yes + No + New + Increase + Not Increase + Not Attending Previous Visit + Male + Female + Profile; + Unique ID + LMP + PSRF Due Date + Filtered By: + Name (A to Z) + HHID - Government + HHID - JiVitA + Due Status + Search Household + No ELCO + Has one or more ELCO + Search Eligible Couples + ELCO Woman Details + Summary + MWRA Registration Date + Last PSF Date + All Eligible Couples + HHID - Government: + HHID - JiVitA: + BRID: + Husband Name: + Age: + HHID-JiVitA: + HHID-Government: + Mauza: + Alphabetical (Woman name) + NBNF due date + ANC reminder Status + EDD and GA + ANC reminder due + Take Picture-NID/BRID + Census New Woman Registration Form + Pregnancy Surveillance And Registration Form + All Pregnant Women + History + Pregnant Woman Details + NBNF form + ANC visit 4 form + ANC visit 3 Form + ANC Visit 2 Form + ANC Visit 1 Form + ANC Register + Please check the credentials + login failed. Try later + No internet connection. Please ensure data connectivity + Please check the form for any error/missing input marked in Red box + ok + Child Details + Anthropometry + Nutrition Status + Unique ID: + Visit Date: + Height: + Weight + Height + Anthelmintic + Height for Age status: + Weight for Length status: + Weight for Age status: + Weight: + Child Name: + Mother Name: + Father Name: + Posyandu: + Village: + Date of Birth: + Date of Birth + Gender: + Nutrition Status: + Birth Weight: + Undernourished : + Failure to gain weight: + Underweight: + Exclusive Breastfeeding: + Weaning Food: + Parent Name + Gizi + Well Nourished + Gender + Visit Schedule + Anthelmintic: + Severely Underweight + Underweight + Normal + Overweight + Over Nourished + Severely Stunted + Stunted + Tall + Severely Wasted + Wasted + Last Vitamin A given: + Last Anthelmintic given: + Re-Confirm children name + + + Mother Details + Diastolic + Monthly Visit + MOTHER NUTRITION + Lab Test Result + HB Level + Last Visit + MUAC + Post-Partum Care + Systolic + Gestational Age + Vitamin A after 2 hrs: + Vitamin A after 24 hrs: + + + yrs + mth + hrs + Kg + Cm + Month + CHILD GROWTH CHART + Length for Age + Height for Age + + + Photo Confirmation + Approval Button Confirmation Desc + Trash Description + + + + M 50,50 + m -48,0 + a 48,48 0 1,0 96,0 + a 48,48 0 1,0 -96,0 + + + + + M 35,40 + m -7,0 + a 7,7 0 1,0 14,0 + a 7,7 0 1,0 -14,0 + + + M 65,40 + m -7,0 + a 7,7 0 1,0 14,0 + a 7,7 0 1,0 -14,0 + + + M 30,75 + Q 50,55 70,75 + + + M 30,65 + Q 50,85 70,65 + + Check Cross + Reset Album + Settings + No. HP : + + diff --git a/opensrp-gizi/src/main/res/values/styles.xml b/opensrp-gizi/src/main/res/values/styles.xml new file mode 100644 index 0000000..c93d1c3 --- /dev/null +++ b/opensrp-gizi/src/main/res/values/styles.xml @@ -0,0 +1,233 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/opensrp-gizi/src/main/res/values/tick_cross.xml b/opensrp-gizi/src/main/res/values/tick_cross.xml new file mode 100644 index 0000000..4fd85c1 --- /dev/null +++ b/opensrp-gizi/src/main/res/values/tick_cross.xml @@ -0,0 +1,26 @@ + + + + + 24 + 24 + 12 + 12 + + M4.8,13.4 L9,17.6 M10.4,16.2 L19.6,7 + + M6.4,6.4 L17.6,17.6 M6.4,17.6 L17.6,6.4 + + + + tick + cross + groupTickCross + + + #999 + + + 450 + + \ No newline at end of file diff --git a/opensrp-gizi/src/test/java/org/ei/opensrp/gizi/ExampleUnitTest.java b/opensrp-gizi/src/test/java/org/ei/opensrp/gizi/ExampleUnitTest.java new file mode 100644 index 0000000..2116a2e --- /dev/null +++ b/opensrp-gizi/src/test/java/org/ei/opensrp/gizi/ExampleUnitTest.java @@ -0,0 +1,15 @@ +package org.ei.opensrp.gizi; + +//import org.junit.Test; + +//import static org.junit.Assert.*; + +/** + * To work on unit tests, switch the Test Artifact in the Build Variants view. + */ +public class ExampleUnitTest { + // @Test + // public void addition_isCorrect() throws Exception { + // assertEquals(4, 2 + 2); + // } +} \ No newline at end of file diff --git a/settings.gradle b/settings.gradle index 7196826..0b643d4 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,2 +1,2 @@ rootProject.name = 'opensrp-app-sid' -include ':opensrp-bidan' \ No newline at end of file +include ':opensrp-gizi' \ No newline at end of file