diff --git a/.github/workflows/time.yml b/.github/workflows/time.yml new file mode 100644 index 000000000..a14bb8ba7 --- /dev/null +++ b/.github/workflows/time.yml @@ -0,0 +1,20 @@ +name: Time + +on: + workflow_dispatch: + +jobs: + cargo-run: + runs-on: self-hosted + env: + NPCORE_CONFIG_TUI: false # Disable TUI + steps: + - name: Checkout Repository + uses: actions/checkout@v2 + + - name: Run + run: | + /usr/bin/time -v cargo run --release --example bimodal_ke 2>&1 | tee time-output.txt # Redirect output to a file + + - name: Results + run: cat time-output.txt # Print the content of the file diff --git a/.gitignore b/.gitignore index caffd081c..d5e6849d5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,6 @@ /target /Cargo.lock -/log +*.log theta.csv cycles.csv pred.csv @@ -14,10 +14,12 @@ simulation_output.csv meta*.csv /examples/rosuva/* /examples/iohexol/* +/examples/vori/* /examples/data/iohexol* /examples/data/rosuva* +/examples/data/vori* /.idea stop .vscode - -*.f90 \ No newline at end of file +*.f90 +settings.json diff --git a/Cargo.toml b/Cargo.toml index c5014716f..04a46a0d2 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "npcore" -version = "0.1.1" +version = "0.1.3" edition = "2021" authors = [ "Julián D. Otálvaro ", @@ -8,7 +8,7 @@ authors = [ "Michael Neely", "Walter Yamada", ] -description = "Rust Library with the building blocks needed to create new Non-Parametric algorithms and its integration with Pmetrics." +description = "Rust library with the building blocks needed to create new Non-Parametric algorithms and its integration with Pmetrics." license = "GPL-3.0" documentation = "https://lapkb.github.io/NPcore/npcore/" repository = "https://github.com/LAPKB/NPcore" @@ -16,36 +16,38 @@ exclude = [".github/*", ".vscode/*"] [dependencies] dashmap = "5.5.3" -#cached = "0.26.2" lazy_static = "1.4.0" csv = "1.2.1" ndarray = { version = "0.15.6", features = ["rayon"] } serde = "1.0.188" serde_derive = "1.0.188" +serde_json = "1.0.66" sobol_burley = "0.5.0" toml = { version = "0.8.1", features = ["preserve_order"] } ode_solvers = "0.3.7" ndarray-stats = "0.5.1" linfa-linalg = "0.1.0" -log = "0.4.20" -log4rs = "1.2.0" rayon = "1.8.0" eyre = "0.6.8" -ratatui = { version = "0.23.0", features = ["crossterm"] } +ratatui = { version = "0.25.0", features = ["crossterm"] } crossterm = "0.27.0" tokio = { version = "1.32.0", features = ["sync", "rt"] } ndarray-csv = "0.5.2" rawpointer = "0.2.1" -argmin = "0.8.1" -itertools = "0.11.0" -faer-core = { version = "0.11.0", features = [] } +argmin = { version = "0.9.0", features = [] } +itertools = "0.12.0" +faer-core = { version = "0.15.0", features = [] } # faer-lu = "0.9" -faer-qr = "0.11.0" +faer-qr = "0.16.0" # faer-cholesky = "0.9" # faer-svd = "0.9" -dyn-stack = "0.9.0" -faer = { version = "0.11.0", features = ["nalgebra", "ndarray"] } - +argmin-math = { version = "0.3.0", features = ["ndarray_v0_15-nolinalg-serde"] } +dyn-stack = "0.10.0" +faer = { version = "0.15.0", features = ["nalgebra", "ndarray"] } +tracing = "0.1.40" +tracing-subscriber = { version = "0.3.17", features = ["env-filter", "fmt", "time"] } +chrono = "0.4" +config = "0.13" [profile.release] codegen-units = 1 diff --git a/README.md b/README.md index d43bd1409..88394f9de 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,43 @@ # NPcore [![Build](https://github.com/LAPKB/NPcore/actions/workflows/rust.yml/badge.svg)](https://github.com/LAPKB/NPcore/actions/workflows/rust.yml) [![Security Audit](https://github.com/LAPKB/NPcore/actions/workflows/security_audit.yml/badge.svg)](https://github.com/LAPKB/NPcore/actions/workflows/security_audit.yml) +![crates.io](https://img.shields.io/crates/v/npcore.svg) -Rust Library with the building blocks needed to create new Non-Parametric algorithms and its integration with [Pmetrics]([https://link-url-here.org](https://github.com/LAPKB/Pmetrics)). +Rust library with the building blocks to create and implement new non-parametric algorithms for population pharmacokinetic modelling and their integration with [Pmetrics](https://github.com/LAPKB/Pmetrics). ## Implemented functionality * Solver for ODE-based population pharmacokinetic models * Supports the Pmetrics data format for seamless integration -* Basic NPAG implementation for parameter estimation * Covariate support, carry-forward or linear interpolation * Option to cache results for improved speed * Powerful simulation engine * Informative Terminal User Interface (TUI) +## Available algoritms + +This project aims to implement several algorithms for non-parametric population pharmacokinetic modelling. + +- [x] Non Parametric Adaptive Grid (NPAG) + - [Yamada et al (2021)](https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7823953/) + - [Neely et al (2012)](https://pubmed.ncbi.nlm.nih.gov/22722776/) +- [x] Non Parametric Optimal Design (NPOD) + - [Otalvaro et al (2023)](https://pubmed.ncbi.nlm.nih.gov/36478350/) + - [Leary et al (2003)](https://www.page-meeting.org/default.asp?abstract=421) +- [ ] Non Parametric Simulated Annealing (NPSA) + - [Chen et al (2023)](https://arxiv.org/abs/2301.12656) + +In the future we also aim to support parametric algorithms, such as the Iterative 2-Stage Bayesian (IT2B) ## Examples There are two examples using NPAG implemented in this repository, `bimodal_ke` and `two_eq_lag`. -You may run them with the following command +You may run them with the following command, e.g. ``` -cargo run --example example_name --release +cargo run --example bimodal_ke --release ``` -Be sure to replace `example_name` with the respective example. -Look at the corresponding `examples/_example_/*.toml`-file to change the configuration for each run. +Look at the corresponding `examples/.../*.toml`-file to change the configuration for each run. ## Documentation diff --git a/examples/bimodal_ke/config.toml b/examples/bimodal_ke/config.toml index a2857d0ad..7072e7a22 100644 --- a/examples/bimodal_ke/config.toml +++ b/examples/bimodal_ke/config.toml @@ -1,7 +1,7 @@ [paths] data = "examples/data/bimodal_ke.csv" -log_out = "log/bimodal_ke.log" -#prior_dist = "theta_bimodal_ke.csv" +log = "bimodal_ke.log" +#prior = "theta_bimodal_ke.csv" [config] cycles = 1024 @@ -9,8 +9,11 @@ engine = "NPAG" init_points = 2129 seed = 347 tui = true -pmetrics_outputs = true +output = true cache = true +idelta = 0.1 +log_level = "info" + [random] Ke = [0.001, 3.0] diff --git a/examples/bimodal_ke/main.rs b/examples/bimodal_ke/main.rs index 542572d80..1d2a6ff30 100644 --- a/examples/bimodal_ke/main.rs +++ b/examples/bimodal_ke/main.rs @@ -8,94 +8,118 @@ use npcore::prelude::{ }; use ode_solvers::*; +// Constants for the absolute and relative tolerance for the dynamic steps used for solving the ODEs const ATOL: f64 = 1e-4; const RTOL: f64 = 1e-4; +// Define the state vector, which must be equal to the number of compartments in the model +// These are re-exported from the `nalgebra`-crate by `ode_solvers`, see https://github.com/srenevey/ode-solvers?tab=readme-ov-file#type-alias-definition +// In brief, for up to 6 compartments, use VectorN, N being the number of compartments. +// For more than 6 compartments, use `nalgebra::SVector`, where N is the number of compartments. +type State = Vector1; + +// Time uses f64 precision +type Time = f64; + +// This is the main structure for the model +// It holds the parameters (defined in config.toml), the scenarios (i.e. datafile), the (possible) infusions and the covariates if any #[derive(Debug, Clone)] -struct Model<'a> { - ke: f64, - _v: f64, - _scenario: &'a Scenario, +struct Model { + params: HashMap, + _scenario: Scenario, infusions: Vec, - cov: Option<&'a HashMap>, + cov: Option>, } -type State = Vector1; -type Time = f64; +// This is a helper function to get the parameter value by name +impl Model { + pub fn get_param(&self, str: &str) -> f64 { + *self.params.get(str).unwrap() + } +} -impl ode_solvers::System for Model<'_> { +impl ode_solvers::System for Model { fn system(&self, t: Time, y: &State, dy: &mut State) { - let ke = self.ke; - - let _lag = 0.0; + // Get the parameters from the model + let ke = self.get_param("ke"); + // Get the infusions that are active at time `t` let mut rateiv = [0.0]; for infusion in &self.infusions { if t >= infusion.time && t <= (infusion.dur + infusion.time) { rateiv[infusion.compartment] += infusion.amount / infusion.dur; } } + // The ordinary differential equations (ODEs) are defined here + // This example is a one-compartmental model with first-order elimination, and intravenous infusions - ///////////////////// USER DEFINED /////////////// - + ////// ODE ////// dy[0] = -ke * y[0] + rateiv[0]; - - //////////////// END USER DEFINED //////////////// } } #[derive(Debug, Clone)] struct Ode {} -impl Predict for Ode { - fn predict(&self, params: Vec, scenario: &Scenario) -> Vec { - let mut system = Model { - ke: params[0], - _v: params[1], - _scenario: scenario, - infusions: vec![], - cov: None, - }; - // let scenario = scenario.reorder_with_lag(vec![]); - let mut yout = vec![]; - let mut x = State::new(0.0); - let mut index: usize = 0; - for block in &scenario.blocks { - system.cov = Some(&block.covs); - for event in &block.events { - if event.evid == 1 { - if event.dur.unwrap_or(0.0) > 0.0 { - //infusion - system.infusions.push(Infusion { - time: event.time, - dur: event.dur.unwrap(), - amount: event.dose.unwrap(), - compartment: event.input.unwrap() - 1, - }); - } else { - //dose - x[event.input.unwrap() - 1] += event.dose.unwrap(); - } - } else if event.evid == 0 { - //obs - yout.push(x[event.outeq.unwrap() - 1] / params[1]); - } - if let Some(next_time) = scenario.times.get(index + 1) { - //TODO: use the last dx as the initial one for the next simulation. - let mut stepper = - Dopri5::new(system.clone(), event.time, *next_time, 1e-3, x, RTOL, ATOL); - let _res = stepper.integrate(); - let y = stepper.y_out(); - x = *y.last().unwrap(); - } - index += 1; - } +impl<'a> Predict<'a> for Ode { + type Model = Model; + type State = State; + fn initial_system(&self, params: &Vec, scenario: Scenario) -> (Self::Model, Scenario) { + let params = HashMap::from([("ke".to_string(), params[0]), ("v".to_string(), params[1])]); + ( + Model { + params, + _scenario: scenario.clone(), //TODO remove + infusions: vec![], + cov: None, + }, + scenario.reorder_with_lag(vec![(0.0, 1)]), + ) + } + + // This function is used to get the output from the model, defined by the output equations (outeq) supplied by the user + fn get_output(&self, time: f64, x: &Self::State, system: &Self::Model, outeq: usize) -> f64 { + // Get parameters from the model also used for calculating the output equations + let v = system.get_param("v"); + #[allow(unused_variables)] + let t = time; + match outeq { + 1 => x[0] / v, // Concentration of the central compartment defined by the amount of drug, x[0], divided by the volume of the central compartment, v + _ => panic!("Invalid output equation"), + } + } + + // Set the initial state of the compartments + fn initial_state(&self) -> State { + State::default() + } + // Add any possible infusions + fn add_infusion(&self, system: &mut Self::Model, infusion: Infusion) { + system.infusions.push(infusion); + } + // Add any possible covariates + fn add_covs(&self, system: &mut Self::Model, cov: Option>) { + system.cov = cov; + } + // Add any possible doses + fn add_dose(&self, state: &mut Self::State, dose: f64, compartment: usize) { + state[compartment] += dose; + } + // Perform a "step" of the model, i.e. solve the ODEs from the current time to the next time + // In the next step, we use this result as the initial state + fn state_step(&self, x: &mut Self::State, system: &Self::Model, time: f64, next_time: f64) { + if time >= next_time { + panic!("time error") } - yout + let mut stepper = Dopri5::new(system.clone(), time, next_time, 1e-3, *x, RTOL, ATOL); + let _res = stepper.integrate(); + let y = stepper.y_out(); + *x = *y.last().unwrap(); } } fn main() -> Result<()> { + // Main entrypoint, see `entrypoints.rs` for more details let _result = start( Engine::new(Ode {}), "examples/bimodal_ke/config.toml".to_string(), diff --git a/examples/data/vori.csv b/examples/data/vori.csv deleted file mode 100644 index 432a1e735..000000000 --- a/examples/data/vori.csv +++ /dev/null @@ -1,3284 +0,0 @@ -ID,EVID,TIME,DUR,DOSE,ADDL,II,INPUT,OUT,OUTEQ,C0,C1,C2,C3,wt,ast,alt,age -4.1,1,0,2,66,.,.,1,.,.,.,.,.,.,11,24,29,103.2738095 -4.1,1,12,2,77,.,.,1,.,.,.,.,.,.,.,.,.,103.3452381 -4.1,1,23.66666667,2,77,.,.,1,.,.,.,.,.,.,.,.,.,103.4146825 -4.1,1,36,2,77,.,.,1,.,.,.,.,.,.,.,.,.,103.4880952 -4.1,1,49,2,77,.,.,1,.,.,.,.,.,.,.,.,.,103.5654762 -4.1,1,61.5,2,77,.,.,1,.,.,.,.,.,.,.,.,.,103.639881 -4.1,1,73,2,77,.,.,1,.,.,.,.,.,.,.,.,.,103.7083333 -4.1,0,79.6666667,.,.,.,.,.,0.6,1,.,.,.,.,.,.,.,103.7480159 -5.1,1,0,2,40,.,.,1,.,.,.,.,.,.,6.6,43,56,24.13541667 -5.1,1,11.25,2,40,.,.,1,.,.,.,.,.,.,.,.,.,24.20238095 -5.1,1,21.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,24.26190476 -5.1,1,30.71666667,0,0,.,.,1,.,.,.,.,.,.,.,42,53,24.31825397 -5.1,1,33.25,2,45,.,.,1,.,.,.,.,.,.,.,.,.,24.33333333 -5.1,1,38.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,24.36309524 -5.1,1,45.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,24.4047619 -5.1,1,45.25,2,45,.,.,1,.,.,.,.,.,.,.,.,.,24.4047619 -5.1,1,49.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,24.42857143 -5.1,1,53.6,0,0,.,.,1,.,.,.,.,.,.,.,45,57,24.45446429 -5.1,1,57.75,2,45,.,.,1,.,.,.,.,.,.,.,.,.,24.47916667 -5.1,1,69.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,24.54761905 -5.1,1,69.75,2,45,.,.,1,.,.,.,.,.,.,.,.,.,24.55059524 -5.1,1,73.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,24.57142857 -5.1,1,79.58333333,0,0,.,.,1,.,.,.,.,.,.,.,55,54,24.60912698 -5.1,1,81.25,2,45,.,.,1,.,.,.,.,.,.,.,.,.,24.61904762 -5.1,1,93.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,24.69047619 -5.1,1,93.25,2,45,.,.,1,.,.,.,.,.,.,.,.,.,24.69047619 -5.1,1,97.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,24.71428571 -5.1,1,103.05,0,0,.,.,1,.,.,.,.,.,.,.,47,49,24.74880952 -5.1,1,105.25,2,45,.,.,1,.,.,.,.,.,.,.,.,.,24.76190476 -5.1,1,109.75,0,0,.,.,1,.,.,.,.,.,.,.,44,50,24.78869048 -5.1,1,117.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,24.83333333 -5.1,1,117.75,2,45,.,.,1,.,.,.,.,.,.,.,.,.,24.83630952 -5.1,1,119.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,24.8452381 -5.1,1,121.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,24.85714286 -5.1,1,123.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,24.86904762 -5.1,1,125.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,24.88095238 -5.1,1,125.8333333,0,0,.,.,1,.,.,.,.,.,.,.,55,48,24.8844246 -5.1,1,127.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,24.89285714 -5.1,1,129.75,2,45,.,.,1,.,.,.,.,.,.,.,.,.,24.9077381 -5.1,1,141.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,24.97619048 -5.1,1,141.25,2,45,.,.,1,.,.,.,.,.,.,.,.,.,24.97619048 -5.1,1,143.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,24.98809524 -5.1,1,145.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,25 -5.1,1,147.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,25.01190476 -5.1,1,148.7666667,0,0,.,.,1,.,.,.,.,.,.,.,48,55,25.02093254 -5.1,1,149.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,25.02380952 -5.1,1,150.75,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,25.0327381 -5.1,1,151.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,25.03571429 -5.1,1,153.25,2,45,.,.,1,.,.,.,.,.,.,.,.,.,25.04761905 -5.1,1,165.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,25.11904762 -5.1,1,166.25,2,45,.,.,1,.,.,.,.,.,.,.,.,.,25.125 -5.1,1,169.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,25.14285714 -5.1,1,173.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,25.16666667 -5.1,1,174.2,0,0,.,.,1,.,.,.,.,.,.,.,47,49,25.17232143 -5.1,1,178.8666667,2,45,.,.,1,.,.,.,.,.,.,.,.,.,25.20009921 -5.1,1,189.25,0,0,.,.,1,.,.,.,.,.,.,6.6,.,.,25.26190476 -5.1,1,191.25,2,45,.,.,1,.,.,.,.,.,.,.,.,.,25.27380952 -5.1,1,197.75,0,0,.,.,1,.,.,.,.,.,.,.,50,39,25.3125 -5.1,1,203.25,2,45,.,.,1,.,.,.,.,.,.,.,.,.,25.3452381 -5.1,1,215.25,2,45,.,.,1,.,.,.,.,.,.,.,.,.,25.41666667 -5.1,1,222.3333333,0,0,.,.,1,.,.,.,.,.,.,.,51,44,25.45882937 -5.1,1,227.25,2,45,.,.,1,.,.,.,.,.,.,.,.,.,25.48809524 -5.1,1,239.25,2,45,.,.,1,.,.,.,.,.,.,.,.,.,25.55952381 -5.1,0,246.75,.,.,.,.,.,2.2,1,.,.,.,.,.,.,.,25.60416667 -6.1,1,0,2,25,.,.,1,.,.,.,.,.,.,6.8,49,46,44.58928571 -6.1,1,12.666666,2,25,.,.,1,.,.,.,.,.,.,.,.,.,44.66468254 -6.1,1,24,2,25,.,.,1,.,.,.,.,.,.,.,.,.,44.73214286 -6.1,1,27.25,0,0,.,.,1,.,.,.,.,.,.,.,54,36,44.7514881 -6.1,1,36,2,25,.,.,1,.,.,.,.,.,.,.,.,.,44.80357143 -6.1,1,48,2,48,.,.,1,.,.,.,.,.,.,.,.,.,44.875 -6.1,1,51.5,0,0,.,.,1,.,.,.,.,.,.,.,48,33,44.89583333 -6.1,1,60,2,48,.,.,1,.,.,.,.,.,.,.,.,.,44.94642857 -6.1,1,72.333333,2,48,.,.,1,.,.,.,.,.,.,.,.,.,45.01984127 -6.1,1,74.433333,0,0,.,.,1,.,.,.,.,.,.,.,58,37,45.03234127 -6.1,1,85,2,48,.,.,1,.,.,.,.,.,.,.,.,.,45.0952381 -6.1,0,86.5,.,.,.,.,.,1.6,1,.,.,.,.,.,.,.,45.10416667 -6.1,1,95.916666,2,48,.,.,1,.,.,.,.,.,.,.,.,.,45.16021825 -6.1,1,97.25,0,0,.,.,1,.,.,.,.,.,.,.,75,43,45.16815476 -6.1,1,108.75,2,48,.,.,1,.,.,.,.,.,.,.,.,.,45.23660714 -6.1,1,120,2,48,.,.,1,.,.,.,.,.,.,.,.,.,45.30357143 -6.1,1,122,0,0,.,.,1,.,.,.,.,.,.,.,71,42,45.31547619 -6.1,1,133,2,48,.,.,1,.,.,.,.,.,.,.,.,.,45.38095238 -6.1,1,145,2,48,.,.,1,.,.,.,.,.,.,.,.,.,45.45238095 -6.1,1,146.166666,0,0,.,.,1,.,.,.,.,.,.,.,82,58,45.4593254 -6.1,1,158,2,48,.,.,1,.,.,.,.,.,.,.,.,.,45.5297619 -6.1,1,169,2,48,.,.,1,.,.,.,.,.,.,.,.,.,45.5952381 -6.1,1,170.433333,0,0,.,.,1,.,.,.,.,.,.,.,74,50,45.60376984 -6.1,1,181,2,48,.,.,1,.,.,.,.,.,.,.,.,.,45.66666667 -6.1,1,193,2,48,.,.,1,.,.,.,.,.,.,.,.,.,45.73809524 -6.1,1,196.083333,0,0,.,.,1,.,.,.,.,.,.,.,74,65,45.75644841 -6.1,1,205,2,48,.,.,1,.,.,.,.,.,.,.,.,.,45.80952381 -6.1,1,209,0,0,.,.,1,.,.,.,.,.,.,6.8,.,.,45.83333333 -6.1,1,213,0,0,.,.,1,.,.,.,.,.,.,6.8,.,.,45.85714286 -6.1,1,217,2,48,.,.,1,.,.,.,.,.,.,.,.,.,45.88095238 -6.1,1,218,0,0,.,.,1,.,.,.,.,.,.,.,72,60,45.88690476 -6.1,1,229,2,48,.,.,1,.,.,.,.,.,.,.,.,.,45.95238095 -6.1,1,233,0,0,.,.,1,.,.,.,.,.,.,6.8,.,.,45.97619048 -6.1,1,237,0,0,.,.,1,.,.,.,.,.,.,6.8,.,.,46 -6.1,1,241,2,48,.,.,1,.,.,.,.,.,.,.,.,.,46.02380952 -6.1,1,242,0,0,.,.,1,.,.,.,.,.,.,.,61,55,46.0297619 -6.1,1,253,2,48,.,.,1,.,.,.,.,.,.,.,.,.,46.0952381 -6.1,1,265,0,0,.,.,1,.,.,.,.,.,.,.,52,41,46.16666667 -6.1,1,265,2,48,.,.,1,.,.,.,.,.,.,.,.,.,46.16666667 -6.1,1,277.5,2,48,.,.,1,.,.,.,.,.,.,.,.,.,46.24107143 -6.1,1,289,2,48,.,.,1,.,.,.,.,.,.,.,.,.,46.30952381 -6.1,1,291,0,0,.,.,1,.,.,.,.,.,.,.,58,36,46.32142857 -6.1,1,300.833333,2,48,.,.,1,.,.,.,.,.,.,.,.,.,46.37996032 -6.1,1,305,0,0,.,.,1,.,.,.,.,.,.,6.8,.,.,46.4047619 -6.1,1,313,2,48,.,.,1,.,.,.,.,.,.,.,.,.,46.45238095 -6.1,1,314,0,0,.,.,1,.,.,.,.,.,.,6.8,.,.,46.45833333 -6.1,1,314,0,0,.,.,1,.,.,.,.,.,.,.,64,46,46.45833333 -6.1,1,325,2,48,.,.,1,.,.,.,.,.,.,.,.,.,46.52380952 -6.1,1,329,0,0,.,.,1,.,.,.,.,.,.,6.8,.,.,46.54761905 -6.1,1,337,0,0,.,.,1,.,.,.,.,.,.,6.8,.,.,46.5952381 -6.1,1,337,2,48,.,.,1,.,.,.,.,.,.,.,.,.,46.5952381 -6.1,1,337.833333,0,0,.,.,1,.,.,.,.,.,.,.,77,54,46.60019841 -6.1,1,349,2,48,.,.,1,.,.,.,.,.,.,.,.,.,46.66666667 -6.1,1,361,2,48,.,.,1,.,.,.,.,.,.,.,.,.,46.73809524 -6.1,1,362.666666,0,0,.,.,1,.,.,.,.,.,.,.,62,53,46.74801587 -6.1,1,373,2,48,.,.,1,.,.,.,.,.,.,.,.,.,46.80952381 -6.1,1,385.5,2,48,.,.,1,.,.,.,.,.,.,.,.,.,46.88392857 -6.1,1,387.166666,0,0,.,.,1,.,.,.,.,.,.,.,60,57,46.89384921 -6.1,1,397,2,48,.,.,1,.,.,.,.,.,.,.,.,.,46.95238095 -6.1,1,409,2,48,.,.,1,.,.,.,.,.,.,.,.,.,47.02380952 -6.1,1,411,0,0,.,.,1,.,.,.,.,.,.,.,108,104,47.03571429 -6.1,1,420.5,2,48,.,.,1,.,.,.,.,.,.,.,.,.,47.0922619 -6.1,1,433,2,48,.,.,1,.,.,.,.,.,.,.,.,.,47.16666667 -6.1,1,433.166666,0,0,.,.,1,.,.,.,.,.,.,.,61,84,47.16765873 -6.1,1,445,2,48,.,.,1,.,.,.,.,.,.,.,.,.,47.23809524 -6.1,1,457,2,48,.,.,1,.,.,.,.,.,.,.,.,.,47.30952381 -6.1,1,459.083333,0,0,.,.,1,.,.,.,.,.,.,.,100,85,47.3219246 -6.1,1,470.5,2,38,.,.,1,.,.,.,.,.,.,.,.,.,47.38988095 -6.1,1,471.25,0,0,.,.,1,.,.,.,.,.,.,.,85,87,47.39434524 -6.1,1,477.016666,0,0,.,.,1,.,.,.,.,.,.,.,63,82,47.42867063 -6.1,0,480.75,.,.,.,.,.,1.3,1,.,.,.,.,.,.,.,47.45089286 -7.1,1,0,0,0,.,.,1,.,.,.,.,.,.,7.2,13,13,44.60843254 -7.1,1,1.783333333,0,0,.,.,1,.,.,.,.,.,.,7.2,.,.,44.61904762 -7.1,1,16.78333333,2,29,.,.,1,.,.,.,.,.,.,.,.,.,44.70833333 -7.1,1,23.28333333,0,0,.,.,1,.,.,.,.,.,.,.,16,11,44.74702381 -7.1,1,27.78333333,0,0,.,.,1,.,.,.,.,.,.,7.2,.,.,44.77380952 -7.1,1,29.78333333,2,50,.,.,1,.,.,.,.,.,.,.,.,.,44.78571429 -7.1,1,37.78333333,0,0,.,.,1,.,.,.,.,.,.,7.2,.,.,44.83333333 -7.1,1,42.28333333,2,50,.,.,1,.,.,.,.,.,.,.,.,.,44.86011905 -7.1,1,47.45,0,0,.,.,1,.,.,.,.,.,.,.,19,10,44.89087302 -7.1,0,54.21666667,.,.,.,.,.,0.2,1,.,.,.,.,.,.,.,44.93115079 -8.1,1,0,0,0,.,.,1,.,.,.,.,.,.,8.64,57,73,62.46130952 -8.1,1,5.75,0,60,.,.,1,.,.,.,.,.,.,.,.,.,62.49553571 -8.1,1,16.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,62.55952381 -8.1,1,24.75,0,0,.,.,1,.,.,.,.,.,.,.,61,67,62.60863095 -8.1,1,28.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,62.63095238 -8.1,1,40.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,62.70238095 -8.1,1,48.75,0,0,.,.,1,.,.,.,.,.,.,.,58,79,62.7514881 -8.1,1,52.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,62.77380952 -8.1,1,64.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,62.8452381 -8.1,1,72.5,0,0,.,.,1,.,.,.,.,.,.,.,63,74,62.89285714 -8.1,1,76.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,62.91666667 -8.1,1,83.23333333,0,0,.,.,1,.,.,.,.,.,.,8.5,.,.,62.95674603 -8.1,1,87,0,60,.,.,1,.,.,.,.,.,.,.,.,.,62.97916667 -8.1,0,96.55,.,.,.,.,.,0.4,1,.,.,.,.,.,.,.,63.0360119 -8.1,1,96.55,0,0,.,.,1,.,.,.,.,.,.,.,56,65,63.0360119 -8.1,1,101,0,60,.,.,1,.,.,.,.,.,.,.,.,.,63.0625 -8.1,1,112.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,63.13095238 -8.1,1,120.5,0,0,.,.,1,.,.,.,.,.,.,.,64,72,63.17857143 -8.1,1,124.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,63.20238095 -8.1,1,136.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,63.27380952 -8.1,1,144.0833333,0,0,.,.,1,.,.,.,.,.,.,.,86,83,63.31894841 -8.1,1,160.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,63.41666667 -8.1,1,167.8333333,0,0,.,.,1,.,.,.,.,.,.,.,123,120,63.46031746 -8.1,1,172.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,63.48809524 -8.1,1,184.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,63.55952381 -8.1,1,192.4166667,0,0,.,.,1,.,.,.,.,.,.,.,136,140,63.60664683 -8.1,1,196.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,63.63095238 -8.1,1,206.5,0,30,.,.,1,.,.,.,.,.,.,.,.,.,63.69047619 -8.1,1,215.75,0,0,.,.,1,.,.,.,.,.,.,.,126,132,63.74553571 -8.1,1,218.5,0,30,.,.,1,.,.,.,.,.,.,.,.,.,63.76190476 -8.1,1,230.5,0,30,.,.,1,.,.,.,.,.,.,.,.,.,63.83333333 -8.1,1,239,0,0,.,.,1,.,.,.,.,.,.,.,147,157,63.88392857 -8.1,1,244,0,30,.,.,1,.,.,.,.,.,.,.,.,.,63.91369048 -8.1,1,251.5,0,0,.,.,1,.,.,.,.,.,.,.,157,162,63.95833333 -8.1,1,254.5,0,30,.,.,1,.,.,.,.,.,.,.,.,.,63.97619048 -8.1,1,263.9166667,0,0,.,.,1,.,.,.,.,.,.,.,129,153,64.03224206 -8.1,1,266.5,0,30,.,.,1,.,.,.,.,.,.,.,.,.,64.04761905 -8.1,1,278.5,0,30,.,.,1,.,.,.,.,.,.,.,.,.,64.11904762 -8.1,1,288.75,0,0,.,.,1,.,.,.,.,.,.,.,136,153,64.18005952 -8.1,1,294.5,0,30,.,.,1,.,.,.,.,.,.,.,.,.,64.21428571 -8.1,1,302.5,0,30,.,.,1,.,.,.,.,.,.,.,.,.,64.26190476 -8.1,1,312.75,0,0,.,.,1,.,.,.,.,.,.,.,182,237,64.32291667 -8.1,1,314.5,0,30,.,.,1,.,.,.,.,.,.,.,.,.,64.33333333 -8.1,0,327.5,.,.,.,.,.,0.05,1,.,.,.,.,.,.,.,64.41071429 -9.1,1,0,2,65,.,.,1,.,.,.,.,.,.,9.2,59,83,73.06845238 -9.1,1,12,2,65,.,.,1,.,.,.,.,.,.,.,.,.,73.13988095 -9.1,1,24,2,65,.,.,1,.,.,.,.,.,.,.,.,.,73.21130952 -9.1,1,36,2,65,.,.,1,.,.,.,.,.,.,.,.,.,73.2827381 -9.1,1,47.5,2,65,.,.,1,.,.,.,.,.,.,.,.,.,73.35119048 -9.1,1,60,2,65,.,.,1,.,.,.,.,.,.,.,.,.,73.42559524 -9.1,1,72,2,65,.,.,1,.,.,.,.,.,.,.,.,.,73.49702381 -9.1,1,84,2,65,.,.,1,.,.,.,.,.,.,.,.,.,73.56845238 -9.1,1,96,2,65,.,.,1,.,.,.,.,.,.,.,.,.,73.63988095 -9.1,1,108,2,65,.,.,1,.,.,.,.,.,.,.,.,.,73.71130952 -9.1,1,120,2,65,.,.,1,.,.,.,.,.,.,.,.,.,73.7827381 -9.1,1,132,2,65,.,.,1,.,.,.,.,.,.,.,.,.,73.85416667 -9.1,1,144,2,65,.,.,1,.,.,.,.,.,.,.,.,.,73.92559524 -9.1,1,156,0,65,.,.,1,.,.,.,.,.,.,.,.,.,73.99702381 -9.1,1,164.5,0,65,.,.,1,.,.,.,.,.,.,.,.,.,74.04761905 -9.1,1,176.5,0,65,.,.,1,.,.,.,.,.,.,.,.,.,74.11904762 -9.1,0,188,.,.,.,.,.,0.3,1,.,.,.,.,.,.,.,74.1875 -9.2,1,0,0,0,.,.,1,.,.,.,.,.,.,9.4,61,43,76.47172619 -9.2,1,0.75,0,65,.,.,1,.,.,.,.,.,.,.,.,.,76.47619048 -9.2,1,7.75,2,65,.,.,1,.,.,.,.,.,.,.,.,.,76.51785714 -9.2,1,12.75,0,0,.,.,1,.,.,.,.,.,.,9.4,.,.,76.54761905 -9.2,1,20.25,2,65,.,.,1,.,.,.,.,.,.,.,.,.,76.5922619 -9.2,1,22.75,0,0,.,.,1,.,.,.,.,.,.,.,56,39,76.60714286 -9.2,1,31.75,2,65,.,.,1,.,.,.,.,.,.,.,.,.,76.66071429 -9.2,1,43.5,2,65,.,.,1,.,.,.,.,.,.,.,.,.,76.73065476 -9.2,1,47,0,0,.,.,1,.,.,.,.,.,.,.,62,39,76.7514881 -9.2,0,55.5,.,.,.,.,.,0.3,1,.,.,.,.,.,.,.,76.80208333 -9.3,1,0,2,65,.,.,1,.,.,.,.,.,.,9.4,62,39,76.80357143 -9.3,1,13,2,65,.,.,1,.,.,.,.,.,.,.,.,.,76.88095238 -9.3,1,25,2,65,.,.,1,.,.,.,.,.,.,.,.,.,76.95238095 -9.3,1,37,2,65,.,.,1,.,.,.,.,.,.,.,.,.,77.02380952 -9.3,1,49,2,65,.,.,1,.,.,.,.,.,.,.,.,.,77.0952381 -9.3,1,61,2,65,.,.,1,.,.,.,.,.,.,.,.,.,77.16666667 -9.3,1,73,2,65,.,.,1,.,.,.,.,.,.,.,.,.,77.23809524 -9.3,1,85,2,65,.,.,1,.,.,.,.,.,.,.,.,.,77.30952381 -9.3,1,97,2,65,.,.,1,.,.,.,.,.,.,.,.,.,77.38095238 -9.3,1,109,2,65,.,.,1,.,.,.,.,.,.,.,.,.,77.45238095 -9.3,1,121,2,65,.,.,1,.,.,.,.,.,.,.,.,.,77.52380952 -9.3,1,133,2,65,.,.,1,.,.,.,.,.,.,.,.,.,77.5952381 -9.3,1,146.5,2,75,.,.,1,.,.,.,.,.,.,.,.,.,77.67559524 -9.3,1,158.1666667,2,75,.,.,1,.,.,.,.,.,.,.,.,.,77.74503968 -9.3,1,170.5,2,75,.,.,1,.,.,.,.,.,.,.,.,.,77.81845238 -9.3,0,182,.,.,.,.,.,0.2,1,.,.,.,.,.,.,.,77.88690476 -9.4,1,0,2,75,.,.,1,.,.,.,.,.,.,9.4,33,32,80.07440476 -9.4,1,11.5,2,75,.,.,1,.,.,.,.,.,.,.,.,.,80.14285714 -9.4,1,16,0,0,.,.,1,.,.,.,.,.,.,.,33,32,80.16964286 -9.4,1,24,2,75,.,.,1,.,.,.,.,.,.,.,.,.,80.2172619 -9.4,1,35.75,2,75,.,.,1,.,.,.,.,.,.,.,.,.,80.28720238 -9.4,1,41.16666667,0,0,.,.,1,.,.,.,.,.,.,.,38,35,80.31944444 -9.4,1,47.5,2,75,.,.,1,.,.,.,.,.,.,.,.,.,80.35714286 -9.4,1,62,2,75,.,.,1,.,.,.,.,.,.,.,.,.,80.44345238 -9.4,1,73.5,2,75,.,.,1,.,.,.,.,.,.,.,.,.,80.51190476 -9.4,1,85.66666667,2,75,.,.,1,.,.,.,.,.,.,.,.,.,80.5843254 -9.4,1,90.5,0,0,.,.,1,.,.,.,.,.,.,.,52,30,80.61309524 -9.4,1,97.5,2,75,.,.,1,.,.,.,.,.,.,.,.,.,80.6547619 -9.4,1,109.5,2,85,.,.,1,.,.,.,.,.,.,.,.,.,80.72619048 -9.4,1,114.1666667,0,0,.,.,1,.,.,.,.,.,.,.,55,48,80.75396825 -9.4,1,121.5,2,85,.,.,1,.,.,.,.,.,.,.,.,.,80.79761905 -9.4,1,133.8333333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,80.87103175 -9.4,1,136.8333333,0,0,.,.,1,.,.,.,.,.,.,.,41,38,80.88888889 -9.4,1,145.5,2,85,.,.,1,.,.,.,.,.,.,.,.,.,80.94047619 -9.4,1,157.5,2,85,.,.,1,.,.,.,.,.,.,.,.,.,81.01190476 -9.4,1,160.75,0,0,.,.,1,.,.,.,.,.,.,.,45,41,81.03125 -9.4,1,175,2,85,.,.,1,.,.,.,.,.,.,.,.,.,81.11607143 -9.4,0,185,.,.,.,.,.,0.2,1,.,.,.,.,.,.,.,81.17559524 -9.5,1,0,0,65,.,.,1,.,.,.,.,.,.,9.4,50,32,84.64781746 -9.5,1,8.1666667,0,65,.,.,1,.,.,.,.,.,.,.,.,.,84.69642857 -9.5,1,16.9166667,0,0,.,.,1,.,.,.,.,.,.,.,52,27,84.7485119 -9.5,1,19.1666667,0,65,.,.,1,.,.,.,.,.,.,.,.,.,84.76190476 -9.5,1,32.1666667,2,70,.,.,1,.,.,.,.,.,.,.,.,.,84.83928571 -9.5,1,40.1666667,0,0,.,.,1,.,.,.,.,.,.,.,45,23,84.88690476 -9.5,1,44.1666667,2,70,.,.,1,.,.,.,.,.,.,.,.,.,84.91071429 -9.5,1,56.1666667,2,70,.,.,1,.,.,.,.,.,.,.,.,.,84.98214286 -9.5,1,65.1666667,0,0,.,.,1,.,.,.,.,.,.,.,44,26,85.03571429 -9.5,0,67.6666667,.,.,.,.,.,0.2,1,.,.,.,.,.,.,.,85.05059524 -9.5,1,68.1666667,2,70,.,.,1,.,.,.,.,.,.,.,.,.,85.05357143 -9.5,1,79.6666667,2,70,.,.,1,.,.,.,.,.,.,.,.,.,85.12202381 -9.5,1,88.1666667,0,0,.,.,1,.,.,.,.,.,.,.,40,26,85.17261905 -9.5,1,92.1666667,2,70,.,.,1,.,.,.,.,.,.,.,.,.,85.19642857 -9.5,1,104.1666667,2,70,.,.,1,.,.,.,.,.,.,.,.,.,85.26785714 -9.5,1,113.1666667,0,0,.,.,1,.,.,.,.,.,.,.,44,21,85.32142857 -9.5,1,116.1666667,2,70,.,.,1,.,.,.,.,.,.,.,.,.,85.33928571 -9.5,1,117.1666667,0,0,.,.,1,.,.,.,.,.,.,10.7,.,.,85.3452381 -9.5,1,127.1666667,0,0,.,.,1,.,.,.,.,.,.,10.43,.,.,85.4047619 -9.5,1,128.1666667,2,70,.,.,1,.,.,.,.,.,.,.,.,.,85.41071429 -9.5,1,137.1666667,0,0,.,.,1,.,.,.,.,.,.,.,41,18,85.46428571 -9.5,1,140.1666667,2,70,.,.,1,.,.,.,.,.,.,.,.,.,85.48214286 -9.5,1,152.1666667,2,70,.,.,1,.,.,.,.,.,.,.,.,.,85.55357143 -9.5,1,160.9166667,0,0,.,.,1,.,.,.,.,.,.,.,46,25,85.60565476 -9.5,1,164.1666667,2,70,.,.,1,.,.,.,.,.,.,.,.,.,85.625 -9.5,1,176.1666667,2,70,.,.,1,.,.,.,.,.,.,.,.,.,85.69642857 -9.5,1,185.1666667,0,0,.,.,1,.,.,.,.,.,.,.,49,23,85.75 -9.5,1,188.1666667,2,90,.,.,1,.,.,.,.,.,.,.,.,.,85.76785714 -9.5,1,203.6666667,2,90,.,.,1,.,.,.,.,.,.,.,.,.,85.86011905 -9.5,1,208.6666667,0,0,.,.,1,.,.,.,.,.,.,.,48,21,85.88988095 -9.5,1,215.1666667,2,100,.,.,1,.,.,.,.,.,.,.,.,.,85.92857143 -9.5,1,227.1666667,2,100,.,.,1,.,.,.,.,.,.,.,.,.,86 -9.5,1,232.6666667,0,0,.,.,1,.,.,.,.,.,.,.,49,27,86.0327381 -9.5,1,239.1666667,2,100,.,.,1,.,.,.,.,.,.,.,.,.,86.07142857 -9.5,1,252.6666667,2,100,.,.,1,.,.,.,.,.,.,.,.,.,86.15178571 -9.5,1,257.1666667,0,0,.,.,1,.,.,.,.,.,.,.,55,23,86.17857143 -9.5,1,263.6666667,2,100,.,.,1,.,.,.,.,.,.,.,.,.,86.2172619 -9.5,1,277.9166667,2,100,.,.,1,.,.,.,.,.,.,.,.,.,86.30208333 -9.5,1,280.1666667,0,0,.,.,1,.,.,.,.,.,.,.,51,21,86.31547619 -9.5,0,289.6666667,.,.,.,.,.,1.5,1,.,.,.,.,.,.,.,86.37202381 -9.5,1,289.6666667,2,100,.,.,1,.,.,.,.,.,.,.,.,.,86.37202381 -9.5,1,300.1666667,2,100,.,.,1,.,.,.,.,.,.,.,.,.,86.43452381 -9.5,1,304.9999997,0,0,.,.,1,.,.,.,.,.,.,.,49,15,86.46329365 -9.5,1,324.1666667,2,100,.,.,1,.,.,.,.,.,.,.,.,.,86.57738095 -9.5,1,328.9999997,0,0,.,.,1,.,.,.,.,.,.,.,50,21,86.60615079 -9.5,1,336.1666667,2,100,.,.,1,.,.,.,.,.,.,.,.,.,86.64880952 -9.5,1,348.1666667,2,100,.,.,1,.,.,.,.,.,.,.,.,.,86.7202381 -9.5,1,352.9999997,0,0,.,.,1,.,.,.,.,.,.,.,55,17,86.74900794 -9.5,1,360.1666667,2,100,.,.,1,.,.,.,.,.,.,.,.,.,86.79166667 -9.5,1,372.1666667,2,100,.,.,1,.,.,.,.,.,.,.,.,.,86.86309524 -9.5,1,376.7499997,0,0,.,.,1,.,.,.,.,.,.,.,48,19,86.89037698 -9.5,1,384.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,86.93452381 -9.5,1,396.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,87.00595238 -9.5,1,400.6666667,0,0,.,.,1,.,.,.,.,.,.,.,50,14,87.0327381 -9.5,1,408.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,87.07738095 -9.5,1,420.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,87.14880952 -9.5,1,424.6666667,0,0,.,.,1,.,.,.,.,.,.,.,50,24,87.17559524 -9.5,1,432.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,87.2202381 -9.5,1,444.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,87.29166667 -9.5,1,448.1666667,0,0,.,.,1,.,.,.,.,.,.,.,47,10,87.31547619 -9.5,1,456.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,87.36309524 -9.5,1,469.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,87.44047619 -9.5,1,473.4166667,0,0,.,.,1,.,.,.,.,.,.,.,49,23,87.46577381 -9.5,1,480.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,87.50595238 -9.5,1,492.6666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,87.58035714 -9.5,1,496.9999997,0,0,.,.,1,.,.,.,.,.,.,.,48,25,87.60615079 -9.5,1,504.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,87.64880952 -9.5,1,516.6666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,87.72321429 -9.5,1,520.9166667,0,0,.,.,1,.,.,.,.,.,.,.,51,27,87.7485119 -9.5,1,528.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,87.79166667 -9.5,1,540.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,87.86309524 -9.5,1,544.9166667,0,0,.,.,1,.,.,.,.,.,.,.,56,35,87.89136905 -9.5,1,552.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,87.93452381 -9.5,1,564.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,88.00595238 -9.5,1,569.1666667,0,0,.,.,1,.,.,.,.,.,.,.,61,28,88.03571429 -9.5,1,576.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,88.07738095 -9.5,1,588.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,88.14880952 -9.5,1,593.1666667,0,0,.,.,1,.,.,.,.,.,.,.,56,32,88.17857143 -9.5,1,600.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,88.2202381 -9.5,1,612.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,88.29166667 -9.5,1,616.6666667,0,0,.,.,1,.,.,.,.,.,.,.,49,37,88.31845238 -9.5,1,624.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,88.36309524 -9.5,1,636.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,88.43452381 -9.5,1,641.2833337,0,0,.,.,1,.,.,.,.,.,.,.,58,30,88.46498016 -9.5,1,648.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,88.50595238 -9.5,1,660.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,88.57738095 -9.5,1,665.1666667,0,0,.,.,1,.,.,.,.,.,.,.,68,6,88.60714286 -9.5,1,671.6666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,88.64583333 -9.5,1,684.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,88.7202381 -9.5,1,689.1666667,0,0,.,.,1,.,.,.,.,.,.,.,68,41,88.75 -9.5,0,695.7499997,.,.,.,.,.,0.4,1,.,.,.,.,.,.,.,88.78918651 -9.5,1,696.1666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,88.79166667 -9.5,1,708.6666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,88.86607143 -9.5,1,712.9999997,0,0,.,.,1,.,.,.,.,.,.,.,99,73,88.89186508 -9.5,1,728.1666667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,88.98214286 -9.5,1,737.1666667,0,0,.,.,1,.,.,.,.,.,.,.,129,113,89.03571429 -9.5,1,740.1666667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,89.05357143 -9.5,1,752.6666667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,89.12797619 -9.5,1,761.1666667,0,0,.,.,1,.,.,.,.,.,.,.,125,123,89.17857143 -9.5,1,767.1666667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,89.21428571 -9.5,1,776.1666667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,89.26785714 -9.5,0,784.9166667,.,.,.,.,.,0.2,1,.,.,.,.,.,.,.,89.31994048 -9.5,1,784.9166667,0,0,.,.,1,.,.,.,.,.,.,.,89,113,89.31994048 -9.5,1,788.6666667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,89.3422619 -9.5,1,800.1666667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,89.41071429 -9.5,1,808.9999997,0,0,.,.,1,.,.,.,.,.,.,.,72,87,89.46329365 -9.5,1,812.1666667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,89.48214286 -9.5,1,824.1666667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,89.55357143 -9.5,1,833.6666667,0,0,.,.,1,.,.,.,.,.,.,.,107,134,89.61011905 -9.5,1,836.1666667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,89.625 -9.5,1,848.1666667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,89.69642857 -9.5,1,856.6666667,0,0,.,.,1,.,.,.,.,.,.,.,120,160,89.74702381 -9.5,1,860.1666667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,89.76785714 -9.5,1,872.1666667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,89.83928571 -9.5,1,881.4166667,0,0,.,.,1,.,.,.,.,.,.,.,179,216,89.89434524 -9.5,1,884.1666667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,89.91071429 -9.5,1,897.1666667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,89.98809524 -9.5,1,905.4999997,0,0,.,.,1,.,.,.,.,.,.,.,158,231,90.03769841 -9.5,1,908.1666667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,90.05357143 -9.5,1,920.1666667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,90.125 -9.5,1,929.1666667,0,0,.,.,1,.,.,.,.,.,.,.,92,144,90.17857143 -9.5,1,934.1666667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,90.20833333 -9.5,1,944.1666667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,90.26785714 -9.5,0,952.6666667,.,.,.,.,.,0.6,1,.,.,.,.,.,.,.,90.31845238 -9.6,1,0,0,120,.,.,1,.,.,.,.,.,.,11.9,55,41,91.5 -9.6,1,9,0,120,.,.,1,.,.,.,.,.,.,.,.,.,91.55357143 -9.6,1,16,0,0,.,.,1,.,.,.,.,.,.,.,88,15,91.5952381 -9.6,1,21.25,0,120,.,.,1,.,.,.,.,.,.,.,.,.,91.6264881 -9.6,1,32,0,240,.,.,1,.,.,.,.,.,.,.,.,.,91.69047619 -9.6,1,41.16666667,0,0,.,.,1,.,.,.,.,.,.,.,53,47,91.74503968 -9.6,1,44,0,240,.,.,1,.,.,.,.,.,.,.,.,.,91.76190476 -9.6,1,56,2,100,.,.,1,.,.,.,.,.,.,.,.,.,91.83333333 -9.6,1,63.25,0,0,.,.,1,.,.,.,.,.,.,.,60,34,91.8764881 -9.6,1,80,2,100,.,.,1,.,.,.,.,.,.,.,.,.,91.97619048 -9.6,1,88.16666667,0,0,.,.,1,.,.,.,.,.,.,.,58,7,92.02480159 -9.6,0,92,.,.,.,.,.,0.3,1,.,.,.,.,.,.,.,92.04761905 -9.6,1,92,2,100,.,.,1,.,.,.,.,.,.,.,.,.,92.04761905 -9.6,1,104,2,100,.,.,1,.,.,.,.,.,.,.,.,.,92.11904762 -9.6,1,112.9666667,0,0,.,.,1,.,.,.,.,.,.,.,59,6,92.17242063 -9.6,1,116,2,100,.,.,1,.,.,.,.,.,.,.,.,.,92.19047619 -9.6,1,128.5,2,100,.,.,1,.,.,.,.,.,.,.,.,.,92.26488095 -9.6,0,136.75,.,.,.,.,.,0.8,1,.,.,.,.,.,.,.,92.3139881 -9.6,1,136.75,0,0,.,.,1,.,.,.,.,.,.,.,55,26,92.3139881 -9.6,1,140,2,100,.,.,1,.,.,.,.,.,.,.,.,.,92.33333333 -9.6,1,152.5,2,100,.,.,1,.,.,.,.,.,.,.,.,.,92.4077381 -9.6,1,162.3333333,0,0,.,.,1,.,.,.,.,.,.,.,66,24,92.46626984 -9.6,1,167,2,100,.,.,1,.,.,.,.,.,.,.,.,.,92.49404762 -9.6,1,179,2,100,.,.,1,.,.,.,.,.,.,.,.,.,92.56547619 -9.6,1,186,0,0,.,.,1,.,.,.,.,.,.,.,61,34,92.60714286 -9.6,1,191,2,100,.,.,1,.,.,.,.,.,.,.,.,.,92.63690476 -9.6,1,203,2,100,.,.,1,.,.,.,.,.,.,.,.,.,92.70833333 -9.6,1,212.5,0,0,.,.,1,.,.,.,.,.,.,.,57,41,92.76488095 -9.6,1,215,0,0,.,.,1,.,.,.,.,.,.,12,.,.,92.7797619 -9.6,1,215,2,100,.,.,1,.,.,.,.,.,.,.,.,.,92.7797619 -9.6,1,224,0,0,.,.,1,.,.,.,.,.,.,11.9,.,.,92.83333333 -9.6,1,226.5,2,120,.,.,1,.,.,.,.,.,.,.,.,.,92.84821429 -9.6,1,233.25,0,0,.,.,1,.,.,.,.,.,.,.,52,36,92.88839286 -9.6,1,239,2,120,.,.,1,.,.,.,.,.,.,.,.,.,92.92261905 -9.6,1,250.5,2,120,.,.,1,.,.,.,.,.,.,.,.,.,92.99107143 -9.6,1,257.25,0,0,.,.,1,.,.,.,.,.,.,.,51,43,93.03125 -9.6,1,262,2,120,.,.,1,.,.,.,.,.,.,.,.,.,93.05952381 -9.6,1,273.5,2,120,.,.,1,.,.,.,.,.,.,.,.,.,93.12797619 -9.6,1,281.8333333,0,0,.,.,1,.,.,.,.,.,.,.,47,28,93.17757937 -9.6,1,287,2,120,.,.,1,.,.,.,.,.,.,.,.,.,93.20833333 -9.6,1,298,2,120,.,.,1,.,.,.,.,.,.,.,.,.,93.27380952 -9.6,1,306,0,0,.,.,1,.,.,.,.,.,.,.,47,33,93.32142857 -9.6,1,310,2,120,.,.,1,.,.,.,.,.,.,.,.,.,93.3452381 -9.6,1,322.25,2,120,.,.,1,.,.,.,.,.,.,.,.,.,93.41815476 -9.6,1,328,0,0,.,.,1,.,.,.,.,.,.,.,48,37,93.45238095 -9.6,1,335,2,120,.,.,1,.,.,.,.,.,.,.,.,.,93.49404762 -9.6,1,346,2,120,.,.,1,.,.,.,.,.,.,.,.,.,93.55952381 -9.6,1,353.3333333,0,0,.,.,1,.,.,.,.,.,.,.,45,30,93.6031746 -9.6,1,360,2,120,.,.,1,.,.,.,.,.,.,.,.,.,93.64285714 -9.6,1,364.75,0,0,.,.,1,.,.,.,.,.,.,.,57,16,93.67113095 -9.6,1,371.5,2,120,.,.,1,.,.,.,.,.,.,.,.,.,93.71130952 -9.6,1,377.6666667,0,0,.,.,1,.,.,.,.,.,.,.,45,17,93.74801587 -9.6,1,384,2,120,.,.,1,.,.,.,.,.,.,.,.,.,93.78571429 -9.6,1,395.5,2,120,.,.,1,.,.,.,.,.,.,.,.,.,93.85416667 -9.6,1,402,0,0,.,.,1,.,.,.,.,.,.,.,49,23,93.89285714 -9.6,1,408,2,120,.,.,1,.,.,.,.,.,.,.,.,.,93.92857143 -9.6,1,419,2,120,.,.,1,.,.,.,.,.,.,.,.,.,93.99404762 -9.6,1,423.75,0,0,.,.,1,.,.,.,.,.,.,.,46,21,94.02232143 -9.6,1,431,2,120,.,.,1,.,.,.,.,.,.,.,.,.,94.06547619 -9.6,1,440,0,150,.,.,1,.,.,.,.,.,.,.,.,.,94.11904762 -9.6,1,450.25,0,0,.,.,1,.,.,.,.,.,.,.,51,21,94.18005952 -9.6,1,452,0,150,.,.,1,.,.,.,.,.,.,.,.,.,94.19047619 -9.6,1,464,0,150,.,.,1,.,.,.,.,.,.,.,.,.,94.26190476 -9.6,0,474.5,.,.,.,.,.,1.5,1,.,.,.,.,.,.,.,94.32440476 -9.6,1,474.5,0,0,.,.,1,.,.,.,.,.,.,.,55,26,94.32440476 -9.6,1,476,0,150,.,.,1,.,.,.,.,.,.,.,.,.,94.33333333 -9.6,1,488,0,150,.,.,1,.,.,.,.,.,.,.,.,.,94.4047619 -9.6,1,497.3333333,0,0,.,.,1,.,.,.,.,.,.,.,49,28,94.46031746 -9.6,1,501,0,150,.,.,1,.,.,.,.,.,.,.,.,.,94.48214286 -9.6,1,512,0,150,.,.,1,.,.,.,.,.,.,.,.,.,94.54761905 -9.6,1,520.5,0,0,.,.,1,.,.,.,.,.,.,.,50,20,94.59821429 -9.6,1,524,0,150,.,.,1,.,.,.,.,.,.,.,.,.,94.61904762 -9.6,1,536,0,150,.,.,1,.,.,.,.,.,.,.,.,.,94.69047619 -9.6,1,543.5,0,0,.,.,1,.,.,.,.,.,.,.,51,12,94.73511905 -9.6,1,548,0,150,.,.,1,.,.,.,.,.,.,.,.,.,94.76190476 -9.6,1,560,0,150,.,.,1,.,.,.,.,.,.,.,.,.,94.83333333 -9.6,1,567.75,0,0,.,.,1,.,.,.,.,.,.,.,49,15,94.87946429 -9.6,1,572.5,0,150,.,.,1,.,.,.,.,.,.,.,.,.,94.9077381 -9.6,1,585,0,150,.,.,1,.,.,.,.,.,.,.,.,.,94.98214286 -9.6,1,594.4166667,0,0,.,.,1,.,.,.,.,.,.,.,49,26,95.03819444 -9.6,1,596,0,150,.,.,1,.,.,.,.,.,.,.,.,.,95.04761905 -9.6,1,608,0,150,.,.,1,.,.,.,.,.,.,.,.,.,95.11904762 -9.6,1,617.8333333,0,0,.,.,1,.,.,.,.,.,.,.,58,34,95.17757937 -9.6,1,620,0,150,.,.,1,.,.,.,.,.,.,.,.,.,95.19047619 -9.6,1,632,0,150,.,.,1,.,.,.,.,.,.,.,.,.,95.26190476 -9.6,0,642,.,.,.,.,.,1.5,1,.,.,.,.,.,.,.,95.32142857 -9.6,1,642,0,0,.,.,1,.,.,.,.,.,.,.,59,29,95.32142857 -9.6,1,644,0,150,.,.,1,.,.,.,.,.,.,.,.,.,95.33333333 -9.6,1,656,0,150,.,.,1,.,.,.,.,.,.,.,.,.,95.4047619 -9.6,1,665,0,0,.,.,1,.,.,.,.,.,.,.,65,34,95.45833333 -9.6,1,668,0,150,.,.,1,.,.,.,.,.,.,.,.,.,95.47619048 -9.6,1,680.5,0,150,.,.,1,.,.,.,.,.,.,.,.,.,95.55059524 -9.6,1,688.25,0,0,.,.,1,.,.,.,.,.,.,.,63,32,95.59672619 -9.6,1,692,0,150,.,.,1,.,.,.,.,.,.,.,.,.,95.61904762 -9.6,1,704,0,150,.,.,1,.,.,.,.,.,.,.,.,.,95.69047619 -9.6,1,713.6666667,0,0,.,.,1,.,.,.,.,.,.,.,84,36,95.74801587 -9.6,1,716,0,150,.,.,1,.,.,.,.,.,.,.,.,.,95.76190476 -9.6,1,728,0,150,.,.,1,.,.,.,.,.,.,.,.,.,95.83333333 -9.6,1,740,0,150,.,.,1,.,.,.,.,.,.,.,.,.,95.9047619 -9.6,1,752.25,0,150,.,.,1,.,.,.,.,.,.,.,.,.,95.97767857 -9.6,1,764,0,150,.,.,1,.,.,.,.,.,.,.,.,.,96.04761905 -10.1,1,0,0,0,.,.,1,.,.,.,.,.,.,10.4,32,12,98.67559524 -10.1,1,2.5,0,80,.,.,1,.,.,.,.,.,.,.,.,.,98.69047619 -10.1,1,14.5,0,80,.,.,1,.,.,.,.,.,.,.,.,.,98.76190476 -10.1,1,17.31666667,0,0,.,.,1,.,.,.,.,.,.,.,32,12,98.77867063 -10.1,0,17.5,.,.,.,.,.,2.5,1,.,.,.,.,.,.,.,98.7797619 -10.1,1,27.25,0,80,.,.,1,.,.,.,.,.,.,.,.,.,98.83779762 -10.1,1,35.75,0,0,.,.,1,.,.,.,.,.,.,.,34,8,98.88839286 -10.1,1,38.5,0,80,.,.,1,.,.,.,.,.,.,.,.,.,98.9047619 -10.1,1,50.5,0,80,.,.,1,.,.,.,.,.,.,.,.,.,98.97619048 -10.1,1,62.66666667,0,80,.,.,1,.,.,.,.,.,.,.,.,.,99.04861111 -10.1,1,74.5,0,80,.,.,1,.,.,.,.,.,.,.,.,.,99.11904762 -10.1,1,87.08333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,99.19394841 -10.1,1,99,0,80,.,.,1,.,.,.,.,.,.,.,.,.,99.26488095 -10.1,1,110.5,0,80,.,.,1,.,.,.,.,.,.,.,.,.,99.33333333 -10.1,1,122.5,0,80,.,.,1,.,.,.,.,.,.,.,.,.,99.4047619 -10.1,0,131.5833333,.,.,.,.,.,0.3,1,.,.,.,.,.,.,.,99.45882937 -10.1,1,134.5,0,80,.,.,1,.,.,.,.,.,.,.,.,.,99.47619048 -10.1,1,146.5,0,80,.,.,1,.,.,.,.,.,.,.,.,.,99.54761905 -10.1,1,158.5,0,80,.,.,1,.,.,.,.,.,.,.,.,.,99.61904762 -10.1,1,170.5,0,80,.,.,1,.,.,.,.,.,.,.,.,.,99.69047619 -10.1,1,182.5,0,80,.,.,1,.,.,.,.,.,.,.,.,.,99.76190476 -10.1,1,194.5,0,80,.,.,1,.,.,.,.,.,.,.,.,.,99.83333333 -10.1,1,203.1666667,0,0,.,.,1,.,.,.,.,.,.,.,29,11,99.88492063 -10.1,1,206.5,0,80,.,.,1,.,.,.,.,.,.,.,.,.,99.9047619 -10.1,1,218.5,0,80,.,.,1,.,.,.,.,.,.,.,.,.,99.97619048 -10.1,1,230.5,0,80,.,.,1,.,.,.,.,.,.,.,.,.,100.047619 -10.1,1,242.5,0,80,.,.,1,.,.,.,.,.,.,.,.,.,100.1190476 -10.1,1,254.5,0,80,.,.,1,.,.,.,.,.,.,.,.,.,100.1904762 -10.1,1,266.5,0,80,.,.,1,.,.,.,.,.,.,.,.,.,100.2619048 -10.1,1,279,0,80,.,.,1,.,.,.,.,.,.,.,.,.,100.3363095 -10.1,1,290.5,0,80,.,.,1,.,.,.,.,.,.,.,.,.,100.4047619 -10.1,0,300,.,.,.,.,.,0.4,1,.,.,.,.,.,.,.,100.4613095 -11.1,1,0,2,73,.,.,1,.,.,.,.,.,.,10.53,0,0,89.96428571 -11.1,1,12,2,73,.,.,1,.,.,.,.,.,.,.,.,.,90.03571429 -11.1,1,24,2,73,.,.,1,.,.,.,.,.,.,.,.,.,90.10714286 -11.1,1,36,2,73,.,.,1,.,.,.,.,.,.,.,.,.,90.17857143 -11.1,1,48,2,73,.,.,1,.,.,.,.,.,.,.,.,.,90.25 -11.1,1,60,2,73,.,.,1,.,.,.,.,.,.,.,.,.,90.32142857 -11.1,1,72,2,73,.,.,1,.,.,.,.,.,.,.,.,.,90.39285714 -11.1,1,84,2,73,.,.,1,.,.,.,.,.,.,.,.,.,90.46428571 -11.1,1,96,2,73,.,.,1,.,.,.,.,.,.,.,.,.,90.53571429 -11.1,0,107.9166667,.,.,.,.,.,0.2,1,.,.,.,.,.,.,.,90.60664683 -11.1,1,107.9166667,2,73,.,.,1,.,.,.,.,.,.,.,.,.,90.60664683 -11.1,1,120,2,73,.,.,1,.,.,.,.,.,.,.,.,.,90.67857143 -11.1,1,132,2,73,.,.,1,.,.,.,.,.,.,.,.,.,90.75 -11.1,1,144,2,73,.,.,1,.,.,.,.,.,.,.,.,.,90.82142857 -11.1,1,156,2,73,.,.,1,.,.,.,.,.,.,.,.,.,90.89285714 -11.1,1,168,2,73,.,.,1,.,.,.,.,.,.,.,.,.,90.96428571 -11.1,1,180,2,73,.,.,1,.,.,.,.,.,.,.,.,.,91.03571429 -11.1,1,200.5,2,73,.,.,1,.,.,.,.,.,.,.,.,.,91.1577381 -11.1,1,212.5,2,84,.,.,1,.,.,.,.,.,.,.,.,.,91.22916667 -11.1,1,224.5,2,84,.,.,1,.,.,.,.,.,.,.,.,.,91.30059524 -11.1,1,236.5,2,84,.,.,1,.,.,.,.,.,.,.,.,.,91.37202381 -11.1,1,248.5,2,84,.,.,1,.,.,.,.,.,.,.,.,.,91.44345238 -11.1,1,260.5,2,84,.,.,1,.,.,.,.,.,.,.,.,.,91.51488095 -11.1,1,272.25,2,84,.,.,1,.,.,.,.,.,.,.,.,.,91.58482143 -11.1,0,275.0833333,.,.,.,.,.,1.4,1,.,.,.,.,.,.,.,91.60168651 -11.1,1,275.0833333,0,0,.,.,1,.,.,.,.,.,.,.,123,111,91.60168651 -11.1,1,284,2,84,.,.,1,.,.,.,.,.,.,.,.,.,91.6547619 -11.1,1,296,2,84,.,.,1,.,.,.,.,.,.,.,.,.,91.72619048 -11.1,1,308,2,84,.,.,1,.,.,.,.,.,.,.,.,.,91.79761905 -11.1,1,320,2,84,.,.,1,.,.,.,.,.,.,.,.,.,91.86904762 -11.1,1,332,2,84,.,.,1,.,.,.,.,.,.,.,.,.,91.94047619 -11.1,1,344,2,84,.,.,1,.,.,.,.,.,.,.,.,.,92.01190476 -11.1,1,347.25,0,0,.,.,1,.,.,.,.,.,.,.,34,109,92.03125 -11.1,1,356,2,84,.,.,1,.,.,.,.,.,.,.,.,.,92.08333333 -11.1,1,368,2,84,.,.,1,.,.,.,.,.,.,.,.,.,92.1547619 -11.1,1,380,0,84,.,.,1,.,.,.,.,.,.,.,.,.,92.22619048 -11.1,1,392,0,84,.,.,1,.,.,.,.,.,.,.,.,.,92.29761905 -11.1,1,410.5,0,84,.,.,1,.,.,.,.,.,.,.,.,.,92.4077381 -11.1,1,422,0,84,.,.,1,.,.,.,.,.,.,.,.,.,92.47619048 -11.1,1,434,0,84,.,.,1,.,.,.,.,.,.,.,.,.,92.54761905 -11.1,1,434.4333333,0,0,.,.,1,.,.,.,.,.,.,11.2,.,.,92.55019841 -11.1,0,443.5,.,.,.,.,.,1.2,1,.,.,.,.,.,.,.,92.60416667 -11.1,1,443.5,0,0,.,.,1,.,.,.,.,.,.,.,17,27,92.60416667 -11.1,1,447,0,84,.,.,1,.,.,.,.,.,.,.,.,.,92.625 -11.1,1,458,0,84,.,.,1,.,.,.,.,.,.,.,.,.,92.69047619 -11.1,1,470.7,0,84,.,.,1,.,.,.,.,.,.,.,.,.,92.76607143 -11.1,1,482,0,84,.,.,1,.,.,.,.,.,.,.,.,.,92.83333333 -11.1,1,495.216667,0,84,.,.,1,.,.,.,.,.,.,.,.,.,92.91200397 -11.1,1,506,0,84,.,.,1,.,.,.,.,.,.,.,.,.,92.97619048 -11.1,1,515.5,0,0,.,.,1,.,.,.,.,.,.,.,24,12,93.0327381 -11.1,1,518,0,84,.,.,1,.,.,.,.,.,.,.,.,.,93.04761905 -11.1,1,530.5,0,95,.,.,1,.,.,.,.,.,.,.,.,.,93.12202381 -11.1,1,542,0,95,.,.,1,.,.,.,.,.,.,.,.,.,93.19047619 -11.1,1,554.333333,0,95,.,.,1,.,.,.,.,.,.,.,.,.,93.26388889 -11.1,1,566,0,95,.,.,1,.,.,.,.,.,.,.,.,.,93.33333333 -11.1,1,578,0,95,.,.,1,.,.,.,.,.,.,.,.,.,93.4047619 -11.1,0,587.25,.,.,.,.,.,0.2,1,.,.,.,.,.,.,.,93.45982143 -11.1,1,590,0,95,.,.,1,.,.,.,.,.,.,.,.,.,93.47619048 -11.1,1,602,0,95,.,.,1,.,.,.,.,.,.,.,.,.,93.54761905 -11.1,1,611,0,0,.,.,1,.,.,.,.,.,.,.,23,22,93.60119048 -11.1,1,614,0,95,.,.,1,.,.,.,.,.,.,.,.,.,93.61904762 -11.1,1,626,0,95,.,.,1,.,.,.,.,.,.,.,.,.,93.69047619 -11.1,1,638,0,95,.,.,1,.,.,.,.,.,.,.,.,.,93.76190476 -11.1,1,650,0,95,.,.,1,.,.,.,.,.,.,.,.,.,93.83333333 -11.1,1,662,0,95,.,.,1,.,.,.,.,.,.,.,.,.,93.9047619 -11.1,1,674,0,95,.,.,1,.,.,.,.,.,.,.,.,.,93.97619048 -11.1,1,683,0,0,.,.,1,.,.,.,.,.,.,.,25,17,94.0297619 -11.1,1,686,0,95,.,.,1,.,.,.,.,.,.,.,.,.,94.04761905 -11.1,0,695.966667,.,.,.,.,.,0.3,1,.,.,.,.,.,.,.,94.10694444 -12.1,1,0,0,0,.,.,1,.,.,.,.,.,.,9.9,34,18,76.04117063 -12.1,1,13.08333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,76.11904762 -12.1,1,13.78333333,0,0,.,.,1,.,.,.,.,.,.,9.9,.,.,76.12321429 -12.1,1,25.08333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,76.19047619 -12.1,1,37.08333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,76.26190476 -12.1,1,46.58333333,0,0,.,.,1,.,.,.,.,.,.,.,26,6,76.31845238 -12.1,1,50.08333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,76.33928571 -12.1,1,61.08333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,76.4047619 -12.1,1,73.08333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,76.47619048 -12.1,1,85.58333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,76.55059524 -12.1,1,97.08333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,76.61904762 -12.1,1,109.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,76.69047619 -12.1,1,118.3333333,0,0,.,.,1,.,.,.,.,.,.,.,30,12,76.74553571 -12.1,1,121.5833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,76.76488095 -12.1,1,133.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,76.83333333 -12.1,1,148.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,76.92261905 -12.1,1,157.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,76.97619048 -12.1,1,171.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,77.05952381 -12.1,1,181.5833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,77.12202381 -12.1,1,193.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,77.19047619 -12.1,1,196.5833333,0,0,.,.,1,.,.,.,.,.,.,.,41,23,77.21130952 -12.1,1,205.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,77.26190476 -12.1,1,217.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,77.33333333 -12.1,1,229.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,77.4047619 -12.1,1,241.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,77.47619048 -12.1,1,253.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,77.54761905 -12.1,1,265.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,77.61904762 -12.1,1,277.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,77.69047619 -12.1,1,289.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,77.76190476 -12.1,1,301.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,77.83333333 -12.1,1,312.0833333,0,0,.,.,1,.,.,.,.,.,.,.,34,15,77.89880952 -12.1,1,315.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,77.91666667 -12.1,1,325.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,77.97619048 -12.1,1,335.75,0,0,.,.,1,.,.,.,.,.,.,.,31,6,78.03968254 -12.1,1,338.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,78.05357143 -12.1,1,349.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,78.11904762 -12.1,1,360,0,0,.,.,1,.,.,.,.,.,.,.,31,12,78.18402778 -12.1,1,361.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,78.19047619 -12.1,1,373.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,78.26190476 -12.1,1,383.3333333,0,0,.,.,1,.,.,.,.,.,.,.,121,39,78.32291667 -12.1,1,386.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,78.33928571 -12.1,1,398.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,78.41071429 -12.1,1,407.3333333,0,0,.,.,1,.,.,.,.,.,.,.,714,448,78.46577381 -12.1,1,410.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,78.48214286 -12.1,1,422.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,78.55357143 -12.1,0,431.3333333,.,.,.,.,.,7.5,1,.,.,.,.,.,.,.,78.60863095 -12.1,1,431.3333333,0,0,.,.,1,.,.,.,.,.,.,.,434,447,78.60863095 -12.1,1,434.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,78.625 -12.1,1,446.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,78.69642857 -12.1,1,455.9166667,0,0,.,.,1,.,.,.,.,.,.,.,363,495,78.75496032 -12.1,1,458.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,78.76785714 -12.1,1,470.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,78.83928571 -12.1,1,482.5833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,78.91369048 -12.1,1,494.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,78.98214286 -12.1,1,505.0833333,0,0,.,.,1,.,.,.,.,.,.,.,81,221,79.04761905 -12.1,1,506.0833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,79.05357143 -12.1,1,519.0833333,0,40,.,.,1,.,.,.,.,.,.,.,.,.,79.13095238 -12.1,1,528.6333333,0,0,.,.,1,.,.,.,.,.,.,.,49,154,79.18779762 -12.1,1,530.0833333,0,40,.,.,1,.,.,.,.,.,.,.,.,.,79.19642857 -12.1,1,542.0833333,0,40,.,.,1,.,.,.,.,.,.,.,.,.,79.26785714 -12.1,0,553.1166667,.,.,.,.,.,2.7,1,.,.,.,.,.,.,.,79.33353175 -13.1,1,0,0,55,.,.,1,.,.,.,.,.,.,7.945,55,48,74.47619048 -13.1,1,12,0,75,.,.,1,.,.,.,.,.,.,.,.,.,74.54761905 -13.1,1,24,0,75,.,.,1,.,.,.,.,.,.,.,.,.,74.61904762 -13.1,1,36,0,75,.,.,1,.,.,.,.,.,.,.,.,.,74.69047619 -13.1,1,46.1666667,0,0,.,.,1,.,.,.,.,.,.,.,55,48,74.75099206 -13.1,1,48,0,75,.,.,1,.,.,.,.,.,.,.,.,.,74.76190476 -13.1,1,60,0,75,.,.,1,.,.,.,.,.,.,.,.,.,74.83333333 -13.1,1,68,0,0,.,.,1,.,.,.,.,.,.,.,63,55,74.88095238 -13.1,1,72,0,75,.,.,1,.,.,.,.,.,.,.,.,.,74.9047619 -13.1,1,84,0,75,.,.,1,.,.,.,.,.,.,.,.,.,74.97619048 -13.1,0,93.25,.,.,.,.,.,0.1,1,.,.,.,.,.,.,.,75.03125 -13.1,1,93.25,0,0,.,.,1,.,.,.,.,.,.,.,59,61,75.03125 -13.1,1,96,0,75,.,.,1,.,.,.,.,.,.,.,.,.,75.04761905 -13.1,1,108,0,75,.,.,1,.,.,.,.,.,.,.,.,.,75.11904762 -13.1,1,115.3333334,0,0,.,.,1,.,.,.,.,.,.,.,58,62,75.16269841 -13.1,1,120,0,75,.,.,1,.,.,.,.,.,.,.,.,.,75.19047619 -13.1,1,132.4166667,0,75,.,.,1,.,.,.,.,.,.,.,.,.,75.26438492 -13.1,1,139.5,0,0,.,.,1,.,.,.,.,.,.,.,54,55,75.30654762 -13.1,1,144,0,75,.,.,1,.,.,.,.,.,.,.,.,.,75.33333333 -13.1,1,156,0,100,.,.,1,.,.,.,.,.,.,.,.,.,75.4047619 -13.1,1,165.75,0,0,.,.,1,.,.,.,.,.,.,.,47,50,75.46279762 -13.1,1,168,0,100,.,.,1,.,.,.,.,.,.,.,.,.,75.47619048 -13.1,1,180,0,100,.,.,1,.,.,.,.,.,.,.,.,.,75.54761905 -13.1,1,189,0,0,.,.,1,.,.,.,.,.,.,.,34,42,75.60119048 -13.1,1,192,0,100,.,.,1,.,.,.,.,.,.,.,.,.,75.61904762 -13.1,1,204,0,100,.,.,1,.,.,.,.,.,.,.,.,.,75.69047619 -13.1,1,213.25,0,0,.,.,1,.,.,.,.,.,.,.,32,29,75.74553571 -13.1,1,216,0,100,.,.,1,.,.,.,.,.,.,.,.,.,75.76190476 -13.1,1,228,0,100,.,.,1,.,.,.,.,.,.,.,.,.,75.83333333 -13.1,1,240,0,100,.,.,1,.,.,.,.,.,.,.,.,.,75.9047619 -13.1,1,252,0,100,.,.,1,.,.,.,.,.,.,.,.,.,75.97619048 -13.1,0,258,.,.,.,.,.,0.2,1,.,.,.,.,.,.,.,76.01190476 -14.1,1,0,2,55,.,.,1,.,.,.,.,.,.,7.96,113,156,50.82688492 -14.1,1,12.0833333,2,55,.,.,1,.,.,.,.,.,.,.,.,.,50.89880952 -14.1,1,25.0833333,2,55,.,.,1,.,.,.,.,.,.,.,.,.,50.97619048 -14.1,1,37.0833333,2,55,.,.,1,.,.,.,.,.,.,.,.,.,51.04761905 -14.1,1,49.0833333,2,55,.,.,1,.,.,.,.,.,.,.,.,.,51.11904762 -14.1,1,61.5833333,2,55,.,.,1,.,.,.,.,.,.,.,.,.,51.19345238 -14.1,1,75.8333333,2,55,.,.,1,.,.,.,.,.,.,.,.,.,51.27827381 -14.1,1,88.0833333,2,55,.,.,1,.,.,.,.,.,.,.,.,.,51.35119048 -14.1,1,100.0833333,2,55,.,.,1,.,.,.,.,.,.,.,.,.,51.42261905 -14.1,1,112.75,2,55,.,.,1,.,.,.,.,.,.,.,.,.,51.49801587 -14.1,0,124.6666666,.,.,.,.,.,2.1,1,.,.,.,.,.,.,.,51.56894841 -14.2,1,0,2,55,.,.,1,.,.,.,.,.,.,7.96,113,156,51.56944444 -14.2,1,11.3333333,2,55,.,.,1,.,.,.,.,.,.,.,.,.,51.63690476 -14.2,1,23.3333333,2,55,.,.,1,.,.,.,.,.,.,.,.,.,51.70833333 -14.2,1,35.8333333,2,55,.,.,1,.,.,.,.,.,.,.,.,.,51.7827381 -14.2,1,48.3333333,2,55,.,.,1,.,.,.,.,.,.,.,.,.,51.85714286 -14.2,1,59.3333333,2,55,.,.,1,.,.,.,.,.,.,.,.,.,51.92261905 -14.2,1,72.3333333,2,55,.,.,1,.,.,.,.,.,.,.,.,.,52 -14.2,1,83.3333333,2,55,.,.,1,.,.,.,.,.,.,.,.,.,52.06547619 -14.2,1,95.3333333,2,55,.,.,1,.,.,.,.,.,.,.,.,.,52.13690476 -14.2,1,107.3333333,2,55,.,.,1,.,.,.,.,.,.,.,.,.,52.20833333 -14.2,1,107.9166666,0,0,.,.,1,.,.,.,.,.,.,7.13,.,.,52.21180556 -14.2,1,115.5833333,0,0,.,.,1,.,.,.,.,.,.,.,113,156,52.25744048 -14.2,1,128.3333333,0,0,.,.,1,.,.,.,.,.,.,7.13,.,.,52.33333333 -14.2,1,131.5,2,55,.,.,1,.,.,.,.,.,.,.,.,.,52.35218254 -14.2,1,142.9166666,2,55,.,.,1,.,.,.,.,.,.,.,.,.,52.42013889 -14.2,1,155.3333333,2,55,.,.,1,.,.,.,.,.,.,.,.,.,52.49404762 -14.2,1,167.3333333,2,55,.,.,1,.,.,.,.,.,.,.,.,.,52.56547619 -14.2,0,176.5833333,.,.,.,.,.,10.9,1,.,.,.,.,.,.,.,52.62053571 -14.2,1,182.3333333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,52.6547619 -14.2,1,182.9,0,0,.,.,1,.,.,.,.,.,.,7.13,.,.,52.65813492 -14.2,1,194.8333333,2,50,.,.,1,.,.,.,.,.,.,.,.,.,52.72916667 -14.2,1,206.8333333,2,50,.,.,1,.,.,.,.,.,.,.,.,.,52.80059524 -14.2,1,218.8333333,2,50,.,.,1,.,.,.,.,.,.,.,.,.,52.87202381 -14.2,0,231.3333333,.,.,.,.,.,5.8,1,.,.,.,.,.,.,.,52.94642857 -14.3,1,0,2,50,.,.,1,.,.,.,.,.,.,7.13,149,156,52.94642857 -14.3,1,11,2,50,.,.,1,.,.,.,.,.,.,.,.,.,53.01190476 -14.3,1,17,0,0,.,.,1,.,.,.,.,.,.,7.13,.,.,53.04761905 -14.3,1,22.75,2,50,.,.,1,.,.,.,.,.,.,.,.,.,53.08184524 -14.3,1,23,0,0,.,.,1,.,.,.,.,.,.,7.13,.,.,53.08333333 -14.3,1,35,2,50,.,.,1,.,.,.,.,.,.,.,.,.,53.1547619 -14.3,1,47,2,50,.,.,1,.,.,.,.,.,.,.,.,.,53.22619048 -14.3,1,59,2,50,.,.,1,.,.,.,.,.,.,.,.,.,53.29761905 -14.3,1,71.08333333,2,50,.,.,1,.,.,.,.,.,.,.,.,.,53.36954365 -14.3,1,82.83333333,2,50,.,.,1,.,.,.,.,.,.,.,.,.,53.43948413 -14.3,1,94.5,2,50,.,.,1,.,.,.,.,.,.,.,.,.,53.50892857 -14.3,1,107,2,50,.,.,1,.,.,.,.,.,.,.,.,.,53.58333333 -14.3,1,118.5,2,50,.,.,1,.,.,.,.,.,.,.,.,.,53.65178571 -14.3,1,120.5,0,0,.,.,1,.,.,.,.,.,.,.,149,156,53.66369048 -14.3,1,131,2,42,.,.,1,.,.,.,.,.,.,.,.,.,53.72619048 -14.3,1,143,2,42,.,.,1,.,.,.,.,.,.,.,.,.,53.79761905 -14.3,1,155,2,42,.,.,1,.,.,.,.,.,.,.,.,.,53.86904762 -14.3,1,167,2,42,.,.,1,.,.,.,.,.,.,.,.,.,53.94047619 -14.3,1,179,2,42,.,.,1,.,.,.,.,.,.,.,.,.,54.01190476 -14.3,1,181.2,0,0,.,.,1,.,.,.,.,.,.,.,30,49,54.025 -14.3,1,185,0,0,.,.,1,.,.,.,.,.,.,7.13,.,.,54.04761905 -14.3,0,190.1166667,.,.,.,.,.,0.7,1,.,.,.,.,.,.,.,54.0780754 -14.3,1,191,2,42,.,.,1,.,.,.,.,.,.,.,.,.,54.08333333 -14.3,1,203,2,42,.,.,1,.,.,.,.,.,.,.,.,.,54.1547619 -14.3,1,214.6833333,0,0,.,.,1,.,.,.,.,.,.,7.13,.,.,54.22430556 -14.3,1,215.5,2,42,.,.,1,.,.,.,.,.,.,.,.,.,54.22916667 -14.3,1,226.75,0,0,.,.,1,.,.,.,.,.,.,7.13,.,.,54.29613095 -14.3,1,227,2,42,.,.,1,.,.,.,.,.,.,.,.,.,54.29761905 -14.3,1,239,2,42,.,.,1,.,.,.,.,.,.,.,.,.,54.36904762 -14.3,1,251,2,42,.,.,1,.,.,.,.,.,.,.,.,.,54.44047619 -14.3,1,253,0,0,.,.,1,.,.,.,.,.,.,7.79,.,.,54.45238095 -14.3,1,263,2,42,.,.,1,.,.,.,.,.,.,.,.,.,54.51190476 -14.3,1,275,2,42,.,.,1,.,.,.,.,.,.,.,.,.,54.58333333 -14.3,1,300.7833333,0,0,.,.,1,.,.,.,.,.,.,7.42,.,.,54.73680556 -14.3,1,305,0,42,.,.,1,.,.,.,.,.,.,.,.,.,54.76190476 -14.4,1,0,0,0,.,.,1,.,.,.,.,.,.,7.9,45,35,64.27321429 -14.4,1,2.35,0,80,.,.,1,.,.,.,.,.,.,.,.,.,64.28720238 -14.4,1,9.183333333,0,0,.,.,1,.,.,.,.,.,.,.,45,35,64.32787698 -14.4,1,10.1,0,80,.,.,1,.,.,.,.,.,.,.,.,.,64.33333333 -14.4,1,22.6,0,80,.,.,1,.,.,.,.,.,.,.,.,.,64.4077381 -14.4,1,34.1,0,80,.,.,1,.,.,.,.,.,.,.,.,.,64.47619048 -14.4,1,46.85,0,80,.,.,1,.,.,.,.,.,.,.,.,.,64.55208333 -14.4,1,60.1,0,80,.,.,1,.,.,.,.,.,.,.,.,.,64.63095238 -14.4,1,70.1,0,80,.,.,1,.,.,.,.,.,.,.,.,.,64.69047619 -14.4,1,83.35,0,80,.,.,1,.,.,.,.,.,.,.,.,.,64.76934524 -14.4,1,94.1,0,80,.,.,1,.,.,.,.,.,.,.,.,.,64.83333333 -14.4,1,106.5166667,0,80,.,.,1,.,.,.,.,.,.,.,.,.,64.90724206 -14.4,1,121.6,0,0,.,.,1,.,.,.,.,.,.,.,51,152,64.99702381 -14.4,1,125.95,0,0,.,.,1,.,.,.,.,.,.,7.8,.,.,65.02291667 -14.4,1,130.1,0,80,.,.,1,.,.,.,.,.,.,.,.,.,65.04761905 -14.4,1,130.1333333,0,0,.,.,1,.,.,.,.,.,.,.,43,107,65.04781746 -14.4,1,142.6,0,80,.,.,1,.,.,.,.,.,.,.,.,.,65.12202381 -14.4,0,142.9333333,.,.,.,.,.,4.76,1,.,.,.,.,.,.,.,65.12400794 -15.1,1,0,2,80,.,.,1,.,.,.,.,.,.,10.89,30,12,90.8452381 -15.1,1,12,2,80,.,.,1,.,.,.,.,.,.,.,.,.,90.91666667 -15.1,1,24,2,80,.,.,1,.,.,.,.,.,.,.,.,.,90.98809524 -15.1,0,29.5,.,.,.,.,.,6.4,1,.,.,.,.,.,.,.,91.02083333 -16.1,1,0,0,0,.,.,1,.,.,.,.,.,.,5.65,76,109,31.03422619 -16.1,1,10.25,0,40,.,.,1,.,.,.,.,.,.,.,.,.,31.0952381 -16.1,1,23.25,0,40,.,.,1,.,.,.,.,.,.,.,.,.,31.17261905 -16.1,1,24.75,0,0,.,.,1,.,.,.,.,.,.,.,78,94,31.18154762 -16.1,1,35.75,0,40,.,.,1,.,.,.,.,.,.,.,.,.,31.24702381 -16.1,1,49,0,0,.,.,1,.,.,.,.,.,.,.,92,94,31.32589286 -16.1,1,50.25,0,40,.,.,1,.,.,.,.,.,.,.,.,.,31.33333333 -16.1,1,62.25,0,40,.,.,1,.,.,.,.,.,.,.,.,.,31.4047619 -16.1,1,72.75,0,0,.,.,1,.,.,.,.,.,.,.,60,80,31.4672619 -16.1,1,74.25,0,40,.,.,1,.,.,.,.,.,.,.,.,.,31.47619048 -16.1,1,86.25,0,40,.,.,1,.,.,.,.,.,.,.,.,.,31.54761905 -16.1,0,96.25,.,.,.,.,.,0.9,1,.,.,.,.,.,.,.,31.60714286 -16.2,1,0,0,0,.,.,1,.,.,.,.,.,.,5.65,84,61,31.60714286 -16.2,1,2,0,40,.,.,1,.,.,.,.,.,.,.,.,.,31.61904762 -16.2,1,14,0,40,.,.,1,.,.,.,.,.,.,.,.,.,31.69047619 -16.2,1,24.25,0,0,.,.,1,.,.,.,.,.,.,.,66,56,31.7514881 -16.2,1,26,0,40,.,.,1,.,.,.,.,.,.,.,.,.,31.76190476 -16.2,1,38,0,40,.,.,1,.,.,.,.,.,.,.,.,.,31.83333333 -16.2,1,47.91666667,0,0,.,.,1,.,.,.,.,.,.,.,62,54,31.89236111 -16.2,1,50,0,40,.,.,1,.,.,.,.,.,.,.,.,.,31.9047619 -16.2,1,62,0,40,.,.,1,.,.,.,.,.,.,.,.,.,31.97619048 -16.2,1,74.41666667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,32.05009921 -16.2,1,86,0,40,.,.,1,.,.,.,.,.,.,.,.,.,32.11904762 -16.2,0,96.83333333,.,.,.,.,.,0.05,1,.,.,.,.,.,.,.,32.18353175 -17.1,1,0,0,0,.,.,1,.,.,.,.,.,.,7,69,30,25.32142857 -17.1,1,7.25,0,50,.,.,1,.,.,.,.,.,.,.,.,.,25.36458333 -17.1,1,14.5,0,50,.,.,1,.,.,.,.,.,.,.,.,.,25.4077381 -17.1,1,27,0,50,.,.,1,.,.,.,.,.,.,.,.,.,25.48214286 -17.1,1,39,0,50,.,.,1,.,.,.,.,.,.,.,.,.,25.55357143 -17.1,1,48.33333333,0,0,.,.,1,.,.,.,.,.,.,.,57,22,25.60912698 -17.1,1,51.5,0,50,.,.,1,.,.,.,.,.,.,.,.,.,25.62797619 -17.1,1,62,0,50,.,.,1,.,.,.,.,.,.,.,.,.,25.69047619 -17.1,0,72.16666667,.,.,.,.,.,0.125,1,.,.,.,.,.,.,.,25.75099206 -17.1,1,75,0,50,.,.,1,.,.,.,.,.,.,.,.,.,25.76785714 -17.1,1,86,0,50,.,.,1,.,.,.,.,.,.,.,.,.,25.83333333 -17.1,1,96.5,0,0,.,.,1,.,.,.,.,.,.,.,54,18,25.89583333 -17.1,1,99,0,50,.,.,1,.,.,.,.,.,.,.,.,.,25.91071429 -17.1,1,110,0,75,.,.,1,.,.,.,.,.,.,.,.,.,25.97619048 -17.1,1,122.75,0,75,.,.,1,.,.,.,.,.,.,.,.,.,26.05208333 -17.1,1,134,0,75,.,.,1,.,.,.,.,.,.,.,.,.,26.11904762 -17.1,1,146.5,0,75,.,.,1,.,.,.,.,.,.,.,.,.,26.19345238 -17.1,1,159,0,75,.,.,1,.,.,.,.,.,.,.,.,.,26.26785714 -17.1,1,168.3333333,0,0,.,.,1,.,.,.,.,.,.,.,55,13,26.3234127 -17.1,1,171,0,75,.,.,1,.,.,.,.,.,.,.,.,.,26.33928571 -17.1,1,182,0,75,.,.,1,.,.,.,.,.,.,.,.,.,26.4047619 -17.1,0,192.3333333,.,.,.,.,.,0.304,1,.,.,.,.,.,.,.,26.46626984 -17.1,1,195,0,75,.,.,1,.,.,.,.,.,.,.,.,.,26.48214286 -17.1,1,206,0,100,.,.,1,.,.,.,.,.,.,.,.,.,26.54761905 -17.1,1,216.25,0,0,.,.,1,.,.,.,.,.,.,.,64,23,26.60863095 -17.1,1,219,0,100,.,.,1,.,.,.,.,.,.,.,.,.,26.625 -17.1,1,230,0,100,.,.,1,.,.,.,.,.,.,.,.,.,26.69047619 -17.1,1,246.5,0,100,.,.,1,.,.,.,.,.,.,.,.,.,26.78869048 -17.1,1,254,0,100,.,.,1,.,.,.,.,.,.,.,.,.,26.83333333 -17.1,1,264.1666667,0,0,.,.,1,.,.,.,.,.,.,.,41,10,26.89384921 -17.1,1,267,0,100,.,.,1,.,.,.,.,.,.,.,.,.,26.91071429 -17.1,1,278,0,100,.,.,1,.,.,.,.,.,.,.,.,.,26.97619048 -17.1,1,291,0,100,.,.,1,.,.,.,.,.,.,.,.,.,27.05357143 -17.1,1,302,0,100,.,.,1,.,.,.,.,.,.,.,.,.,27.11904762 -17.1,1,315,0,100,.,.,1,.,.,.,.,.,.,.,.,.,27.19642857 -17.1,1,326,0,100,.,.,1,.,.,.,.,.,.,.,.,.,27.26190476 -17.1,0,335.5,.,.,.,.,.,0.741,1,.,.,.,.,.,.,.,27.31845238 -17.1,1,335.5,0,0,.,.,1,.,.,.,.,.,.,.,55,9,27.31845238 -17.1,1,339,0,100,.,.,1,.,.,.,.,.,.,.,.,.,27.33928571 -17.1,1,350,0,100,.,.,1,.,.,.,.,.,.,.,.,.,27.4047619 -17.1,1,363,0,100,.,.,1,.,.,.,.,.,.,.,.,.,27.48214286 -17.1,1,374,0,100,.,.,1,.,.,.,.,.,.,.,.,.,27.54761905 -17.1,1,384.5,0,0,.,.,1,.,.,.,.,.,.,.,78,7,27.61011905 -17.1,1,387,0,100,.,.,1,.,.,.,.,.,.,.,.,.,27.625 -17.1,1,398,0,150,.,.,1,.,.,.,.,.,.,.,.,.,27.69047619 -17.1,1,411,0,150,.,.,1,.,.,.,.,.,.,.,.,.,27.76785714 -17.1,1,422,0,150,.,.,1,.,.,.,.,.,.,.,.,.,27.83333333 -17.1,0,432.3333333,.,.,.,.,.,1.8,1,.,.,.,.,.,.,.,27.89484127 -17.1,1,432.3333333,0,0,.,.,1,.,.,.,.,.,.,.,189,40,27.89484127 -17.1,1,435,0,150,.,.,1,.,.,.,.,.,.,.,.,.,27.91071429 -17.1,1,446,0,150,.,.,1,.,.,.,.,.,.,.,.,.,27.97619048 -17.1,1,456,0,0,.,.,1,.,.,.,.,.,.,.,194,54,28.03571429 -17.1,1,459,0,150,.,.,1,.,.,.,.,.,.,.,.,.,28.05357143 -17.1,1,470,0,150,.,.,1,.,.,.,.,.,.,.,.,.,28.11904762 -17.1,1,480,0,0,.,.,1,.,.,.,.,.,.,.,359,109,28.17857143 -17.1,1,483,0,150,.,.,1,.,.,.,.,.,.,.,.,.,28.19642857 -17.1,1,490.5833333,0,0,.,.,1,.,.,.,.,.,.,7,.,.,28.24156746 -17.1,1,494,0,150,.,.,1,.,.,.,.,.,.,.,.,.,28.26190476 -17.1,0,504.5,.,.,.,.,.,2.89,1,.,.,.,.,.,.,.,28.32440476 -17.1,1,504.5,0,0,.,.,1,.,.,.,.,.,.,.,407,133,28.32440476 -17.1,1,507,0,150,.,.,1,.,.,.,.,.,.,.,.,.,28.33928571 -17.1,1,518,0,150,.,.,1,.,.,.,.,.,.,.,.,.,28.4047619 -17.1,1,527,0,0,.,.,1,.,.,.,.,.,.,.,371,131,28.45833333 -17.1,1,530.5,0,150,.,.,1,.,.,.,.,.,.,.,.,.,28.47916667 -17.1,1,531.3833333,0,0,.,.,1,.,.,.,.,.,.,7,.,.,28.4844246 -17.1,1,542,2,150,.,.,1,.,.,.,.,.,.,.,.,.,28.54761905 -17.1,1,552,0,0,.,.,1,.,.,.,.,.,.,.,323,97,28.60714286 -17.1,1,554.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,28.62202381 -17.1,1,566.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,28.69345238 -17.1,0,576.3333333,.,.,.,.,.,3.11,1,.,.,.,.,.,.,.,28.75198413 -17.1,1,576.3333333,0,0,.,.,1,.,.,.,.,.,.,.,141,63,28.75198413 -17.1,1,578.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,28.76488095 -17.1,1,590.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,28.83630952 -17.1,1,600.8333333,0,0,.,.,1,.,.,.,.,.,.,.,249,71,28.89781746 -17.1,1,602.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,28.9077381 -17.1,1,614.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,28.97916667 -17.1,1,624.5,0,0,.,.,1,.,.,.,.,.,.,.,452,115,29.03869048 -17.1,1,626,2,150,.,.,1,.,.,.,.,.,.,.,.,.,29.04761905 -17.1,1,638,2,150,.,.,1,.,.,.,.,.,.,.,.,.,29.11904762 -17.1,1,648.6666667,0,0,.,.,1,.,.,.,.,.,.,.,171,85,29.18253968 -17.1,1,650.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,29.19345238 -17.1,1,662,2,150,.,.,1,.,.,.,.,.,.,.,.,.,29.26190476 -17.1,1,674.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,29.33630952 -17.1,1,676.75,0,0,.,.,1,.,.,.,.,.,.,.,334,97,29.34970238 -17.1,1,686,2,150,.,.,1,.,.,.,.,.,.,.,.,.,29.4047619 -17.1,1,695.9666667,0,0,.,.,1,.,.,.,.,.,.,.,170,75,29.4640873 -17.1,1,698,2,150,.,.,1,.,.,.,.,.,.,.,.,.,29.47619048 -17.1,1,710,2,150,.,.,1,.,.,.,.,.,.,.,.,.,29.54761905 -17.1,0,720.5,.,.,.,.,.,5.94,1,.,.,.,.,.,.,.,29.61011905 -17.1,1,720.5,0,0,.,.,1,.,.,.,.,.,.,.,413,88,29.61011905 -17.1,1,722,2,150,.,.,1,.,.,.,.,.,.,.,.,.,29.61904762 -17.1,1,734,0,125,.,.,1,.,.,.,.,.,.,.,.,.,29.69047619 -17.1,1,734,0,150,.,.,1,.,.,.,.,.,.,.,.,.,29.69047619 -17.1,1,744.8333333,0,0,.,.,1,.,.,.,.,.,.,.,304,114,29.75496032 -17.1,1,747,0,150,.,.,1,.,.,.,.,.,.,.,.,.,29.76785714 -17.1,1,758,0,150,.,.,1,.,.,.,.,.,.,.,.,.,29.83333333 -17.1,0,768.75,.,.,.,.,.,4.76,1,.,.,.,.,.,.,.,29.89732143 -17.2,1,0,0,0,.,.,1,.,.,.,.,.,.,7,131,87,29.89732143 -17.2,1,1.75,0,150,.,.,1,.,.,.,.,.,.,.,.,.,29.9077381 -17.2,1,13.25,0,150,.,.,1,.,.,.,.,.,.,.,.,.,29.97619048 -17.2,1,23.66666667,0,0,.,.,1,.,.,.,.,.,.,.,268,98,30.03819444 -17.2,1,25.91666667,0,150,.,.,1,.,.,.,.,.,.,.,.,.,30.0515873 -17.2,1,37.25,0,150,.,.,1,.,.,.,.,.,.,.,.,.,30.11904762 -17.2,1,47.25,0,0,.,.,1,.,.,.,.,.,.,.,156,71,30.17857143 -17.2,1,49.25,0,150,.,.,1,.,.,.,.,.,.,.,.,.,30.19047619 -17.2,1,61.25,0,150,.,.,1,.,.,.,.,.,.,.,.,.,30.26190476 -17.2,0,71.75,.,.,.,.,.,2.3,1,.,.,.,.,.,.,.,30.32440476 -17.2,1,71.75,0,0,.,.,1,.,.,.,.,.,.,.,143,70,30.32440476 -17.2,1,73.75,0,150,.,.,1,.,.,.,.,.,.,.,.,.,30.33630952 -17.2,1,85.25,0,150,.,.,1,.,.,.,.,.,.,.,.,.,30.4047619 -17.2,1,95.25,0,0,.,.,1,.,.,.,.,.,.,.,143,57,30.46428571 -17.2,1,97.25,0,150,.,.,1,.,.,.,.,.,.,.,.,.,30.47619048 -17.2,1,109.25,0,150,.,.,1,.,.,.,.,.,.,.,.,.,30.54761905 -17.2,0,119.25,.,.,.,.,.,1.75,1,.,.,.,.,.,.,.,30.60714286 -17.2,1,119.25,0,0,.,.,1,.,.,.,.,.,.,.,188,68,30.60714286 -17.2,1,121.25,0,150,.,.,1,.,.,.,.,.,.,.,.,.,30.61904762 -17.2,1,133.25,0,200,.,.,1,.,.,.,.,.,.,.,.,.,30.69047619 -17.2,1,143.75,0,0,.,.,1,.,.,.,.,.,.,.,368,77,30.75297619 -17.2,1,145.75,0,200,.,.,1,.,.,.,.,.,.,.,.,.,30.76488095 -17.2,1,157.25,0,200,.,.,1,.,.,.,.,.,.,.,.,.,30.83333333 -17.2,0,167.7,.,.,.,.,.,6.91,1,.,.,.,.,.,.,.,30.89553571 -17.2,1,167.7,0,0,.,.,1,.,.,.,.,.,.,.,301,84,30.89553571 -17.2,1,169.75,0,200,.,.,1,.,.,.,.,.,.,.,.,.,30.9077381 -17.2,1,191.3833333,0,0,.,.,1,.,.,.,.,.,.,.,127,56,31.03650794 -17.2,1,215.4166667,0,0,.,.,1,.,.,.,.,.,.,.,80,47,31.17956349 -17.2,1,219.9166667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,31.20634921 -17.2,0,220,.,.,.,.,.,0.028,1,.,.,.,.,.,.,.,31.20684524 -17.2,0,239.25,.,.,.,.,.,0.062,1,.,.,.,.,.,.,.,31.32142857 -17.2,1,239.25,0,0,.,.,1,.,.,.,.,.,.,.,67,42,31.32142857 -17.2,1,249,0,100,.,.,1,.,.,.,.,.,.,.,.,.,31.37946429 -17.2,1,253.25,0,100,.,.,1,.,.,.,.,.,.,.,.,.,31.4047619 -17.2,1,263.4166667,0,0,.,.,1,.,.,.,.,.,.,.,52,39,31.46527778 -17.2,1,265.25,0,100,.,.,1,.,.,.,.,.,.,.,.,.,31.47619048 -17.2,1,280.25,0,100,.,.,1,.,.,.,.,.,.,.,.,.,31.56547619 -17.2,0,288,.,.,.,.,.,0.583,1,.,.,.,.,.,.,.,31.61160714 -17.2,1,288,0,0,.,.,1,.,.,.,.,.,.,.,46,30,31.61160714 -17.2,1,289.25,0,100,.,.,1,.,.,.,.,.,.,.,.,.,31.61904762 -17.2,1,301.25,0,100,.,.,1,.,.,.,.,.,.,.,.,.,31.69047619 -17.2,1,310.25,0,0,.,.,1,.,.,.,.,.,.,.,46,33,31.74404762 -17.2,1,312.9,0,0,.,.,1,.,.,.,.,.,.,7,.,.,31.75982143 -17.2,1,320.5,0,100,.,.,1,.,.,.,.,.,.,.,.,.,31.80505952 -17.2,1,329.25,0,150,.,.,1,.,.,.,.,.,.,.,.,.,31.85714286 -17.2,0,335.6166667,.,.,.,.,.,1.48,1,.,.,.,.,.,.,.,31.89503968 -17.2,1,335.6166667,0,0,.,.,1,.,.,.,.,.,.,.,40,34,31.89503968 -17.2,1,339.0833333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,31.9156746 -17.2,1,349.25,0,150,.,.,1,.,.,.,.,.,.,.,.,.,31.97619048 -17.2,1,359.25,0,0,.,.,1,.,.,.,.,.,.,.,42,15,32.03571429 -17.2,1,361.25,0,150,.,.,1,.,.,.,.,.,.,.,.,.,32.04761905 -17.2,1,373.25,0,150,.,.,1,.,.,.,.,.,.,.,.,.,32.11904762 -17.2,1,383.25,0,0,.,.,1,.,.,.,.,.,.,.,50,13,32.17857143 -17.2,1,385.75,0,150,.,.,1,.,.,.,.,.,.,.,.,.,32.19345238 -17.2,1,397.25,0,150,.,.,1,.,.,.,.,.,.,.,.,.,32.26190476 -17.2,0,407.5,.,.,.,.,.,2.57,1,.,.,.,.,.,.,.,32.32291667 -17.2,1,407.5,0,0,.,.,1,.,.,.,.,.,.,.,81,32,32.32291667 -17.2,1,409.25,0,150,.,.,1,.,.,.,.,.,.,.,.,.,32.33333333 -17.2,1,421.25,0,150,.,.,1,.,.,.,.,.,.,.,.,.,32.4047619 -17.2,1,431.5,0,0,.,.,1,.,.,.,.,.,.,.,92,30,32.46577381 -17.2,1,433.25,0,150,.,.,1,.,.,.,.,.,.,.,.,.,32.47619048 -17.2,1,445.25,0,125,.,.,1,.,.,.,.,.,.,.,.,.,32.54761905 -17.2,0,455.5,.,.,.,.,.,3.06,1,.,.,.,.,.,.,.,32.60863095 -18.1,1,0,2,52.5,.,.,1,.,.,.,.,.,.,7.5,112,112,79.81547619 -18.1,1,13.5,2,52.5,.,.,1,.,.,.,.,.,.,.,.,.,79.89583333 -18.1,1,25,2,52.5,.,.,1,.,.,.,.,.,.,.,.,.,79.96428571 -18.1,0,36.58333333,.,.,.,.,.,4.28,1,.,.,.,.,.,.,.,80.03323413 -18.1,1,37.58333333,2,52.5,.,.,1,.,.,.,.,.,.,.,60,106,80.03918651 -18.1,1,49,2,52.5,.,.,1,.,.,.,.,.,.,.,.,.,80.10714286 -18.1,1,61,2,52.5,.,.,1,.,.,.,.,.,.,.,.,.,80.17857143 -18.1,0,72,.,.,.,.,.,6.52,1,.,.,.,.,.,.,.,80.24404762 -18.2,1,0,2,52.5,.,.,1,.,.,.,.,.,.,7.5,60,106,80.2514881 -18.2,1,11.25,2,52.5,.,.,1,.,.,.,.,.,.,.,.,.,80.31845238 -18.2,1,23.75,2,52.5,.,.,1,.,.,.,.,.,.,.,.,.,80.39285714 -18.2,1,35.5833333,2,52.5,.,.,1,.,.,.,.,.,.,.,.,.,80.46329365 -18.2,1,47.75,2,52.5,.,.,1,.,.,.,.,.,.,.,.,.,80.53571429 -18.2,1,59.75,0,0,.,.,1,.,.,.,.,.,.,.,66,63,80.60714286 -18.2,1,59.75,2,52.5,.,.,1,.,.,.,.,.,.,.,.,.,80.60714286 -18.2,1,71.75,2,52.5,.,.,1,.,.,.,.,.,.,.,.,.,80.67857143 -18.2,1,83.75,2,52.5,.,.,1,.,.,.,.,.,.,.,.,.,80.75 -18.2,1,96.25,2,45,.,.,1,.,.,.,.,.,.,.,.,.,80.82440476 -18.2,0,107.25,.,.,.,.,.,2.74,1,.,.,.,.,.,.,.,80.88988095 -18.2,1,107.75,2,45,.,.,1,.,.,.,.,.,.,.,.,.,80.89285714 -18.2,1,119.75,2,45,.,.,1,.,.,.,.,.,.,.,.,.,80.96428571 -18.2,1,131.25,0,0,.,.,1,.,.,.,.,.,.,.,76,73,81.0327381 -18.2,1,131.75,2,45,.,.,1,.,.,.,.,.,.,.,.,.,81.03571429 -18.2,1,144.25,2,45,.,.,1,.,.,.,.,.,.,.,.,.,81.11011905 -18.2,0,155.4166667,.,.,.,.,.,1.33,1,.,.,.,.,.,.,.,81.1765873 -18.2,1,155.4166667,0,0,.,.,1,.,.,.,.,.,.,.,154,87,81.1765873 -18.2,1,156.25,2,45,.,.,1,.,.,.,.,.,.,.,.,.,81.18154762 -18.2,1,167.75,2,45,.,.,1,.,.,.,.,.,.,.,.,.,81.25 -18.2,1,180,2,45,.,.,1,.,.,.,.,.,.,.,.,.,81.32291667 -18.2,1,180.4166667,0,0,.,.,1,.,.,.,.,.,.,.,138,84,81.32539683 -18.2,1,191.75,2,45,.,.,1,.,.,.,.,.,.,.,.,.,81.39285714 -18.2,1,203.5,0,0,.,.,1,.,.,.,.,.,.,.,116,91,81.46279762 -18.2,1,203.75,2,45,.,.,1,.,.,.,.,.,.,.,.,.,81.46428571 -18.2,1,215.75,0,0,.,.,1,.,.,.,.,.,.,7.5,.,.,81.53571429 -18.2,1,215.75,2,45,.,.,1,.,.,.,.,.,.,.,.,.,81.53571429 -18.2,1,227.5,0,0,.,.,1,.,.,.,.,.,.,.,83,86,81.60565476 -18.2,1,227.75,2,45,.,.,1,.,.,.,.,.,.,.,.,.,81.60714286 -18.2,1,239.75,2,45,.,.,1,.,.,.,.,.,.,.,.,.,81.67857143 -18.2,1,251.75,2,45,.,.,1,.,.,.,.,.,.,.,.,.,81.75 -18.2,1,263.75,2,45,.,.,1,.,.,.,.,.,.,.,.,.,81.82142857 -18.2,1,275.75,2,45,.,.,1,.,.,.,.,.,.,.,.,.,81.89285714 -18.2,1,287.75,2,45,.,.,1,.,.,.,.,.,.,.,.,.,81.96428571 -18.2,1,300,2,45,.,.,1,.,.,.,.,.,.,.,.,.,82.03720238 -18.2,1,311.9,2,45,.,.,1,.,.,.,.,.,.,.,.,.,82.10803571 -18.2,0,323.0833333,.,.,.,.,.,2.33,1,.,.,.,.,.,.,.,82.17460317 -18.3,1,0,0,0,.,.,1,.,.,.,.,.,.,7.5,63,55,82.61259921 -18.3,1,11.08333333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,82.67857143 -18.3,1,11.83333333,0,0,.,.,1,.,.,.,.,.,.,7.5,.,.,82.68303571 -18.3,1,23.08333333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,82.75 -18.3,1,37.08333333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,82.83333333 -18.3,1,49.08333333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,82.9047619 -18.3,1,61.08333333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,82.97619048 -18.3,1,73.08333333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,83.04761905 -18.3,1,85.08333333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,83.11904762 -18.3,1,98.08333333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,83.19642857 -18.3,1,109.5833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,83.26488095 -18.3,1,121.5833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,83.33630952 -18.3,1,133.0833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,83.4047619 -18.3,1,146.3333333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,83.48363095 -18.3,1,159.0833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,83.55952381 -18.3,1,167.3333333,0,0,.,.,1,.,.,.,.,.,.,.,55,69,83.60863095 -18.3,1,171.0833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,83.63095238 -18.3,1,183.0833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,83.70238095 -18.3,1,196.0833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,83.7797619 -18.3,1,211.0833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,83.86904762 -18.3,1,223.5833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,83.94345238 -18.3,1,235.8333333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,84.01636905 -18.3,1,247.5833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,84.08630952 -18.3,1,260.0833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,84.16071429 -18.3,1,271.5833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,84.22916667 -18.3,1,283.5833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,84.30059524 -18.3,1,295.8333333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,84.3735119 -18.3,1,307.5833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,84.44345238 -18.3,1,316.8666667,0,0,.,.,1,.,.,.,.,.,.,7.5,.,.,84.49871032 -18.3,1,319.8333333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,84.51636905 -18.3,1,331.5833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,84.58630952 -18.3,1,333.5833333,0,0,.,.,1,.,.,.,.,.,.,.,124,78,84.59821429 -18.3,1,334.1833333,0,0,.,.,1,.,.,.,.,.,.,7.5,.,.,84.60178571 -18.3,0,343.75,.,.,.,.,.,4.37,1,.,.,.,.,.,.,.,84.65873016 -18.3,1,343.8333333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,84.65922619 -18.3,1,355.5833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,84.72916667 -18.3,1,358.8333333,0,0,.,.,1,.,.,.,.,.,.,.,81,83,84.7485119 -18.3,1,367.5833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,84.80059524 -18.3,1,376.7833333,0,0,.,.,1,.,.,.,.,.,.,7.5,.,.,84.85535714 -18.3,1,379.5833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,84.87202381 -18.3,1,391.5833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,84.94345238 -18.3,1,403.5833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,85.01488095 -18.3,1,415.5833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,85.08630952 -18.3,1,427.5833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,85.1577381 -18.3,1,439.5833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,85.22916667 -18.3,1,451.5833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,85.30059524 -18.3,1,463.5833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,85.37202381 -18.3,1,475.0833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,85.44047619 -18.3,1,487.0833333,2,45,.,.,1,.,.,.,.,.,.,.,.,.,85.51190476 -18.3,0,498.0833333,.,.,.,.,.,4.92,1,.,.,.,.,.,.,.,85.57738095 -18.3,1,498.0833333,0,0,.,.,1,.,.,.,.,.,.,.,71,55,85.57738095 -18.3,1,499.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,85.58333333 -18.3,1,511.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,85.6547619 -18.3,1,523.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,85.72619048 -18.3,1,535.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,85.79761905 -18.3,1,547.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,85.86904762 -18.3,1,552.8,0,0,.,.,1,.,.,.,.,.,.,7.5,.,.,85.9030754 -18.3,1,560.8333333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,85.95089286 -18.3,1,573.5833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,86.02678571 -18.3,1,585.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,86.0952381 -18.3,1,597.5833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,86.16964286 -18.3,1,609.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,86.23809524 -18.3,1,621.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,86.30952381 -18.3,1,633.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,86.38095238 -18.3,1,645.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,86.45238095 -18.3,1,657.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,86.52380952 -18.3,1,669.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,86.5952381 -18.3,1,670.1666667,0,0,.,.,1,.,.,.,.,.,.,.,52,47,86.60168651 -18.3,1,681.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,86.66666667 -18.3,1,693.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,86.73809524 -18.3,1,705.5833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,86.8125 -18.3,1,717.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,86.88095238 -18.3,1,729.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,86.95238095 -18.3,1,741.75,0,50,.,.,1,.,.,.,.,.,.,.,.,.,87.02777778 -18.3,1,754.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,87.10119048 -18.3,1,766.3333333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,87.17410714 -18.3,1,778.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,87.24404762 -18.3,1,790.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,87.31547619 -18.3,1,802.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,87.38690476 -18.3,1,814.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,87.45833333 -18.3,1,826.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,87.5297619 -18.3,1,837.8333333,0,0,.,.,1,.,.,.,.,.,.,.,65,41,87.59970238 -18.3,1,838.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,87.60119048 -18.3,1,850.0833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,87.67261905 -18.3,1,866.5833333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,87.77083333 -18.3,0,877.95,.,.,.,.,.,4.14,1,.,.,.,.,.,.,.,87.83849206 -18.4,1,0,0,40,9,12,1,.,.,.,.,.,.,7.6,65,41,93.83333333 -18.4,0,119.5,.,.,.,.,.,2.02,1,.,.,.,.,.,.,.,94.04464286 -18.5,1,0,0,40,.,.,1,.,.,.,.,.,.,7.6,70,38,97.05357143 -18.5,1,11,0,40,.,.,1,.,.,.,.,.,.,.,.,.,97.11904762 -18.5,1,23,0,40,.,.,1,.,.,.,.,.,.,.,.,.,97.19047619 -18.5,1,35,0,40,.,.,1,.,.,.,.,.,.,.,.,.,97.26190476 -18.5,1,48,0,40,.,.,1,.,.,.,.,.,.,.,.,.,97.33928571 -18.5,1,99.55,0,0,.,.,1,.,.,.,.,.,.,.,78,45,97.64613095 -18.5,1,102.7,0,0,.,.,1,.,.,.,.,.,.,7.7,.,.,97.66488095 -18.5,1,107,0,40,.,.,1,.,.,.,.,.,.,.,.,.,97.69047619 -18.5,1,119,0,40,.,.,1,.,.,.,.,.,.,.,.,.,97.76190476 -18.5,1,131,0,40,.,.,1,.,.,.,.,.,.,.,.,.,97.83333333 -18.5,1,144.416667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,97.91319444 -18.5,1,155,0,40,.,.,1,.,.,.,.,.,.,.,.,.,97.97619048 -18.5,1,168.833334,0,40,.,.,1,.,.,.,.,.,.,.,.,.,98.05853175 -18.5,1,179,0,40,.,.,1,.,.,.,.,.,.,.,.,.,98.11904762 -18.5,1,191,0,40,.,.,1,.,.,.,.,.,.,.,.,.,98.19047619 -18.5,1,203,0,40,.,.,1,.,.,.,.,.,.,.,.,.,98.26190476 -18.5,1,221,0,40,.,.,1,.,.,.,.,.,.,.,.,.,98.36904762 -18.5,1,227,0,40,.,.,1,.,.,.,.,.,.,.,.,.,98.4047619 -18.5,1,239,0,40,.,.,1,.,.,.,.,.,.,.,.,.,98.47619048 -18.5,1,251,0,40,.,.,1,.,.,.,.,.,.,.,.,.,98.54761905 -18.5,1,263.166667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,98.62003968 -18.5,1,275,0,40,.,.,1,.,.,.,.,.,.,.,.,.,98.69047619 -18.5,1,287.75,0,40,.,.,1,.,.,.,.,.,.,.,.,.,98.76636905 -18.5,1,289.516667,0,0,.,.,1,.,.,.,.,.,.,7.7,.,.,98.77688492 -18.5,0,300.333334,.,.,.,.,.,2.03,1,.,.,.,.,.,.,.,98.84126984 -18.5,1,300.416667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,98.84176587 -18.5,1,311,0,40,.,.,1,.,.,.,.,.,.,.,.,.,98.9047619 -18.5,1,323,0,40,.,.,1,.,.,.,.,.,.,.,.,.,98.97619048 -18.5,1,338.5,0,40,.,.,1,.,.,.,.,.,.,.,.,.,99.06845238 -18.5,1,347,0,40,.,.,1,.,.,.,.,.,.,.,.,.,99.11904762 -18.5,1,363,0,40,.,.,1,.,.,.,.,.,.,.,.,.,99.21428571 -18.5,1,371,0,40,.,.,1,.,.,.,.,.,.,.,.,.,99.26190476 -18.5,1,381.166667,0,0,.,.,1,.,.,.,.,.,.,.,52,38,99.32242063 -18.5,1,383.666667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,99.33730159 -18.5,1,395,0,40,.,.,1,.,.,.,.,.,.,.,.,.,99.4047619 -18.5,1,408,0,40,.,.,1,.,.,.,.,.,.,.,.,.,99.48214286 -18.5,1,419,0,40,.,.,1,.,.,.,.,.,.,.,.,.,99.54761905 -18.5,1,432,0,40,.,.,1,.,.,.,.,.,.,.,.,.,99.625 -18.5,1,443,0,40,.,.,1,.,.,.,.,.,.,.,.,.,99.69047619 -18.5,1,457,0,40,.,.,1,.,.,.,.,.,.,.,.,.,99.77380952 -18.5,1,467,0,40,.,.,1,.,.,.,.,.,.,.,.,.,99.83333333 -18.5,1,480,0,40,.,.,1,.,.,.,.,.,.,.,.,.,99.91071429 -18.5,0,490.666667,.,.,.,.,.,1.54,1,.,.,.,.,.,.,.,99.97420635 -19.1,1,0,0,0,.,.,1,.,.,.,.,.,.,8.12,38,27,27.74255952 -19.1,1,5.033333333,0,0,.,.,1,.,.,.,.,.,.,8.12,.,.,27.77251984 -19.1,1,8.75,2,56,.,.,1,.,.,.,.,.,.,.,.,.,27.79464286 -19.1,1,9.616666667,0,0,.,.,1,.,.,.,.,.,.,8.12,.,.,27.79980159 -19.1,1,20.25,2,56,.,.,1,.,.,.,.,.,.,.,.,.,27.86309524 -19.1,1,25.25,0,0,.,.,1,.,.,.,.,.,.,.,49,44,27.89285714 -19.1,1,33.25,2,56,.,.,1,.,.,.,.,.,.,.,.,.,27.94047619 -19.1,1,44.25,2,56,.,.,1,.,.,.,.,.,.,.,.,.,28.00595238 -19.1,1,48.75,0,0,.,.,1,.,.,.,.,.,.,.,52,39,28.0327381 -19.1,1,55.75,2,56,.,.,1,.,.,.,.,.,.,.,.,.,28.07440476 -19.1,1,67.75,2,56,.,.,1,.,.,.,.,.,.,.,.,.,28.14583333 -19.1,1,72.75,0,0,.,.,1,.,.,.,.,.,.,.,48,39,28.17559524 -19.1,1,80.25,2,56,.,.,1,.,.,.,.,.,.,.,.,.,28.2202381 -19.1,1,93.5,2,56,.,.,1,.,.,.,.,.,.,.,.,.,28.29910714 -19.1,1,97.06666667,0,0,.,.,1,.,.,.,.,.,.,.,55,42,28.3203373 -19.1,1,104.25,2,56,.,.,1,.,.,.,.,.,.,.,.,.,28.36309524 -19.1,1,115.75,2,56,.,.,1,.,.,.,.,.,.,.,.,.,28.43154762 -19.1,0,120.7166667,.,.,.,.,.,1.84,1,.,.,.,.,.,.,.,28.46111111 -19.1,1,120.7166667,0,0,.,.,1,.,.,.,.,.,.,.,48,40,28.46111111 -19.1,0,127.75,.,.,.,.,.,0.29,1,.,.,.,.,.,.,.,28.50297619 -19.1,1,128.25,2,56,.,.,1,.,.,.,.,.,.,.,.,.,28.50595238 -19.1,1,140.25,2,75,.,.,1,.,.,.,.,.,.,.,.,.,28.57738095 -19.1,1,143.25,0,0,.,.,1,.,.,.,.,.,.,.,51,41,28.5952381 -19.1,1,152.25,2,75,.,.,1,.,.,.,.,.,.,.,.,.,28.64880952 -19.1,1,164.25,2,75,.,.,1,.,.,.,.,.,.,.,.,.,28.7202381 -19.1,1,167.5,0,0,.,.,1,.,.,.,.,.,.,.,46,45,28.73958333 -19.1,1,177.25,2,75,.,.,1,.,.,.,.,.,.,.,.,.,28.79761905 -19.1,1,187.75,2,75,.,.,1,.,.,.,.,.,.,.,.,.,28.86011905 -19.1,1,193.25,0,0,.,.,1,.,.,.,.,.,.,.,56,50,28.89285714 -19.1,1,199.75,2,75,.,.,1,.,.,.,.,.,.,.,.,.,28.93154762 -19.1,1,211.75,2,75,.,.,1,.,.,.,.,.,.,.,.,.,29.00297619 -19.1,0,216.25,.,.,.,.,.,1.04,1,.,.,.,.,.,.,.,29.0297619 -19.1,1,216.25,0,0,.,.,1,.,.,.,.,.,.,.,45,37,29.0297619 -19.1,1,224.25,2,75,.,.,1,.,.,.,.,.,.,.,.,.,29.07738095 -19.1,1,236.25,2,75,.,.,1,.,.,.,.,.,.,.,.,.,29.14880952 -19.1,1,239.7666667,0,0,.,.,1,.,.,.,.,.,.,.,40,32,29.16974206 -19.1,1,248.25,2,75,.,.,1,.,.,.,.,.,.,.,.,.,29.2202381 -19.1,1,260.25,2,75,.,.,1,.,.,.,.,.,.,.,.,.,29.29166667 -19.1,1,265.25,0,0,.,.,1,.,.,.,.,.,.,.,45,33,29.32142857 -19.1,1,272.75,2,75,.,.,1,.,.,.,.,.,.,.,.,.,29.36607143 -19.1,1,284.75,2,75,.,.,1,.,.,.,.,.,.,.,.,.,29.4375 -19.1,0,288.75,.,.,.,.,.,2.33,1,.,.,.,.,.,.,.,29.46130952 -19.1,1,288.75,0,0,.,.,1,.,.,.,.,.,.,.,43,34,29.46130952 -19.1,1,295.75,2,75,.,.,1,.,.,.,.,.,.,.,.,.,29.50297619 -19.1,1,307.75,2,75,.,.,1,.,.,.,.,.,.,.,.,.,29.57440476 -19.1,1,313.25,0,0,.,.,1,.,.,.,.,.,.,.,42,32,29.60714286 -19.1,1,320.25,2,75,.,.,1,.,.,.,.,.,.,.,.,.,29.64880952 -19.1,1,332.75,2,75,.,.,1,.,.,.,.,.,.,.,.,.,29.72321429 -19.1,0,336.25,.,.,.,.,.,2.35,1,.,.,.,.,.,.,.,29.74404762 -19.2,1,0,0,0,.,.,1,.,.,.,.,.,.,8.36,80,17,29.74404762 -19.2,1,8,2,75,.,.,1,.,.,.,.,.,.,.,.,.,29.79166667 -19.2,1,19.5,2,75,.,.,1,.,.,.,.,.,.,.,.,.,29.86011905 -19.2,1,24.5,0,0,.,.,1,.,.,.,.,.,.,.,57,32,29.88988095 -19.2,1,32,2,75,.,.,1,.,.,.,.,.,.,.,.,.,29.93452381 -19.2,1,43.75,2,75,.,.,1,.,.,.,.,.,.,.,.,.,30.00446429 -19.2,1,48.25,0,0,.,.,1,.,.,.,.,.,.,.,49,30,30.03125 -19.2,1,55.5,2,75,.,.,1,.,.,.,.,.,.,.,.,.,30.07440476 -19.2,1,67.75,2,75,.,.,1,.,.,.,.,.,.,.,.,.,30.14732143 -19.2,1,72.25,0,0,.,.,1,.,.,.,.,.,.,.,70,14,30.17410714 -19.2,1,81.5,2,75,.,.,1,.,.,.,.,.,.,.,.,.,30.22916667 -19.2,1,87,0,0,.,.,1,.,.,.,.,.,.,8.36,.,.,30.26190476 -19.2,1,95,2,75,.,.,1,.,.,.,.,.,.,.,.,.,30.30952381 -19.2,1,97.5,0,0,.,.,1,.,.,.,.,.,.,.,39,33,30.32440476 -19.2,1,108,2,75,.,.,1,.,.,.,.,.,.,.,.,.,30.38690476 -19.2,0,120.25,.,.,.,.,.,0.217,1,.,.,.,.,.,.,.,30.45982143 -19.2,1,120.25,0,0,.,.,1,.,.,.,.,.,.,.,44,39,30.45982143 -19.2,1,120.5,2,75,.,.,1,.,.,.,.,.,.,.,.,.,30.46130952 -19.2,1,133.5,2,100,.,.,1,.,.,.,.,.,.,.,.,.,30.53869048 -19.2,1,144,0,0,.,.,1,.,.,.,.,.,.,.,51,39,30.60119048 -19.2,1,145,2,100,.,.,1,.,.,.,.,.,.,.,.,.,30.60714286 -19.2,1,157,2,100,.,.,1,.,.,.,.,.,.,.,.,.,30.67857143 -19.2,0,169,.,.,.,.,.,0.418,1,.,.,.,.,.,.,.,30.75 -19.2,1,169,0,0,.,.,1,.,.,.,.,.,.,.,35,39,30.75 -19.2,1,169,2,100,.,.,1,.,.,.,.,.,.,.,.,.,30.75 -19.2,1,183,2,125,.,.,1,.,.,.,.,.,.,.,.,.,30.83333333 -19.2,1,192.5,0,0,.,.,1,.,.,.,.,.,.,.,74,33,30.88988095 -19.2,1,195.5,2,125,.,.,1,.,.,.,.,.,.,.,.,.,30.9077381 -19.2,1,207,2,125,.,.,1,.,.,.,.,.,.,.,.,.,30.97619048 -19.2,1,214.4666667,0,0,.,.,1,.,.,.,.,.,.,.,34,38,31.02063492 -19.2,0,219,.,.,.,.,.,0.855,1,.,.,.,.,.,.,.,31.04761905 -19.2,1,219,2,125,.,.,1,.,.,.,.,.,.,.,.,.,31.04761905 -19.2,1,231,2,150,.,.,1,.,.,.,.,.,.,.,.,.,31.11904762 -19.2,1,238.3333333,0,0,.,.,1,.,.,.,.,.,.,.,35,36,31.16269841 -19.2,1,253,2,150,.,.,1,.,.,.,.,.,.,.,.,.,31.25 -19.2,1,255.4333333,0,0,.,.,1,.,.,.,.,.,.,8.36,.,.,31.26448413 -19.2,1,261,0,0,.,.,1,.,.,.,.,.,.,.,25,29,31.29761905 -19.2,1,266,2,150,.,.,1,.,.,.,.,.,.,.,.,.,31.32738095 -19.2,1,276,0,0,.,.,1,.,.,.,.,.,.,.,26,27,31.38690476 -19.2,1,277.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,31.39583333 -19.2,0,284.5833333,.,.,.,.,.,2.17,1,.,.,.,.,.,.,.,31.43799603 -19.2,1,284.5833333,0,0,.,.,1,.,.,.,.,.,.,.,33,27,31.43799603 -19.2,1,289,2,150,.,.,1,.,.,.,.,.,.,.,.,.,31.46428571 -19.2,1,302.25,2,150,.,.,1,.,.,.,.,.,.,.,.,.,31.54315476 -19.2,1,311.8333333,0,0,.,.,1,.,.,.,.,.,.,.,25,22,31.60019841 -19.2,1,312.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,31.60416667 -19.2,1,324.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,31.67559524 -19.2,1,337,2,150,.,.,1,.,.,.,.,.,.,.,.,.,31.75 -19.2,1,337.25,0,0,.,.,1,.,.,.,.,.,.,.,22,25,31.7514881 -19.2,1,344.0166667,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,31.79176587 -19.2,1,345,0,0,.,.,1,.,.,.,.,.,.,.,35,22,31.79761905 -19.2,1,349,2,150,.,.,1,.,.,.,.,.,.,.,.,.,31.82142857 -19.2,1,361,0,0,.,.,1,.,.,.,.,.,.,.,45,22,31.89285714 -19.2,1,361,2,150,.,.,1,.,.,.,.,.,.,.,.,.,31.89285714 -19.2,1,373,2,150,.,.,1,.,.,.,.,.,.,.,.,.,31.96428571 -19.2,1,384.75,0,0,.,.,1,.,.,.,.,.,.,.,60,21,32.03422619 -19.2,1,385,2,150,.,.,1,.,.,.,.,.,.,.,.,.,32.03571429 -19.2,1,397,2,150,.,.,1,.,.,.,.,.,.,.,.,.,32.10714286 -19.2,1,408.6666667,0,0,.,.,1,.,.,.,.,.,.,.,74,26,32.1765873 -19.2,1,409,2,150,.,.,1,.,.,.,.,.,.,.,.,.,32.17857143 -19.2,1,421.3333333,2,150,.,.,1,.,.,.,.,.,.,.,.,.,32.25198413 -19.2,1,432.5,0,0,.,.,1,.,.,.,.,.,.,.,97,26,32.31845238 -19.2,1,433.25,2,150,.,.,1,.,.,.,.,.,.,.,.,.,32.32291667 -19.2,1,445,2,150,.,.,1,.,.,.,.,.,.,.,.,.,32.39285714 -19.2,0,456.5,.,.,.,.,.,1.28,1,.,.,.,.,.,.,.,32.46130952 -19.3,1,0,2,150,.,.,1,.,.,.,.,.,.,9.09,89,21,32.46428571 -19.3,1,14.8333333,2,150,.,.,1,.,.,.,.,.,.,.,.,.,32.55257937 -19.3,1,26,2,175,.,.,1,.,.,.,.,.,.,.,81,22,32.61904762 -19.3,1,37,2,175,.,.,1,.,.,.,.,.,.,.,.,.,32.68452381 -19.3,0,47.8333333,.,.,.,.,.,0.995,1,.,.,.,.,.,.,.,32.74900794 -19.3,1,48,2,175,.,.,1,.,.,.,.,.,.,.,94,25,32.75 -19.3,1,60,2,175,.,.,1,.,.,.,.,.,.,.,.,.,32.82142857 -19.3,0,71.8333333,.,.,.,.,.,0.766,1,.,.,.,.,.,.,.,32.89186508 -19.3,1,72,2,200,.,.,1,.,.,.,.,.,.,.,84,28,32.89285714 -19.3,1,84,2,200,.,.,1,.,.,.,.,.,.,.,.,.,32.96428571 -19.3,1,96,2,200,.,.,1,.,.,.,.,.,.,.,69,26,33.03571429 -19.3,1,108,2,200,.,.,1,.,.,.,.,.,.,.,.,.,33.10714286 -19.3,1,120,2,200,.,.,1,.,.,.,.,.,.,.,95,23,33.17857143 -19.3,1,132,2,200,.,.,1,.,.,.,.,.,.,.,.,.,33.25 -19.3,1,144,2,200,.,.,1,.,.,.,.,.,.,.,59,24,33.32142857 -19.3,1,156,2,200,.,.,1,.,.,.,.,.,.,.,.,.,33.39285714 -19.3,0,168.25,.,.,.,.,.,0.746,1,.,.,.,.,.,.,.,33.46577381 -19.3,1,168.5,2,200,.,.,1,.,.,.,.,.,.,9.09,55,19,33.4672619 -19.3,1,180,2,225,.,.,1,.,.,.,.,.,.,.,.,.,33.53571429 -19.3,1,192,2,225,.,.,1,.,.,.,.,.,.,.,60,13,33.60714286 -19.3,1,204,2,225,.,.,1,.,.,.,.,.,.,.,57,15,33.67857143 -19.3,1,216,2,225,.,.,1,.,.,.,.,.,.,.,49,16,33.75 -19.3,1,228,2,225,.,.,1,.,.,.,.,.,.,.,.,.,33.82142857 -19.3,0,239.5,.,.,.,.,.,0.952,1,.,.,.,.,.,.,.,33.88988095 -19.4,1,0,0,0,.,.,1,.,.,.,.,.,.,9.09,53,13,33.88988095 -19.4,1,0.25,2,225,.,.,1,.,.,.,.,.,.,.,.,.,33.89136905 -19.4,1,12.5,2,225,.,.,1,.,.,.,.,.,.,.,.,.,33.96428571 -19.4,1,22.66666667,0,0,.,.,1,.,.,.,.,.,.,.,62,11,34.02480159 -19.4,1,24.5,2,225,.,.,1,.,.,.,.,.,.,.,.,.,34.03571429 -19.4,1,36.5,2,225,.,.,1,.,.,.,.,.,.,.,.,.,34.10714286 -19.4,1,46.5,0,0,.,.,1,.,.,.,.,.,.,.,33,17,34.16666667 -19.4,1,48.5,2,225,.,.,1,.,.,.,.,.,.,.,.,.,34.17857143 -19.4,1,62.83333333,2,225,.,.,1,.,.,.,.,.,.,.,.,.,34.26388889 -19.4,1,72.83333333,0,0,.,.,1,.,.,.,.,.,.,.,42,14,34.3234127 -19.4,1,73,2,225,.,.,1,.,.,.,.,.,.,.,.,.,34.32440476 -19.4,1,84.5,2,225,.,.,1,.,.,.,.,.,.,.,.,.,34.39285714 -19.4,0,96.25,.,.,.,.,.,0.57,1,.,.,.,.,.,.,.,34.46279762 -19.4,1,96.25,0,0,.,.,1,.,.,.,.,.,.,.,70,14,34.46279762 -19.4,1,97.25,2,225,.,.,1,.,.,.,.,.,.,.,.,.,34.46875 -19.4,1,109,2,250,.,.,1,.,.,.,.,.,.,.,.,.,34.53869048 -19.4,1,118.8333333,0,0,.,.,1,.,.,.,.,.,.,.,37,13,34.59722222 -19.4,1,120,2,250,.,.,1,.,.,.,.,.,.,.,.,.,34.60416667 -19.4,1,132.5,2,250,.,.,1,.,.,.,.,.,.,.,.,.,34.67857143 -19.4,1,142.25,0,0,.,.,1,.,.,.,.,.,.,.,37,16,34.73660714 -19.4,1,144.5,2,250,.,.,1,.,.,.,.,.,.,.,.,.,34.75 -19.4,1,156.75,2,250,.,.,1,.,.,.,.,.,.,.,.,.,34.82291667 -19.4,0,166.9166667,.,.,.,.,.,1.61,1,.,.,.,.,.,.,.,34.88343254 -19.4,1,166.9166667,0,0,.,.,1,.,.,.,.,.,.,.,51,24,34.88343254 -19.4,1,168.5,2,250,.,.,1,.,.,.,.,.,.,.,.,.,34.89285714 -19.4,1,180.5,2,250,.,.,1,.,.,.,.,.,.,.,.,.,34.96428571 -19.4,1,192.25,0,0,.,.,1,.,.,.,.,.,.,.,47,24,35.03422619 -19.4,1,192.5,2,250,.,.,1,.,.,.,.,.,.,.,.,.,35.03571429 -19.4,1,204.5,2,250,.,.,1,.,.,.,.,.,.,.,.,.,35.10714286 -19.4,1,215.8,0,0,.,.,1,.,.,.,.,.,.,.,24,25,35.17440476 -19.4,1,216.5,2,250,.,.,1,.,.,.,.,.,.,.,.,.,35.17857143 -19.4,1,229.5,2,250,.,.,1,.,.,.,.,.,.,.,.,.,35.25595238 -19.4,1,238,0,0,.,.,1,.,.,.,.,.,.,.,28,16,35.30654762 -19.4,1,240.5,2,250,.,.,1,.,.,.,.,.,.,.,.,.,35.32142857 -19.4,1,252.5,2,250,.,.,1,.,.,.,.,.,.,.,.,.,35.39285714 -19.4,0,264,.,.,.,.,.,1.28,1,.,.,.,.,.,.,.,35.46130952 -19.4,1,264,0,0,.,.,1,.,.,.,.,.,.,.,34,19,35.46130952 -19.4,1,264.25,2,250,.,.,1,.,.,.,.,.,.,.,.,.,35.46279762 -19.4,1,277.25,2,275,.,.,1,.,.,.,.,.,.,.,.,.,35.54017857 -19.4,1,287,0,0,.,.,1,.,.,.,.,.,.,.,33,19,35.59821429 -19.4,1,289.75,2,275,.,.,1,.,.,.,.,.,.,.,.,.,35.61458333 -19.4,1,292.5,0,0,.,.,1,.,.,.,.,.,.,.,31,29,35.63095238 -19.4,1,294.5,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,35.64285714 -19.4,1,300.6833333,0,0,.,.,1,.,.,.,.,.,.,.,40,23,35.6796627 -19.4,1,302.5,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,35.69047619 -19.4,1,303.6666667,2,275,.,.,1,.,.,.,.,.,.,.,.,.,35.69742063 -19.4,0,312.3333333,.,.,.,.,.,4.35,1,.,.,.,.,.,.,.,35.74900794 -19.4,1,312.3333333,0,0,.,.,1,.,.,.,.,.,.,.,33,15,35.74900794 -19.4,1,314.6666667,2,275,.,.,1,.,.,.,.,.,.,.,.,.,35.76289683 -19.4,1,327.5,2,275,.,.,1,.,.,.,.,.,.,.,.,.,35.83928571 -19.4,0,335.5,.,.,.,.,.,7.79,1,.,.,.,.,.,.,.,35.88690476 -19.5,1,0,0,0,.,.,1,.,.,.,.,.,.,9.09,35,15,35.88690476 -19.5,1,3.5,2,275,.,.,1,.,.,.,.,.,.,.,.,.,35.9077381 -19.5,1,15.5,2,275,.,.,1,.,.,.,.,.,.,.,.,.,35.97916667 -19.5,1,24,0,0,.,.,1,.,.,.,.,.,.,.,29,14,36.0297619 -19.5,1,28,2,275,.,.,1,.,.,.,.,.,.,.,.,.,36.05357143 -19.5,1,39,2,30,.,.,1,.,.,.,.,.,.,.,.,.,36.11904762 -19.5,1,48.96666667,0,0,.,.,1,.,.,.,.,.,.,.,84,6,36.17837302 -19.5,1,49,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,36.17857143 -19.5,1,68,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,36.29166667 -19.5,1,71.5,0,0,.,.,1,.,.,.,.,.,.,.,19,14,36.3125 -19.5,1,75,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,36.33333333 -19.5,1,75.33333333,2,175,.,.,1,.,.,.,.,.,.,.,.,.,36.33531746 -19.5,1,87,2,175,.,.,1,.,.,.,.,.,.,.,.,.,36.4047619 -19.5,1,93,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,36.44047619 -19.5,0,95.5,.,.,.,.,.,0.582,1,.,.,.,.,.,.,.,36.45535714 -19.5,1,95.5,0,0,.,.,1,.,.,.,.,.,.,.,33,17,36.45535714 -19.5,1,99.5,2,175,.,.,1,.,.,.,.,.,.,.,.,.,36.47916667 -19.5,1,111,2,175,.,.,1,.,.,.,.,.,.,.,.,.,36.54761905 -19.5,1,117,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,36.58333333 -19.5,1,119,0,0,.,.,1,.,.,.,.,.,.,.,25,18,36.5952381 -19.5,1,123.5,2,175,.,.,1,.,.,.,.,.,.,.,.,.,36.62202381 -19.5,1,135,2,175,.,.,1,.,.,.,.,.,.,.,.,.,36.69047619 -19.5,1,144.25,0,0,.,.,1,.,.,.,.,.,.,.,37,16,36.74553571 -19.5,1,147,2,175,.,.,1,.,.,.,.,.,.,.,.,.,36.76190476 -19.5,0,158.75,.,.,.,.,.,0.849,1,.,.,.,.,.,.,.,36.83184524 -19.5,1,168.25,0,0,.,.,1,.,.,.,.,.,.,.,55,6,36.88839286 -19.5,1,171,2,175,.,.,1,.,.,.,.,.,.,.,.,.,36.9047619 -19.5,1,183,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,36.97619048 -19.5,1,183,2,175,.,.,1,.,.,.,.,.,.,.,.,.,36.97619048 -19.5,1,192.75,0,0,.,.,1,.,.,.,.,.,.,.,28,15,37.03422619 -19.5,1,195,2,175,.,.,1,.,.,.,.,.,.,.,.,.,37.04761905 -19.5,1,207,2,200,.,.,1,.,.,.,.,.,.,.,.,.,37.11904762 -19.5,1,216.5,0,0,.,.,1,.,.,.,.,.,.,.,16,25,37.17559524 -19.5,1,219,2,200,.,.,1,.,.,.,.,.,.,.,.,.,37.19047619 -19.5,1,231.0833333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,37.26240079 -19.5,1,239,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,37.30952381 -19.5,1,239.4166667,0,0,.,.,1,.,.,.,.,.,.,.,16,25,37.31200397 -19.5,1,243,2,200,.,.,1,.,.,.,.,.,.,.,.,.,37.33333333 -19.5,1,245,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,37.3452381 -19.5,1,255.1333333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,37.40555556 -19.5,0,263.5833333,.,.,.,.,.,1.54,1,.,.,.,.,.,.,.,37.45585317 -19.5,1,263.5833333,0,0,.,.,1,.,.,.,.,.,.,.,33,19,37.45585317 -19.5,1,267,2,200,.,.,1,.,.,.,.,.,.,.,.,.,37.47619048 -19.5,1,278.5833333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,37.54513889 -19.5,1,288.15,0,0,.,.,1,.,.,.,.,.,.,.,21,23,37.60208333 -19.5,1,291.3333333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,37.62103175 -19.5,1,302.75,2,200,.,.,1,.,.,.,.,.,.,.,.,.,37.6889881 -19.5,1,303,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,37.69047619 -19.5,1,312.5,0,0,.,.,1,.,.,.,.,.,.,.,33,27,37.74702381 -19.5,1,315,2,200,.,.,1,.,.,.,.,.,.,.,.,.,37.76190476 -19.5,1,327,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,37.83333333 -19.5,1,327.3333333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,37.83531746 -19.5,1,336.5,0,0,.,.,1,.,.,.,.,.,.,.,31,23,37.88988095 -19.5,1,340,2,200,.,.,1,.,.,.,.,.,.,.,.,.,37.91071429 -19.5,1,351,2,200,.,.,1,.,.,.,.,.,.,.,.,.,37.97619048 -19.5,1,357,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,38.01190476 -19.5,1,359.6666667,0,0,.,.,1,.,.,.,.,.,.,.,28,22,38.02777778 -19.5,1,363.5,2,200,.,.,1,.,.,.,.,.,.,.,.,.,38.05059524 -19.5,1,375.5833333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,38.12251984 -19.5,1,383.8333333,0,0,.,.,1,.,.,.,.,.,.,.,27,17,38.17162698 -19.5,1,387,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,38.19047619 -19.5,1,387.75,2,200,.,.,1,.,.,.,.,.,.,.,.,.,38.19494048 -19.5,1,400,2,200,.,.,1,.,.,.,.,.,.,.,.,.,38.26785714 -19.5,1,407,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,38.30952381 -19.5,1,407.1666667,0,0,.,.,1,.,.,.,.,.,.,.,23,17,38.31051587 -19.5,1,415,2,200,.,.,1,.,.,.,.,.,.,.,.,.,38.35714286 -19.5,1,423,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,38.4047619 -19.5,1,428,2,200,.,.,1,.,.,.,.,.,.,.,.,.,38.43452381 -19.5,1,431.1666667,0,0,.,.,1,.,.,.,.,.,.,.,25,23,38.45337302 -19.5,1,433,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,38.46428571 -19.5,1,442,2,200,.,.,1,.,.,.,.,.,.,.,.,.,38.51785714 -19.5,1,447,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,38.54761905 -19.5,1,453.3333333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,38.58531746 -19.5,1,455.5,0,0,.,.,1,.,.,.,.,.,.,.,24,16,38.59821429 -19.5,1,457,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,38.60714286 -19.5,0,465,.,.,.,.,.,1.06,1,.,.,.,.,.,.,.,38.6547619 -19.6,1,0,2,200,.,.,1,.,.,.,.,.,.,9.09,24,16,38.65575397 -19.6,1,11.5,2,200,.,.,1,.,.,.,.,.,.,.,.,.,38.72420635 -19.6,1,14.9166666,0,0,.,.,1,.,.,.,.,.,.,.,17,17,38.74454365 -19.6,1,15.3333333,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,38.74702381 -19.6,1,24.0833333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,38.79910714 -19.6,1,36.1333333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,38.87083333 -19.6,1,38.3333333,0,0,.,.,1,.,.,.,.,.,.,.,16,12,38.88392857 -19.6,1,48.0833333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,38.94196429 -19.6,1,59.5,2,200,.,.,1,.,.,.,.,.,.,.,.,.,39.00992063 -19.6,1,62.1666666,0,0,.,.,1,.,.,.,.,.,.,.,15,15,39.02579365 -19.6,1,72.25,2,200,.,.,1,.,.,.,.,.,.,.,.,.,39.08581349 -19.6,1,83.5,2,200,.,.,1,.,.,.,.,.,.,.,.,.,39.15277778 -19.6,1,86,0,0,.,.,1,.,.,.,.,.,.,.,13,18,39.16765873 -19.6,1,96,2,200,.,.,1,.,.,.,.,.,.,.,.,.,39.22718254 -19.6,1,107.8333333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,39.29761905 -19.6,1,109.8333333,0,0,.,.,1,.,.,.,.,.,.,.,21,24,39.30952381 -19.6,1,120,2,200,.,.,1,.,.,.,.,.,.,.,.,.,39.37003968 -19.6,1,131.8333333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,39.44047619 -19.6,1,135.3333333,0,0,.,.,1,.,.,.,.,.,.,.,30,28,39.46130952 -19.6,1,135.8333333,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,39.46428571 -19.6,1,144.4166666,2,200,.,.,1,.,.,.,.,.,.,.,.,.,39.51537698 -19.6,1,149.8333333,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,39.54761905 -19.6,1,156.25,2,200,.,.,1,.,.,.,.,.,.,.,.,.,39.58581349 -19.6,1,159.1666666,0,0,.,.,1,.,.,.,.,.,.,.,23,22,39.6031746 -19.6,1,159.8333333,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,39.60714286 -19.6,1,168.0333333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,39.65595238 -19.6,1,173.8333333,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,39.69047619 -19.6,1,180.0833333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,39.72767857 -19.6,1,182.3333333,0,0,.,.,1,.,.,.,.,.,.,.,19,19,39.74107143 -19.6,1,183.8333333,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,39.75 -19.6,1,183.8333333,0,0,.,.,1,.,.,.,.,.,.,.,16,18,39.75 -19.6,1,185.8333333,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,39.76190476 -19.6,1,192.1833333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,39.79970238 -19.6,1,203.8333333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,39.86904762 -19.6,1,206.3333333,0,0,.,.,1,.,.,.,.,.,.,.,21,19,39.88392857 -19.6,1,216.3333333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,39.94345238 -19.6,1,227.8333333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,40.01190476 -19.6,1,229.8333333,0,0,.,.,1,.,.,.,.,.,.,.,19,18,40.02380952 -19.6,1,240.5833333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,40.08779762 -19.6,1,251.8333333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,40.1547619 -19.6,1,255,0,0,.,.,1,.,.,.,.,.,.,.,29,24,40.17361111 -19.6,1,263.8333333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,40.22619048 -19.6,1,264.65,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,40.23105159 -19.6,1,275.8333333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,40.29761905 -19.6,1,278.1666666,0,0,.,.,1,.,.,.,.,.,.,.,27,23,40.31150794 -19.6,1,288.3,2,200,.,.,1,.,.,.,.,.,.,.,.,.,40.3718254 -19.6,1,300.0833333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,40.44196429 -19.6,1,303.0833333,0,0,.,.,1,.,.,.,.,.,.,.,26,21,40.45982143 -19.6,1,309.7333333,0,0,.,.,1,.,.,.,.,.,.,9.09,.,.,40.49940476 -19.6,1,313.0833333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,40.51934524 -19.6,1,323.8333333,2,200,.,.,1,.,.,.,.,.,.,.,.,.,40.58333333 -19.6,1,327.5833333,0,0,.,.,1,.,.,.,.,.,.,.,24,18,40.60565476 -19.6,0,335.35,.,.,.,.,.,2.16,1,.,.,.,.,.,.,.,40.65188492 -19.7,1,0,2,200,.,.,1,.,.,.,.,.,.,10,59,23,44.01190476 -19.7,1,12,2,250,.,.,1,.,.,.,.,.,.,.,.,.,44.08333333 -19.7,1,18,0,0,.,.,1,.,.,.,.,.,.,10,.,.,44.11904762 -19.7,1,22,0,0,.,.,1,.,.,.,.,.,.,10,.,.,44.14285714 -19.7,1,24.666667,2,250,.,.,1,.,.,.,.,.,.,.,.,.,44.15873016 -19.7,1,27.583333,0,0,.,.,1,.,.,.,.,.,.,.,42,25,44.17609127 -19.7,1,36.75,2,250,.,.,1,.,.,.,.,.,.,.,.,.,44.23065476 -19.7,1,49.666667,2,250,.,.,1,.,.,.,.,.,.,.,.,.,44.30753968 -19.7,1,51.666667,0,0,.,.,1,.,.,.,.,.,.,.,75,34,44.31944444 -19.7,1,60,2,250,.,.,1,.,.,.,.,.,.,.,.,.,44.36904762 -19.7,1,72.5,2,250,.,.,1,.,.,.,.,.,.,.,.,.,44.44345238 -19.7,1,74,0,0,.,.,1,.,.,.,.,.,.,10,.,.,44.45238095 -19.7,1,76.25,0,0,.,.,1,.,.,.,.,.,.,.,46,34,44.46577381 -19.7,1,78.416667,0,0,.,.,1,.,.,.,.,.,.,10,.,.,44.47867063 -19.7,1,82,0,0,.,.,1,.,.,.,.,.,.,10,.,.,44.5 -19.7,1,83.5,2,250,.,.,1,.,.,.,.,.,.,.,.,.,44.50892857 -19.7,1,90,0,0,.,.,1,.,.,.,.,.,.,10,.,.,44.54761905 -19.7,1,95.666667,2,250,.,.,1,.,.,.,.,.,.,.,.,.,44.58134921 -19.7,1,98.416667,0,0,.,.,1,.,.,.,.,.,.,.,42,29,44.59771825 -19.7,1,100,0,0,.,.,1,.,.,.,.,.,.,10,.,.,44.60714286 -19.7,1,108,2,250,.,.,1,.,.,.,.,.,.,.,.,.,44.6547619 -19.7,1,120,2,250,.,.,1,.,.,.,.,.,.,.,.,.,44.72619048 -19.7,1,124.75,0,0,.,.,1,.,.,.,.,.,.,.,44,33,44.75446429 -19.7,1,126,0,0,.,.,1,.,.,.,.,.,.,10,.,.,44.76190476 -19.7,1,132,2,250,.,.,1,.,.,.,.,.,.,.,.,.,44.79761905 -19.7,1,138,0,0,.,.,1,.,.,.,.,.,.,10,.,.,44.83333333 -19.7,1,145,2,250,.,.,1,.,.,.,.,.,.,.,.,.,44.875 -19.7,0,148.166667,.,.,.,.,.,8.32,1,.,.,.,.,.,.,.,44.89384921 -19.7,1,148.166667,0,0,.,.,1,.,.,.,.,.,.,.,21,23,44.89384921 -19.7,1,150,0,0,.,.,1,.,.,.,.,.,.,10,.,.,44.9047619 -19.7,1,156.083333,2,250,.,.,1,.,.,.,.,.,.,.,.,.,44.94097222 -19.7,1,162,0,0,.,.,1,.,.,.,.,.,.,10,.,.,44.97619048 -19.7,1,168.5,2,250,.,.,1,.,.,.,.,.,.,.,.,.,45.01488095 -19.7,1,170,0,0,.,.,1,.,.,.,.,.,.,10,.,.,45.02380952 -19.7,1,171.333333,0,0,.,.,1,.,.,.,.,.,.,.,32,28,45.03174603 -19.7,1,180,2,250,.,.,1,.,.,.,.,.,.,.,.,.,45.08333333 -19.7,1,186,0,0,.,.,1,.,.,.,.,.,.,10,.,.,45.11904762 -19.7,1,190,0,0,.,.,1,.,.,.,.,.,.,10,.,.,45.14285714 -19.7,1,193.166667,2,250,.,.,1,.,.,.,.,.,.,.,.,.,45.16170635 -19.7,1,194,0,0,.,.,1,.,.,.,.,.,.,10,.,.,45.16666667 -19.7,1,195.883333,0,0,.,.,1,.,.,.,.,.,.,.,27,25,45.17787698 -19.7,1,204,2,250,.,.,1,.,.,.,.,.,.,.,.,.,45.22619048 -19.7,1,210,0,0,.,.,1,.,.,.,.,.,.,10,.,.,45.26190476 -19.7,1,214,0,0,.,.,1,.,.,.,.,.,.,10,.,.,45.28571429 -19.7,1,216,0,0,.,.,1,.,.,.,.,.,.,10,.,.,45.29761905 -19.7,1,216.5,2,250,.,.,1,.,.,.,.,.,.,.,.,.,45.30059524 -19.7,1,218.666667,0,0,.,.,1,.,.,.,.,.,.,.,27,24,45.31349206 -19.7,1,222,0,0,.,.,1,.,.,.,.,.,.,10,.,.,45.33333333 -19.7,1,226,0,0,.,.,1,.,.,.,.,.,.,10,.,.,45.35714286 -19.7,1,227.75,2,250,.,.,1,.,.,.,.,.,.,.,.,.,45.36755952 -19.7,1,241,2,250,.,.,1,.,.,.,.,.,.,.,.,.,45.44642857 -19.7,1,244,0,0,.,.,1,.,.,.,.,.,.,.,35,28,45.46428571 -19.7,0,250.333333,.,.,.,.,.,4.93,1,.,.,.,.,.,.,.,45.50198413 -19.7,1,253,2,250,.,.,1,.,.,.,.,.,.,.,.,.,45.51785714 -19.7,1,264.416667,2,250,.,.,1,.,.,.,.,.,.,.,.,.,45.58581349 -19.7,1,268.25,0,0,.,.,1,.,.,.,.,.,.,.,23,21,45.60863095 -19.7,1,270,0,0,.,.,1,.,.,.,.,.,.,10,.,.,45.61904762 -19.7,1,276.016667,2,250,.,.,1,.,.,.,.,.,.,.,.,.,45.65486111 -19.7,1,285.5,0,0,.,.,1,.,.,.,.,.,.,.,30,32,45.71130952 -19.7,1,286,0,0,.,.,1,.,.,.,.,.,.,10,.,.,45.71428571 -19.7,1,290,2,250,.,.,1,.,.,.,.,.,.,.,.,.,45.73809524 -19.7,1,291.983333,0,0,.,.,1,.,.,.,.,.,.,.,28,26,45.74990079 -19.7,1,303.666667,2,250,.,.,1,.,.,.,.,.,.,.,.,.,45.81944444 -19.7,1,306,0,0,.,.,1,.,.,.,.,.,.,10,.,.,45.83333333 -19.7,1,310,0,0,.,.,1,.,.,.,.,.,.,10,.,.,45.85714286 -19.7,1,315,2,250,.,.,1,.,.,.,.,.,.,.,.,.,45.88690476 -19.7,1,316.416667,0,0,.,.,1,.,.,.,.,.,.,.,33,34,45.8953373 -19.7,1,327,2,250,.,.,1,.,.,.,.,.,.,.,.,.,45.95833333 -19.7,1,330,0,0,.,.,1,.,.,.,.,.,.,10,.,.,45.97619048 -19.7,1,334,0,0,.,.,1,.,.,.,.,.,.,10,.,.,46 -19.7,1,337.5,2,250,.,.,1,.,.,.,.,.,.,.,.,.,46.02083333 -19.7,1,338,0,0,.,.,1,.,.,.,.,.,.,10,.,.,46.02380952 -19.7,0,340.5,.,.,.,.,.,13.3,1,.,.,.,.,.,.,.,46.03869048 -19.7,1,340.5,0,0,.,.,1,.,.,.,.,.,.,.,40,28,46.03869048 -19.7,1,350,2,250,.,.,1,.,.,.,.,.,.,.,.,.,46.0952381 -19.7,1,354,0,0,.,.,1,.,.,.,.,.,.,10,.,.,46.11904762 -19.7,1,362.5,2,250,.,.,1,.,.,.,.,.,.,.,.,.,46.16964286 -19.7,1,363,0,0,.,.,1,.,.,.,.,.,.,.,39,28,46.17261905 -19.7,1,364,0,0,.,.,1,.,.,.,.,.,.,10,.,.,46.17857143 -19.7,1,375.5,2,250,.,.,1,.,.,.,.,.,.,.,.,.,46.24702381 -19.7,1,378,0,0,.,.,1,.,.,.,.,.,.,10,.,.,46.26190476 -19.7,1,382,0,0,.,.,1,.,.,.,.,.,.,10,.,.,46.28571429 -19.7,1,386,2,250,.,.,1,.,.,.,.,.,.,.,.,.,46.30952381 -19.7,1,386.333333,0,0,.,.,1,.,.,.,.,.,.,.,48,30,46.31150794 -19.7,1,398.25,2,250,.,.,1,.,.,.,.,.,.,.,.,.,46.38244048 -19.7,1,410,2,250,.,.,1,.,.,.,.,.,.,.,.,.,46.45238095 -19.7,1,414,0,0,.,.,1,.,.,.,.,.,.,10,.,.,46.47619048 -19.7,1,422.5,2,250,.,.,1,.,.,.,.,.,.,.,.,.,46.52678571 -19.7,1,424,0,0,.,.,1,.,.,.,.,.,.,.,84,46,46.53571429 -19.7,1,435.5,2,250,.,.,1,.,.,.,.,.,.,.,.,.,46.60416667 -19.7,1,435.75,0,0,.,.,1,.,.,.,.,.,.,.,99,51,46.60565476 -19.7,1,446.5,2,250,.,.,1,.,.,.,.,.,.,.,.,.,46.66964286 -19.7,0,458,.,.,.,.,.,7.16,1,.,.,.,.,.,.,.,46.73809524 -19.7,1,458,0,0,.,.,1,.,.,.,.,.,.,.,63,47,46.73809524 -19.7,1,459,2,250,.,.,1,.,.,.,.,.,.,.,.,.,46.74404762 -19.7,1,470.5,2,200,.,.,1,.,.,.,.,.,.,.,.,.,46.8125 -19.7,1,474,0,0,.,.,1,.,.,.,.,.,.,10,.,.,46.83333333 -19.7,1,482.583333,0,0,.,.,1,.,.,.,.,.,.,.,44,38,46.8844246 -19.7,1,483,0,0,.,.,1,.,.,.,.,.,.,10,.,.,46.88690476 -19.7,1,499,2,150,.,.,1,.,.,.,.,.,.,.,.,.,46.98214286 -19.7,0,507,.,.,.,.,.,5.9,1,.,.,.,.,.,.,.,47.0297619 -19.7,1,507,0,0,.,.,1,.,.,.,.,.,.,.,33,32,47.0297619 -19.7,1,511.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,47.05654762 -19.7,1,523,2,150,.,.,1,.,.,.,.,.,.,.,.,.,47.125 -19.7,1,530.333333,0,0,.,.,1,.,.,.,.,.,.,.,32,29,47.16865079 -19.7,1,536,2,150,.,.,1,.,.,.,.,.,.,.,.,.,47.20238095 -19.7,1,546,0,0,.,.,1,.,.,.,.,.,.,10,.,.,47.26190476 -19.7,1,547,2,150,.,.,1,.,.,.,.,.,.,.,.,.,47.26785714 -19.7,1,554.733333,0,0,.,.,1,.,.,.,.,.,.,.,41,36,47.31388889 -19.7,1,559,2,150,.,.,1,.,.,.,.,.,.,.,.,.,47.33928571 -19.7,1,571,2,150,.,.,1,.,.,.,.,.,.,.,.,.,47.41071429 -19.7,0,580,.,.,.,.,.,7.58,1,.,.,.,.,.,.,.,47.46428571 -19.7,1,580,0,0,.,.,1,.,.,.,.,.,.,.,29,37,47.46428571 -19.7,0,585,.,.,.,.,.,5.23,1,.,.,.,.,.,.,.,47.49404762 -19.7,1,589.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,47.52083333 -19.7,0,604.5,.,.,.,.,.,5.44,1,.,.,.,.,.,.,.,47.61011905 -19.7,1,604.5,0,0,.,.,1,.,.,.,.,.,.,.,48,21,47.61011905 -19.7,1,612,2,100,.,.,1,.,.,.,.,.,.,.,.,.,47.6547619 -19.7,1,624,2,100,.,.,1,.,.,.,.,.,.,.,.,.,47.72619048 -19.7,1,628.25,0,0,.,.,1,.,.,.,.,.,.,.,170,49,47.7514881 -19.7,1,630,0,0,.,.,1,.,.,.,.,.,.,10,.,.,47.76190476 -19.7,0,635.5,.,.,.,.,.,5.41,1,.,.,.,.,.,.,.,47.79464286 -19.7,1,648,2,80,.,.,1,.,.,.,.,.,.,.,.,.,47.86904762 -19.7,1,651.166667,0,0,.,.,1,.,.,.,.,.,.,.,182,62,47.88789683 -19.7,0,675,.,.,.,.,.,0.464,1,.,.,.,.,.,.,.,48.0297619 -20.1,1,0,0,0,.,.,1,.,.,.,.,.,.,9.1,52,62,81.38551587 -20.1,1,3.733333333,0,65,.,.,1,.,.,.,.,.,.,.,.,.,81.4077381 -20.1,1,15.73333333,0,65,.,.,1,.,.,.,.,.,.,.,.,.,81.47916667 -20.1,1,27.23333333,0,65,.,.,1,.,.,.,.,.,.,.,.,.,81.54761905 -20.1,1,37.23333333,0,0,.,.,1,.,.,.,.,.,.,.,42,48,81.60714286 -20.1,1,39.48333333,0,65,.,.,1,.,.,.,.,.,.,.,.,.,81.62053571 -20.1,1,52.23333333,0,65,.,.,1,.,.,.,.,.,.,.,.,.,81.69642857 -20.1,1,63.23333333,0,65,.,.,1,.,.,.,.,.,.,.,.,.,81.76190476 -20.1,1,76.06666667,0,65,.,.,1,.,.,.,.,.,.,.,.,.,81.83829365 -20.1,1,89.23333333,0,65,.,.,1,.,.,.,.,.,.,.,.,.,81.91666667 -20.1,1,96.58333333,0,0,.,.,1,.,.,.,.,.,.,9.31,.,.,81.96041667 -20.1,1,99.23333333,0,65,.,.,1,.,.,.,.,.,.,.,.,.,81.97619048 -20.1,0,111.9833333,.,.,.,.,.,0.057,1,.,.,.,.,.,.,.,82.05208333 -20.1,1,111.9833333,0,0,.,.,1,.,.,.,.,.,.,.,50,49,82.05208333 -20.1,1,112.4833333,0,65,.,.,1,.,.,.,.,.,.,.,.,.,82.05505952 -20.1,1,123.2333333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,82.11904762 -20.1,1,135.2333333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,82.19047619 -20.1,1,148.2333333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,82.26785714 -20.1,1,159.7333333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,82.33630952 -20.1,1,165.7333333,0,0,.,.,1,.,.,.,.,.,.,.,56,49,82.37202381 -20.1,1,171.2333333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,82.4047619 -20.1,1,183.4833333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,82.47767857 -20.1,1,195.2333333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,82.54761905 -20.1,1,207.9833333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,82.6235119 -20.1,1,219.2333333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,82.69047619 -20.1,0,230.7333333,.,.,.,.,.,0.12,1,.,.,.,.,.,.,.,82.75892857 -20.1,1,230.7333333,0,0,.,.,1,.,.,.,.,.,.,.,56,44,82.75892857 -20.1,1,231.7333333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,82.76488095 -20.1,1,244.2333333,0,125,.,.,1,.,.,.,.,.,.,.,.,.,82.83928571 -20.1,1,257.2333333,0,125,.,.,1,.,.,.,.,.,.,.,.,.,82.91666667 -20.1,1,259.7333333,0,0,.,.,1,.,.,.,.,.,.,9.31,.,.,82.93154762 -20.1,1,267.7333333,0,125,.,.,1,.,.,.,.,.,.,.,.,.,82.97916667 -20.1,1,277.2333333,0,0,.,.,1,.,.,.,.,.,.,.,42,39,83.03571429 -20.1,1,279.9,0,125,.,.,1,.,.,.,.,.,.,.,.,.,83.0515873 -20.1,1,291.7333333,0,125,.,.,1,.,.,.,.,.,.,.,.,.,83.12202381 -20.1,1,304.2333333,0,125,.,.,1,.,.,.,.,.,.,.,.,.,83.19642857 -20.1,1,315.2333333,0,125,.,.,1,.,.,.,.,.,.,.,.,.,83.26190476 -20.1,0,326.15,.,.,.,.,.,0.245,1,.,.,.,.,.,.,.,83.32688492 -20.1,1,326.15,0,0,.,.,1,.,.,.,.,.,.,.,54,39,83.32688492 -20.1,1,328.15,0,125,.,.,1,.,.,.,.,.,.,.,.,.,83.33878968 -20.1,1,339.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,83.4047619 -20.1,1,353.7333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,83.49107143 -20.1,1,363.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,83.54761905 -20.1,1,375.4,0,150,.,.,1,.,.,.,.,.,.,.,.,.,83.62003968 -20.1,1,378.15,0,0,.,.,1,.,.,.,.,.,.,.,77,59,83.63640873 -20.1,1,387.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,83.69047619 -20.1,0,396.9833333,.,.,.,.,.,0.275,1,.,.,.,.,.,.,.,83.7485119 -20.1,1,400.7333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,83.77083333 -20.1,1,411.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,83.83333333 -20.1,1,424.7333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,83.91369048 -20.1,1,431.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,83.95238095 -20.1,1,437.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,83.98809524 -20.1,1,444.4833333,0,0,.,.,1,.,.,.,.,.,.,.,50,41,84.03125 -20.1,1,448.65,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.05605159 -20.1,1,456.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.10119048 -20.1,1,460.9,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.12896825 -20.1,1,473.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.20238095 -20.1,1,479.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.23809524 -20.1,1,485.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.27380952 -20.1,1,489.2333333,0,0,.,.,1,.,.,.,.,.,.,.,90,74,84.29761905 -20.1,0,496.7333333,.,.,.,.,.,0.537,1,.,.,.,.,.,.,.,84.3422619 -20.1,1,497.5666667,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.34722222 -20.1,1,503.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.38095238 -20.1,1,509.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.41666667 -20.1,1,521.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.48809524 -20.1,1,528.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.5297619 -20.1,1,533.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.55952381 -20.1,1,545.7333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.63392857 -20.1,1,551.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.66666667 -20.1,1,557.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.70238095 -20.1,0,565.7333333,.,.,.,.,.,0.881,1,.,.,.,.,.,.,.,84.75297619 -20.1,1,565.7333333,0,0,.,.,1,.,.,.,.,.,.,.,50,43,84.75297619 -20.1,1,570.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.7797619 -20.1,1,575.7333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.8125 -20.1,1,581.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.8452381 -20.1,1,593.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.91666667 -20.1,1,599.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.95238095 -20.1,1,605.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,84.98809524 -20.1,1,615.65,0,0,.,.,1,.,.,.,.,.,.,.,65,50,85.05009921 -20.1,1,617.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,85.05952381 -20.1,1,623.2333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,85.0952381 -20.1,1,629.7333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,85.13392857 -20.1,1,641.7333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,85.20535714 -20.1,1,647.9833333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,85.24255952 -20.1,1,653.7333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,85.27678571 -20.1,0,661.9833333,.,.,.,.,.,1.17,1,.,.,.,.,.,.,.,85.32589286 -20.2,1,0,0,150,.,.,1,.,.,.,.,.,.,11,55,69,98.27529762 -20.2,1,7.75,0,0,.,.,1,.,.,.,.,.,.,.,48,60,98.32142857 -20.2,1,11.983334,0,150,.,.,1,.,.,.,.,.,.,.,.,.,98.34662698 -20.2,1,16.966667,0,150,.,.,1,.,.,.,.,.,.,.,.,.,98.37628968 -20.2,1,23.75,0,150,.,.,1,.,.,.,.,.,.,.,.,.,98.41666667 -20.2,1,31.75,0,0,.,.,1,.,.,.,.,.,.,.,44,49,98.46428571 -20.2,1,35.25,0,150,.,.,1,.,.,.,.,.,.,.,.,.,98.48511905 -20.2,1,39.75,0,150,.,.,1,.,.,.,.,.,.,.,.,.,98.51190476 -20.2,1,47.75,0,150,.,.,1,.,.,.,.,.,.,.,.,.,98.55952381 -20.2,1,55.25,0,0,.,.,1,.,.,.,.,.,.,.,34,40,98.60416667 -20.2,1,59.75,0,150,.,.,1,.,.,.,.,.,.,.,.,.,98.63095238 -20.2,1,63.75,0,150,.,.,1,.,.,.,.,.,.,.,.,.,98.6547619 -20.2,1,71.75,0,150,.,.,1,.,.,.,.,.,.,.,.,.,98.70238095 -20.2,1,78.833334,0,0,.,.,1,.,.,.,.,.,.,.,131,81,98.74454365 -20.2,1,83.75,0,150,.,.,1,.,.,.,.,.,.,.,.,.,98.77380952 -20.2,0,83.916667,.,.,.,.,.,3.34,1,.,.,.,.,.,.,.,98.77480159 -20.2,1,89.75,0,125,.,.,1,.,.,.,.,.,.,.,.,.,98.80952381 -20.2,1,95.75,0,125,.,.,1,.,.,.,.,.,.,.,.,.,98.8452381 -20.2,1,103.75,0,0,.,.,1,.,.,.,.,.,.,.,829,364,98.89285714 -20.2,1,108,0,125,.,.,1,.,.,.,.,.,.,.,.,.,98.91815476 -20.2,1,127.25,0,0,.,.,1,.,.,.,.,.,.,.,217,273,99.0327381 -20.2,0,131.583334,.,.,.,.,.,0.422,1,.,.,.,.,.,.,.,99.05853175 -21.1,1,0,0,0,.,.,1,.,.,.,.,.,.,7.2,31,24,41.1780754 -21.1,1,56.58333333,2,60,.,.,1,.,.,.,.,.,.,.,.,.,41.51488095 -21.1,1,69.08333333,2,60,.,.,1,.,.,.,.,.,.,.,.,.,41.58928571 -21.1,1,71.58333333,0,0,.,.,1,.,.,.,.,.,.,.,20,20,41.60416667 -21.1,1,81.08333333,2,60,.,.,1,.,.,.,.,.,.,.,.,.,41.66071429 -21.1,1,93.08333333,2,60,.,.,1,.,.,.,.,.,.,.,.,.,41.73214286 -21.1,0,105.0833333,.,.,.,.,.,0.593,1,.,.,.,.,.,.,.,41.80357143 -21.1,1,105.0833333,2,60,.,.,1,.,.,.,.,.,.,.,.,.,41.80357143 -21.1,1,117.25,2,60,.,.,1,.,.,.,.,.,.,.,.,.,41.87599206 -21.1,1,129.0833333,2,60,.,.,1,.,.,.,.,.,.,.,.,.,41.94642857 -21.1,1,141.0833333,2,60,.,.,1,.,.,.,.,.,.,.,.,.,42.01785714 -21.1,1,151.5833333,0,0,.,.,1,.,.,.,.,.,.,.,33,25,42.08035714 -21.1,1,153.0833333,2,60,.,.,1,.,.,.,.,.,.,.,.,.,42.08928571 -21.1,1,165.0833333,2,60,.,.,1,.,.,.,.,.,.,.,.,.,42.16071429 -21.1,1,177.0833333,2,60,.,.,1,.,.,.,.,.,.,.,.,.,42.23214286 -21.1,1,189.0833333,2,80,.,.,1,.,.,.,.,.,.,.,.,.,42.30357143 -21.1,1,191.5,0,0,.,.,1,.,.,.,.,.,.,.,24,27,42.31795635 -21.1,1,201.0833333,2,80,.,.,1,.,.,.,.,.,.,.,.,.,42.375 -21.1,1,213.0833333,2,80,.,.,1,.,.,.,.,.,.,.,.,.,42.44642857 -21.1,0,224.6666667,.,.,.,.,.,0.926,1,.,.,.,.,.,.,.,42.51537698 -21.1,1,225.0833333,2,80,.,.,1,.,.,.,.,.,.,.,.,.,42.51785714 -21.1,1,237.0833333,2,80,.,.,1,.,.,.,.,.,.,.,.,.,42.58928571 -21.1,1,239.0833333,0,0,.,.,1,.,.,.,.,.,.,.,19,15,42.60119048 -21.1,1,249.0833333,2,80,.,.,1,.,.,.,.,.,.,.,.,.,42.66071429 -21.1,1,262.3333333,2,80,.,.,1,.,.,.,.,.,.,.,.,.,42.73958333 -21.1,1,264.0833333,0,0,.,.,1,.,.,.,.,.,.,.,20,20,42.75 -21.1,1,273.25,2,90,.,.,1,.,.,.,.,.,.,.,.,.,42.80456349 -21.1,1,285.0833333,2,90,.,.,1,.,.,.,.,.,.,.,.,.,42.875 -21.1,1,288.0833333,0,0,.,.,1,.,.,.,.,.,.,.,18,16,42.89285714 -21.1,1,297.0833333,2,90,.,.,1,.,.,.,.,.,.,.,.,.,42.94642857 -21.1,1,309.4166667,2,90,.,.,1,.,.,.,.,.,.,.,.,.,43.01984127 -21.1,1,312.25,0,0,.,.,1,.,.,.,.,.,.,.,21,17,43.03670635 -21.1,0,321.3333333,.,.,.,.,.,9.59,1,.,.,.,.,.,.,.,43.09077381 -21.1,1,321.35,2,90,.,.,1,.,.,.,.,.,.,.,.,.,43.09087302 -21.1,1,333.25,2,90,.,.,1,.,.,.,.,.,.,.,.,.,43.16170635 -21.1,1,336.5,0,0,.,.,1,.,.,.,.,.,.,.,21,25,43.18105159 -21.1,1,345.15,2,90,.,.,1,.,.,.,.,.,.,.,.,.,43.23253968 -21.1,0,356.5833333,.,.,.,.,.,7.82,1,.,.,.,.,.,.,.,43.30059524 -21.1,1,356.5833333,0,0,.,.,1,.,.,.,.,.,.,.,26,14,43.30059524 -21.1,1,357.0833333,2,90,.,.,1,.,.,.,.,.,.,.,.,.,43.30357143 -21.1,1,369.0833333,2,90,.,.,1,.,.,.,.,.,.,.,.,.,43.375 -21.1,1,381.0833333,2,90,.,.,1,.,.,.,.,.,.,.,.,.,43.44642857 -21.1,1,389.4,0,0,.,.,1,.,.,.,.,.,.,7.2,.,.,43.49593254 -21.1,1,389.5333333,0,0,.,.,1,.,.,.,.,.,.,7.2,.,.,43.49672619 -21.1,1,393.0833333,2,90,.,.,1,.,.,.,.,.,.,.,.,.,43.51785714 -21.1,1,405.0833333,2,90,.,.,1,.,.,.,.,.,.,.,.,.,43.58928571 -21.1,1,407.3666667,0,0,.,.,1,.,.,.,.,.,.,.,46,20,43.60287698 -21.1,1,418.8333333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,43.67113095 -21.1,1,431.0833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,43.74404762 -21.1,1,442.5833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,43.8125 -21.1,0,454.0833333,.,.,.,.,.,3.53,1,.,.,.,.,.,.,.,43.88095238 -21.1,1,454.0833333,0,0,.,.,1,.,.,.,.,.,.,.,31,30,43.88095238 -21.1,1,456.5833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,43.89583333 -21.1,1,468.5833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,43.9672619 -21.1,1,480.5833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,44.03869048 -21.1,1,494.5833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,44.12202381 -21.1,1,503.0833333,0,0,.,.,1,.,.,.,.,.,.,.,32,24,44.17261905 -21.1,1,506.5833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,44.19345238 -21.1,1,518.5833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,44.26488095 -21.1,1,530.0833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,44.33333333 -21.1,1,542.5833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,44.4077381 -21.1,1,550.0833333,0,0,.,.,1,.,.,.,.,.,.,.,22,37,44.45238095 -21.1,1,551.3333333,0,0,.,.,1,.,.,.,.,.,.,.,40,20,44.45982143 -21.1,1,554.5833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,44.47916667 -21.1,1,566.5833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,44.55059524 -21.1,1,582.8333333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,44.64732143 -21.1,1,594.5833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,44.7172619 -21.1,1,599.8333333,0,0,.,.,1,.,.,.,.,.,.,.,31,20,44.7485119 -21.1,1,606.8333333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,44.79017857 -21.1,1,618.4166667,2,85,.,.,1,.,.,.,.,.,.,.,.,.,44.85912698 -21.1,1,630.5833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,44.93154762 -21.1,1,643.0833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,45.00595238 -21.1,1,646.25,0,0,.,.,1,.,.,.,.,.,.,.,47,26,45.02480159 -21.1,1,655.0833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,45.07738095 -21.1,1,667.3333333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,45.15029762 -21.1,1,670.0833333,0,0,.,.,1,.,.,.,.,.,.,.,60,19,45.16666667 -21.1,0,677.8333333,.,.,.,.,.,4.3,1,.,.,.,.,.,.,.,45.21279762 -21.2,1,0,2,85,.,.,1,.,.,.,.,.,.,7.2,63,23,45.21626984 -21.2,1,12.66666667,2,85,.,.,1,.,.,.,.,.,.,.,.,.,45.29166667 -21.2,1,16.83333333,0,0,.,.,1,.,.,.,.,.,.,.,63,23,45.31646825 -21.2,1,23.66666667,2,85,.,.,1,.,.,.,.,.,.,.,.,.,45.35714286 -21.2,1,36.16666667,2,85,.,.,1,.,.,.,.,.,.,.,.,.,45.43154762 -21.2,1,48.16666667,2,85,.,.,1,.,.,.,.,.,.,.,.,.,45.50297619 -21.2,1,60.25,2,85,.,.,1,.,.,.,.,.,.,.,.,.,45.57490079 -21.2,1,66,0,0,.,.,1,.,.,.,.,.,.,.,65,27,45.60912698 -21.2,1,72.16666667,2,85,.,.,1,.,.,.,.,.,.,.,.,.,45.64583333 -21.2,1,84.25,2,85,.,.,1,.,.,.,.,.,.,.,.,.,45.71775794 -21.2,1,96.41666667,2,85,.,.,1,.,.,.,.,.,.,.,.,.,45.79017857 -21.2,1,108.1666667,2,85,.,.,1,.,.,.,.,.,.,.,.,.,45.86011905 -21.2,1,111.8333333,0,0,.,.,1,.,.,.,.,.,.,.,59,38,45.88194444 -21.2,1,120.1666667,2,85,.,.,1,.,.,.,.,.,.,.,.,.,45.93154762 -21.2,1,132.1666667,2,85,.,.,1,.,.,.,.,.,.,.,.,.,46.00297619 -21.2,1,144.1666667,2,85,.,.,1,.,.,.,.,.,.,.,.,.,46.07440476 -21.2,1,156,2,85,.,.,1,.,.,.,.,.,.,.,.,.,46.14484127 -21.2,1,160.1666667,0,0,.,.,1,.,.,.,.,.,.,.,68,47,46.16964286 -21.2,1,168.1666667,2,85,.,.,1,.,.,.,.,.,.,.,.,.,46.2172619 -21.2,1,180.1666667,2,85,.,.,1,.,.,.,.,.,.,.,.,.,46.28869048 -21.2,1,192,2,85,.,.,1,.,.,.,.,.,.,.,.,.,46.35912698 -21.2,1,204.1666667,2,85,.,.,1,.,.,.,.,.,.,.,.,.,46.43154762 -21.2,1,209.6666667,0,0,.,.,1,.,.,.,.,.,.,.,65,55,46.46428571 -21.2,1,212.6333333,0,0,.,.,1,.,.,.,.,.,.,7.2,.,.,46.48194444 -21.2,0,215.35,.,.,.,.,.,0.457,1,.,.,.,.,.,.,.,46.49811508 -21.2,1,216.1666667,2,85,.,.,1,.,.,.,.,.,.,.,.,.,46.50297619 -21.2,1,227,2,85,.,.,1,.,.,.,.,.,.,.,.,.,46.56746032 -21.2,1,238.6666667,2,85,.,.,1,.,.,.,.,.,.,.,.,.,46.63690476 -21.2,1,248.6666667,0,85,.,.,1,.,.,.,.,.,.,.,.,.,46.69642857 -21.2,1,257.75,0,0,.,.,1,.,.,.,.,.,.,.,30,35,46.75049603 -21.2,1,263.1666667,0,85,.,.,1,.,.,.,.,.,.,.,.,.,46.7827381 -21.2,1,275.6666667,0,85,.,.,1,.,.,.,.,.,.,.,.,.,46.85714286 -21.2,1,280.6666667,0,0,.,.,1,.,.,.,.,.,.,.,32,22,46.88690476 -21.2,1,289.4166667,0,85,.,.,1,.,.,.,.,.,.,.,.,.,46.9389881 -21.2,1,299.6666667,0,85,.,.,1,.,.,.,.,.,.,.,.,.,47 -21.2,1,304,0,0,.,.,1,.,.,.,.,.,.,.,33,27,47.02579365 -21.2,1,310.6666667,0,85,.,.,1,.,.,.,.,.,.,.,.,.,47.06547619 -21.2,1,322.6666667,0,85,.,.,1,.,.,.,.,.,.,.,.,.,47.13690476 -21.2,1,329.1666667,0,0,.,.,1,.,.,.,.,.,.,.,43,25,47.17559524 -21.2,1,334.6666667,0,85,.,.,1,.,.,.,.,.,.,.,.,.,47.20833333 -21.2,0,335.3333333,.,.,.,.,.,0.086,1,.,.,.,.,.,.,.,47.21230159 -21.2,1,346.6666667,0,85,.,.,1,.,.,.,.,.,.,.,.,.,47.2797619 -21.2,1,353.4166667,0,0,.,.,1,.,.,.,.,.,.,.,43,32,47.31994048 -21.2,1,358.6666667,0,85,.,.,1,.,.,.,.,.,.,.,.,.,47.35119048 -21.2,1,370.1666667,0,110,.,.,1,.,.,.,.,.,.,.,.,.,47.41964286 -21.2,1,376.8333333,0,0,.,.,1,.,.,.,.,.,.,.,50,34,47.4593254 -21.2,1,382.6666667,0,110,.,.,1,.,.,.,.,.,.,.,.,.,47.49404762 -21.2,1,394.9166667,0,110,.,.,1,.,.,.,.,.,.,.,.,.,47.56696429 -21.2,1,400.6666667,0,0,.,.,1,.,.,.,.,.,.,.,52,35,47.60119048 -21.2,1,407.1666667,0,110,.,.,1,.,.,.,.,.,.,.,.,.,47.63988095 -21.2,1,419.0833333,0,110,.,.,1,.,.,.,.,.,.,.,.,.,47.71081349 -21.2,0,430.75,.,.,.,.,.,0.589,1,.,.,.,.,.,.,.,47.78025794 -21.2,1,430.8333333,0,110,.,.,1,.,.,.,.,.,.,.,.,.,47.78075397 -21.2,1,442.5833333,0,110,.,.,1,.,.,.,.,.,.,.,.,.,47.85069444 -21.2,1,454.6666667,0,115,.,.,1,.,.,.,.,.,.,.,.,.,47.92261905 -21.2,1,466.6666667,0,115,.,.,1,.,.,.,.,.,.,.,.,.,47.99404762 -21.2,1,478.6666667,0,115,.,.,1,.,.,.,.,.,.,.,.,.,48.06547619 -21.2,1,490.6666667,0,115,.,.,1,.,.,.,.,.,.,.,.,.,48.13690476 -21.2,1,497.6666667,0,0,.,.,1,.,.,.,.,.,.,.,59,38,48.17857143 -21.2,0,502.1666667,.,.,.,.,.,0.405,1,.,.,.,.,.,.,.,48.20535714 -21.3,1,0,0,115,.,.,1,.,.,.,.,.,.,6.7,45,26,49.8422619 -21.3,1,10.5,0,115,.,.,1,.,.,.,.,.,.,.,.,.,49.9047619 -21.3,1,23.5,0,115,.,.,1,.,.,.,.,.,.,.,.,.,49.98214286 -21.3,1,35.5,0,115,.,.,1,.,.,.,.,.,.,.,.,.,50.05357143 -21.3,1,47.5,0,115,.,.,1,.,.,.,.,.,.,.,.,.,50.125 -21.3,1,56.3333333,0,0,.,.,1,.,.,.,.,.,.,.,24,14,50.17757937 -21.3,1,59.5,0,115,.,.,1,.,.,.,.,.,.,.,.,.,50.19642857 -21.3,0,71.1666667,.,.,.,.,.,4.77,1,.,.,.,.,.,.,.,50.26587302 -21.3,1,72,0,115,.,.,1,.,.,.,.,.,.,.,.,.,50.27083333 -21.3,1,83.5,0,115,.,.,1,.,.,.,.,.,.,.,.,.,50.33928571 -21.3,1,86.2166667,0,0,.,.,1,.,.,.,.,.,.,6.7,.,.,50.35545635 -21.3,1,95.5,0,115,.,.,1,.,.,.,.,.,.,.,.,.,50.41071429 -21.3,1,104.5,0,0,.,.,1,.,.,.,.,.,.,.,21,12,50.46428571 -21.3,1,108,0,115,.,.,1,.,.,.,.,.,.,.,.,.,50.48511905 -21.3,0,119,.,.,.,.,.,7.55,1,.,.,.,.,.,.,.,50.55059524 -22.1,1,0,0,0,.,.,1,.,.,.,.,.,.,7.74,45,35,20.02380952 -22.1,1,18,0,55,.,.,1,.,.,.,.,.,.,.,.,.,20.13095238 -22.1,1,24.25,0,0,.,.,1,.,.,.,.,.,.,.,39,39,20.16815476 -22.1,1,30,0,55,.,.,1,.,.,.,.,.,.,.,.,.,20.20238095 -22.1,1,42,0,55,.,.,1,.,.,.,.,.,.,.,.,.,20.27380952 -22.1,1,46.91666667,0,0,.,.,1,.,.,.,.,.,.,.,46,29,20.3030754 -22.1,1,54,0,55,.,.,1,.,.,.,.,.,.,.,.,.,20.3452381 -22.1,1,66.25,0,55,.,.,1,.,.,.,.,.,.,.,.,.,20.41815476 -22.1,1,72.25,0,0,.,.,1,.,.,.,.,.,.,.,41,34,20.45386905 -22.1,1,78,0,55,.,.,1,.,.,.,.,.,.,.,.,.,20.48809524 -22.1,1,90,0,55,.,.,1,.,.,.,.,.,.,.,.,.,20.55952381 -22.1,1,95.66666667,0,0,.,.,1,.,.,.,.,.,.,.,52,37,20.59325397 -22.1,0,102,.,.,.,.,.,0.094,1,.,.,.,.,.,.,.,20.63095238 -22.1,1,102,0,55,.,.,1,.,.,.,.,.,.,.,.,.,20.63095238 -22.1,1,114,0,75,.,.,1,.,.,.,.,.,.,.,.,.,20.70238095 -22.1,1,120.8166667,0,0,.,.,1,.,.,.,.,.,.,.,42,34,20.74295635 -22.1,1,126,0,75,.,.,1,.,.,.,.,.,.,.,.,.,20.77380952 -22.1,1,138.5,0,75,.,.,1,.,.,.,.,.,.,.,.,.,20.84821429 -22.1,1,145,0,0,.,.,1,.,.,.,.,.,.,.,51,35,20.88690476 -22.1,1,150,0,75,.,.,1,.,.,.,.,.,.,.,.,.,20.91666667 -22.1,1,162,0,75,.,.,1,.,.,.,.,.,.,.,.,.,20.98809524 -22.1,1,168.3333333,0,0,.,.,1,.,.,.,.,.,.,.,47,39,21.02579365 -22.1,0,172.9166667,.,.,.,.,.,0.272,1,.,.,.,.,.,.,.,21.0530754 -22.1,1,174,0,75,.,.,1,.,.,.,.,.,.,.,.,.,21.05952381 -22.1,1,186,0,100,.,.,1,.,.,.,.,.,.,.,.,.,21.13095238 -22.1,1,191.6666667,0,0,.,.,1,.,.,.,.,.,.,.,65,35,21.16468254 -22.1,1,198,0,100,.,.,1,.,.,.,.,.,.,.,.,.,21.20238095 -22.1,1,210,0,100,.,.,1,.,.,.,.,.,.,.,.,.,21.27380952 -22.1,1,218.3333333,0,0,.,.,1,.,.,.,.,.,.,.,46,37,21.3234127 -22.1,0,220.5,.,.,.,.,.,0.204,1,.,.,.,.,.,.,.,21.33630952 -22.1,1,222,0,100,.,.,1,.,.,.,.,.,.,.,.,.,21.3452381 -23.1,1,0,0,0,.,.,1,.,.,.,.,.,.,8.02,114,77,26.88789683 -23.1,1,7.833333333,0,60,.,.,1,.,.,.,.,.,.,.,.,.,26.93452381 -23.1,1,18.58333333,0,60,.,.,1,.,.,.,.,.,.,.,.,.,26.9985119 -23.1,1,24.58333333,0,0,.,.,1,.,.,.,.,.,.,.,97,75,27.03422619 -23.1,1,29.33333333,0,60,.,.,1,.,.,.,.,.,.,.,.,.,27.0625 -23.1,1,40.83333333,0,60,.,.,1,.,.,.,.,.,.,.,.,.,27.13095238 -23.1,1,49.33333333,0,0,.,.,1,.,.,.,.,.,.,.,70,64,27.18154762 -23.1,1,52.83333333,0,60,.,.,1,.,.,.,.,.,.,.,.,.,27.20238095 -23.1,1,64.83333333,0,60,.,.,1,.,.,.,.,.,.,.,.,.,27.27380952 -23.1,1,71.33333333,0,0,.,.,1,.,.,.,.,.,.,.,59,55,27.3125 -23.1,0,76.08333333,.,.,.,.,.,0.202,1,.,.,.,.,.,.,.,27.34077381 -23.1,1,76.33333333,0,60,.,.,1,.,.,.,.,.,.,.,.,.,27.3422619 -23.1,1,88.83333333,0,60,.,.,1,.,.,.,.,.,.,.,.,.,27.41666667 -23.1,1,95.33333333,0,0,.,.,1,.,.,.,.,.,.,.,54,56,27.45535714 -23.1,1,103.8333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,27.50595238 -23.1,1,115.8333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,27.57738095 -23.1,1,120.3333333,0,0,.,.,1,.,.,.,.,.,.,.,72,67,27.60416667 -23.1,1,127.8333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,27.64880952 -23.1,1,134.8333333,0,0,.,.,1,.,.,.,.,.,.,8.47,.,.,27.69047619 -23.1,1,138.8333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,27.71428571 -23.1,1,145.0833333,0,0,.,.,1,.,.,.,.,.,.,.,67,72,27.7514881 -23.1,0,149.8333333,.,.,.,.,.,0.297,1,.,.,.,.,.,.,.,27.7797619 -23.1,1,149.8333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,27.7797619 -23.1,1,161.8333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,27.85119048 -23.1,1,168.3333333,0,0,.,.,1,.,.,.,.,.,.,.,61,65,27.88988095 -23.1,1,180.8333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,27.96428571 -23.1,1,184.8333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,27.98809524 -23.1,1,192.3333333,0,0,.,.,1,.,.,.,.,.,.,.,60,67,28.0327381 -23.1,1,197.3333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,28.0625 -23.1,1,203.3333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,28.09821429 -23.1,1,208.8333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,28.13095238 -23.1,1,214.0833333,0,0,.,.,1,.,.,.,.,.,.,.,50,62,28.16220238 -23.1,1,221.8333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,28.20833333 -23.1,1,227.5833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,28.24255952 -23.1,1,232.8333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,28.27380952 -23.1,1,238.5,0,0,.,.,1,.,.,.,.,.,.,.,51,57,28.30753968 -23.1,0,244.75,.,.,.,.,.,0.71,1,.,.,.,.,.,.,.,28.34474206 -23.1,1,245,0,70,.,.,1,.,.,.,.,.,.,.,.,.,28.34623016 -23.1,1,251.8333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,28.38690476 -23.1,1,256.3333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,28.41369048 -23.1,1,264.4666667,0,0,.,.,1,.,.,.,.,.,.,.,57,64,28.46210317 -23.1,1,268.8333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,28.48809524 -23.1,1,274.8333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,28.52380952 -23.1,1,280.8333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,28.55952381 -23.1,1,288.5833333,0,0,.,.,1,.,.,.,.,.,.,.,49,57,28.60565476 -23.1,1,292.8333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,28.63095238 -23.1,1,298.8333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,28.66666667 -23.1,1,305.3333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,28.70535714 -23.1,1,312.8333333,0,0,.,.,1,.,.,.,.,.,.,.,68,42,28.75 -23.1,0,316.5833333,.,.,.,.,.,0.7,1,.,.,.,.,.,.,.,28.77232143 -23.1,1,316.8333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,28.77380952 -23.1,1,322.8333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,28.80952381 -23.1,1,328.8333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,28.8452381 -23.1,1,336.75,0,0,.,.,1,.,.,.,.,.,.,.,41,41,28.89236111 -23.1,1,340.8333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,28.91666667 -23.1,1,346.8333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,28.95238095 -23.1,1,352.8333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,28.98809524 -23.1,1,360.5833333,0,0,.,.,1,.,.,.,.,.,.,.,49,47,29.03422619 -23.1,0,364.8666667,.,.,.,.,.,0.597,1,.,.,.,.,.,.,.,29.05972222 -23.1,1,365.0833333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,29.0610119 -23.1,1,371.3333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,29.09821429 -23.1,1,376.8333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,29.13095238 -23.1,1,384.8333333,0,0,.,.,1,.,.,.,.,.,.,.,50,36,29.17857143 -23.1,1,389.3333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,29.20535714 -23.1,1,394.5833333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,29.23660714 -23.1,1,400.8333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,29.27380952 -23.1,1,408.8333333,0,0,.,.,1,.,.,.,.,.,.,.,58,41,29.32142857 -23.1,1,412.8333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,29.3452381 -23.1,1,418.8333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,29.38095238 -23.1,1,424.8333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,29.41666667 -23.1,1,432.1666667,0,0,.,.,1,.,.,.,.,.,.,.,60,46,29.46031746 -23.1,1,436.8333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,29.48809524 -23.1,1,442.8333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,29.52380952 -23.1,1,448.8333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,29.55952381 -23.1,1,457.0833333,0,0,.,.,1,.,.,.,.,.,.,.,71,39,29.60863095 -23.1,1,461.3333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,29.63392857 -23.1,1,467.3333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,29.66964286 -23.1,1,472.8333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,29.70238095 -23.1,1,480.3333333,0,0,.,.,1,.,.,.,.,.,.,.,52,40,29.74702381 -23.1,0,484.8333333,.,.,.,.,.,0.678,1,.,.,.,.,.,.,.,29.77380952 -23.1,1,485.5833333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,29.77827381 -23.1,1,491.5833333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,29.8139881 -23.1,1,496.8333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,29.8452381 -23.1,1,504.5,0,0,.,.,1,.,.,.,.,.,.,.,61,46,29.89087302 -23.1,1,508.8333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,29.91666667 -23.1,1,515.5833333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,29.95684524 -23.1,1,520.8333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,29.98809524 -23.1,1,529.1666667,0,0,.,.,1,.,.,.,.,.,.,.,65,47,30.03769841 -23.1,1,532.8333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,30.05952381 -23.1,1,538.8333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,30.0952381 -23.1,1,544.8333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,30.13095238 -23.1,1,552.25,0,0,.,.,1,.,.,.,.,.,.,.,47,33,30.17509921 -23.1,1,556.8333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,30.20238095 -23.1,1,562.8333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,30.23809524 -23.1,1,568.8333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,30.27380952 -23.1,1,576.5833333,0,0,.,.,1,.,.,.,.,.,.,.,49,36,30.31994048 -23.1,0,580.45,.,.,.,.,.,1.5,1,.,.,.,.,.,.,.,30.34295635 -23.1,1,581.3333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,30.34821429 -23.1,1,587.3333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,30.38392857 -23.1,1,592.8333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,30.41666667 -23.1,1,600.5833333,0,0,.,.,1,.,.,.,.,.,.,.,46,45,30.46279762 -23.1,1,604.8333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,30.48809524 -23.1,1,610.8333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,30.52380952 -23.1,1,616.8333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,30.55952381 -23.1,1,624.8333333,0,0,.,.,1,.,.,.,.,.,.,.,40,39,30.60714286 -23.1,1,628.8333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,30.63095238 -23.1,1,634.8333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,30.66666667 -23.1,1,641.3333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,30.70535714 -23.1,1,648.4166667,0,0,.,.,1,.,.,.,.,.,.,.,35,35,30.74751984 -23.1,0,652.5,.,.,.,.,.,2.24,1,.,.,.,.,.,.,.,30.7718254 -23.2,1,0,0,90,.,.,1,.,.,.,.,.,.,8.47,35,35,30.77876984 -23.2,1,5.666666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,30.8125 -23.2,1,11.16666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,30.8452381 -23.2,1,17.66666667,0,0,.,.,1,.,.,.,.,.,.,.,38,35,30.88392857 -23.2,1,23.16666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,30.91666667 -23.2,1,29.16666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,30.95238095 -23.2,1,35.16666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,30.98809524 -23.2,1,43.25,0,0,.,.,1,.,.,.,.,.,.,.,27,27,31.03621032 -23.2,1,47.16666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.05952381 -23.2,1,53.16666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.0952381 -23.2,1,58.16666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.125 -23.2,1,67.66666667,0,0,.,.,1,.,.,.,.,.,.,.,29,28,31.18154762 -23.2,1,71.16666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.20238095 -23.2,1,77.16666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.23809524 -23.2,1,82.91666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.27232143 -23.2,1,91.66666667,0,0,.,.,1,.,.,.,.,.,.,.,34,32,31.32440476 -23.2,1,95.41666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.34672619 -23.2,1,101.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.38095238 -23.2,1,107.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.41666667 -23.2,1,115.4166667,0,0,.,.,1,.,.,.,.,.,.,.,30,28,31.46577381 -23.2,1,119.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.48809524 -23.2,1,125.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.52380952 -23.2,1,131.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.55952381 -23.2,1,138.5833333,0,0,.,.,1,.,.,.,.,.,.,.,32,23,31.60367063 -23.2,1,143.8333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.63492063 -23.2,1,149.9166667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.67113095 -23.2,1,155.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.70238095 -23.2,1,161.5,0,0,.,.,1,.,.,.,.,.,.,.,42,31,31.74007937 -23.2,0,167.1666667,.,.,.,.,.,0.975,1,.,.,.,.,.,.,.,31.77380952 -23.2,1,167.5833333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.77628968 -23.2,1,173.3666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.81071429 -23.2,1,179.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.8452381 -23.2,1,186.3666667,0,0,.,.,1,.,.,.,.,.,.,.,59,33,31.88809524 -23.2,1,191.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.91666667 -23.2,1,197.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.95238095 -23.2,1,203.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,31.98809524 -23.2,1,209.6666667,0,0,.,.,1,.,.,.,.,.,.,.,61,28,32.02678571 -23.2,1,215.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.05952381 -23.2,1,221.6666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.09821429 -23.2,1,227.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.13095238 -23.2,1,233.4166667,0,0,.,.,1,.,.,.,.,.,.,.,80,31,32.16815476 -23.2,1,239.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.20238095 -23.2,1,245.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.23809524 -23.2,1,251.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.27380952 -23.2,1,259.6666667,0,0,.,.,1,.,.,.,.,.,.,.,180,47,32.32440476 -23.2,1,263.5833333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.34771825 -23.2,1,269.5833333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.38343254 -23.2,1,275.6666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.41964286 -23.2,1,282.3333333,0,0,.,.,1,.,.,.,.,.,.,.,106,32,32.4593254 -23.2,1,286.9166667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.48660714 -23.2,1,293.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.52380952 -23.2,1,299.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.55952381 -23.2,1,305.6666667,0,0,.,.,1,.,.,.,.,.,.,.,84,39,32.59821429 -23.2,1,311.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.63095238 -23.2,1,317.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.66666667 -23.2,1,323.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.70238095 -23.2,1,331.4166667,0,0,.,.,1,.,.,.,.,.,.,.,89,33,32.7514881 -23.2,1,335.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.77380952 -23.2,1,341.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.80952381 -23.2,1,347.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.8452381 -23.2,1,355.1666667,0,0,.,.,1,.,.,.,.,.,.,.,67,35,32.89285714 -23.2,1,358.6666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.91369048 -23.2,1,365.9166667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.95684524 -23.2,1,371.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,32.98809524 -23.2,1,378.1666667,0,0,.,.,1,.,.,.,.,.,.,.,133,42,33.0297619 -23.2,0,383.4,.,.,.,.,.,1,1,.,.,.,.,.,.,.,33.0609127 -23.2,1,384.9166667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.06994048 -23.2,1,389.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.0952381 -23.2,1,395.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.13095238 -23.2,1,402.6666667,0,0,.,.,1,.,.,.,.,.,.,.,136,39,33.17559524 -23.2,1,405.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.19047619 -23.2,1,413.6666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.24107143 -23.2,1,419.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.27380952 -23.2,1,426.1666667,0,0,.,.,1,.,.,.,.,.,.,.,124,39,33.31547619 -23.2,1,431.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.3452381 -23.2,1,437.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.38095238 -23.2,1,443.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.41666667 -23.2,1,450.2166667,0,0,.,.,1,.,.,.,.,.,.,.,166,44,33.45863095 -23.2,1,455.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.48809524 -23.2,1,461.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.52380952 -23.2,1,471.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.58333333 -23.2,1,475.4166667,0,0,.,.,1,.,.,.,.,.,.,.,152,40,33.60863095 -23.2,1,479.9166667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.63541667 -23.2,1,485.6666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.66964286 -23.2,1,491.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.70238095 -23.2,1,497.1666667,0,0,.,.,1,.,.,.,.,.,.,.,161,41,33.73809524 -23.2,0,501.8333333,.,.,.,.,.,1.31,1,.,.,.,.,.,.,.,33.76587302 -23.2,1,502.8333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.7718254 -23.2,1,509.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.80952381 -23.2,1,515.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.8452381 -23.2,1,522.9166667,0,0,.,.,1,.,.,.,.,.,.,.,92,31,33.89136905 -23.2,1,525.6666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.9077381 -23.2,1,532.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.94642857 -23.2,1,537.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,33.97619048 -23.2,1,546.25,0,0,.,.,1,.,.,.,.,.,.,.,163,47,34.03025794 -23.2,1,549.8333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,34.0515873 -23.2,1,555.5833333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,34.08581349 -23.2,1,561.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,34.11904762 -23.2,1,571.75,0,0,.,.,1,.,.,.,.,.,.,.,278,44,34.18204365 -23.2,1,574.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,34.19642857 -23.2,1,581.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,34.23809524 -23.2,1,585.6666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,34.26488095 -23.2,1,594,0,0,.,.,1,.,.,.,.,.,.,.,265,48,34.31448413 -23.2,1,597.6666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,34.33630952 -23.2,1,603.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,34.36904762 -23.2,1,609.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,34.4047619 -23.2,1,621.3333333,0,0,.,.,1,.,.,.,.,.,.,.,290,59,34.47718254 -23.2,1,621.6666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,34.47916667 -23.2,1,627.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,34.51190476 -23.2,1,633.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,34.54761905 -23.2,1,643.5,0,0,.,.,1,.,.,.,.,.,.,.,318,69,34.60912698 -23.2,1,645.3333333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,34.62003968 -23.2,1,651.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,34.6547619 -23.2,1,657.4166667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,34.69196429 -23.2,1,667.1666667,0,0,.,.,1,.,.,.,.,.,.,.,292,78,34.75 -23.2,0,670.0833333,.,.,.,.,.,2.22,1,.,.,.,.,.,.,.,34.76736111 -24.1,1,0,0,0,.,.,1,.,.,.,.,.,.,9.9,37,18,77.83958333 -24.1,1,7.7,0,85,.,.,1,.,.,.,.,.,.,.,.,.,77.88541667 -24.1,1,18.95,2,85,.,.,1,.,.,.,.,.,.,.,.,.,77.95238095 -24.1,1,30.45,2,85,.,.,1,.,.,.,.,.,.,.,.,.,78.02083333 -24.1,1,42.95,2,85,.,.,1,.,.,.,.,.,.,.,.,.,78.0952381 -24.1,1,54.95,2,85,.,.,1,.,.,.,.,.,.,.,.,.,78.16666667 -24.1,0,66.85,.,.,.,.,.,1.77,1,.,.,.,.,.,.,.,78.2375 -24.2,1,0,2,85,9,12,1,.,.,.,.,.,.,9.9,125,6,80.52331349 -24.2,0,113.6666666,.,.,.,.,.,0.097,1,.,.,.,.,.,.,.,80.55704365 -24.2,1,113.8333333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,80.55803571 -24.2,1,124.0833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,80.61904762 -24.2,1,136.75,2,85,.,.,1,.,.,.,.,.,.,.,.,.,80.69444444 -24.2,1,149.0833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,80.76785714 -24.2,0,160.5,.,.,.,.,.,0.173,1,.,.,.,.,.,.,.,80.83581349 -24.2,1,160.5,0,0,.,.,1,.,.,.,.,.,.,.,27,17,80.83581349 -24.2,1,161.0833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,80.83928571 -24.2,1,173.0833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,80.91071429 -24.2,1,185.0833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,80.98214286 -24.2,1,197.0833333,0,0,.,.,1,.,.,.,.,.,.,.,23,20,81.05357143 -24.2,1,197.0833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,81.05357143 -24.2,1,209.0833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,81.125 -24.2,1,221.0833333,2,85,.,.,1,.,.,.,.,.,.,.,.,.,81.19642857 -24.2,1,222.5166666,0,0,.,.,1,.,.,.,.,.,.,9.9,.,.,81.20496032 -24.2,1,237.4166666,2,85,.,.,1,.,.,.,.,.,.,.,.,.,81.29365079 -24.2,1,245.15,0,0,.,.,1,.,.,.,.,.,.,9.9,.,.,81.33968254 -24.2,1,256.9166666,0,100,.,.,1,.,.,.,.,.,.,.,.,.,81.40972222 -24.2,1,273.0833333,2,100,.,.,1,.,.,.,.,.,.,.,.,.,81.50595238 -24.2,1,286.0833333,2,100,.,.,1,.,.,.,.,.,.,.,.,.,81.58333333 -24.2,1,298.0833333,2,100,.,.,1,.,.,.,.,.,.,.,.,.,81.6547619 -24.2,1,305.0833333,2,100,.,.,1,.,.,.,.,.,.,.,.,.,81.69642857 -24.2,0,316.9166666,.,.,.,.,.,0.369,1,.,.,.,.,.,.,.,81.76686508 -24.2,1,317.3333333,2,100,.,.,1,.,.,.,.,.,.,.,.,.,81.76934524 -24.2,0,318.3333333,.,.,.,.,.,4.14,1,.,.,.,.,.,.,.,81.77529762 -24.2,0,319.3333333,.,.,.,.,.,5.43,1,.,.,.,.,.,.,.,81.78125 -24.2,0,321.3333333,.,.,.,.,.,2.39,1,.,.,.,.,.,.,.,81.79315476 -24.2,0,323.3333333,.,.,.,.,.,1.25,1,.,.,.,.,.,.,.,81.80505952 -24.2,0,325.3333333,.,.,.,.,.,0.64,1,.,.,.,.,.,.,.,81.81696429 -24.2,0,329.3333333,.,.,.,.,.,0.336,1,.,.,.,.,.,.,.,81.84077381 -24.2,1,329.4166666,2,100,.,.,1,.,.,.,.,.,.,.,.,.,81.84126984 -24.2,1,339.0833333,0,0,.,.,1,.,.,.,.,.,.,.,30,28,81.89880952 -24.2,1,341.0833333,2,100,.,.,1,.,.,.,.,.,.,.,.,.,81.91071429 -24.2,1,353.0833333,2,100,.,.,1,.,.,.,.,.,.,.,.,.,81.98214286 -24.2,1,364.6666666,2,100,.,.,1,.,.,.,.,.,.,.,.,.,82.05109127 -24.2,1,378.0833333,0,160,.,.,1,.,.,.,.,.,.,.,.,.,82.13095238 -24.2,1,389.0833333,0,160,.,.,1,.,.,.,.,.,.,.,.,.,82.19642857 -24.2,1,401.0833333,0,160,.,.,1,.,.,.,.,.,.,.,.,.,82.26785714 -24.2,0,412.0833333,.,.,.,.,.,3.28,1,.,.,.,.,.,.,.,82.33333333 -25.1,1,0,0,0,.,.,1,.,.,.,.,.,.,5.85,32,33,16.88988095 -25.1,1,10.75,0,40,.,.,1,.,.,.,.,.,.,.,.,.,16.95386905 -25.1,1,24.5,0,40,.,.,1,.,.,.,.,.,.,.,.,.,17.03571429 -25.1,1,38.5,0,40,.,.,1,.,.,.,.,.,.,.,.,.,17.11904762 -25.1,1,50.5,0,40,.,.,1,.,.,.,.,.,.,.,.,.,17.19047619 -25.1,1,62.5,0,40,.,.,1,.,.,.,.,.,.,.,.,.,17.26190476 -25.1,1,74.5,0,40,.,.,1,.,.,.,.,.,.,.,.,.,17.33333333 -25.1,1,86.5,0,40,.,.,1,.,.,.,.,.,.,.,.,.,17.4047619 -25.1,1,95.75,0,0,.,.,1,.,.,.,.,.,.,.,37,31,17.45982143 -25.1,1,99,0,40,.,.,1,.,.,.,.,.,.,.,.,.,17.47916667 -25.1,1,110.5,0,40,.,.,1,.,.,.,.,.,.,.,.,.,17.54761905 -25.1,1,123,0,40,.,.,1,.,.,.,.,.,.,.,.,.,17.62202381 -25.1,1,134.5,0,40,.,.,1,.,.,.,.,.,.,.,.,.,17.69047619 -25.1,1,147,0,40,.,.,1,.,.,.,.,.,.,.,.,.,17.76488095 -25.1,1,159,0,40,.,.,1,.,.,.,.,.,.,.,.,.,17.83630952 -25.1,1,168.5,0,0,.,.,1,.,.,.,.,.,.,.,28,26,17.89285714 -25.1,1,170.5,0,40,.,.,1,.,.,.,.,.,.,.,.,.,17.9047619 -25.1,1,182.5,0,40,.,.,1,.,.,.,.,.,.,.,.,.,17.97619048 -25.1,1,194.5,0,40,.,.,1,.,.,.,.,.,.,.,.,.,18.04761905 -25.1,1,208,0,40,.,.,1,.,.,.,.,.,.,.,.,.,18.12797619 -25.1,1,220,0,40,.,.,1,.,.,.,.,.,.,.,.,.,18.19940476 -25.1,1,230.5,0,40,.,.,1,.,.,.,.,.,.,.,.,.,18.26190476 -25.1,1,242.5,0,40,.,.,1,.,.,.,.,.,.,.,.,.,18.33333333 -25.1,1,255.1666667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,18.40873016 -25.1,0,266,.,.,.,.,.,0.167,1,.,.,.,.,.,.,.,18.47321429 -25.1,1,266,0,0,.,.,1,.,.,.,.,.,.,.,35,43,18.47321429 -25.1,1,266.8333333,0,40,.,.,1,.,.,.,.,.,.,.,.,.,18.4781746 -25.1,1,279.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,18.55357143 -25.1,1,290.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,18.61904762 -25.1,1,303.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,18.69642857 -25.1,1,315.8333333,0,60,.,.,1,.,.,.,.,.,.,.,.,.,18.76984127 -25.1,1,326.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,18.83333333 -25.1,1,339.4166667,0,0,.,.,1,.,.,.,.,.,.,.,38,45,18.91021825 -25.1,1,339.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,18.91071429 -25.1,1,351.75,0,60,.,.,1,.,.,.,.,.,.,.,.,.,18.98363095 -25.1,0,363,.,.,.,.,.,0.574,1,.,.,.,.,.,.,.,19.05059524 -25.1,1,363.3333333,0,60,.,.,1,.,.,.,.,.,.,.,.,.,19.05257937 -25.1,1,378,0,60,.,.,1,.,.,.,.,.,.,.,.,.,19.13988095 -25.1,1,388.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,19.20238095 -25.1,1,398.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,19.26190476 -25.1,1,411,0,60,.,.,1,.,.,.,.,.,.,.,.,.,19.33630952 -25.1,1,425.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,19.42261905 -25.1,0,433.5,.,.,.,.,.,0.789,1,.,.,.,.,.,.,.,19.4702381 -25.1,1,433.5,0,0,.,.,1,.,.,.,.,.,.,.,35,33,19.4702381 -25.1,1,434.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,19.47619048 -25.1,1,448.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,19.55952381 -25.1,1,458.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,19.61904762 -25.1,1,470.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,19.69047619 -25.1,1,482.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,19.76190476 -25.1,1,494.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,19.83333333 -25.1,1,503.5,0,0,.,.,1,.,.,.,.,.,.,.,94,22,19.88690476 -25.1,1,506.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,19.9047619 -25.1,1,518.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,19.97619048 -25.1,1,531.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,20.05357143 -25.1,1,542.75,0,90,.,.,1,.,.,.,.,.,.,.,.,.,20.12053571 -25.1,1,555.25,0,90,.,.,1,.,.,.,.,.,.,.,.,.,20.19494048 -25.1,1,566.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,20.26190476 -25.1,1,578.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,20.33333333 -25.1,1,590.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,20.4047619 -25.1,0,602.3333333,.,.,.,.,.,1.62,1,.,.,.,.,.,.,.,20.47519841 -25.1,1,602.3333333,0,0,.,.,1,.,.,.,.,.,.,.,37,37,20.47519841 -25.1,1,603.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,20.48214286 -25.1,1,615.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,20.55357143 -25.1,1,628.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,20.63095238 -25.1,1,638.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,20.69047619 -25.1,1,651.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,20.76785714 -25.1,1,662.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,20.83333333 -25.1,1,671.75,0,0,.,.,1,.,.,.,.,.,.,.,73,130,20.88839286 -25.1,1,674.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,20.9047619 -25.1,1,686.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,20.97619048 -25.1,1,697,0,0,.,.,1,.,.,.,.,.,.,.,138,188,21.03869048 -25.1,1,700.1666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,21.05753968 -25.1,1,711,0,90,.,.,1,.,.,.,.,.,.,.,.,.,21.12202381 -25.1,1,722.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,21.19047619 -25.1,1,734.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,21.26190476 -25.1,1,746.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,21.33333333 -25.1,1,752,0,0,.,.,1,.,.,.,.,.,.,.,53,147,21.36607143 -25.1,1,758.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,21.4047619 -25.1,1,768.5,0,0,.,.,1,.,.,.,.,.,.,.,83,142,21.46428571 -25.1,1,770.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,21.47619048 -25.1,1,782.0333333,0,0,.,.,1,.,.,.,.,.,.,7.2,.,.,21.54484127 -25.1,1,782.05,0,0,.,.,1,.,.,.,.,.,.,7,.,.,21.54494048 -25.1,1,783,0,90,.,.,1,.,.,.,.,.,.,.,.,.,21.55059524 -25.1,0,791.75,.,.,.,.,.,2.96,1,.,.,.,.,.,.,.,21.60267857 -25.2,1,0,0,90,.,.,1,.,.,.,.,.,.,7,28,30,24.03571429 -25.2,1,12,0,90,.,.,1,.,.,.,.,.,.,.,.,.,24.10714286 -25.2,1,24,0,90,.,.,1,.,.,.,.,.,.,.,.,.,24.17857143 -25.2,1,36,0,90,.,.,1,.,.,.,.,.,.,.,.,.,24.25 -25.2,1,59.75,0,90,.,.,1,.,.,.,.,.,.,.,.,.,24.32142857 -25.2,0,59.75,.,.,.,.,.,0.769,1,.,.,.,.,.,.,.,24.46279762 -25.2,1,60,0,0,.,.,1,.,.,.,.,.,.,.,50,39,24.46279762 -25.2,1,71.666667,0,90,.,.,1,.,.,.,.,.,.,.,.,.,24.46428571 -25.2,1,84,0,90,.,.,1,.,.,.,.,.,.,.,.,.,24.53373016 -25.2,1,96,0,90,.,.,1,.,.,.,.,.,.,.,.,.,24.60714286 -25.2,1,108,0,90,.,.,1,.,.,.,.,.,.,.,.,.,24.67857143 -25.2,1,119.5,0,90,.,.,1,.,.,.,.,.,.,.,.,.,24.75 -25.2,1,131.833333,0,90,.,.,1,.,.,.,.,.,.,.,.,.,24.81845238 -25.2,0,131.833333,.,.,.,.,.,0.605,1,.,.,.,.,.,.,.,24.89186508 -25.3,1,0,0,100,9,12,1,.,.,.,.,.,.,8.7,25,29,43.26190476 -25.3,0,119.5,.,.,.,.,.,10.6,1,.,.,.,.,.,.,.,43.3422619 -26.1,1,0,2,90,.,.,1,.,.,.,.,.,.,8.675,85,69,33.9672619 -26.1,1,12,2,90,.,.,1,.,.,.,.,.,.,.,.,.,34.03869048 -26.1,1,22.66666667,0,0,.,.,1,.,.,.,.,.,.,.,85,69,34.10218254 -26.1,1,25,2,80,.,.,1,.,.,.,.,.,.,.,.,.,34.11607143 -26.1,1,37.5,2,80,.,.,1,.,.,.,.,.,.,.,.,.,34.19047619 -26.1,1,49.49999997,2,80,.,.,1,.,.,.,.,.,.,.,.,.,34.26190476 -26.1,1,61.49999997,2,80,.,.,1,.,.,.,.,.,.,.,.,.,34.33333333 -26.1,1,73.49999997,2,80,.,.,1,.,.,.,.,.,.,.,.,.,34.4047619 -26.1,0,84.99999997,.,.,.,.,.,4.77,1,.,.,.,.,.,.,.,34.47321429 -27.1,1,0,0,0,.,.,1,.,.,.,.,.,.,10.3,171,157,34.60565476 -27.1,1,14.25,0,70,.,.,1,.,.,.,.,.,.,.,.,.,34.69047619 -27.1,1,24.56666667,0,0,.,.,1,.,.,.,.,.,.,.,155,145,34.75188492 -27.1,1,26.75,0,70,.,.,1,.,.,.,.,.,.,.,.,.,34.76488095 -27.1,1,38.25,0,70,.,.,1,.,.,.,.,.,.,.,.,.,34.83333333 -27.1,1,47,0,0,.,.,1,.,.,.,.,.,.,.,149,136,34.88541667 -27.1,0,51,.,.,.,.,.,0.164,1,.,.,.,.,.,.,.,34.90922619 -27.1,1,51,0,70,.,.,1,.,.,.,.,.,.,.,.,.,34.90922619 -27.1,1,62.75,0,80,.,.,1,.,.,.,.,.,.,.,.,.,34.97916667 -27.1,1,74.25,0,80,.,.,1,.,.,.,.,.,.,.,143,131,35.04761905 -27.1,1,86.25,0,80,.,.,1,.,.,.,.,.,.,.,.,.,35.11904762 -27.1,1,95.75,0,0,.,.,1,.,.,.,.,.,.,.,111,108,35.17559524 -27.1,1,98.75,0,80,.,.,1,.,.,.,.,.,.,.,.,.,35.19345238 -27.1,1,110.4166667,0,80,.,.,1,.,.,.,.,.,.,.,.,.,35.26289683 -27.1,0,120.75,.,.,.,.,.,0.726,1,.,.,.,.,.,.,.,35.32440476 -27.1,1,120.75,0,0,.,.,1,.,.,.,.,.,.,.,138,114,35.32440476 -27.1,1,122.25,0,80,.,.,1,.,.,.,.,.,.,.,.,.,35.33333333 -27.1,1,134.05,0,80,.,.,1,.,.,.,.,.,.,.,.,.,35.40357143 -27.1,1,144.75,0,0,.,.,1,.,.,.,.,.,.,.,161,131,35.4672619 -27.1,1,146.25,0,80,.,.,1,.,.,.,.,.,.,.,.,.,35.47619048 -27.1,1,158.3333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,35.54811508 -27.1,1,168.75,0,0,.,.,1,.,.,.,.,.,.,.,184,111,35.61011905 -27.1,1,170.25,0,80,.,.,1,.,.,.,.,.,.,.,.,.,35.61904762 -27.1,1,182.25,0,80,.,.,1,.,.,.,.,.,.,.,.,.,35.69047619 -27.1,1,192.5833333,0,0,.,.,1,.,.,.,.,.,.,.,152,90,35.75198413 -27.1,1,194.25,0,80,.,.,1,.,.,.,.,.,.,.,.,.,35.76190476 -27.1,1,207,0,80,.,.,1,.,.,.,.,.,.,.,.,.,35.83779762 -27.1,1,216.5833333,0,0,.,.,1,.,.,.,.,.,.,.,148,93,35.89484127 -27.1,0,218.25,.,.,.,.,.,0.591,1,.,.,.,.,.,.,.,35.9047619 -27.1,1,218.75,0,80,.,.,1,.,.,.,.,.,.,.,.,.,35.9077381 -27.1,1,230.25,0,80,.,.,1,.,.,.,.,.,.,.,.,.,35.97619048 -27.1,1,240.75,0,0,.,.,1,.,.,.,.,.,.,.,133,71,36.03869048 -27.1,1,242.75,0,80,.,.,1,.,.,.,.,.,.,.,.,.,36.05059524 -27.1,1,254.25,0,80,.,.,1,.,.,.,.,.,.,.,.,.,36.11904762 -27.1,1,264.75,0,0,.,.,1,.,.,.,.,.,.,.,134,61,36.18154762 -27.1,1,266.25,0,80,.,.,1,.,.,.,.,.,.,.,.,.,36.19047619 -27.1,1,278.25,0,80,.,.,1,.,.,.,.,.,.,.,.,.,36.26190476 -27.1,0,288.75,.,.,.,.,.,1.01,1,.,.,.,.,.,.,.,36.32440476 -27.1,1,290.6666667,0,80,.,.,1,.,.,.,.,.,.,.,.,.,36.33581349 -27.1,1,291.25,0,0,.,.,1,.,.,.,.,.,.,.,156,38,36.33928571 -27.1,1,303.25,0,80,.,.,1,.,.,.,.,.,.,.,.,.,36.41071429 -27.1,1,312.75,0,0,.,.,1,.,.,.,.,.,.,.,96,39,36.4672619 -27.1,1,315.4166667,0,0,.,.,1,.,.,.,.,.,.,.,100,49,36.48313492 -27.1,1,317.4166667,0,80,.,.,1,.,.,.,.,.,.,.,.,.,36.49503968 -27.1,1,333.8333333,0,0,.,.,1,.,.,.,.,.,.,.,69,38,36.59275794 -27.1,1,357.75,0,0,.,.,1,.,.,.,.,.,.,.,55,39,36.73511905 -27.1,1,384.5833333,0,0,.,.,1,.,.,.,.,.,.,.,73,42,36.89484127 -27.1,1,391.75,0,80,.,.,1,.,.,.,.,.,.,.,.,.,36.9375 -27.1,1,398.75,0,80,.,.,1,.,.,.,.,.,.,.,.,.,36.97916667 -27.1,1,408.75,0,0,.,.,1,.,.,.,.,.,.,.,65,36,37.03869048 -27.1,1,410.25,0,80,.,.,1,.,.,.,.,.,.,.,.,.,37.04761905 -27.1,1,422.25,0,80,.,.,1,.,.,.,.,.,.,.,.,.,37.11904762 -27.1,1,432.6666667,0,0,.,.,1,.,.,.,.,.,.,.,63,27,37.18105159 -27.1,1,434.25,0,80,.,.,1,.,.,.,.,.,.,.,.,.,37.19047619 -27.1,1,446.25,0,80,.,.,1,.,.,.,.,.,.,.,.,.,37.26190476 -27.1,0,455.5833333,.,.,.,.,.,0.893,1,.,.,.,.,.,.,.,37.31746032 -27.1,1,455.5833333,0,0,.,.,1,.,.,.,.,.,.,.,65,21,37.31746032 -27.1,1,458.5833333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,37.33531746 -27.1,1,462.3166667,0,0,.,.,1,.,.,.,.,.,.,10.3,.,.,37.35753968 -27.1,1,470.25,0,80,.,.,1,.,.,.,.,.,.,.,.,.,37.4047619 -27.1,1,479.75,0,0,.,.,1,.,.,.,.,.,.,.,65,13,37.46130952 -27.1,1,482.75,0,80,.,.,1,.,.,.,.,.,.,.,.,.,37.47916667 -27.1,1,495.0833333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,37.55257937 -27.1,0,503.75,.,.,.,.,.,0.768,1,.,.,.,.,.,.,.,37.60416667 -27.1,1,503.75,0,0,.,.,1,.,.,.,.,.,.,.,56,14,37.60416667 -27.1,1,506.25,0,80,.,.,1,.,.,.,.,.,.,.,.,.,37.61904762 -27.1,1,518.6666667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,37.69295635 -27.1,1,528.25,0,0,.,.,1,.,.,.,.,.,.,.,56,13,37.75 -27.1,1,530.25,0,100,.,.,1,.,.,.,.,.,.,.,.,.,37.76190476 -27.1,1,542.25,0,100,.,.,1,.,.,.,.,.,.,.,.,.,37.83333333 -27.1,1,552.9166667,0,0,.,.,1,.,.,.,.,.,.,.,61,15,37.8968254 -27.1,1,554.25,0,100,.,.,1,.,.,.,.,.,.,.,.,.,37.9047619 -27.1,0,554.5,.,.,.,.,.,0.441,1,.,.,.,.,.,.,.,37.90625 -27.1,1,566.5833333,0,120,.,.,1,.,.,.,.,.,.,.,.,.,37.9781746 -27.1,1,576.25,0,0,.,.,1,.,.,.,.,.,.,.,50,12,38.03571429 -27.1,1,578.75,0,120,.,.,1,.,.,.,.,.,.,.,.,.,38.05059524 -27.1,1,590.25,0,120,.,.,1,.,.,.,.,.,.,.,.,.,38.11904762 -27.1,1,600.3333333,0,0,.,.,1,.,.,.,.,.,.,.,52,9,38.17906746 -27.1,1,602.4166667,0,120,.,.,1,.,.,.,.,.,.,.,.,.,38.19146825 -27.1,1,614.25,0,120,.,.,1,.,.,.,.,.,.,.,.,.,38.26190476 -27.1,1,622.9166667,0,0,.,.,1,.,.,.,.,.,.,.,58,8,38.31349206 -27.1,0,624.75,.,.,.,.,.,1.31,1,.,.,.,.,.,.,.,38.32440476 -27.2,1,0,0,120,.,.,1,.,.,.,.,.,.,9.7,58,8,38.33333333 -27.2,1,12,0,120,.,.,1,.,.,.,.,.,.,.,.,.,38.4047619 -27.2,1,22,0,0,.,.,1,.,.,.,.,.,.,.,67,17,38.46428571 -27.2,1,24,0,120,.,.,1,.,.,.,.,.,.,.,.,.,38.47619048 -27.2,1,36,0,120,.,.,1,.,.,.,.,.,.,.,.,.,38.54761905 -27.2,1,48.25,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,38.62053571 -27.2,1,48.41666667,0,120,.,.,1,.,.,.,.,.,.,.,.,.,38.62152778 -27.2,1,49.75,0,0,.,.,1,.,.,.,.,.,.,.,69,33,38.62946429 -27.2,1,60,0,120,.,.,1,.,.,.,.,.,.,.,.,.,38.69047619 -27.2,1,69.16666667,0,0,.,.,1,.,.,.,.,.,.,.,51,21,38.74503968 -27.2,1,72,0,120,.,.,1,.,.,.,.,.,.,.,.,.,38.76190476 -27.2,1,84,0,120,.,.,1,.,.,.,.,.,.,.,.,.,38.83333333 -27.2,1,94,0,0,.,.,1,.,.,.,.,.,.,.,65,32,38.89285714 -27.2,0,94.58333333,.,.,.,.,.,0.656,1,.,.,.,.,.,.,.,38.89632937 -27.2,1,96,0,120,.,.,1,.,.,.,.,.,.,.,.,.,38.9047619 -27.2,1,108,0,120,.,.,1,.,.,.,.,.,.,.,.,.,38.97619048 -27.2,1,118.5833333,0,0,.,.,1,.,.,.,.,.,.,.,81,33,39.03918651 -27.2,1,120.25,0,150,.,.,1,.,.,.,.,.,.,.,.,.,39.04910714 -27.2,1,132,0,150,.,.,1,.,.,.,.,.,.,.,.,.,39.11904762 -27.2,1,142.5,0,0,.,.,1,.,.,.,.,.,.,.,70,22,39.18154762 -27.2,1,144.5,0,150,.,.,1,.,.,.,.,.,.,.,.,.,39.19345238 -27.2,1,156,0,150,.,.,1,.,.,.,.,.,.,.,.,.,39.26190476 -27.2,0,167,.,.,.,.,.,0.901,1,.,.,.,.,.,.,.,39.32738095 -27.3,1,0,0,0,.,.,1,.,.,.,.,.,.,9.7,86,35,39.32738095 -27.3,1,1,0,150,.,.,1,.,.,.,.,.,.,.,.,.,39.33333333 -27.3,1,13,0,110,.,.,1,.,.,.,.,.,.,.,.,.,39.4047619 -27.3,1,21,0,110,.,.,1,.,.,.,.,.,.,.,.,.,39.45238095 -27.3,1,23.5,0,0,.,.,1,.,.,.,.,.,.,.,75,23,39.4672619 -27.3,1,29.5,0,110,.,.,1,.,.,.,.,.,.,.,.,.,39.50297619 -27.3,1,37.33333333,0,110,.,.,1,.,.,.,.,.,.,.,.,.,39.54960317 -27.3,1,45,0,110,.,.,1,.,.,.,.,.,.,.,.,.,39.5952381 -27.3,1,46.25,0,0,.,.,1,.,.,.,.,.,.,.,102,33,39.60267857 -27.3,1,53,0,110,.,.,1,.,.,.,.,.,.,.,.,.,39.64285714 -27.3,1,61.16666667,0,110,.,.,1,.,.,.,.,.,.,.,.,.,39.69146825 -27.3,1,69.5,0,110,.,.,1,.,.,.,.,.,.,.,.,.,39.74107143 -27.3,1,71.25,0,0,.,.,1,.,.,.,.,.,.,.,106,26,39.7514881 -27.3,1,77.25,0,110,.,.,1,.,.,.,.,.,.,.,.,.,39.78720238 -27.3,1,85,0,110,.,.,1,.,.,.,.,.,.,.,.,.,39.83333333 -27.3,1,93,0,110,.,.,1,.,.,.,.,.,.,.,.,.,39.88095238 -27.3,1,95.5,0,0,.,.,1,.,.,.,.,.,.,.,76,27,39.89583333 -27.3,0,101,.,.,.,.,.,3.36,1,.,.,.,.,.,.,.,39.92857143 -27.3,1,101,0,110,.,.,1,.,.,.,.,.,.,.,.,.,39.92857143 -27.3,1,109,0,110,.,.,1,.,.,.,.,.,.,.,.,.,39.97619048 -27.3,1,117,0,110,.,.,1,.,.,.,.,.,.,.,.,.,40.02380952 -27.3,1,119.0833333,0,0,.,.,1,.,.,.,.,.,.,.,78,21,40.03621032 -27.3,0,125,.,.,.,.,.,2.19,1,.,.,.,.,.,.,.,40.07142857 -27.4,1,0,0,110,.,.,1,.,.,.,.,.,.,9.7,78,21,40.07142857 -27.4,1,8,0,110,.,.,1,.,.,.,.,.,.,.,.,.,40.11904762 -27.4,1,16,0,110,.,.,1,.,.,.,.,.,.,.,.,.,40.16666667 -27.4,1,18,0,0,.,.,1,.,.,.,.,.,.,.,71,23,40.17857143 -27.4,1,32,0,150,.,.,1,.,.,.,.,.,.,.,.,.,40.26190476 -27.4,0,42.5,.,.,.,.,.,0.399,1,.,.,.,.,.,.,.,40.32440476 -27.4,1,42.5,0,0,.,.,1,.,.,.,.,.,.,.,81,27,40.32440476 -27.4,1,44,0,150,.,.,1,.,.,.,.,.,.,.,.,.,40.33333333 -27.4,1,58,0,100,.,.,1,.,.,.,.,.,.,.,.,.,40.41666667 -27.4,1,66.5,0,0,.,.,1,.,.,.,.,.,.,.,106,39,40.4672619 -27.4,1,73,0,100,.,.,1,.,.,.,.,.,.,.,.,.,40.50595238 -27.4,1,77.5,0,100,.,.,1,.,.,.,.,.,.,.,.,.,40.5327381 -27.4,1,82,0,100,.,.,1,.,.,.,.,.,.,.,.,.,40.55952381 -27.4,1,90.5,0,0,.,.,1,.,.,.,.,.,.,.,150,51,40.61011905 -27.4,1,94,0,100,.,.,1,.,.,.,.,.,.,.,.,.,40.63095238 -27.4,1,101,0,100,.,.,1,.,.,.,.,.,.,.,.,.,40.67261905 -27.4,1,106,0,100,.,.,1,.,.,.,.,.,.,.,.,.,40.70238095 -27.4,1,113,0,0,.,.,1,.,.,.,.,.,.,.,138,40,40.74404762 -27.4,1,116,0,100,.,.,1,.,.,.,.,.,.,.,.,.,40.76190476 -27.4,1,122,0,100,.,.,1,.,.,.,.,.,.,.,.,.,40.79761905 -27.4,1,128,0,100,.,.,1,.,.,.,.,.,.,.,.,.,40.83333333 -27.4,0,137.5,.,.,.,.,.,0.796,1,.,.,.,.,.,.,.,40.88988095 -27.4,1,137.5,0,0,.,.,1,.,.,.,.,.,.,.,90,32,40.88988095 -27.4,1,140,0,100,.,.,1,.,.,.,.,.,.,.,.,.,40.9047619 -27.4,1,146,0,100,.,.,1,.,.,.,.,.,.,.,.,.,40.94047619 -27.4,1,152,0,100,.,.,1,.,.,.,.,.,.,.,.,.,40.97619048 -27.4,1,162.5666667,0,0,.,.,1,.,.,.,.,.,.,.,63,27,41.0390873 -27.4,1,164,0,100,.,.,1,.,.,.,.,.,.,.,.,.,41.04761905 -27.4,1,170,0,100,.,.,1,.,.,.,.,.,.,.,.,.,41.08333333 -27.4,1,176,0,100,.,.,1,.,.,.,.,.,.,.,.,.,41.11904762 -27.4,1,186.45,0,0,.,.,1,.,.,.,.,.,.,.,46,21,41.18125 -27.4,1,188,0,100,.,.,1,.,.,.,.,.,.,.,.,.,41.19047619 -27.4,1,191.7,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,41.2125 -27.4,1,194,0,100,.,.,1,.,.,.,.,.,.,.,.,.,41.22619048 -27.4,1,198,0,0,.,.,1,.,.,.,.,.,.,.,57,27,41.25 -27.4,1,200.75,0,100,.,.,1,.,.,.,.,.,.,.,.,.,41.26636905 -27.4,0,210.4166667,.,.,.,.,.,0.431,1,.,.,.,.,.,.,.,41.32390873 -27.5,1,0,0,100,.,.,1,.,.,.,.,.,.,9.7,53,30,41.33779762 -27.5,1,5.25,0,100,.,.,1,.,.,.,.,.,.,.,.,.,41.36904762 -27.5,1,11.75,0,100,.,.,1,.,.,.,.,.,.,.,.,.,41.4077381 -27.5,1,18.5,0,0,.,.,1,.,.,.,.,.,.,.,110,7,41.44791667 -27.5,1,23.25,0,100,.,.,1,.,.,.,.,.,.,.,.,.,41.47619048 -27.5,1,26,0,0,.,.,1,.,.,.,.,.,.,.,88,17,41.49255952 -27.5,1,29.25,0,100,.,.,1,.,.,.,.,.,.,.,.,.,41.51190476 -27.5,1,32.2666667,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,41.52986111 -27.5,1,37.0833333,0,0,.,.,1,.,.,.,.,.,.,.,47,20,41.55853175 -27.5,1,39.4166667,2,100,.,.,1,.,.,.,.,.,.,.,.,.,41.57242063 -27.5,1,45,0,0,.,.,1,.,.,.,.,.,.,.,55,14,41.60565476 -27.5,1,47.25,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,41.61904762 -27.5,0,52.4166667,.,.,.,.,.,5.22,1,.,.,.,.,.,.,.,41.64980159 -27.5,1,53.75,2,100,.,.,1,.,.,.,.,.,.,.,.,.,41.6577381 -27.5,1,60.25,0,0,.,.,1,.,.,.,.,.,.,.,49,18,41.69642857 -27.5,0,64.4166667,.,.,.,.,.,5.71,1,.,.,.,.,.,.,.,41.72123016 -27.5,1,65.8333333,2,100,.,.,1,.,.,.,.,.,.,.,.,.,41.7296627 -27.5,1,71.25,0,0,.,.,1,.,.,.,.,.,.,.,53,12,41.76190476 -27.5,0,76.25,.,.,.,.,.,3.83,1,.,.,.,.,.,.,.,41.79166667 -27.6,1,0,2,100,.,.,1,.,.,.,.,.,.,9.7,53,12,41.81111111 -27.6,1,3.733333333,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,41.83333333 -27.6,1,7.733333333,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,41.85714286 -27.6,1,7.816666667,0,0,.,.,1,.,.,.,.,.,.,.,53,19,41.85763889 -27.6,1,12.23333333,2,100,.,.,1,.,.,.,.,.,.,.,.,.,41.88392857 -27.6,1,23.73333333,2,150,.,.,1,.,.,.,.,.,.,.,.,.,41.95238095 -27.6,1,26.06666667,0,0,.,.,1,.,.,.,.,.,.,.,68,23,41.96626984 -27.6,1,27.73333333,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,41.97619048 -27.6,1,31.73333333,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,42 -27.6,1,36.06666667,2,150,.,.,1,.,.,.,.,.,.,.,.,.,42.02579365 -27.6,1,47.73333333,2,150,.,.,1,.,.,.,.,.,.,.,.,.,42.0952381 -27.6,1,58.73333333,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,42.16071429 -27.6,1,59.23333333,2,150,.,.,1,.,.,.,.,.,.,.,.,.,42.16369048 -27.6,1,59.73333333,0,0,.,.,1,.,.,.,.,.,.,.,63,19,42.16666667 -27.6,1,63.73333333,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,42.19047619 -27.6,1,72.48333333,2,100,.,.,1,.,.,.,.,.,.,.,.,.,42.24255952 -27.6,1,73.73333333,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,42.25 -27.6,1,83.73333333,2,100,.,.,1,.,.,.,.,.,.,.,.,.,42.30952381 -27.6,1,84.23333333,0,0,.,.,1,.,.,.,.,.,.,.,74,20,42.3125 -27.6,0,95.15,.,.,.,.,.,0.591,1,.,.,.,.,.,.,.,42.37748016 -27.6,1,96.48333333,2,100,.,.,1,.,.,.,.,.,.,.,.,.,42.38541667 -27.6,1,107.7333333,2,100,.,.,1,.,.,.,.,.,.,.,.,.,42.45238095 -27.6,0,119.0666667,.,.,.,.,.,0.821,1,.,.,.,.,.,.,.,42.51984127 -27.6,1,119.7333333,2,100,.,.,1,.,.,.,.,.,.,.,.,.,42.52380952 -27.6,0,131.7333333,.,.,.,.,.,0.695,1,.,.,.,.,.,.,.,42.5952381 -27.6,1,131.7333333,0,0,.,.,1,.,.,.,.,.,.,.,72,12,42.5952381 -27.6,1,131.9833333,2,100,.,.,1,.,.,.,.,.,.,.,.,.,42.59672619 -27.6,1,135.7333333,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,42.61904762 -27.6,0,143.8666667,.,.,.,.,.,0.916,1,.,.,.,.,.,.,.,42.66746032 -27.6,1,144.0666667,2,110,.,.,1,.,.,.,.,.,.,.,.,.,42.66865079 -27.6,0,155.5666667,.,.,.,.,.,0.975,1,.,.,.,.,.,.,.,42.73710317 -27.7,1,0,2,110,.,.,1,.,.,.,.,.,.,9.7,72,12,42.73809524 -27.7,1,4,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,42.76190476 -27.7,1,12.33333333,2,150,.,.,1,.,.,.,.,.,.,.,.,.,42.81150794 -27.7,1,12.66666667,0,0,.,.,1,.,.,.,.,.,.,.,49,10,42.81349206 -27.7,1,24.33333333,0,0,.,.,1,.,.,.,.,.,.,.,53,6,42.88293651 -27.7,1,24.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,42.88392857 -27.7,1,28,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,42.9047619 -27.7,1,35.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,42.94940476 -27.7,1,48,2,150,.,.,1,.,.,.,.,.,.,.,.,.,43.02380952 -27.7,1,60,2,150,.,.,1,.,.,.,.,.,.,.,.,.,43.0952381 -27.7,1,72,2,150,.,.,1,.,.,.,.,.,.,.,.,.,43.16666667 -27.7,1,84,2,150,.,.,1,.,.,.,.,.,.,.,.,.,43.23809524 -27.7,0,94.83333333,.,.,.,.,.,2.48,1,.,.,.,.,.,.,.,43.30257937 -27.8,1,0,2,150,.,.,1,.,.,.,.,.,.,9.7,36,6,43.30952381 -27.8,1,12.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,43.38392857 -27.8,1,24,2,150,.,.,1,.,.,.,.,.,.,.,.,.,43.45238095 -27.8,1,26.16666667,0,0,.,.,1,.,.,.,.,.,.,.,48,10,43.46527778 -27.8,1,36.58333333,2,150,.,.,1,.,.,.,.,.,.,.,.,.,43.52728175 -27.8,1,48,2,150,.,.,1,.,.,.,.,.,.,.,.,.,43.5952381 -27.8,1,49.25,0,0,.,.,1,.,.,.,.,.,.,.,42,23,43.60267857 -27.8,1,60,2,150,.,.,1,.,.,.,.,.,.,.,.,.,43.66666667 -27.8,1,72,2,150,.,.,1,.,.,.,.,.,.,.,.,.,43.73809524 -27.8,1,84,2,150,.,.,1,.,.,.,.,.,.,.,.,.,43.80952381 -27.8,1,96,2,150,.,.,1,.,.,.,.,.,.,.,.,.,43.88095238 -27.8,1,98.08333333,0,0,.,.,1,.,.,.,.,.,.,.,44,26,43.89335317 -27.8,1,108,2,150,.,.,1,.,.,.,.,.,.,.,.,.,43.95238095 -27.8,1,120,2,150,.,.,1,.,.,.,.,.,.,.,.,.,44.02380952 -27.8,1,121.4166667,0,0,.,.,1,.,.,.,.,.,.,.,60,33,44.03224206 -27.8,1,132,2,150,.,.,1,.,.,.,.,.,.,.,.,.,44.0952381 -27.8,1,144,2,150,.,.,1,.,.,.,.,.,.,.,.,.,44.16666667 -27.8,1,144.2166667,0,0,.,.,1,.,.,.,.,.,.,.,64,49,44.16795635 -27.8,1,156,2,150,.,.,1,.,.,.,.,.,.,.,.,.,44.23809524 -27.8,1,168,2,150,.,.,1,.,.,.,.,.,.,.,.,.,44.30952381 -27.8,1,170.1666667,0,0,.,.,1,.,.,.,.,.,.,.,69,90,44.32242063 -27.8,1,180,2,150,.,.,1,.,.,.,.,.,.,.,.,.,44.38095238 -27.8,1,192.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,44.45535714 -27.8,1,194,0,0,.,.,1,.,.,.,.,.,.,.,84,118,44.46428571 -27.8,1,196,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,44.47619048 -27.8,1,204.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,44.52678571 -27.8,1,216,2,150,.,.,1,.,.,.,.,.,.,.,.,.,44.5952381 -27.8,1,218.1666667,0,0,.,.,1,.,.,.,.,.,.,.,52,124,44.60813492 -27.8,1,228.1666667,2,150,.,.,1,.,.,.,.,.,.,.,.,.,44.66765873 -27.8,1,240,2,150,.,.,1,.,.,.,.,.,.,.,.,.,44.73809524 -27.8,1,242.3333333,0,0,.,.,1,.,.,.,.,.,.,.,47,125,44.75198413 -27.8,1,252.25,2,150,.,.,1,.,.,.,.,.,.,.,.,.,44.8110119 -27.8,1,264,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,44.88095238 -27.8,1,264,2,150,.,.,1,.,.,.,.,.,.,.,.,.,44.88095238 -27.8,1,272.9166667,0,0,.,.,1,.,.,.,.,.,.,.,38,107,44.93402778 -27.8,1,276.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,44.95535714 -27.8,1,280,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,44.97619048 -27.8,1,287.8333333,2,150,.,.,1,.,.,.,.,.,.,.,.,.,45.02281746 -27.8,1,290.5833333,0,0,.,.,1,.,.,.,.,.,.,.,45,98,45.03918651 -27.8,1,300,2,150,.,.,1,.,.,.,.,.,.,.,.,.,45.0952381 -27.8,1,311.9166667,2,150,.,.,1,.,.,.,.,.,.,.,.,.,45.16617063 -27.8,1,313.9166667,0,0,.,.,1,.,.,.,.,.,.,.,37,82,45.1780754 -27.8,1,324,2,150,.,.,1,.,.,.,.,.,.,.,.,.,45.23809524 -27.8,1,335.9166667,2,150,.,.,1,.,.,.,.,.,.,.,.,.,45.30902778 -27.8,1,338,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,45.32142857 -27.8,1,338.0833333,0,0,.,.,1,.,.,.,.,.,.,.,37,72,45.3219246 -27.8,1,340,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,45.33333333 -27.8,1,348,2,150,.,.,1,.,.,.,.,.,.,.,.,.,45.38095238 -27.8,1,360,2,150,.,.,1,.,.,.,.,.,.,.,.,.,45.45238095 -27.8,1,362.3333333,0,0,.,.,1,.,.,.,.,.,.,.,111,48,45.46626984 -27.8,0,370.9166667,.,.,.,.,.,1.56,1,.,.,.,.,.,.,.,45.51736111 -27.8,1,372,2,150,.,.,1,.,.,.,.,.,.,.,.,.,45.52380952 -27.8,1,383.8333333,2,150,.,.,1,.,.,.,.,.,.,.,.,.,45.59424603 -27.8,1,386,0,0,.,.,1,.,.,.,.,.,.,.,112,42,45.60714286 -27.8,1,396,2,150,.,.,1,.,.,.,.,.,.,.,.,.,45.66666667 -27.8,0,408,.,.,.,.,.,0.679,1,.,.,.,.,.,.,.,45.73809524 -27.8,1,408,0,0,.,.,1,.,.,.,.,.,.,.,70,42,45.73809524 -27.8,1,408,2,150,.,.,1,.,.,.,.,.,.,.,.,.,45.73809524 -27.8,1,412,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,45.76190476 -27.8,1,419.75,2,150,.,.,1,.,.,.,.,.,.,.,.,.,45.80803571 -27.8,1,432,2,150,.,.,1,.,.,.,.,.,.,.,.,.,45.88095238 -27.8,1,432.75,0,0,.,.,1,.,.,.,.,.,.,.,24,33,45.88541667 -27.8,1,436,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,45.9047619 -27.8,1,444.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,45.95535714 -27.8,1,456,2,150,.,.,1,.,.,.,.,.,.,.,.,.,46.02380952 -27.8,1,456.3333333,0,0,.,.,1,.,.,.,.,.,.,.,28,29,46.02579365 -27.8,1,468.3333333,2,150,.,.,1,.,.,.,.,.,.,.,.,.,46.09722222 -27.8,1,472,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,46.11904762 -27.8,1,479.6666667,2,150,.,.,1,.,.,.,.,.,.,.,.,.,46.16468254 -27.8,1,481.8333333,0,0,.,.,1,.,.,.,.,.,.,.,25,27,46.17757937 -27.8,1,492,2,150,.,.,1,.,.,.,.,.,.,.,.,.,46.23809524 -27.8,0,503.3666667,.,.,.,.,.,1.82,1,.,.,.,.,.,.,.,46.30575397 -27.8,1,504,2,150,.,.,1,.,.,.,.,.,.,.,.,.,46.30952381 -27.8,1,504.0833333,0,0,.,.,1,.,.,.,.,.,.,.,30,15,46.31001984 -27.8,1,516.3333333,2,150,.,.,1,.,.,.,.,.,.,.,.,.,46.38293651 -27.8,1,520,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,46.4047619 -27.8,1,528.1333333,2,150,.,.,1,.,.,.,.,.,.,.,.,.,46.4531746 -27.8,1,528.5,0,0,.,.,1,.,.,.,.,.,.,.,35,20,46.45535714 -27.8,1,540.5,2,150,.,.,1,.,.,.,.,.,.,.,.,.,46.52678571 -27.8,1,552,2,150,.,.,1,.,.,.,.,.,.,.,.,.,46.5952381 -27.8,1,552.25,0,0,.,.,1,.,.,.,.,.,.,.,32,21,46.59672619 -27.8,1,554,0,0,.,.,1,.,.,.,.,.,.,9.7,.,.,46.60714286 -27.8,1,564,2,150,.,.,1,.,.,.,.,.,.,.,.,.,46.66666667 -27.8,0,575.9166667,.,.,.,.,.,1.78,1,.,.,.,.,.,.,.,46.73759921 -28.1,1,0,2,48,.,.,1,.,.,.,.,.,.,6.25,99,41,24.35714286 -28.1,1,8.5,2,48,.,.,1,.,.,.,.,.,.,.,.,.,24.4077381 -28.1,1,18.9,0,0,.,.,1,.,.,.,.,.,.,.,243,79,24.46964286 -28.1,1,21,2,42,.,.,1,.,.,.,.,.,.,.,.,.,24.48214286 -28.1,1,35.16666667,2,42,.,.,1,.,.,.,.,.,.,.,.,.,24.56646825 -28.1,1,47,2,42,.,.,1,.,.,.,.,.,.,.,.,.,24.63690476 -28.1,1,58,2,42,.,.,1,.,.,.,.,.,.,.,.,.,24.70238095 -28.1,1,66.4166667,0,0,.,.,1,.,.,.,.,.,.,.,100,44,24.75248016 -28.1,1,70,2,42,.,.,1,.,.,.,.,.,.,.,.,.,24.77380952 -28.1,1,82,2,42,.,.,1,.,.,.,.,.,.,.,.,.,24.8452381 -28.1,1,91.8333333,0,0,.,.,1,.,.,.,.,.,.,.,61,48,24.90376984 -28.1,1,94.1666667,2,42,.,.,1,.,.,.,.,.,.,.,.,.,24.91765873 -28.1,0,105.75,.,.,.,.,.,6.08,1,.,.,.,.,.,.,.,24.98660714 -28.1,1,106,2,42,.,.,1,.,.,.,.,.,.,.,.,.,24.98809524 -28.1,1,122,2,42,.,.,1,.,.,.,.,.,.,.,.,.,25.08333333 -28.1,1,134.3333333,2,42,.,.,1,.,.,.,.,.,.,.,.,.,25.15674603 -28.1,1,136.3333333,0,0,.,.,1,.,.,.,.,.,.,.,71,51,25.16865079 -28.1,1,146,2,42,.,.,1,.,.,.,.,.,.,.,.,.,25.22619048 -28.1,1,158,2,32,.,.,1,.,.,.,.,.,.,.,.,.,25.29761905 -28.1,1,160.0833333,0,0,.,.,1,.,.,.,.,.,.,.,111,47,25.31001984 -28.1,1,170,2,32,.,.,1,.,.,.,.,.,.,.,.,.,25.36904762 -28.1,1,182,2,32,.,.,1,.,.,.,.,.,.,.,.,.,25.44047619 -28.1,0,194.1666667,.,.,.,.,.,4.54,1,.,.,.,.,.,.,.,25.51289683 -28.2,1,0,2,32,.,.,1,.,.,.,.,.,.,6.25,111,47,25.51339286 -28.2,1,13.8333333,2,32,.,.,1,.,.,.,.,.,.,.,144,45,25.6547619 -28.2,1,23.8333333,2,32,.,.,1,.,.,.,.,.,.,.,.,.,25.72619048 -28.2,1,35.8333333,2,32,.,.,1,.,.,.,.,.,.,.,.,.,25.79761905 -28.2,1,47.8333333,2,32,.,.,1,.,.,.,.,.,.,.,.,.,25.86904762 -28.2,1,63.1,2,32,.,.,1,.,.,.,.,.,.,.,82,39,25.94047619 -28.2,1,71.8333333,2,32,.,.,1,.,.,.,.,.,.,.,.,.,26.01488095 -28.2,1,84.3333333,2,32,.,.,1,.,.,.,.,.,.,.,.,.,26.08333333 -28.2,1,95.8333333,2,32,.,.,1,.,.,.,.,.,.,.,.,.,26.1577381 -28.2,1,108.3333333,2,32,.,.,1,.,.,.,.,.,.,.,.,.,26.22619048 -28.2,1,119.8333333,2,32,.,.,1,.,.,.,.,.,.,.,.,.,26.29761905 -28.2,1,131.8333333,2,32,.,.,1,.,.,.,.,.,.,.,.,.,26.36904762 -28.2,1,143.8333333,0,32,.,.,1,.,.,.,.,.,.,.,.,.,26.41666667 -28.2,0,151.8333333,.,.,.,.,.,0.89,1,.,.,.,.,.,.,.,26.48015873 -28.2,1,162.5,0,32,.,.,1,.,.,.,.,.,.,.,.,.,26.49107143 -28.2,1,174.8333333,0,32,.,.,1,.,.,.,.,.,.,.,.,.,26.62797619 -28.2,1,187.3333333,0,32,.,.,1,.,.,.,.,.,.,.,.,.,26.70138889 -28.2,1,199.6666666,0,32,.,.,1,.,.,.,.,.,.,.,.,.,26.77083333 -28.2,1,211.3333333,0,32,.,.,1,.,.,.,.,.,.,.,77,47,26.83630952 -28.2,0,231.3333333,.,.,.,.,.,1.11,1,.,.,.,.,.,.,.,26.90793651 -28.3,1,0,0,44,9,12,1,.,.,.,.,.,.,5.735,107,169,38.97619048 -28.3,1,121.4,0,44,.,.,1,.,.,.,.,.,.,.,.,.,39.05357143 -28.3,1,124.2,0,0,.,.,1,.,.,.,.,.,.,5.7,.,.,39.0702381 -28.3,1,132.4,0,44,.,.,1,.,.,.,.,.,.,.,.,.,39.11904762 -28.3,0,144.233333,.,.,.,.,.,1.77,1,.,.,.,.,.,.,.,39.18948413 -28.4,1,0,0,44,9,12,1,.,.,.,.,.,.,6.115,60,77,41.33482143 -28.4,0,118.75,.,.,.,.,.,0.536,1,.,.,.,.,.,.,.,41.39880952 -28.5,1,0,0,50,9,12,1,.,.,.,.,.,.,6,47,40,43.33482143 -28.5,0,119.9166666,.,.,.,.,.,0.387,1,.,.,.,.,.,.,.,43.40575397 -28.5,1,120,0,50,.,.,1,.,.,.,.,.,.,.,.,.,43.40625 -28.5,1,133.25,0,50,.,.,1,.,.,.,.,.,.,.,.,.,43.48511905 -28.5,1,143.75,0,60,.,.,1,.,.,.,.,.,.,.,.,.,43.54761905 -28.5,1,155.75,0,60,.,.,1,.,.,.,.,.,.,.,.,.,43.61904762 -28.5,1,168.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,43.69494048 -28.5,1,179.75,0,60,.,.,1,.,.,.,.,.,.,.,.,.,43.76190476 -28.5,0,191.25,.,.,.,.,.,0.729,1,.,.,.,.,.,.,.,43.83035714 -28.6,1,0,0,72,9,12,1,.,.,.,.,.,.,6.3,33,41,45.54761905 -28.6,0,120.5,.,.,.,.,.,2.61,1,.,.,.,.,.,.,.,45.62202381 -29.1,1,0,2,70,.,.,1,.,.,.,.,.,.,10,10,21,80.9702381 -29.1,1,12,2,70,.,.,1,.,.,.,.,.,.,.,.,.,81.04166667 -29.1,1,25.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,81.12202381 -29.1,1,37,0,70,.,.,1,.,.,.,.,.,.,.,.,.,81.19047619 -29.1,1,49.33333334,0,70,.,.,1,.,.,.,.,.,.,.,.,.,81.26388889 -29.1,0,60,.,.,.,.,.,0.545,1,.,.,.,.,.,.,.,81.32738095 -29.2,1,0,0,0,.,.,1,.,.,.,.,.,.,10.57,19,27,83.39434524 -29.2,1,4.9166667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,83.42361111 -29.2,1,16.75,0,100,.,.,1,.,.,.,.,.,.,.,.,.,83.49404762 -29.2,1,28.75,0,100,.,.,1,.,.,.,.,.,.,.,.,.,83.56547619 -29.2,1,40.75,0,100,.,.,1,.,.,.,.,.,.,.,.,.,83.63690476 -29.2,1,52.75,0,100,.,.,1,.,.,.,.,.,.,.,.,.,83.70833333 -29.2,1,64.75,0,100,.,.,1,.,.,.,.,.,.,.,.,.,83.7797619 -29.2,0,76.5,.,.,.,.,.,0.061,1,.,.,.,.,.,.,.,83.84970238 -30.1,1,0,0,0,.,.,1,.,.,.,.,.,.,14.7,34,26,102.8968254 -30.1,1,8.333333333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,102.9464286 -30.1,1,13.83333333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,102.9791667 -30.1,1,22.83333333,0,0,.,.,1,.,.,.,.,.,.,.,35,26,103.0327381 -30.1,1,26.33333333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,103.0535714 -30.1,1,37.33333333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,103.1190476 -30.1,1,48,0,0,.,.,1,.,.,.,.,.,.,.,30,22,103.1825397 -30.1,0,48.83333333,.,.,.,.,.,0.187,1,.,.,.,.,.,.,.,103.1875 -30.1,1,49.33333333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,103.1904762 -30.1,0,49.83333333,.,.,.,.,.,0.296,1,.,.,.,.,.,.,.,103.1934524 -30.1,0,50.33333333,.,.,.,.,.,1.34,1,.,.,.,.,.,.,.,103.1964286 -30.1,0,50.83333333,.,.,.,.,.,1.93,1,.,.,.,.,.,.,.,103.1994048 -30.1,0,51.33333333,.,.,.,.,.,1.73,1,.,.,.,.,.,.,.,103.202381 -30.1,0,53.33333333,.,.,.,.,.,0.511,1,.,.,.,.,.,.,.,103.2142857 -30.1,0,55.33333333,.,.,.,.,.,0.346,1,.,.,.,.,.,.,.,103.2261905 -30.1,0,57.33333333,.,.,.,.,.,0.281,1,.,.,.,.,.,.,.,103.2380952 -30.1,0,61.48333333,.,.,.,.,.,0.118,1,.,.,.,.,.,.,.,103.2627976 -30.1,1,61.66666667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,103.2638889 -30.1,0,72.08333333,.,.,.,.,.,0.212,1,.,.,.,.,.,.,.,103.3258929 -30.1,1,72.08333333,0,0,.,.,1,.,.,.,.,.,.,.,45,23,103.3258929 -30.1,1,73.33333333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,103.3333333 -30.1,1,85.83333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,103.4077381 -30.1,1,94.83333333,0,0,.,.,1,.,.,.,.,.,.,.,34,24,103.4613095 -30.1,1,99.33333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,103.4880952 -30.1,1,109.3333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,103.547619 -30.1,1,119.8333333,0,0,.,.,1,.,.,.,.,.,.,.,45,18,103.610119 -30.1,1,122.3333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,103.625 -30.1,1,133.3333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,103.6904762 -30.1,1,143.3333333,0,0,.,.,1,.,.,.,.,.,.,.,33,23,103.75 -30.1,0,145.3333333,.,.,.,.,.,0.443,1,.,.,.,.,.,.,.,103.7619048 -30.1,1,145.3333333,0,150,.,.,1,.,.,.,.,.,.,.,.,.,103.7619048 -30.1,1,158.0833333,0,175,.,.,1,.,.,.,.,.,.,.,.,.,103.8377976 -30.1,1,167.8333333,0,0,.,.,1,.,.,.,.,.,.,.,21,25,103.8958333 -30.1,1,169.0833333,0,0,.,.,1,.,.,.,.,.,.,.,31,22,103.9032738 -30.1,1,169.7166667,0,0,.,.,1,.,.,.,.,.,.,14.7,.,.,103.9070437 -30.1,1,174.8333333,0,175,.,.,1,.,.,.,.,.,.,.,.,.,103.9375 -30.1,1,181.8333333,0,175,.,.,1,.,.,.,.,.,.,.,.,.,103.9791667 -31.1,1,0,0,0,.,.,1,.,.,.,.,.,.,6.9,41,36,34.03869048 -31.1,1,37.5,0,56,.,.,1,.,.,.,.,.,.,.,.,.,34.26190476 -31.1,1,47.5,0,0,.,.,1,.,.,.,.,.,.,.,49,39,34.32142857 -31.1,1,50.5,0,56,.,.,1,.,.,.,.,.,.,.,.,.,34.33928571 -31.1,1,61.5,0,56,.,.,1,.,.,.,.,.,.,.,.,.,34.4047619 -31.1,1,74.16666667,0,56,.,.,1,.,.,.,.,.,.,.,.,.,34.48015873 -31.1,1,85.5,0,56,.,.,1,.,.,.,.,.,.,.,.,.,34.54761905 -31.1,1,95.5,0,0,.,.,1,.,.,.,.,.,.,.,41,30,34.60714286 -31.1,1,97.5,0,56,.,.,1,.,.,.,.,.,.,.,.,.,34.61904762 -31.1,1,109.5,0,56,.,.,1,.,.,.,.,.,.,.,.,.,34.69047619 -31.1,1,122.25,0,56,.,.,1,.,.,.,.,.,.,.,.,.,34.76636905 -31.1,1,134.5,0,56,.,.,1,.,.,.,.,.,.,.,.,.,34.83928571 -31.1,1,145.5,0,56,.,.,1,.,.,.,.,.,.,.,.,.,34.9047619 -31.1,1,158,0,56,.,.,1,.,.,.,.,.,.,.,.,.,34.97916667 -31.1,1,168,0,0,.,.,1,.,.,.,.,.,.,.,41,23,35.03869048 -31.1,0,170,.,.,.,.,.,0.736,1,.,.,.,.,.,.,.,35.05059524 -31.1,1,170,0,56,.,.,1,.,.,.,.,.,.,.,.,.,35.05059524 -31.1,1,181.5,0,60,.,.,1,.,.,.,.,.,.,.,.,.,35.11904762 -31.1,1,194,0,60,.,.,1,.,.,.,.,.,.,.,.,.,35.19345238 -31.1,1,206.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,35.26785714 -31.1,1,214.9166667,0,0,.,.,1,.,.,.,.,.,.,.,46,30,35.31795635 -31.1,1,218.25,0,70,.,.,1,.,.,.,.,.,.,.,.,.,35.33779762 -31.1,1,229.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,35.4047619 -31.1,1,242.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,35.48214286 -31.1,1,253.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,35.54761905 -31.1,1,263.5,0,0,.,.,1,.,.,.,.,.,.,.,57,29,35.60714286 -31.1,1,266.75,0,70,.,.,1,.,.,.,.,.,.,.,.,.,35.6264881 -31.1,1,277.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,35.69047619 -31.1,1,289.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,35.76190476 -31.1,1,301.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,35.83333333 -31.1,1,314.75,0,70,.,.,1,.,.,.,.,.,.,.,.,.,35.91220238 -31.1,1,325.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,35.97619048 -31.1,0,336.25,.,.,.,.,.,1.51,1,.,.,.,.,.,.,.,36.04017857 -31.1,1,336.25,0,0,.,.,1,.,.,.,.,.,.,.,42,27,36.04017857 -31.1,1,338,0,70,.,.,1,.,.,.,.,.,.,.,.,.,36.05059524 -31.1,1,349.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,36.11904762 -31.1,1,362.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,36.19642857 -31.1,1,373.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,36.26190476 -31.1,1,384,0,0,.,.,1,.,.,.,.,.,.,.,41,19,36.32440476 -31.1,1,386,0,70,.,.,1,.,.,.,.,.,.,.,.,.,36.33630952 -31.1,1,399.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,36.41666667 -31.1,1,407.6666667,0,0,.,.,1,.,.,.,.,.,.,6.9,.,.,36.46527778 -31.1,1,413.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,36.5 -31.1,1,421.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,36.54761905 -31.1,1,433.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,36.61904762 -31.1,1,437.25,0,0,.,.,1,.,.,.,.,.,.,.,47,21,36.64136905 -31.1,1,445.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,36.69047619 -31.1,1,457.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,36.76190476 -31.1,1,469.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,36.83333333 -31.1,1,482.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,36.91071429 -31.1,1,494.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,36.98214286 -31.1,1,506.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,37.05357143 -32.1,1,0,0,0,.,.,1,.,.,.,.,.,.,6,35,30,42.46309524 -32.1,1,14.36666667,2,90,.,.,1,.,.,.,.,.,.,.,.,.,42.54861111 -32.1,1,26.95,2,90,.,.,1,.,.,.,.,.,.,.,.,.,42.6235119 -32.1,1,39.2,0,40,.,.,1,.,.,.,.,.,.,.,.,.,42.69642857 -32.1,1,51.7,0,40,.,.,1,.,.,.,.,.,.,.,.,.,42.77083333 -32.1,1,63.45,0,40,.,.,1,.,.,.,.,.,.,.,.,.,42.84077381 -32.1,1,71.36666667,0,0,.,.,1,.,.,.,.,.,.,.,37,25,42.88789683 -32.1,1,75.2,0,40,.,.,1,.,.,.,.,.,.,.,.,.,42.91071429 -32.1,1,87.2,0,40,.,.,1,.,.,.,.,.,.,.,.,.,42.98214286 -32.1,1,99.2,0,40,.,.,1,.,.,.,.,.,.,.,.,.,43.05357143 -32.1,1,111.2,0,40,.,.,1,.,.,.,.,.,.,.,.,.,43.125 -32.1,0,122.2,.,.,.,.,.,0.23,1,.,.,.,.,.,.,.,43.19047619 -32.1,1,122.2,0,0,.,.,1,.,.,.,.,.,.,.,47,42,43.19047619 -32.1,1,123.2,0,40,.,.,1,.,.,.,.,.,.,.,.,.,43.19642857 -32.1,1,135.2,0,50,.,.,1,.,.,.,.,.,.,.,.,.,43.26785714 -32.1,1,143.1166667,0,0,.,.,1,.,.,.,.,.,.,.,44,42,43.31498016 -32.1,1,147.2,0,50,.,.,1,.,.,.,.,.,.,.,.,.,43.33928571 -32.1,1,159.2,0,50,.,.,1,.,.,.,.,.,.,.,.,.,43.41071429 -32.1,1,171.45,0,50,.,.,1,.,.,.,.,.,.,.,.,.,43.48363095 -32.1,1,183.2,0,50,.,.,1,.,.,.,.,.,.,.,.,.,43.55357143 -32.1,1,195.2,0,50,.,.,1,.,.,.,.,.,.,.,.,.,43.625 -32.1,1,207.7,0,50,.,.,1,.,.,.,.,.,.,.,.,.,43.69940476 -32.1,1,219.2,0,50,.,.,1,.,.,.,.,.,.,.,.,.,43.76785714 -32.1,1,232.2,0,50,.,.,1,.,.,.,.,.,.,.,.,.,43.8452381 -32.1,0,243.1166667,.,.,.,.,.,1.85,1,.,.,.,.,.,.,.,43.91021825 -32.1,1,243.1166667,0,0,.,.,1,.,.,.,.,.,.,.,115,93,43.91021825 -32.1,1,244.2,0,50,.,.,1,.,.,.,.,.,.,.,.,.,43.91666667 -32.1,1,256.2,0,50,.,.,1,.,.,.,.,.,.,.,.,.,43.98809524 -32.1,1,268.2,0,50,.,.,1,.,.,.,.,.,.,.,.,.,44.05952381 -32.1,1,280.2,0,50,.,.,1,.,.,.,.,.,.,.,.,.,44.13095238 -32.1,0,294.2,.,.,.,.,.,2.36,1,.,.,.,.,.,.,.,44.21428571 -32.1,1,295.2,0,50,.,.,1,.,.,.,.,.,.,.,.,.,44.2202381 -32.1,0,295.7,.,.,.,.,.,2.47,1,.,.,.,.,.,.,.,44.22321429 -32.1,0,296.2,.,.,.,.,.,9.15,1,.,.,.,.,.,.,.,44.22619048 -32.1,0,296.7,.,.,.,.,.,5.64,1,.,.,.,.,.,.,.,44.22916667 -32.1,0,297.2,.,.,.,.,.,5.3,1,.,.,.,.,.,.,.,44.23214286 -32.1,0,299.2,.,.,.,.,.,3.7,1,.,.,.,.,.,.,.,44.24404762 -32.1,0,301.2,.,.,.,.,.,3.47,1,.,.,.,.,.,.,.,44.25595238 -32.1,0,303.2,.,.,.,.,.,3.43,1,.,.,.,.,.,.,.,44.26785714 -32.1,0,307.2,.,.,.,.,.,1.85,1,.,.,.,.,.,.,.,44.29166667 -32.1,1,307.2,0,50,.,.,1,.,.,.,.,.,.,.,.,.,44.29166667 -32.1,1,314.2,0,0,.,.,1,.,.,.,.,.,.,.,80,92,44.33333333 -32.1,1,315.2,0,50,.,.,1,.,.,.,.,.,.,.,.,.,44.33928571 -32.1,1,327.2,0,50,.,.,1,.,.,.,.,.,.,.,.,.,44.41071429 -32.1,1,338.95,0,50,.,.,1,.,.,.,.,.,.,.,.,.,44.48065476 -32.1,1,350.95,0,50,.,.,1,.,.,.,.,.,.,.,.,.,44.55208333 -32.1,1,363.5333333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,44.62698413 -32.1,1,375.2,0,50,.,.,1,.,.,.,.,.,.,.,.,.,44.69642857 -32.1,1,388.0333333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,44.77281746 -32.1,1,399.45,0,50,.,.,1,.,.,.,.,.,.,.,.,.,44.84077381 -32.1,1,407.2,0,0,.,.,1,.,.,.,.,.,.,.,71,99,44.88690476 -32.1,0,410.2833333,.,.,.,.,.,0.669,1,.,.,.,.,.,.,.,44.90525794 -32.1,1,410.7,0,50,.,.,1,.,.,.,.,.,.,.,.,.,44.9077381 -32.1,0,422.2,.,.,.,.,.,0.272,1,.,.,.,.,.,.,.,44.97619048 -32.1,1,423.5333333,0,50,.,.,1,.,.,.,.,.,.,.,.,.,44.98412698 -32.1,1,434.95,0,50,.,.,1,.,.,.,.,.,.,.,.,.,45.05208333 -32.1,1,447.2,0,50,.,.,1,.,.,.,.,.,.,.,.,.,45.125 -32.1,1,458.7,0,50,.,.,1,.,.,.,.,.,.,.,.,.,45.19345238 -32.1,1,471.2,0,55,.,.,1,.,.,.,.,.,.,.,.,.,45.26785714 -32.1,1,479.2,0,0,.,.,1,.,.,.,.,.,.,.,68,90,45.31547619 -32.1,1,483.2,0,55,.,.,1,.,.,.,.,.,.,.,.,.,45.33928571 -32.1,1,495.45,0,55,.,.,1,.,.,.,.,.,.,.,.,.,45.41220238 -32.1,1,508.3666667,0,55,.,.,1,.,.,.,.,.,.,.,.,.,45.4890873 -32.1,1,519.45,0,55,.,.,1,.,.,.,.,.,.,.,.,.,45.55505952 -32.1,1,532.2,0,55,.,.,1,.,.,.,.,.,.,.,.,.,45.63095238 -32.1,1,544.8666667,0,55,.,.,1,.,.,.,.,.,.,.,.,.,45.70634921 -32.1,1,556.2,0,55,.,.,1,.,.,.,.,.,.,.,.,.,45.77380952 -32.1,1,568.45,0,55,.,.,1,.,.,.,.,.,.,.,.,.,45.84672619 -32.1,0,580.95,.,.,.,.,.,1.38,1,.,.,.,.,.,.,.,45.92113095 -32.1,1,580.95,0,0,.,.,1,.,.,.,.,.,.,.,90,157,45.92113095 -32.1,1,581.45,0,55,.,.,1,.,.,.,.,.,.,.,.,.,45.92410714 -32.1,1,593.2,0,55,.,.,1,.,.,.,.,.,.,.,.,.,45.99404762 -32.1,0,604.45,.,.,.,.,.,0.285,1,.,.,.,.,.,.,.,46.0610119 -32.1,1,605.45,0,55,.,.,1,.,.,.,.,.,.,.,.,.,46.06696429 -32.1,1,617.2,0,55,.,.,1,.,.,.,.,.,.,.,.,.,46.13690476 -32.1,1,629.2,0,55,.,.,1,.,.,.,.,.,.,.,.,.,46.20833333 -32.1,1,641.2,0,60,.,.,1,.,.,.,.,.,.,.,.,.,46.2797619 -32.1,1,647.95,0,0,.,.,1,.,.,.,.,.,.,.,60,85,46.31994048 -32.1,1,653.2,0,60,.,.,1,.,.,.,.,.,.,.,.,.,46.35119048 -32.1,1,665.2,0,60,.,.,1,.,.,.,.,.,.,.,.,.,46.42261905 -32.1,1,677.2,0,60,.,.,1,.,.,.,.,.,.,.,.,.,46.49404762 -32.1,1,689.2,0,60,.,.,1,.,.,.,.,.,.,.,.,.,46.56547619 -32.1,1,701.2,0,60,.,.,1,.,.,.,.,.,.,.,.,.,46.63690476 -32.1,1,713.3666667,0,60,.,.,1,.,.,.,.,.,.,.,.,.,46.7093254 -32.1,1,725.2,0,60,.,.,1,.,.,.,.,.,.,.,.,.,46.7797619 -32.1,0,736.2,.,.,.,.,.,1.48,1,.,.,.,.,.,.,.,46.8452381 -32.1,1,737.2,0,60,.,.,1,.,.,.,.,.,.,.,.,.,46.85119048 -32.1,1,742.7,0,0,.,.,1,.,.,.,.,.,.,.,66,76,46.88392857 -32.1,1,749.2,0,60,.,.,1,.,.,.,.,.,.,.,.,.,46.92261905 -32.1,1,761.2,0,60,.,.,1,.,.,.,.,.,.,.,.,.,46.99404762 -32.1,1,773.2,0,60,.,.,1,.,.,.,.,.,.,.,.,.,47.06547619 -32.1,1,785.2,0,60,.,.,1,.,.,.,.,.,.,.,.,.,47.13690476 -32.1,1,797.2,0,60,.,.,1,.,.,.,.,.,.,.,.,.,47.20833333 -32.1,1,809.2,0,60,.,.,1,.,.,.,.,.,.,.,.,.,47.2797619 -32.1,1,815.2,0,0,.,.,1,.,.,.,.,.,.,.,67,92,47.31547619 -32.1,1,821.2,0,0,.,.,1,.,.,.,.,.,.,6.95,.,.,47.35119048 -32.1,1,821.2,0,60,.,.,1,.,.,.,.,.,.,.,.,.,47.35119048 -32.1,1,833.2,0,60,.,.,1,.,.,.,.,.,.,.,.,.,47.42261905 -32.1,1,845.2,0,60,.,.,1,.,.,.,.,.,.,.,.,.,47.49404762 -32.1,1,856.7,0,60,.,.,1,.,.,.,.,.,.,.,.,.,47.5625 -32.1,1,868.8666667,0,60,.,.,1,.,.,.,.,.,.,.,.,.,47.63492063 -32.1,1,884.7,0,60,.,.,1,.,.,.,.,.,.,.,.,.,47.72916667 -32.1,1,891.5333333,0,0,.,.,1,.,.,.,.,.,.,.,162,139,47.76984127 -32.1,1,896.2,0,60,.,.,1,.,.,.,.,.,.,.,.,.,47.79761905 -32.1,1,905.2,0,60,.,.,1,.,.,.,.,.,.,.,.,.,47.85119048 -32.1,1,911.7,0,0,.,.,1,.,.,.,.,.,.,.,376,215,47.88988095 -32.1,1,914.7,0,0,.,.,1,.,.,.,.,.,.,.,421,231,47.9077381 -32.1,1,917.2,0,60,.,.,1,.,.,.,.,.,.,.,.,.,47.92261905 -33.1,1,0,0,0,.,.,1,.,.,.,.,.,.,11.09,31,31,53.61011905 -33.1,1,14.55,0,75,.,.,1,.,.,.,.,.,.,.,.,.,53.69672619 -33.1,1,24.25,0,0,.,.,1,.,.,.,.,.,.,.,38,26,53.75446429 -33.1,1,25.95,0,75,.,.,1,.,.,.,.,.,.,.,.,.,53.76458333 -33.1,1,37.3,0,75,.,.,1,.,.,.,.,.,.,.,.,.,53.83214286 -33.1,1,48,0,0,.,.,1,.,.,.,.,.,.,.,36,25,53.89583333 -33.1,1,49.96666667,0,75,.,.,1,.,.,.,.,.,.,.,.,.,53.90753968 -33.1,1,61.48333333,0,75,.,.,1,.,.,.,.,.,.,.,.,.,53.97609127 -33.1,1,72.08333333,0,0,.,.,1,.,.,.,.,.,.,.,31,28,54.03918651 -33.1,1,73.88333333,0,75,.,.,1,.,.,.,.,.,.,.,.,.,54.04990079 -33.1,1,85.71666667,0,75,.,.,1,.,.,.,.,.,.,.,.,.,54.1203373 -33.1,1,91.25,0,0,.,.,1,.,.,.,.,.,.,.,29,22,54.15327381 -33.1,0,96.25,.,.,.,.,.,0.256,1,.,.,.,.,.,.,.,54.18303571 -33.1,1,98.05,0,75,.,.,1,.,.,.,.,.,.,.,.,.,54.19375 -33.1,1,110.5166667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,54.26795635 -33.1,1,120.1666667,0,0,.,.,1,.,.,.,.,.,.,.,37,20,54.32539683 -33.1,1,121.9833333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,54.33621032 -33.1,1,133.9166667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,54.40724206 -33.1,1,144,0,0,.,.,1,.,.,.,.,.,.,.,27,17,54.4672619 -33.1,1,146.5,0,100,.,.,1,.,.,.,.,.,.,.,.,.,54.48214286 -33.1,1,157.6333333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,54.5484127 -33.1,0,168.1666667,.,.,.,.,.,0.437,1,.,.,.,.,.,.,.,54.61111111 -33.1,1,168.1666667,0,0,.,.,1,.,.,.,.,.,.,.,26,22,54.61111111 -33.1,1,170.2666667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,54.62361111 -33.1,1,181.7166667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,54.69176587 -33.1,1,192,0,0,.,.,1,.,.,.,.,.,.,.,29,28,54.75297619 -33.1,1,193.9333333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,54.76448413 -33.1,1,205.6,0,100,.,.,1,.,.,.,.,.,.,.,.,.,54.83392857 -33.1,1,216,0,0,.,.,1,.,.,.,.,.,.,.,42,31,54.89583333 -33.1,1,217.8666667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,54.90694444 -33.1,1,230.5166667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,54.98224206 -33.1,1,240.0833333,0,0,.,.,1,.,.,.,.,.,.,.,47,34,55.03918651 -33.1,1,242.3666667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,55.05277778 -33.1,1,253.7166667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,55.1203373 -33.1,1,263.9166667,0,0,.,.,1,.,.,.,.,.,.,.,33,23,55.18105159 -33.1,1,265.8833333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,55.19275794 -33.1,1,277.5333333,0,125,.,.,1,.,.,.,.,.,.,.,.,.,55.26210317 -33.1,1,288.25,0,0,.,.,1,.,.,.,.,.,.,.,28,22,55.32589286 -33.1,1,292.7833333,0,125,.,.,1,.,.,.,.,.,.,.,.,.,55.35287698 -33.1,1,302.5833333,0,125,.,.,1,.,.,.,.,.,.,.,.,.,55.41121032 -33.1,1,312,0,0,.,.,1,.,.,.,.,.,.,.,31,16,55.4672619 -33.1,1,313.9833333,0,125,.,.,1,.,.,.,.,.,.,.,.,.,55.47906746 -33.1,1,326,0,125,.,.,1,.,.,.,.,.,.,.,.,.,55.55059524 -33.1,1,335,0,0,.,.,1,.,.,.,.,.,.,.,29,19,55.60416667 -33.1,0,336.5833333,.,.,.,.,.,2.18,1,.,.,.,.,.,.,.,55.61359127 -33.1,1,337.75,0,125,.,.,1,.,.,.,.,.,.,.,.,.,55.62053571 -33.1,1,350.0333333,0,125,.,.,1,.,.,.,.,.,.,.,.,.,55.69365079 -33.1,1,360,0,0,.,.,1,.,.,.,.,.,.,.,27,19,55.75297619 -33.1,1,361.7166667,0,125,.,.,1,.,.,.,.,.,.,.,.,.,55.76319444 -33.1,1,362.9333333,0,0,.,.,1,.,.,.,.,.,.,11.09,.,.,55.77043651 -33.1,1,373.8333333,0,125,.,.,1,.,.,.,.,.,.,.,.,.,55.83531746 -33.1,1,384.4166667,0,0,.,.,1,.,.,.,.,.,.,.,33,18,55.89831349 -33.1,1,386.15,0,125,.,.,1,.,.,.,.,.,.,.,.,.,55.90863095 -33.1,1,397.75,0,125,.,.,1,.,.,.,.,.,.,.,.,.,55.97767857 -33.1,1,409.6,0,125,.,.,1,.,.,.,.,.,.,.,.,.,56.04821429 -33.1,1,421.4666667,0,125,.,.,1,.,.,.,.,.,.,.,.,.,56.11884921 -33.1,1,432.5,0,0,.,.,1,.,.,.,.,.,.,.,40,20,56.18452381 -33.1,1,434.4833333,0,125,.,.,1,.,.,.,.,.,.,.,.,.,56.19632937 -33.1,1,445.75,0,125,.,.,1,.,.,.,.,.,.,.,.,.,56.26339286 -33.1,1,458.3333333,0,125,.,.,1,.,.,.,.,.,.,.,.,.,56.33829365 -33.1,1,469.8,0,125,.,.,1,.,.,.,.,.,.,.,.,.,56.40654762 -33.1,1,483.9166667,0,125,.,.,1,.,.,.,.,.,.,.,.,.,56.4905754 -33.1,1,493.7166667,0,125,.,.,1,.,.,.,.,.,.,.,.,.,56.54890873 -33.1,0,505.1166667,.,.,.,.,.,1.21,1,.,.,.,.,.,.,.,56.61676587 -33.1,1,505.1166667,0,0,.,.,1,.,.,.,.,.,.,.,30,21,56.61676587 -33.1,1,507.45,0,125,.,.,1,.,.,.,.,.,.,.,.,.,56.63065476 -33.1,1,517.6166667,0,125,.,.,1,.,.,.,.,.,.,.,.,.,56.69117063 -33.1,1,524.1833333,0,0,.,.,1,.,.,.,.,.,.,11.09,.,.,56.73025794 -33.1,1,532.7833333,0,125,.,.,1,.,.,.,.,.,.,.,.,.,56.78144841 -33.1,1,541.4666667,0,125,.,.,1,.,.,.,.,.,.,.,.,.,56.83313492 -33.1,1,551.5,0,0,.,.,1,.,.,.,.,.,.,.,33,28,56.89285714 -33.1,1,554.05,0,125,.,.,1,.,.,.,.,.,.,.,.,.,56.90803571 -33.1,1,565.6166667,0,125,.,.,1,.,.,.,.,.,.,.,.,.,56.97688492 -33.1,1,578.0833333,0,125,.,.,1,.,.,.,.,.,.,.,.,.,57.05109127 -33.1,1,589.85,0,125,.,.,1,.,.,.,.,.,.,.,.,.,57.12113095 -33.1,1,600,0,0,.,.,1,.,.,.,.,.,.,.,54,22,57.18154762 -33.1,1,602.6666667,0,125,.,.,1,.,.,.,.,.,.,.,.,.,57.19742063 -33.1,1,613.35,0,125,.,.,1,.,.,.,.,.,.,.,.,.,57.2610119 -33.1,1,626.0833333,0,125,.,.,1,.,.,.,.,.,.,.,.,.,57.33680556 -33.1,1,637.5833333,0,125,.,.,1,.,.,.,.,.,.,.,.,.,57.40525794 -33.1,1,650.25,0,125,.,.,1,.,.,.,.,.,.,.,.,.,57.48065476 -33.1,1,651.9166667,0,0,.,.,1,.,.,.,.,.,.,.,41,36,57.4905754 -33.1,1,661.35,0,125,.,.,1,.,.,.,.,.,.,.,.,.,57.54672619 -33.1,1,671.5,0,0,.,.,1,.,.,.,.,.,.,.,35,23,57.60714286 -33.1,1,674.55,0,125,.,.,1,.,.,.,.,.,.,.,.,.,57.62529762 -33.1,0,674.75,.,.,.,.,.,0.566,1,.,.,.,.,.,.,.,57.6264881 -34.1,1,0,0,0,.,.,1,.,.,.,.,.,.,6.85,34,31,16.74702381 -34.1,1,10,0,48,.,.,1,.,.,.,.,.,.,.,.,.,16.80654762 -34.1,1,22.41666667,0,48,.,.,1,.,.,.,.,.,.,.,.,.,16.88045635 -34.1,1,23.5,0,0,.,.,1,.,.,.,.,.,.,.,47,40,16.88690476 -34.1,1,34.5,0,48,.,.,1,.,.,.,.,.,.,.,.,.,16.95238095 -34.1,1,46.21666667,0,48,.,.,1,.,.,.,.,.,.,.,.,.,17.02212302 -34.1,1,48.51666667,0,0,.,.,1,.,.,.,.,.,.,.,98,77,17.03581349 -34.1,1,62.93333333,0,48,.,.,1,.,.,.,.,.,.,.,.,.,17.12162698 -34.1,1,73,0,0,.,.,1,.,.,.,.,.,.,.,157,87,17.18154762 -34.1,0,74.5,.,.,.,.,.,0.176,1,.,.,.,.,.,.,.,17.19047619 -34.2,1,0,0,40,.,.,1,.,.,.,.,.,.,6.85,27,31,18.64434524 -34.2,1,7.4333333,0,40,.,.,1,.,.,.,.,.,.,.,.,.,18.68859127 -34.2,1,16.75,0,0,.,.,1,.,.,.,.,.,.,.,27,31,18.74404762 -34.2,1,20.1166667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,18.7640873 -34.2,1,31.7333333,0,40,.,.,1,.,.,.,.,.,.,.,.,.,18.83323413 -34.2,1,40.4,0,0,.,.,1,.,.,.,.,.,.,.,24,33,18.88482143 -34.2,1,45.9666667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,18.91795635 -34.2,1,56.1,0,40,.,.,1,.,.,.,.,.,.,.,.,.,18.97827381 -34.2,1,64.9833333,0,0,.,.,1,.,.,.,.,.,.,.,23,31,19.03115079 -34.2,1,68.4333333,0,40,.,.,1,.,.,.,.,.,.,.,.,.,19.05168651 -34.2,1,80.5833333,0,40,.,.,1,.,.,.,.,.,.,.,26,32,19.12400794 -34.2,1,92.35,0,40,.,.,1,.,.,.,.,.,.,.,.,.,19.19404762 -34.2,1,104.85,0,40,.,.,1,.,.,.,.,.,.,.,.,.,19.26845238 -34.2,1,114.1666667,0,0,.,.,1,.,.,.,.,.,.,.,28,27,19.32390873 -34.2,1,116.2833333,0,40,.,.,1,.,.,.,.,.,.,.,.,.,19.33650794 -34.2,1,127.9333333,0,40,.,.,1,.,.,.,.,.,.,.,.,.,19.40585317 -34.2,1,135.75,0,0,.,.,1,.,.,.,.,.,.,.,29,38,19.45238095 -34.2,1,140.55,0,40,.,.,1,.,.,.,.,.,.,.,.,.,19.48095238 -34.2,1,152.1166667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,19.54980159 -34.2,1,160.25,0,0,.,.,1,.,.,.,.,.,.,.,35,38,19.59821429 -34.2,0,164.0666667,.,.,.,.,.,0.09,1,.,.,.,.,.,.,.,19.62093254 -34.2,1,164.3666667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,19.62271825 -34.2,1,176.2166667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,19.69325397 -34.2,1,182.75,0,0,.,.,1,.,.,.,.,.,.,.,32,39,19.73214286 -34.2,1,188.3333333,0,40,.,.,1,.,.,.,.,.,.,.,.,.,19.76537698 -34.2,1,200.1666667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,19.83581349 -34.2,1,206.75,0,0,.,.,1,.,.,.,.,.,.,.,32,42,19.875 -34.2,1,212.35,0,40,.,.,1,.,.,.,.,.,.,.,.,.,19.90833333 -34.2,1,223.9333333,0,40,.,.,1,.,.,.,.,.,.,.,.,.,19.97728175 -34.2,1,234.5833333,0,0,.,.,1,.,.,.,.,.,.,.,35,46,20.0406746 -34.2,1,237.25,0,40,.,.,1,.,.,.,.,.,.,.,.,.,20.05654762 -34.2,1,248.0666667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,20.12093254 -34.2,1,257.75,0,0,.,.,1,.,.,.,.,.,.,.,40,44,20.17857143 -34.2,1,260.9666667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,20.19771825 -34.2,1,272.0666667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,20.26378968 -34.2,1,281.75,0,0,.,.,1,.,.,.,.,.,.,.,35,48,20.32142857 -34.2,1,284.3,0,40,.,.,1,.,.,.,.,.,.,.,.,.,20.33660714 -34.2,1,296.2166667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,20.40753968 -34.2,1,305.95,0,0,.,.,1,.,.,.,.,.,.,.,34,47,20.46547619 -34.2,1,309.4333333,0,40,.,.,1,.,.,.,.,.,.,.,.,.,20.48621032 -34.2,1,320.2166667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,20.55039683 -34.2,1,330.25,0,0,.,.,1,.,.,.,.,.,.,.,35,51,20.61011905 -34.2,0,331.6666667,.,.,.,.,.,0.111,1,.,.,.,.,.,.,.,20.61855159 -34.2,1,332.85,0,40,.,.,1,.,.,.,.,.,.,.,.,.,20.62559524 -34.2,1,344.0333333,0,40,.,.,1,.,.,.,.,.,.,.,.,.,20.6921627 -34.2,1,354.05,0,0,.,.,1,.,.,.,.,.,.,.,41,51,20.75178571 -34.2,1,356.1833333,0,40,.,.,1,.,.,.,.,.,.,.,.,.,20.76448413 -34.2,1,367.7666667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,20.83343254 -34.2,1,377.5833333,0,0,.,.,1,.,.,.,.,.,.,.,37,49,20.89186508 -34.2,1,379.9,0,40,.,.,1,.,.,.,.,.,.,.,.,.,20.90565476 -34.2,1,391.8833333,0,40,.,.,1,.,.,.,.,.,.,.,.,.,20.97698413 -34.2,1,401.5166667,0,0,.,.,1,.,.,.,.,.,.,.,38,49,21.0343254 -34.2,1,404.4,0,40,.,.,1,.,.,.,.,.,.,.,.,.,21.0514881 -34.2,1,417.1166667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,21.12718254 -34.2,1,425.25,0,0,.,.,1,.,.,.,.,.,.,.,32,49,21.17559524 -34.2,1,428.1666667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,21.19295635 -34.2,1,442.3666667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,21.27748016 -34.2,1,449.4166667,0,0,.,.,1,.,.,.,.,.,.,.,35,51,21.31944444 -34.2,1,452.5166667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,21.33789683 -34.2,1,464,0,40,.,.,1,.,.,.,.,.,.,.,.,.,21.40625 -34.2,1,474.1666667,0,0,.,.,1,.,.,.,.,.,.,.,40,54,21.46676587 -34.2,1,476.2,0,40,.,.,1,.,.,.,.,.,.,.,.,.,21.47886905 -34.2,1,488.25,0,40,.,.,1,.,.,.,.,.,.,.,.,.,21.55059524 -34.2,1,497.9166667,0,0,.,.,1,.,.,.,.,.,.,.,33,47,21.60813492 -34.2,0,499.75,.,.,.,.,.,0.114,1,.,.,.,.,.,.,.,21.61904762 -34.2,1,499.9333333,0,40,.,.,1,.,.,.,.,.,.,.,.,.,21.62013889 -34.2,1,512.25,0,40,.,.,1,.,.,.,.,.,.,.,.,.,21.69345238 -34.2,1,520.9166667,0,0,.,.,1,.,.,.,.,.,.,.,44,49,21.74503968 -34.2,1,524.6,0,40,.,.,1,.,.,.,.,.,.,.,.,.,21.76696429 -34.2,1,535.6666667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,21.8328373 -34.2,1,546.3166667,0,0,.,.,1,.,.,.,.,.,.,.,34,45,21.89623016 -34.2,1,548.9666667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,21.91200397 -34.2,1,559.75,0,40,.,.,1,.,.,.,.,.,.,.,.,.,21.97619048 -34.2,1,570.5,0,0,.,.,1,.,.,.,.,.,.,.,29,41,22.04017857 -34.2,1,572.2166667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,22.05039683 -34.2,1,583.5333333,0,40,.,.,1,.,.,.,.,.,.,.,.,.,22.11775794 -34.2,1,594.25,0,0,.,.,1,.,.,.,.,.,.,.,37,43,22.18154762 -34.2,1,597.05,0,40,.,.,1,.,.,.,.,.,.,.,.,.,22.19821429 -34.2,1,608.0666667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,22.26378968 -34.2,1,618.5,0,0,.,.,1,.,.,.,.,.,.,.,33,39,22.32589286 -34.2,1,620.1166667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,22.33551587 -34.2,1,632.2,0,40,.,.,1,.,.,.,.,.,.,.,.,.,22.40744048 -34.2,1,642.1666667,0,0,.,.,1,.,.,.,.,.,.,.,32,36,22.46676587 -34.2,1,644.1666667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,22.47867063 -34.2,1,656.1,0,40,.,.,1,.,.,.,.,.,.,.,.,.,22.54970238 -34.2,1,665.75,0,0,.,.,1,.,.,.,.,.,.,.,27,31,22.60714286 -34.2,1,668.55,0,40,.,.,1,.,.,.,.,.,.,.,.,.,22.62380952 -34.2,1,680.2166667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,22.69325397 -34.2,1,690.5,0,0,.,.,1,.,.,.,.,.,.,.,32,36,22.75446429 -34.2,1,692.75,0,40,.,.,1,.,.,.,.,.,.,.,.,.,22.76785714 -34.2,1,704.35,0,40,.,.,1,.,.,.,.,.,.,.,.,.,22.83690476 -34.2,0,716.083333,.,.,.,.,.,0.09,1,.,.,.,.,.,.,.,22.90674603 -34.2,1,716.083333,0,0,.,.,1,.,.,.,.,.,.,.,29,32,22.90674603 -34.2,1,716.75,0,40,.,.,1,.,.,.,.,.,.,.,.,.,22.91071429 -34.2,1,728.383333,0,40,.,.,1,.,.,.,.,.,.,.,.,.,22.97996032 -34.2,1,738,0,0,.,.,1,.,.,.,.,.,.,.,36,26,23.03720238 -34.2,1,740.75,0,40,.,.,1,.,.,.,.,.,.,.,.,.,23.05357143 -34.2,1,752.583333,0,40,.,.,1,.,.,.,.,.,.,.,.,.,23.12400794 -34.2,1,762.25,0,0,.,.,1,.,.,.,.,.,.,.,32,30,23.18154762 -34.2,1,764.016667,0,40,.,.,1,.,.,.,.,.,.,.,.,.,23.19206349 -34.2,1,776.066667,0,48,.,.,1,.,.,.,.,.,.,.,.,.,23.26378968 -34.2,1,786.5,0,0,.,.,1,.,.,.,.,.,.,.,34,26,23.32589286 -34.2,1,788.816667,0,48,.,.,1,.,.,.,.,.,.,.,.,.,23.33968254 -34.2,1,800.4,0,48,.,.,1,.,.,.,.,.,.,.,.,.,23.40863095 -34.2,1,810.416667,0,0,.,.,1,.,.,.,.,.,.,.,25,31,23.46825397 -34.2,1,811.666667,0,0,.,.,1,.,.,.,.,.,.,7,.,.,23.47569444 -34.2,1,812.166667,0,48,.,.,1,.,.,.,.,.,.,.,.,.,23.47867063 -34.2,1,824.833333,0,48,.,.,1,.,.,.,.,.,.,.,.,.,23.55406746 -34.2,1,836.366667,0,0,.,.,1,.,.,.,.,.,.,.,28,28,23.62271825 -34.2,1,836.716667,0,48,.,.,1,.,.,.,.,.,.,.,.,.,23.62480159 -34.2,1,848.616667,0,48,.,.,1,.,.,.,.,.,.,.,.,.,23.69563492 -34.2,1,858.25,0,0,.,.,1,.,.,.,.,.,.,.,25,25,23.75297619 -34.2,1,860.5,0,48,.,.,1,.,.,.,.,.,.,.,.,.,23.76636905 -34.2,1,871.683333,0,48,.,.,1,.,.,.,.,.,.,.,.,.,23.83293651 -34.2,1,882.25,0,0,.,.,1,.,.,.,.,.,.,.,31,32,23.89583333 -34.2,0,883.583333,.,.,.,.,.,0.083,1,.,.,.,.,.,.,.,23.90376984 -34.2,1,884.233333,0,48,.,.,1,.,.,.,.,.,.,.,.,.,23.90763889 -34.2,1,896.766667,0,48,.,.,1,.,.,.,.,.,.,.,.,.,23.98224206 -34.2,1,906.25,0,0,.,.,1,.,.,.,.,.,.,.,32,35,24.03869048 -34.2,1,907.966667,0,48,.,.,1,.,.,.,.,.,.,.,.,.,24.04890873 -34.2,1,920.116667,0,48,.,.,1,.,.,.,.,.,.,.,.,.,24.12123016 -34.2,1,932.35,0,48,.,.,1,.,.,.,.,.,.,.,.,.,24.19404762 -34.2,1,943.816667,0,48,.,.,1,.,.,.,.,.,.,.,.,.,24.26230159 -34.2,1,956.566667,0,48,.,.,1,.,.,.,.,.,.,.,.,.,24.33819444 -34.2,1,971.416667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,24.4265873 -34.2,1,980.366667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,24.47986111 -34.2,1,992.633333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,24.55287698 -34.2,1,998.75,0,0,.,.,1,.,.,.,.,.,.,.,39,26,24.58928571 -34.2,1,1003.916667,0,0,.,.,1,.,.,.,.,.,.,7,.,.,24.62003968 -34.2,1,1004.1,0,70,.,.,1,.,.,.,.,.,.,.,.,.,24.62113095 -34.2,1,1016.183333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,24.69305556 -34.2,1,1029.35,0,70,.,.,1,.,.,.,.,.,.,.,.,.,24.77142857 -34.2,1,1040.516667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,24.83789683 -34.2,0,1051.583333,.,.,.,.,.,0.071,1,.,.,.,.,.,.,.,24.90376984 -34.2,1,1051.766667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,24.90486111 -34.2,1,1064.05,0,70,.,.,1,.,.,.,.,.,.,.,.,.,24.97797619 -34.2,1,1074.5,0,0,.,.,1,.,.,.,.,.,.,.,23,28,25.04017857 -34.2,1,1077.133333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,25.05585317 -34.2,1,1089.183333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,25.12757937 -34.2,1,1100.183333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,25.19305556 -34.2,1,1112.333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,25.26537698 -34.2,1,1124.633333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,25.33859127 -34.2,1,1136.666667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,25.41021825 -34.2,1,1148.25,0,70,.,.,1,.,.,.,.,.,.,.,.,.,25.47916667 -34.2,1,1160.5,0,70,.,.,1,.,.,.,.,.,.,.,.,.,25.55208333 -34.2,1,1170.25,0,0,.,.,1,.,.,.,.,.,.,.,26,29,25.61011905 -34.2,1,1172.666667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,25.62450397 -34.2,1,1185.633333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,25.70168651 -34.2,1,1196.716667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,25.76765873 -34.2,1,1208.016667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,25.83492063 -34.2,1,1220.816667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,25.91111111 -34.2,1,1232.183333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,25.97876984 -34.2,1,1241.583333,0,0,.,.,1,.,.,.,.,.,.,.,31,36,26.03472222 -34.2,1,1244.916667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,26.05456349 -34.2,1,1256.833333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,26.12549603 -34.2,1,1268.116667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,26.19265873 -34.2,1,1280.333333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,26.26537698 -34.2,1,1292.233333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,26.33621032 -34.2,1,1304.8,0,70,.,.,1,.,.,.,.,.,.,.,.,.,26.4110119 -34.2,1,1315.65,0,70,.,.,1,.,.,.,.,.,.,.,.,.,26.47559524 -34.2,1,1328.183333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,26.55019841 -34.2,1,1338.25,0,0,.,.,1,.,.,.,.,.,.,.,38,39,26.61011905 -34.2,1,1340.25,0,70,.,.,1,.,.,.,.,.,.,.,.,.,26.62202381 -34.2,1,1351.566667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,26.68938492 -34.2,1,1363.766667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,26.76200397 -34.2,1,1376.35,0,70,.,.,1,.,.,.,.,.,.,.,.,.,26.83690476 -34.2,1,1388.416667,0,70,.,.,1,.,.,.,.,.,.,.,.,.,26.90873016 -34.2,1,1395.483333,0,0,.,.,1,.,.,.,.,.,.,7,.,.,26.95079365 -34.2,1,1400.383333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,26.97996032 -34.2,1,1411.883333,0,70,.,.,1,.,.,.,.,.,.,.,.,.,27.0484127 -35.1,1,0,0,0,.,.,1,.,.,.,.,.,.,6.2,118,57,17.03839286 -35.1,1,11.83333333,2,43.4,.,.,1,.,.,.,.,.,.,.,.,.,17.10882937 -35.1,1,23.51666667,2,43.4,.,.,1,.,.,.,.,.,.,.,.,.,17.17837302 -35.1,1,23.63333333,0,0,.,.,1,.,.,.,.,.,.,.,87,49,17.17906746 -35.1,1,35.5,2,43.4,.,.,1,.,.,.,.,.,.,.,.,.,17.24970238 -35.1,0,47.71666667,.,.,.,.,.,0.468,1,.,.,.,.,.,.,.,17.32242063 -35.1,1,47.71666667,0,0,.,.,1,.,.,.,.,.,.,.,76,48,17.32242063 -35.1,1,47.81666667,2,43.4,.,.,1,.,.,.,.,.,.,.,.,.,17.32301587 -35.1,1,59.13333333,2,43.4,.,.,1,.,.,.,.,.,.,.,.,.,17.39037698 -35.1,1,71.55,0,0,.,.,1,.,.,.,.,.,.,.,67,42,17.46428571 -35.1,1,71.81666667,2,43.4,.,.,1,.,.,.,.,.,.,.,.,.,17.46587302 -35.1,1,83.15,2,43.4,.,.,1,.,.,.,.,.,.,.,.,.,17.53333333 -35.1,1,94.73333333,0,0,.,.,1,.,.,.,.,.,.,.,65,36,17.60228175 -35.1,1,95.76666667,2,43.4,.,.,1,.,.,.,.,.,.,.,.,.,17.60843254 -35.1,1,107.6833333,2,60,.,.,1,.,.,.,.,.,.,.,.,.,17.67936508 -35.1,0,119.3,.,.,.,.,.,0.856,1,.,.,.,.,.,.,.,17.7485119 -35.1,1,119.3,0,0,.,.,1,.,.,.,.,.,.,.,62,35,17.7485119 -35.1,1,119.4666667,2,60,.,.,1,.,.,.,.,.,.,.,.,.,17.74950397 -35.1,1,131.4166667,2,60,.,.,1,.,.,.,.,.,.,.,.,.,17.82063492 -35.1,1,132.05,0,0,.,.,1,.,.,.,.,.,.,6.2,.,.,17.82440476 -35.1,1,143.2833333,2,60,.,.,1,.,.,.,.,.,.,.,.,.,17.89126984 -35.1,1,144.2166667,0,0,.,.,1,.,.,.,.,.,.,.,58,42,17.8968254 -35.1,1,155.6166667,2,60,.,.,1,.,.,.,.,.,.,.,.,.,17.96468254 -35.1,0,167.3833333,.,.,.,.,.,0.67,1,.,.,.,.,.,.,.,18.03472222 -35.1,1,167.3833333,0,0,.,.,1,.,.,.,.,.,.,.,58,32,18.03472222 -35.1,1,167.55,2,60,.,.,1,.,.,.,.,.,.,.,.,.,18.03571429 -35.1,1,180.1833333,2,60,.,.,1,.,.,.,.,.,.,.,.,.,18.1109127 -35.1,1,190.55,0,0,.,.,1,.,.,.,.,.,.,.,50,36,18.17261905 -35.1,1,191.3666667,2,60,.,.,1,.,.,.,.,.,.,.,.,.,18.17748016 -35.1,1,203.4,2,80,.,.,1,.,.,.,.,.,.,.,.,.,18.24910714 -35.1,1,215.0166667,0,0,.,.,1,.,.,.,.,.,.,.,43,36,18.31825397 -35.1,1,215.8666667,2,80,.,.,1,.,.,.,.,.,.,.,.,.,18.32331349 -35.1,1,227.15,2,80,.,.,1,.,.,.,.,.,.,.,.,.,18.39047619 -35.1,0,239.1333333,.,.,.,.,.,0.96,1,.,.,.,.,.,.,.,18.46180556 -35.1,1,239.1333333,0,0,.,.,1,.,.,.,.,.,.,.,41,31,18.46180556 -35.1,1,239.55,2,80,.,.,1,.,.,.,.,.,.,.,.,.,18.46428571 -35.1,1,251.2833333,2,90,.,.,1,.,.,.,.,.,.,.,.,.,18.53412698 -35.1,1,263.4666667,0,0,.,.,1,.,.,.,.,.,.,.,45,31,18.60664683 -35.1,1,263.6333333,2,90,.,.,1,.,.,.,.,.,.,.,.,.,18.60763889 -35.1,1,275.6333333,2,90,.,.,1,.,.,.,.,.,.,.,.,.,18.67906746 -35.1,0,287.4666667,.,.,.,.,.,2.7,1,.,.,.,.,.,.,.,18.74950397 -35.1,1,287.4666667,0,0,.,.,1,.,.,.,.,.,.,6.2,41,26,18.74950397 -35.1,1,287.5166667,2,90,.,.,1,.,.,.,.,.,.,.,.,.,18.74980159 -35.1,1,299.6166667,2,90,.,.,1,.,.,.,.,.,.,.,.,.,18.8218254 -35.1,1,306.3,0,0,.,.,1,.,.,.,.,.,.,.,46,28,18.86160714 -35.1,1,311.6333333,2,90,.,.,1,.,.,.,.,.,.,.,.,.,18.89335317 -35.1,1,323.3166667,2,90,.,.,1,.,.,.,.,.,.,.,.,.,18.96289683 -35.1,1,329.9666667,0,0,.,.,1,.,.,.,.,.,.,.,40,33,19.00248016 -35.1,1,335.55,2,90,.,.,1,.,.,.,.,.,.,.,.,.,19.03571429 -35.1,1,347.15,2,90,.,.,1,.,.,.,.,.,.,.,.,.,19.1047619 -35.1,1,357.55,0,0,.,.,1,.,.,.,.,.,.,.,33,28,19.16666667 -35.1,1,359.2166667,2,90,.,.,1,.,.,.,.,.,.,.,.,.,19.1765873 -35.1,1,371.1833333,2,90,.,.,1,.,.,.,.,.,.,.,.,.,19.24781746 -35.1,1,382.9666667,0,0,.,.,1,.,.,.,.,.,.,.,26,25,19.31795635 -35.1,1,383.45,2,90,.,.,1,.,.,.,.,.,.,.,.,.,19.32083333 -35.1,1,395.55,2,90,.,.,1,.,.,.,.,.,.,.,.,.,19.39285714 -35.1,1,407.7166667,0,0,.,.,1,.,.,.,.,.,.,.,26,26,19.46527778 -35.1,1,407.7833333,2,90,.,.,1,.,.,.,.,.,.,.,.,.,19.4656746 -35.1,1,419.6166667,2,90,.,.,1,.,.,.,.,.,.,.,.,.,19.53611111 -35.1,1,431.55,2,90,.,.,1,.,.,.,.,.,.,.,.,.,19.60714286 -35.1,1,434.55,0,0,.,.,1,.,.,.,.,.,.,.,29,15,19.625 -35.1,1,443.7666667,2,90,.,.,1,.,.,.,.,.,.,.,.,.,19.67986111 -35.1,1,455.05,0,0,.,.,1,.,.,.,.,.,.,.,30,20,19.74702381 -35.1,1,455.3833333,2,90,.,.,1,.,.,.,.,.,.,.,.,.,19.74900794 -35.1,1,467.8166667,2,90,.,.,1,.,.,.,.,.,.,.,.,.,19.82301587 -35.1,1,479.55,2,90,.,.,1,.,.,.,.,.,.,.,.,.,19.89285714 -35.1,1,495.05,0,100,.,.,1,.,.,.,.,.,.,.,.,.,19.98511905 -35.1,1,503.05,0,0,.,.,1,.,.,.,.,.,.,.,32,30,20.0327381 -35.1,1,506.4,0,100,.,.,1,.,.,.,.,.,.,.,.,.,20.05267857 -35.1,1,518.5333333,0,100,.,.,1,.,.,.,.,.,.,.,.,.,20.12490079 -35.1,1,529.95,0,100,.,.,1,.,.,.,.,.,.,.,.,.,20.19285714 -35.1,1,541.65,0,100,.,.,1,.,.,.,.,.,.,.,.,.,20.2625 -35.1,1,553.6166667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,20.33373016 -35.1,1,565.6166667,0,100,.,.,1,.,.,.,.,.,.,.,.,.,20.40515873 -35.1,0,576.55,.,.,.,.,.,0.735,1,.,.,.,.,.,.,.,20.4702381 -36.1,1,0,0,0,.,.,1,.,.,.,.,.,.,8.21,29,31,100.3239087 -36.1,1,1.583333333,0,0,.,.,1,.,.,.,.,.,.,8.21,.,.,100.3333333 -36.1,1,5.283333333,2,80,.,.,1,.,.,.,.,.,.,.,.,.,100.3553571 -36.1,1,11.58333333,0,0,.,.,1,.,.,.,.,.,.,8.21,.,.,100.3928571 -36.1,1,16.4,2,80,.,.,1,.,.,.,.,.,.,.,.,.,100.4215278 -36.1,1,22.58333333,0,0,.,.,1,.,.,.,.,.,.,.,24,24,100.4583333 -36.1,1,27.4,2,80,.,.,1,.,.,.,.,.,.,.,.,.,100.487004 -36.1,1,31.1,0,0,.,.,1,.,.,.,.,.,.,8.21,.,.,100.5090278 -36.1,1,40.11666667,2,74,.,.,1,.,.,.,.,.,.,.,.,.,100.5626984 -36.1,1,46.83333333,0,0,.,.,1,.,.,.,.,.,.,.,34,35,100.6026786 -36.1,1,49.58333333,0,0,.,.,1,.,.,.,.,.,.,.,35,32,100.6190476 -36.1,1,53.03333333,2,74,.,.,1,.,.,.,.,.,.,.,.,.,100.6395833 -36.1,0,64.35,.,.,.,.,.,4.26,1,.,.,.,.,.,.,.,100.7069444 -36.1,1,65.68333333,2,74,.,.,1,.,.,.,.,.,.,.,.,.,100.714881 -36.1,1,71.58333333,0,0,.,.,1,.,.,.,.,.,.,.,77,25,100.75 -36.1,1,79.56666667,2,74,.,.,1,.,.,.,.,.,.,.,.,.,100.7975198 -36.1,0,90.58333333,.,.,.,.,.,1.5,1,.,.,.,.,.,.,.,100.8630952 -36.1,1,92.11666667,2,74,.,.,1,.,.,.,.,.,.,.,.,.,100.8722222 -36.1,1,93.4,0,0,.,.,1,.,.,.,.,.,.,.,34,29,100.8798611 -36.1,1,104.5333333,2,74,.,.,1,.,.,.,.,.,.,.,.,.,100.946131 -36.1,1,115.3166667,2,74,.,.,1,.,.,.,.,.,.,.,.,.,101.0103175 -36.1,1,119.0833333,0,0,.,.,1,.,.,.,.,.,.,.,42,28,101.0327381 -36.1,1,130.0833333,2,74,.,.,1,.,.,.,.,.,.,.,.,.,101.0982143 -36.1,1,142.8333333,2,74,.,.,1,.,.,.,.,.,.,.,.,.,101.1741071 -36.1,1,143.4166667,0,0,.,.,1,.,.,.,.,.,.,.,55,39,101.1775794 -36.1,1,154.8333333,2,74,.,.,1,.,.,.,.,.,.,.,.,.,101.2455357 -36.1,1,166.2666667,2,74,.,.,1,.,.,.,.,.,.,.,.,.,101.3135913 -36.1,1,167.4166667,0,0,.,.,1,.,.,.,.,.,.,.,53,34,101.3204365 -36.1,1,178.85,2,74,.,.,1,.,.,.,.,.,.,.,.,.,101.3884921 -36.1,1,190.2166667,2,74,.,.,1,.,.,.,.,.,.,.,.,.,101.4561508 -36.1,1,190.6666667,0,0,.,.,1,.,.,.,.,.,.,.,37,30,101.4588294 -36.1,1,191.5833333,0,0,.,.,1,.,.,.,.,.,.,8.21,.,.,101.4642857 -36.1,1,202.6333333,2,74,.,.,1,.,.,.,.,.,.,.,.,.,101.5300595 -36.1,1,213.5833333,0,0,.,.,1,.,.,.,.,.,.,8.21,.,.,101.5952381 -36.1,1,214.2333333,2,74,.,.,1,.,.,.,.,.,.,.,.,.,101.5991071 -36.1,1,215.5833333,0,0,.,.,1,.,.,.,.,.,.,.,47,34,101.6071429 -36.1,1,226.3666667,2,74,.,.,1,.,.,.,.,.,.,.,.,.,101.6713294 -36.1,1,238.4333333,2,74,.,.,1,.,.,.,.,.,.,.,.,.,101.7431548 -36.1,1,239.5833333,0,0,.,.,1,.,.,.,.,.,.,8.21,.,.,101.75 -36.1,1,239.9166667,0,0,.,.,1,.,.,.,.,.,.,.,55,33,101.7519841 -36.1,1,250.3,2,74,.,.,1,.,.,.,.,.,.,.,.,.,101.8137897 -36.1,1,262.7833333,2,74,.,.,1,.,.,.,.,.,.,.,.,.,101.8880952 -36.1,1,263.5833333,0,0,.,.,1,.,.,.,.,.,.,.,52,32,101.8928571 -36.1,1,265.5833333,0,0,.,.,1,.,.,.,.,.,.,8.21,.,.,101.9047619 -36.1,1,274.5666667,2,74,.,.,1,.,.,.,.,.,.,.,.,.,101.9582341 -36.1,1,286.4166667,0,0,.,.,1,.,.,.,.,.,.,.,25,31,102.0287698 -36.1,1,289.0333333,2,74,.,.,1,.,.,.,.,.,.,.,.,.,102.0443452 -36.1,1,301.3166667,2,74,.,.,1,.,.,.,.,.,.,.,.,.,102.1174603 -36.1,0,312.0833333,.,.,.,.,.,4.9,1,.,.,.,.,.,.,.,102.1815476 -36.2,1,0,0,0,.,.,1,.,.,.,.,.,.,8.21,17,24,102.1815476 -36.2,1,1.466666667,2,74,.,.,1,.,.,.,.,.,.,.,.,.,102.1902778 -36.2,1,14.18333333,2,74,.,.,1,.,.,.,.,.,.,.,.,.,102.2659722 -36.2,1,23,0,0,.,.,1,.,.,.,.,.,.,.,16,17,102.3184524 -36.2,1,25.31666667,2,74,.,.,1,.,.,.,.,.,.,.,.,.,102.3322421 -36.2,1,37.5,0,0,.,.,1,.,.,.,.,.,.,8.21,.,.,102.4047619 -36.2,1,37.51666667,2,74,.,.,1,.,.,.,.,.,.,.,.,.,102.4048611 -36.2,1,41.5,0,0,.,.,1,.,.,.,.,.,.,8.21,.,.,102.4285714 -36.2,1,45.5,0,0,.,.,1,.,.,.,.,.,.,8.21,.,.,102.452381 -36.2,1,46.25,0,0,.,.,1,.,.,.,.,.,.,.,27,19,102.4568452 -36.2,1,49.51666667,2,74,.,.,1,.,.,.,.,.,.,.,.,.,102.4762897 -36.2,1,61.36666667,2,74,.,.,1,.,.,.,.,.,.,.,.,.,102.5468254 -36.2,1,61.5,0,0,.,.,1,.,.,.,.,.,.,8.21,.,.,102.547619 -36.2,1,65.5,0,0,.,.,1,.,.,.,.,.,.,8.21,.,.,102.5714286 -36.2,1,70,0,0,.,.,1,.,.,.,.,.,.,.,60,35,102.5982143 -36.2,1,71.5,0,0,.,.,1,.,.,.,.,.,.,8.21,.,.,102.6071429 -36.2,1,74,2,74,.,.,1,.,.,.,.,.,.,.,.,.,102.6220238 -36.2,1,86,2,74,.,.,1,.,.,.,.,.,.,.,.,.,102.6934524 -36.2,1,94,0,0,.,.,1,.,.,.,.,.,.,.,97,63,102.7410714 -36.2,1,97.3,2,74,.,.,1,.,.,.,.,.,.,.,.,.,102.7607143 -36.2,1,109.3666667,2,74,.,.,1,.,.,.,.,.,.,.,.,.,102.8325397 -36.2,1,117.5833333,0,0,.,.,1,.,.,.,.,.,.,.,128,87,102.8814484 -36.2,1,121.1833333,2,74,.,.,1,.,.,.,.,.,.,.,.,.,102.902877 -36.2,1,133.8666667,2,74,.,.,1,.,.,.,.,.,.,.,.,.,102.978373 -36.2,1,142.75,0,0,.,.,1,.,.,.,.,.,.,.,332,185,103.03125 -36.2,1,145.5,2,74,.,.,1,.,.,.,.,.,.,.,.,.,103.047619 -36.2,1,157.5,2,74,.,.,1,.,.,.,.,.,.,.,.,.,103.1190476 -36.2,0,168.5,.,.,.,.,.,0.327,1,.,.,.,.,.,.,.,103.1845238 -36.2,1,168.5,0,0,.,.,1,.,.,.,.,.,.,.,638,370,103.1845238 -36.2,1,169.5,2,74,.,.,1,.,.,.,.,.,.,.,.,.,103.1904762 -36.2,1,181.45,2,74,.,.,1,.,.,.,.,.,.,.,.,.,103.2616071 -36.2,1,191.5,0,0,.,.,1,.,.,.,.,.,.,.,620,399,103.3214286 -36.2,1,193.5,2,74,.,.,1,.,.,.,.,.,.,.,.,.,103.3333333 -36.2,0,205.5833333,.,.,.,.,.,0.176,1,.,.,.,.,.,.,.,103.4052579 -37.1,1,0,0,0,.,.,1,.,.,.,.,.,.,11.6,87,106,88.7531746 -37.1,1,14.08333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,88.83700397 -37.1,1,23.46666667,0,0,.,.,1,.,.,.,.,.,.,.,87,98,88.89285714 -37.1,1,26.26666667,0,80,.,.,1,.,.,.,.,.,.,.,.,.,88.90952381 -37.1,1,37.96666667,0,80,.,.,1,.,.,.,.,.,.,.,.,.,88.97916667 -37.1,1,47.21666667,0,0,.,.,1,.,.,.,.,.,.,.,92,116,89.03422619 -37.1,1,50.33333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,89.05277778 -37.1,1,61.65,0,80,.,.,1,.,.,.,.,.,.,.,.,.,89.12013889 -37.1,1,70.71666667,0,0,.,.,1,.,.,.,.,.,.,.,71,91,89.17410714 -37.1,1,73.63333333,0,80,.,.,1,.,.,.,.,.,.,.,.,.,89.19146825 -37.1,1,85.85,0,80,.,.,1,.,.,.,.,.,.,.,.,.,89.26418651 -37.1,1,97.56666667,0,80,.,.,1,.,.,.,.,.,.,.,.,.,89.33392857 -37.1,0,98.46666667,.,.,.,.,.,0.05,1,.,.,.,.,.,.,.,89.33928571 -38.1,1,0,0,0,.,.,1,.,.,.,.,.,.,3.7,44,34,1.12202381 -38.1,1,0.116666667,0,0,.,.,1,.,.,.,.,.,.,3.7,.,.,1.122718254 -38.1,1,0.916666667,2,26,.,.,1,.,.,.,.,.,.,.,.,.,1.127480159 -38.1,1,5.5,0,0,.,.,1,.,.,.,.,.,.,3.7,.,.,1.154761905 -38.1,1,12.53333333,2,26,.,.,1,.,.,.,.,.,.,.,.,.,1.196626984 -38.1,1,24.43333333,2,26,.,.,1,.,.,.,.,.,.,.,.,.,1.267460317 -38.1,1,27.5,0,0,.,.,1,.,.,.,.,.,.,3.7,.,.,1.285714286 -38.1,1,32,0,0,.,.,1,.,.,.,.,.,.,.,39,32,1.3125 -38.1,1,35,2,26,.,.,1,.,.,.,.,.,.,.,.,.,1.330357143 -38.1,1,47.5,0,0,.,.,1,.,.,.,.,.,.,3.7,.,.,1.404761905 -38.1,1,48.16666667,2,26,.,.,1,.,.,.,.,.,.,.,.,.,1.408730159 -38.1,1,57.41666667,0,0,.,.,1,.,.,.,.,.,.,.,35,31,1.463789683 -38.1,0,60,.,.,.,.,.,0.532,1,.,.,.,.,.,.,.,1.479166667 -38.2,1,0,2,26,.,.,1,.,.,.,.,.,.,3.7,35,31,1.491468254 -38.2,1,2.85,0,0,.,.,1,.,.,.,.,.,.,3.7,.,.,1.50843254 -38.2,1,9.433333333,0,0,.,.,1,.,.,.,.,.,.,3.7,.,.,1.547619048 -38.2,1,11.16666667,2,52,.,.,1,.,.,.,.,.,.,.,.,.,1.557936508 -38.2,0,23.2,.,.,.,.,.,0.456,1,.,.,.,.,.,.,.,1.629563492 -38.2,1,25.85,2,52,.,.,1,.,.,.,.,.,.,.,.,.,1.645337302 -38.2,1,37.68333333,2,52,.,.,1,.,.,.,.,.,.,.,.,.,1.71577381 -38.2,0,48.93333333,.,.,.,.,.,0.239,1,.,.,.,.,.,.,.,1.782738095 diff --git a/examples/debug.rs b/examples/debug.rs deleted file mode 100644 index ff5597ba5..000000000 --- a/examples/debug.rs +++ /dev/null @@ -1,196 +0,0 @@ -use std::collections::HashMap; - -use eyre::Result; -use ndarray::Array; -use npcore::prelude::{ - datafile::{CovLine, Infusion, Scenario}, - predict::Predict, -}; -use ode_solvers::*; - -const ATOL: f64 = 1e-4; -const RTOL: f64 = 1e-4; - -#[derive(Debug, Clone)] -struct Model<'a> { - ke: f64, - _v: f64, - _scenario: &'a Scenario, - infusions: Vec, - cov: Option<&'a HashMap>, -} - -type State = Vector1; -type Time = f64; - -impl ode_solvers::System for Model<'_> { - fn system(&self, t: Time, y: &State, dy: &mut State) { - let ke = self.ke; - - let _lag = 0.0; - - let mut rateiv = [0.0]; - for infusion in &self.infusions { - if t >= infusion.time && t <= (infusion.dur + infusion.time) { - rateiv[infusion.compartment] += infusion.amount / infusion.dur; - } - } - - ///////////////////// USER DEFINED /////////////// - - dy[0] = -ke * y[0] + rateiv[0]; - - //////////////// END USER DEFINED //////////////// - } -} - -#[derive(Debug, Clone)] -struct Ode {} - -impl Predict for Ode { - fn predict(&self, params: Vec, scenario: &Scenario) -> Vec { - let mut system = Model { - ke: params[0], - _v: params[1], - _scenario: scenario, - infusions: vec![], - cov: None, - }; - let lag = 0.0; - let mut yout = vec![]; - let mut x = State::new(0.0); - let mut index: usize = 0; - for block in &scenario.blocks { - //if no code is needed here, remove the blocks from the codebase - //It seems that blocks is an abstractions we're going to end up not using - system.cov = Some(&block.covs); - for event in &block.events { - let lag_time = event.time + lag; - if event.evid == 1 { - if event.dur.unwrap_or(0.0) > 0.0 { - //infusion - system.infusions.push(Infusion { - time: lag_time, - dur: event.dur.unwrap(), - amount: event.dose.unwrap(), - compartment: event.input.unwrap() - 1, - }); - // x = simulate_next_state(x, &system, scenario, event, index); - if let Some(next_time) = scenario.times.get(index + 1) { - if *next_time > event.time { - let mut stepper = Dopri5::new( - system.clone(), - event.time, - *next_time, - 1e-3, - x, - RTOL, - ATOL, - ); - - let _res = stepper.integrate(); - let y = stepper.y_out(); - x = *y.last().unwrap(); - } else if *next_time < event.time { - log::error!("Panic: Next event's time is in the past!"); - panic!("Panic: Next event's time is in the past!"); - } - } - } else { - //dose - if lag > 0.0 { - // let mut stepper = - // Rk4::new(system.clone(), event.time, x, lag_time, 0.1); - if let Some(next_time) = scenario.times.get(index + 1) { - if *next_time < lag_time { - log::error!("Panic: lag time overpasses next observation, not implemented. Stopping."); - panic!("Panic: lag time overpasses next observation, not implemented. Stopping."); - } - let mut stepper = Dopri5::new( - system.clone(), - event.time, - lag_time, - 1e-3, - x, - RTOL, - ATOL, - ); - - let _int = stepper.integrate(); - let y = stepper.y_out(); - x = *y.last().unwrap(); - } - } - - x[event.input.unwrap() - 1] += event.dose.unwrap(); - if let Some(next_time) = scenario.times.get(index + 1) { - if *next_time > lag_time { - let mut stepper = Dopri5::new( - system.clone(), - lag_time, - *next_time, - 1e-3, - x, - RTOL, - ATOL, - ); - - let _res = stepper.integrate(); - let y = stepper.y_out(); - x = *y.last().unwrap(); - } else if *next_time > event.time { - log::error!("Panic: Next event's time is in the past!"); - panic!("Panic: Next event's time is in the past!"); - } - } - } - } else if event.evid == 0 { - //obs - yout.push(x[event.outeq.unwrap() - 1] / params[1]); - if let Some(next_time) = scenario.times.get(index + 1) { - // let mut stepper = Rk4::new(system.clone(), lag_time, x, *next_time, 0.1); - if *next_time > event.time { - let mut stepper = Dopri5::new( - system.clone(), - event.time, - *next_time, - 1e-3, - x, - RTOL, - ATOL, - ); - - let _res = stepper.integrate(); - let y = stepper.y_out(); - x = *y.last().unwrap(); - } else if *next_time < event.time { - log::error!("Panic: Next event's time is in the past!"); - panic!("Panic: Next event's time is in the past!"); - } - } - } - index += 1; - } - } - yout - } -} - -fn main() -> Result<()> { - let scenarios = - npcore::routines::datafile::parse(&"examples/data/bimodal_ke.csv".to_string()).unwrap(); - let scenario = scenarios.first().unwrap(); - // let block = scenario.blocks.get(0).unwrap(); - // dbg!(&block.covs); - // dbg!(&block.covs.get("WT").unwrap().interp(12.0)); - - let sim = Ode {}; - // Vamos a asumir que todos los valores de covs están presentes - let yobs = Array::from_vec(scenario.obs.clone()); - let ypred = - Array::from_vec(sim.predict(vec![0.3137412105321884, 116.93967163562775], scenario)); - dbg!(&yobs); - dbg!(&ypred); - dbg!(&yobs - &ypred); - Ok(()) -} diff --git a/examples/two_eq_lag/config.toml b/examples/two_eq_lag/config.toml index ab6a8f6ee..ba94e8b44 100644 --- a/examples/two_eq_lag/config.toml +++ b/examples/two_eq_lag/config.toml @@ -1,11 +1,11 @@ [paths] data = "examples/data/two_eq_lag.csv" -log_out = "log/two_eq_lag.log" +log_out = "two_eq_lag.log" #prior_dist = "theta_two_eq_lag.csv" [config] cycles = 1000 -engine = "NPAG" +engine = "NPOD" init_points = 1000 seed = 22 tui = true @@ -22,4 +22,4 @@ v = [30.0, 120.0] [error] value = 0.0 class = "additive" -poly = [0.1, 0.25, -0.001, 0.0] +poly = [0.1, 0.25, -0.001, 0.0] \ No newline at end of file diff --git a/examples/two_eq_lag/main.rs b/examples/two_eq_lag/main-old.rs similarity index 100% rename from examples/two_eq_lag/main.rs rename to examples/two_eq_lag/main-old.rs diff --git a/examples/vori/config.toml b/examples/vori/config.toml deleted file mode 100644 index 9c6a3e2a2..000000000 --- a/examples/vori/config.toml +++ /dev/null @@ -1,27 +0,0 @@ -[paths] -data = "examples/data/vori.csv" -log_out = "log/vori.log" -[config] -cycles = 100 -engine = "NPAG" -init_points = 10000 -seed = 347 -tui = true -pmetrics_outputs = true -cache = true -[random] -Age50 = [1.0, 24.0] -FA1 = [0.1, 1.0] -Hill = [0.01, 5.0] -Ka = [0.01, 15.0] -KCP = [0.01, 15.0] -Km = [5.0, 60.0] -KPC = [0.01, 15.0] -Vc0 = [1.0, 5.0] -Vmax0 = [1.0, 60.0] -[fixed] -[constant] -[error] -value = 1.4 -class = "additive" -poly = [0.02, 0.1, 0.0, 0.0] diff --git a/examples/vori/main.rs b/examples/vori/main.rs deleted file mode 100644 index 9483446e7..000000000 --- a/examples/vori/main.rs +++ /dev/null @@ -1,173 +0,0 @@ -#![allow(dead_code)] -#![allow(unused_variables)] -use eyre::Result; -use npcore::prelude::{ - datafile::{CovLine, Infusion, Scenario}, - predict::{Engine, Predict}, - start, -}; -const ATOL: f64 = 1e-4; -const RTOL: f64 = 1e-4; -use ode_solvers::*; -use std::collections::HashMap; -#[derive(Debug, Clone)] -struct Model<'a> { - age50: f64, - fa1: f64, - hill: f64, - ka: f64, - kcp: f64, - km: f64, - kpc: f64, - vc0: f64, - vmax0: f64, - _scenario: &'a Scenario, - infusions: Vec, - cov: Option<&'a HashMap>, -} - -type State = SVector; -type Time = f64; - -impl ode_solvers::System for Model<'_> { - fn system(&self, t: Time, x: &State, dx: &mut State) { - let age50 = self.age50; - let fa1 = self.fa1; - let hill = self.hill; - let ka = self.ka; - let kcp = self.kcp; - let km = self.km; - let kpc = self.kpc; - let vc0 = self.vc0; - let vmax0 = self.vmax0; - let wt = self.cov.unwrap().get("wt").unwrap().interp(t); - let ast = self.cov.unwrap().get("ast").unwrap().interp(t); - let alt = self.cov.unwrap().get("alt").unwrap().interp(t); - let age = self.cov.unwrap().get("age").unwrap().interp(t); - - let vm = vmax0 * wt.powf(0.75); - let v = vc0 * wt; - let fage = age.powf(hill) / (age50.powf(hill) + age.powf(hill)); - - let mut rateiv = [0.0]; //TODO: hardcoded - for infusion in &self.infusions { - if t >= infusion.time && t <= (infusion.dur + infusion.time) { - rateiv[infusion.compartment] += infusion.amount / infusion.dur; - } - } - - dx[0] = -ka * x[0]; - dx[1] = - ka * x[0] + rateiv[0] - fage * vm / (km * v + x[1]) * x[1] - kcp * x[1] + kpc * x[2]; - dx[2] = kcp * x[1] - kpc * x[2]; - } -} - -#[derive(Debug, Clone)] -struct Ode {} - -impl Predict for Ode { - fn predict(&self, params: Vec, scenario: &Scenario) -> Vec { - let mut system = Model { - age50: params[0], - fa1: params[1], - hill: params[2], - ka: params[3], - kcp: params[4], - km: params[5], - kpc: params[6], - vc0: params[7], - vmax0: params[8], - _scenario: scenario, - infusions: vec![], - cov: None, - }; - let mut yout = vec![]; - let mut x = State::new(0.0, 0.0, 0.0); - let mut index: usize = 0; - for block in &scenario.blocks { - system.cov = Some(&block.covs); - for event in &block.events { - if event.evid == 1 { - if event.dur.unwrap_or(0.0) > 0.0 { - //infusion - system.infusions.push(Infusion { - time: event.time, - dur: event.dur.unwrap(), - amount: event.dose.unwrap(), - compartment: event.input.unwrap() - 1, - }); - } else { - //dose - x[event.input.unwrap() - 1] += event.dose.unwrap(); - } - } else if event.evid == 0 { - //obs - yout.push(eval_outeq( - ¶ms, - system.cov.unwrap(), - &x, - event.time, - event.outeq.unwrap(), - )); - } - if let Some(next_time) = scenario.times.get(index + 1) { - // let mut stepper = Rk4::new(system.clone(), lag_time, x, *next_time, 0.1); - if event.time < *next_time { - let mut stepper = Dopri5::new( - system.clone(), - event.time, - *next_time, - 1e-3, - x, - RTOL, - ATOL, - ); - let _res = stepper.integrate(); - let y = stepper.y_out(); - x = *y.last().unwrap(); - } else if event.time > *next_time { - log::error!("next time is in the past!"); - log::error!("event_time: {}\nnext_time: {}", event.time, *next_time); - } - } - index += 1; - } - } - yout - } -} - -fn eval_outeq( - params: &[f64], - cov: &HashMap, - x: &State, - time: f64, - outeq: usize, -) -> f64 { - let age50 = params[0]; - let fa1 = params[1]; - let hill = params[2]; - let ka = params[3]; - let kcp = params[4]; - let km = params[5]; - let kpc = params[6]; - let vc0 = params[7]; - let vmax0 = params[8]; - let wt = cov.get("wt").unwrap().interp(time); - let ast = cov.get("ast").unwrap().interp(time); - let alt = cov.get("alt").unwrap().interp(time); - let age = cov.get("age").unwrap().interp(time); - let vm = vmax0 * wt.powf(0.75); - let v = vc0 * wt; - let fage = age.powf(hill) / (age50.powf(hill) + age.powf(hill)); - match outeq { - 1 => x[1] / v, - _ => panic!("Invalid output equation"), - } -} - -fn main() -> Result<()> { - start(Engine::new(Ode {}), "examples/vori/config.toml".to_string())?; - Ok(()) -} diff --git a/src/algorithms.rs b/src/algorithms.rs index aacb057f2..25155f7c1 100644 --- a/src/algorithms.rs +++ b/src/algorithms.rs @@ -1,18 +1,14 @@ -use crate::prelude::{self, output::NPCycle, settings::run::Data}; +use crate::prelude::{self, settings::Settings}; use output::NPResult; -use prelude::*; +use prelude::{datafile::Scenario, *}; use simulation::predict::{Engine, Predict}; use tokio::sync::mpsc; mod npag; +mod npod; mod postprob; -pub enum Type { - NPAG, - POSTPROB, -} - pub trait Algorithm { fn fit(&mut self) -> NPResult; fn to_npresult(&self) -> NPResult; @@ -20,34 +16,39 @@ pub trait Algorithm { pub fn initialize_algorithm( engine: Engine, - settings: Data, - tx: mpsc::UnboundedSender, + settings: Settings, + scenarios: Vec, + tx: mpsc::UnboundedSender, ) -> Box where - S: Predict + std::marker::Sync + Clone + 'static, + S: Predict<'static> + std::marker::Sync + Clone + 'static, { if std::path::Path::new("stop").exists() { match std::fs::remove_file("stop") { - Ok(_) => log::info!("Removed previous stop file"), + Ok(_) => tracing::info!("Removed previous stop file"), Err(err) => panic!("Unable to remove previous stop file: {}", err), } } - let ranges = settings.computed.random.ranges.clone(); + let ranges = settings.random.ranges(); let theta = initialization::sample_space(&settings, &ranges); - let mut scenarios = datafile::parse(&settings.parsed.paths.data).unwrap(); - if let Some(exclude) = &settings.parsed.config.exclude { - for val in exclude { - scenarios.remove(val.as_integer().unwrap() as usize); - } - } + //This should be a macro, so it can automatically expands as soon as we add a new option in the Type Enum - match settings.parsed.config.engine.as_str() { + match settings.config.engine.as_str() { "NPAG" => Box::new(npag::NPAG::new( engine, ranges, theta, scenarios, - settings.parsed.error.poly, + settings.error.poly, + tx, + settings, + )), + "NPOD" => Box::new(npod::NPOD::new( + engine, + ranges, + theta, + scenarios, + settings.error.poly, tx, settings, )), @@ -55,7 +56,7 @@ where engine, theta, scenarios, - settings.parsed.error.poly, + settings.error.poly, tx, settings, )), diff --git a/src/algorithms/npag.rs b/src/algorithms/npag.rs index b8fb6029f..81f690a86 100644 --- a/src/algorithms/npag.rs +++ b/src/algorithms/npag.rs @@ -1,29 +1,32 @@ -use crate::prelude::{ - algorithms::Algorithm, - datafile::Scenario, - evaluation::sigma::{ErrorPoly, ErrorType}, - ipm, - optimization::expansion::adaptative_grid, - output::NPResult, - output::{CycleLog, NPCycle}, - prob, qr, - settings::run::Data, - simulation::predict::Engine, - simulation::predict::{sim_obs, Predict}, +use crate::{ + prelude::{ + algorithms::Algorithm, + datafile::Scenario, + evaluation::sigma::{ErrorPoly, ErrorType}, + ipm, + output::NPResult, + output::{CycleLog, NPCycle}, + prob, qr, + settings::Settings, + simulation::predict::Engine, + simulation::predict::{sim_obs, Predict}, + }, + routines::expansion::adaptative_grid::adaptative_grid, + tui::ui::Comm, }; use ndarray::{Array, Array1, Array2, Axis}; use ndarray_stats::{DeviationExt, QuantileExt}; use tokio::sync::mpsc::UnboundedSender; -const THETA_E: f64 = 1e-4; //convergence Criteria -const THETA_G: f64 = 1e-4; //objf stop criteria +const THETA_E: f64 = 1e-4; // Convergence criteria +const THETA_G: f64 = 1e-4; // Objective function convergence criteria const THETA_F: f64 = 1e-2; const THETA_D: f64 = 1e-4; pub struct NPAG where - S: Predict + std::marker::Sync + Clone, + S: Predict<'static> + std::marker::Sync + Clone, { engine: Engine, ranges: Vec<(f64, f64)>, @@ -45,13 +48,13 @@ where cache: bool, scenarios: Vec, c: (f64, f64, f64, f64), - tx: UnboundedSender, - settings: Data, + tx: UnboundedSender, + settings: Settings, } impl Algorithm for NPAG where - S: Predict + std::marker::Sync + Clone, + S: Predict<'static> + std::marker::Sync + Clone, { fn fit(&mut self) -> NPResult { self.run() @@ -62,7 +65,7 @@ where self.theta.clone(), self.psi.clone(), self.w.clone(), - self.objf, + -2. * self.objf, self.cycle, self.converged, self.settings.clone(), @@ -72,7 +75,7 @@ where impl NPAG where - S: Predict + std::marker::Sync + Clone, + S: Predict<'static> + std::marker::Sync + Clone, { /// Creates a new NPAG instance. /// @@ -95,11 +98,11 @@ where theta: Array2, scenarios: Vec, c: (f64, f64, f64, f64), - tx: UnboundedSender, - settings: Data, + tx: UnboundedSender, + settings: Settings, ) -> Self where - S: Predict + std::marker::Sync, + S: Predict<'static> + std::marker::Sync, { Self { engine: sim_eng, @@ -115,15 +118,15 @@ where f1: f64::default(), cycle: 1, gamma_delta: 0.1, - gamma: settings.parsed.error.value, - error_type: match settings.parsed.error.class.as_str() { + gamma: settings.error.value, + error_type: match settings.error.class.to_lowercase().as_str() { "additive" => ErrorType::Add, "proportional" => ErrorType::Prop, _ => panic!("Error type not supported"), }, converged: false, - cycle_log: CycleLog::new(&settings.computed.random.names), - cache: settings.parsed.config.cache.unwrap_or(false), + cycle_log: CycleLog::new(&settings.random.names()), + cache: settings.config.cache, tx, settings, scenarios, @@ -195,7 +198,10 @@ where pub fn run(&mut self) -> NPResult { while self.eps > THETA_E { - // log::info!("Cycle: {}", cycle); + // Enter a span for each cycle, provding context for further errors + let cycle_span = tracing::span!(tracing::Level::INFO, "Cycle", cycle = self.cycle); + let _enter = cycle_span.enter(); + // psi n_sub rows, nspp columns let cache = if self.cycle == 1 { false } else { self.cache }; let ypred = sim_obs(&self.engine, &self.scenarios, &self.theta, cache); @@ -240,12 +246,15 @@ where keep.push(*perm.get(i).unwrap()); } } - log::info!( - "QR decomp, cycle {}, kept: {}, thrown {}", - self.cycle, - keep.len(), - self.psi.ncols() - keep.len() - ); + + // If a support point is dropped, log it + if self.psi.ncols() != keep.len() { + tracing::debug!( + "QRD dropped {} support point(s)", + self.psi.ncols() - keep.len(), + ); + } + self.theta = self.theta.select(Axis(0), &keep); self.psi = self.psi.select(Axis(1), &keep); @@ -259,36 +268,39 @@ where self.optim_gamma(); - let mut state = NPCycle { + let state = NPCycle { cycle: self.cycle, objf: -2. * self.objf, delta_objf: (self.last_objf - self.objf).abs(), nspp: self.theta.shape()[0], - stop_text: "".to_string(), theta: self.theta.clone(), gamlam: self.gamma, }; - self.tx.send(state.clone()).unwrap(); + self.tx.send(Comm::NPCycle(state.clone())).unwrap(); - // If the objective function decreased, log an error. - // Increasing objf signals instability of model misspecification. + // Increasing objf signals instability or model misspecification. if self.last_objf > self.objf { - log::error!("Objective function decreased"); + tracing::info!( + "Objective function decreased from {} to {}", + self.last_objf, + self.objf + ); } self.w = self.lambda.clone(); let pyl = self.psi.dot(&self.w); + self.cycle_log + .push_and_write(state, self.settings.config.output); + // Stop if we have reached convergence criteria if (self.last_objf - self.objf).abs() <= THETA_G && self.eps > THETA_E { self.eps /= 2.; if self.eps <= THETA_E { self.f1 = pyl.mapv(|x| x.ln()).sum(); if (self.f1 - self.f0).abs() <= THETA_F { - log::info!("Likelihood criteria convergence"); + tracing::info!("The run converged"); self.converged = true; - state.stop_text = "The run converged!".to_string(); - self.tx.send(state).unwrap(); break; } else { self.f0 = self.f1; @@ -298,23 +310,18 @@ where } // Stop if we have reached maximum number of cycles - if self.cycle >= self.settings.parsed.config.cycles { - log::info!("Maximum number of cycles reached"); - state.stop_text = "No (max cycle)".to_string(); - self.tx.send(state).unwrap(); + if self.cycle >= self.settings.config.cycles { + tracing::warn!("Maximum number of cycles reached"); break; } // Stop if stopfile exists if std::path::Path::new("stop").exists() { - log::info!("Stopfile detected - breaking"); - state.stop_text = "No (stopped)".to_string(); - self.tx.send(state).unwrap(); + tracing::warn!("Stopfile detected - breaking"); break; } - self.cycle_log - .push_and_write(state, self.settings.parsed.config.pmetrics_outputs.unwrap()); + // If we have not reached convergence or otherwise stopped, expand grid and prepare for new cycle self.adaptative_grid(); self.cycle += 1; self.last_objf = self.objf; diff --git a/src/algorithms/npod.rs b/src/algorithms/npod.rs new file mode 100644 index 000000000..46949bdb2 --- /dev/null +++ b/src/algorithms/npod.rs @@ -0,0 +1,325 @@ +use crate::{ + prelude::{ + algorithms::Algorithm, + condensation::prune::prune, + datafile::Scenario, + evaluation::sigma::{ErrorPoly, ErrorType}, + ipm, + optimization::d_optimizer::SppOptimizer, + output::NPResult, + output::{CycleLog, NPCycle}, + prob, qr, + settings::Settings, + simulation::predict::Engine, + simulation::predict::{sim_obs, Predict}, + }, + tui::ui::Comm, +}; +use ndarray::parallel::prelude::*; +use ndarray::{Array, Array1, Array2, Axis}; +use ndarray_stats::{DeviationExt, QuantileExt}; +use tokio::sync::mpsc::UnboundedSender; + +const THETA_D: f64 = 1e-4; +const THETA_F: f64 = 1e-2; + +pub struct NPOD +where + S: Predict<'static> + std::marker::Sync + Clone, +{ + engine: Engine, + ranges: Vec<(f64, f64)>, + psi: Array2, + theta: Array2, + lambda: Array1, + w: Array1, + last_objf: f64, + objf: f64, + cycle: usize, + gamma_delta: f64, + gamma: f64, + error_type: ErrorType, + converged: bool, + cycle_log: CycleLog, + cache: bool, + scenarios: Vec, + c: (f64, f64, f64, f64), + tx: UnboundedSender, + settings: Settings, +} + +impl Algorithm for NPOD +where + S: Predict<'static> + std::marker::Sync + Clone, +{ + fn fit(&mut self) -> NPResult { + self.run() + } + fn to_npresult(&self) -> NPResult { + NPResult::new( + self.scenarios.clone(), + self.theta.clone(), + self.psi.clone(), + self.w.clone(), + self.objf, + self.cycle, + self.converged, + self.settings.clone(), + ) + } +} + +impl NPOD +where + S: Predict<'static> + std::marker::Sync + Clone, +{ + /// Creates a new NPOD instance. + /// + /// # Parameters + /// + /// - `sim_eng`: An instance of the prediction engine. + /// - `ranges`: A vector of value ranges for each parameter. + /// - `theta`: An initial parameter matrix. + /// - `scenarios`: A vector of scenarios. + /// - `c`: A tuple containing coefficients for the error polynomial. + /// - `tx`: An unbounded sender for communicating progress. + /// - `settings`: Data settings and configurations. + /// + /// # Returns + /// + /// Returns a new `NPOD` instance. + pub fn new( + sim_eng: Engine, + ranges: Vec<(f64, f64)>, + theta: Array2, + scenarios: Vec, + c: (f64, f64, f64, f64), + tx: UnboundedSender, + settings: Settings, + ) -> Self + where + S: Predict<'static> + std::marker::Sync, + { + Self { + engine: sim_eng, + ranges, + psi: Array2::default((0, 0)), + theta, + lambda: Array1::default(0), + w: Array1::default(0), + last_objf: -1e30, + objf: f64::INFINITY, + cycle: 1, + gamma_delta: 0.1, + gamma: settings.error.value, + error_type: match settings.error.class.as_str() { + "additive" => ErrorType::Add, + "proportional" => ErrorType::Prop, + _ => panic!("Error type not supported"), + }, + converged: false, + cycle_log: CycleLog::new(&settings.random.names()), + cache: settings.config.cache, + tx, + settings, + scenarios, + c, + } + } + + fn optim_gamma(&mut self) { + //Gam/Lam optimization + // TODO: Move this to e.g. /evaluation/error.rs + let gamma_up = self.gamma * (1.0 + self.gamma_delta); + let gamma_down = self.gamma / (1.0 + self.gamma_delta); + let ypred = sim_obs(&self.engine, &self.scenarios, &self.theta, self.cache); + let psi_up = prob::calculate_psi( + &ypred, + &self.scenarios, + &ErrorPoly { + c: self.c, + gl: gamma_up, + e_type: &self.error_type, + }, + ); + let psi_down = prob::calculate_psi( + &ypred, + &self.scenarios, + &ErrorPoly { + c: self.c, + gl: gamma_down, + e_type: &self.error_type, + }, + ); + let (lambda_up, objf_up) = match ipm::burke(&psi_up) { + Ok((lambda, objf)) => (lambda, objf), + Err(err) => { + //todo: write out report + panic!("Error in IPM: {:?}", err); + } + }; + let (lambda_down, objf_down) = match ipm::burke(&psi_down) { + Ok((lambda, objf)) => (lambda, objf), + Err(err) => { + //todo: write out report + panic!("Error in IPM: {:?}", err); + } + }; + if objf_up > self.objf { + self.gamma = gamma_up; + self.objf = objf_up; + self.gamma_delta *= 4.; + self.lambda = lambda_up; + self.psi = psi_up; + } + if objf_down > self.objf { + self.gamma = gamma_down; + self.objf = objf_down; + self.gamma_delta *= 4.; + self.lambda = lambda_down; + self.psi = psi_down; + } + self.gamma_delta *= 0.5; + if self.gamma_delta <= 0.01 { + self.gamma_delta = 0.1; + } + } + + pub fn run(&mut self) -> NPResult { + while (self.last_objf - self.objf).abs() > THETA_F { + self.last_objf = self.objf; + // log::info!("Cycle: {}", cycle); + // psi n_sub rows, nspp columns + let cache = if self.cycle == 1 { false } else { self.cache }; + let ypred = sim_obs(&self.engine, &self.scenarios, &self.theta, cache); + + self.psi = prob::calculate_psi( + &ypred, + &self.scenarios, + &ErrorPoly { + c: self.c, + gl: self.gamma, + e_type: &self.error_type, + }, + ); + (self.lambda, _) = match ipm::burke(&self.psi) { + Ok((lambda, objf)) => (lambda, objf), + Err(err) => { + //todo: write out report + panic!("Error in IPM: {:?}", err); + } + }; + + let mut keep = Vec::::new(); + for (index, lam) in self.lambda.iter().enumerate() { + if *lam > self.lambda.max().unwrap() / 1000_f64 { + keep.push(index); + } + } + + self.theta = self.theta.select(Axis(0), &keep); + self.psi = self.psi.select(Axis(1), &keep); + + //Rank-Revealing Factorization + let (r, perm) = qr::calculate_r(&self.psi); + + let mut keep = Vec::::new(); + //The minimum between the number of subjects and the actual number of support points + let lim_loop = self.psi.nrows().min(self.psi.ncols()); + for i in 0..lim_loop { + let test = norm_zero(&r.column(i).to_owned()); + let ratio = r.get((i, i)).unwrap() / test; + if ratio.abs() >= 1e-8 { + keep.push(*perm.get(i).unwrap()); + } + } + tracing::info!( + "QR decomp, cycle {}, kept: {}, thrown {}", + self.cycle, + keep.len(), + self.psi.ncols() - keep.len() + ); + self.theta = self.theta.select(Axis(0), &keep); + self.psi = self.psi.select(Axis(1), &keep); + + (self.lambda, self.objf) = match ipm::burke(&self.psi) { + Ok((lambda, objf)) => (lambda, objf), + Err(err) => { + //todo: write out report + panic!("Error in IPM: {:?}", err); + } + }; + + self.optim_gamma(); + + let state = NPCycle { + cycle: self.cycle, + objf: -2. * self.objf, + delta_objf: (self.last_objf - self.objf).abs(), + nspp: self.theta.shape()[0], + theta: self.theta.clone(), + gamlam: self.gamma, + }; + self.tx.send(Comm::NPCycle(state.clone())).unwrap(); + + // If the objective function decreased, log an error. + // Increasing objf signals instability of model misspecification. + if self.last_objf > self.objf { + tracing::error!("Objective function decreased"); + } + + self.w = self.lambda.clone(); + let pyl = self.psi.dot(&self.w); + + // Add new point to theta based on the optimization of the D function + let sigma = ErrorPoly { + c: self.c, + gl: self.gamma, + e_type: &self.error_type, + }; + // for spp in self.theta.clone().rows() { + // let optimizer = SppOptimizer::new(&self.engine, &self.scenarios, &sigma, &pyl); + // let candidate_point = optimizer.optimize_point(spp.to_owned()).unwrap(); + // prune(&mut self.theta, candidate_point, &self.ranges, THETA_D); + // } + let mut candididate_points: Vec> = Vec::default(); + for spp in self.theta.clone().rows() { + candididate_points.push(spp.to_owned()); + } + candididate_points.par_iter_mut().for_each(|spp| { + let optimizer = SppOptimizer::new(&self.engine, &self.scenarios, &sigma, &pyl); + let candidate_point = optimizer.optimize_point(spp.to_owned()).unwrap(); + *spp = candidate_point; + }); + for cp in candididate_points { + prune(&mut self.theta, cp, &self.ranges, THETA_D); + } + + // Stop if we have reached maximum number of cycles + if self.cycle >= self.settings.config.cycles { + tracing::warn!("Maximum number of cycles reached"); + break; + } + + // Stop if stopfile exists + if std::path::Path::new("stop").exists() { + tracing::warn!("Stopfile detected - breaking"); + break; + } + //TODO: the cycle migh break before reaching this point + self.cycle_log + .push_and_write(state, self.settings.config.output); + + self.cycle += 1; + + // log::info!("cycle: {}, objf: {}", self.cycle, self.objf); + // dbg!((self.last_objf - self.objf).abs()); + } + + self.to_npresult() + } +} +fn norm_zero(a: &Array1) -> f64 { + let zeros: Array1 = Array::zeros(a.len()); + a.l2_dist(&zeros).unwrap() +} diff --git a/src/algorithms/postprob.rs b/src/algorithms/postprob.rs index 44f31618d..85e6b1353 100644 --- a/src/algorithms/postprob.rs +++ b/src/algorithms/postprob.rs @@ -1,14 +1,16 @@ -use crate::prelude::{ - algorithms::Algorithm, - datafile::Scenario, - evaluation::sigma::{ErrorPoly, ErrorType}, - ipm, - output::NPCycle, - output::NPResult, - prob, - settings::run::Data, - simulation::predict::Engine, - simulation::predict::{sim_obs, Predict}, +use crate::{ + prelude::{ + algorithms::Algorithm, + datafile::Scenario, + evaluation::sigma::{ErrorPoly, ErrorType}, + ipm, + output::NPResult, + prob, + settings::Settings, + simulation::predict::Engine, + simulation::predict::{sim_obs, Predict}, + }, + tui::ui::Comm, }; use ndarray::{Array1, Array2}; @@ -18,7 +20,7 @@ use tokio::sync::mpsc::UnboundedSender; /// Reweights the prior probabilities to the observed data and error model pub struct POSTPROB where - S: Predict + std::marker::Sync + Clone, + S: Predict<'static> + std::marker::Sync + Clone, { engine: Engine, psi: Array2, @@ -32,13 +34,13 @@ where scenarios: Vec, c: (f64, f64, f64, f64), #[allow(dead_code)] - tx: UnboundedSender, - settings: Data, + tx: UnboundedSender, + settings: Settings, } impl Algorithm for POSTPROB where - S: Predict + std::marker::Sync + Clone, + S: Predict<'static> + std::marker::Sync + Clone, { fn fit(&mut self) -> NPResult { self.run() @@ -59,18 +61,18 @@ where impl POSTPROB where - S: Predict + std::marker::Sync + Clone, + S: Predict<'static> + std::marker::Sync + Clone, { pub fn new( sim_eng: Engine, theta: Array2, scenarios: Vec, c: (f64, f64, f64, f64), - tx: UnboundedSender, - settings: Data, + tx: UnboundedSender, + settings: Settings, ) -> Self where - S: Predict + std::marker::Sync, + S: Predict<'static> + std::marker::Sync, { Self { engine: sim_eng, @@ -80,8 +82,8 @@ where objf: f64::INFINITY, cycle: 0, converged: false, - gamma: settings.parsed.error.value, - error_type: match settings.parsed.error.class.as_str() { + gamma: settings.error.value, + error_type: match settings.error.class.as_str() { "additive" => ErrorType::Add, "proportional" => ErrorType::Prop, _ => panic!("Error type not supported"), diff --git a/src/entrypoints.rs b/src/entrypoints.rs index f5841a369..885e9dde7 100644 --- a/src/entrypoints.rs +++ b/src/entrypoints.rs @@ -1,10 +1,12 @@ use crate::algorithms::initialize_algorithm; -use crate::prelude::output::NPCycle; use crate::prelude::{ output::NPResult, predict::{Engine, Predict}, *, }; +use crate::routines::datafile::Scenario; +use crate::routines::settings::*; + use csv::{ReaderBuilder, WriterBuilder}; use eyre::Result; @@ -16,27 +18,51 @@ use std::thread::spawn; use std::time::Instant; use tokio::sync::mpsc::{self}; +/// Simulate predictions from a model and prior distribution +/// +/// This function is used to simulate predictions from a model and prior distribution. +/// The output is a CSV file with the following columns: +/// - `id`: subject ID, corresponding to the desired dose regimen +/// - `point`: support point index (0-indexed) +/// - `time`: prediction time +/// - `pred`: simulated prediction +/// +/// # Arguments +/// The user can specify the desired settings in a TOML configuration file, see `routines::settings::simulator` for details. +/// - `idelta`: the interval between predictions. Default is 0.0. +/// - `tad`: the time after dose, which if greater than the last prediction time is the time for which it will predict . Default is 0.0. pub fn simulate(engine: Engine, settings_path: String) -> Result<()> where - S: Predict + std::marker::Sync + std::marker::Send + 'static + Clone, + S: Predict<'static> + std::marker::Sync + std::marker::Send + 'static + Clone, { - let settings = settings::simulator::read(settings_path); - let theta_file = File::open(settings.paths.theta).unwrap(); + let settings: Settings = read_settings(settings_path).unwrap(); + let theta_file = File::open(settings.paths.prior.unwrap()).unwrap(); let mut reader = ReaderBuilder::new() - .has_headers(false) + .has_headers(true) .from_reader(theta_file); let theta: Array2 = reader.deserialize_array2_dynamic().unwrap(); - let scenarios = datafile::parse(&settings.paths.data).unwrap(); + // Expand data + let idelta = settings.config.idelta; + let tad = settings.config.tad; + let mut scenarios = datafile::parse(&settings.paths.data).unwrap(); + scenarios.iter_mut().for_each(|scenario| { + *scenario = scenario.add_event_interval(idelta, tad); + }); + + // Perform simulation let ypred = sim_obs(&engine, &scenarios, &theta, false); + // Prepare writer let sim_file = File::create("simulation_output.csv").unwrap(); let mut sim_writer = WriterBuilder::new() .has_headers(false) .from_writer(sim_file); sim_writer - .write_record(["id", "point", "time", "sim_obs"]) + .write_record(["id", "point", "time", "pred"]) .unwrap(); + + // Write output for (id, scenario) in scenarios.iter().enumerate() { let time = scenario.obs_times.clone(); for (point, _spp) in theta.rows().into_iter().enumerate() { @@ -52,29 +78,113 @@ where } Ok(()) } + +/// Primary entrypoint for NPcore +/// +/// This function is the primary entrypoint for NPcore, and is used to run the algorithm. +/// The settings for this function is specified in a TOML configuration file, see `routines::settings::run` for details. pub fn start(engine: Engine, settings_path: String) -> Result where - S: Predict + std::marker::Sync + std::marker::Send + 'static + Clone, + S: Predict<'static> + std::marker::Sync + std::marker::Send + 'static + Clone, { let now = Instant::now(); - let settings = settings::run::read(settings_path); - logger::setup_log(&settings); - let (tx, rx) = mpsc::unbounded_channel::(); - let mut algorithm = initialize_algorithm(engine.clone(), settings.clone(), tx); + let settings = match read_settings(settings_path) { + Ok(s) => s, + Err(e) => { + eprintln!("Error reading settings: {:?}", e); + std::process::exit(-1); + } + }; + let (tx, rx) = mpsc::unbounded_channel::(); + let maintx = tx.clone(); + logger::setup_log(&settings, tx.clone()); + tracing::info!("Starting NPcore"); + + // Read input data and remove excluded scenarios (if any) + let mut scenarios = datafile::parse(&settings.paths.data).unwrap(); + if let Some(exclude) = &settings.config.exclude { + for val in exclude { + scenarios.remove(val.as_ptr() as usize); + } + } + + // Provide information of the input data + tracing::info!( + "Datafile contains {} subjects with a total of {} observations", + scenarios.len(), + scenarios.iter().map(|s| s.obs_times.len()).sum::() + ); + // Spawn new thread for TUI let settings_tui = settings.clone(); - if settings.parsed.config.tui { - let _ui_handle = spawn(move || { + let handle = if settings.config.tui { + spawn(move || { start_ui(rx, settings_tui).expect("Failed to start TUI"); - }); - } + }) + } else { + // Drop messages if TUI is not enabled to reduce memory usage + spawn(move || { + drop_messages(rx); + }) + }; + // Initialize algorithm and run + let mut algorithm = initialize_algorithm(engine.clone(), settings.clone(), scenarios, tx); let result = algorithm.fit(); - log::info!("Total time: {:.2?}", now.elapsed()); + tracing::info!("Total time: {:.2?}", now.elapsed()); - if let Some(write) = &settings.parsed.config.pmetrics_outputs { - result.write_outputs(*write, &engine); + // Write output files (if configured) + if settings.config.output { + let idelta = settings.config.idelta; + let tad = settings.config.tad; + result.write_outputs(true, &engine, idelta, tad); } + tracing::info!("Program complete"); + maintx.send(Comm::StopUI).unwrap(); + handle.join().unwrap(); + Ok(result) } + +/// Alternative entrypoint, primarily meant for third-party libraries or APIs +/// +/// This entrypoint takes an `Engine` (from the model), `Data` from the settings, and `scenarios` containing dose information and observations +/// +/// It does not write any output files, and does not start a TUI. +/// +/// Returns an NPresult object +pub fn start_internal( + engine: Engine, + settings: Settings, + scenarios: Vec, +) -> Result +where + S: Predict<'static> + std::marker::Sync + std::marker::Send + 'static + Clone, +{ + let now = Instant::now(); + let (tx, rx) = mpsc::unbounded_channel::(); + logger::setup_log(&settings, tx.clone()); + + let mut algorithm = initialize_algorithm(engine.clone(), settings.clone(), scenarios, tx); + + let _ = spawn(move || { + drop_messages(rx); + }); + + let result = algorithm.fit(); + tracing::info!("Total time: {:.2?}", now.elapsed()); + Ok(result) +} + +fn drop_messages(mut rx: mpsc::UnboundedReceiver) { + loop { + match rx.try_recv() { + Ok(comm) => match comm { + Comm::StopUI => break, + _ => {} + }, + Err(_e) => {} + } + } +} diff --git a/src/lib.rs b/src/lib.rs index 93613688a..8aa99a42e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -5,16 +5,20 @@ pub mod routines { pub mod datafile; pub mod initialization; pub mod optimization { - pub mod expansion; + pub mod d_optimizer; pub mod optim; } pub mod output; - - pub mod settings { - pub mod run; - pub mod simulator; + pub mod condensation { + pub mod prune; + } + pub mod expansion { + pub mod adaptative_grid; } + + pub mod settings; pub mod evaluation { + pub mod ipm; pub mod prob; pub mod qr; @@ -32,10 +36,13 @@ pub mod prelude { pub use crate::algorithms; pub use crate::entrypoints::simulate; pub use crate::entrypoints::start; + pub use crate::entrypoints::start_internal; pub use crate::logger; pub use crate::prelude::evaluation::{prob, sigma, *}; + pub use crate::routines::condensation; + pub use crate::routines::expansion::*; pub use crate::routines::initialization::*; - pub use crate::routines::optimization::*; + pub use crate::routines::optimization; pub use crate::routines::simulation::*; pub use crate::routines::*; pub use crate::tui::ui::*; diff --git a/src/logger.rs b/src/logger.rs index 5ddbea7a2..755fb17ea 100644 --- a/src/logger.rs +++ b/src/logger.rs @@ -1,23 +1,115 @@ -use crate::prelude::settings::run::Data; -use log::LevelFilter; -use log4rs::append::file::FileAppender; -use log4rs::config::{Appender, Config, Root}; -use log4rs::encode::pattern::PatternEncoder; -use std::fs; - -pub fn setup_log(settings: &Data) { - if let Some(log_path) = &settings.parsed.paths.log_out { - if fs::remove_file(log_path).is_ok() {}; - let logfile = FileAppender::builder() - .encoder(Box::new(PatternEncoder::new("{l}: {m}\n"))) - .build(log_path) - .unwrap(); - - let config = Config::builder() - .appender(Appender::builder().build("logfile", Box::new(logfile))) - .build(Root::builder().appender("logfile").build(LevelFilter::Info)) - .unwrap(); - - log4rs::init_config(config).unwrap(); +use crate::routines::settings::Settings; +use crate::tui::ui::Comm; +use std::io::{self, Write}; +use tokio::sync::mpsc::UnboundedSender; +use tracing_subscriber::fmt::time::FormatTime; +use tracing_subscriber::fmt::{self}; +use tracing_subscriber::prelude::__tracing_subscriber_SubscriberExt; +use tracing_subscriber::registry::Registry; +use tracing_subscriber::util::SubscriberInitExt; +use tracing_subscriber::EnvFilter; + +/// Setup logging for the library +/// +/// This function sets up logging for the library. It uses the `tracing` crate, and the `tracing-subscriber` crate for formatting. +/// +/// The log level is defined in the configuration file, and defaults to `INFO`. +/// +/// If `log_out` is specifified in teh configuration file, a log file is created with the specified name. +/// +/// Additionally, if the `tui` option is set to `true`, the log messages are also written to the TUI. +/// +/// If not, the log messages are written to stdout. +pub fn setup_log(settings: &Settings, ui_tx: UnboundedSender) { + // Use the log level defined in configuration file, or default to info + let log_level = settings.config.log_level.as_str(); + + // Use the log file defined in configuration file, or default to npcore.log + let log_path = settings.paths.log.as_ref().unwrap(); + + let env_filter = EnvFilter::new(&log_level); + + // Define a registry with that level as an environment filter + let subscriber = Registry::default().with(env_filter); + + // Define a layer for the log file + let file = std::fs::OpenOptions::new() + .create(true) + .write(true) + .truncate(true) + .open(log_path) + .expect("Failed to open log file - does the directory exist?"); + + let file_layer = fmt::layer() + .with_writer(file) + .with_ansi(false) + .with_timer(CompactTimestamp); + + // Define layer for stdout + let stdout_layer = if !settings.config.tui { + let layer = fmt::layer() + .with_writer(std::io::stdout) + .with_ansi(true) + .with_target(false) + .with_timer(CompactTimestamp); + Some(layer) + } else { + None + }; + + // Define layer for TUI + let tui_writer_closure = move || TuiWriter { + ui_tx: ui_tx.clone(), + }; + + let tui_layer = if settings.config.tui { + let layer = fmt::layer() + .with_writer(tui_writer_closure) + .with_ansi(false) + .with_target(false) + .with_timer(CompactTimestamp); + Some(layer) + } else { + None }; + + // Combine layers with subscriber + subscriber + .with(file_layer) + .with(stdout_layer) + .with(tui_layer) + .init(); + tracing::debug!("Logging is configured with level: {}", log_level); +} + +#[derive(Clone)] +struct CompactTimestamp; + +impl FormatTime for CompactTimestamp { + fn format_time( + &self, + w: &mut tracing_subscriber::fmt::format::Writer<'_>, + ) -> Result<(), std::fmt::Error> { + write!(w, "{}", chrono::Local::now().format("%H:%M:%S")) + } +} + +struct TuiWriter { + ui_tx: UnboundedSender, +} + +impl Write for TuiWriter { + fn write(&mut self, buf: &[u8]) -> io::Result { + let msg = String::from_utf8_lossy(buf); + // Send the message through the channel + self.ui_tx + .send(Comm::LogMessage(msg.to_string())) + .map_err(|_| io::Error::new(io::ErrorKind::Other, "Failed to send log message"))?; + Ok(buf.len()) + } + + fn flush(&mut self) -> io::Result<()> { + // Flushing is not required for this use case + Ok(()) + } } diff --git a/src/routines/condensation/prune.rs b/src/routines/condensation/prune.rs new file mode 100644 index 000000000..597327b87 --- /dev/null +++ b/src/routines/condensation/prune.rs @@ -0,0 +1,19 @@ +use ndarray::{Array1, Array2}; + +pub fn prune( + theta: &mut Array2, + candidate: Array1, + limits: &[(f64, f64)], + min_dist: f64, +) { + for spp in theta.rows() { + let mut dist: f64 = 0.; + for (i, val) in candidate.clone().into_iter().enumerate() { + dist += (val - spp.get(i).unwrap()).abs() / (limits[i].1 - limits[i].0); + } + if dist <= min_dist { + return; + } + } + theta.push_row(candidate.view()).unwrap(); +} diff --git a/src/routines/datafile.rs b/src/routines/datafile.rs index 5ececd279..d11e825e9 100644 --- a/src/routines/datafile.rs +++ b/src/routines/datafile.rs @@ -7,7 +7,8 @@ use crate::tui::inputs::events::Events; type Record = HashMap; -/// A Scenario is a collection of blocks that represent a single subject in the Datafile +/// A Scenario is a collection of blocks that represent a single subject in the datafile +/// Each block is a collection of events that represent a single dose, possibly followed by observations #[derive(Debug, Clone)] pub struct Scenario { pub id: String, @@ -24,6 +25,86 @@ impl Scenario { Ok(scenario) } + /// Adds "mock" events to a Scenario in order to generate predictions at those times + /// The interval is mapped to the `idelta`-setting in the configuration file + /// Time after dose (`tad`) will ensure that predictions are made until the last dose + tad + pub fn add_event_interval(&self, interval: f64, tad: f64) -> Self { + // Clone the underlying Event data instead of the references + let all_events = self + .clone() + .blocks + .iter() + .flat_map(|block| block.events.iter().cloned()) + .collect::>(); + + // Determine the start and end times + let start_time = all_events.first().unwrap().time; + let mut end_time = all_events.last().unwrap().time; + + // Pad end time to accomodate time after dose + if tad > 0.0 { + let last_dose_time = all_events + .iter() + .filter(|event| event.evid == 1) + .map(|event| event.time) + .fold(std::f64::NEG_INFINITY, f64::max); + + if end_time < last_dose_time + tad { + end_time = last_dose_time + tad + } + } + + // Determine the unique output equations in the events + // TODO: This should be read from the model / engine + let mut outeqs: Vec<_> = all_events.iter().filter_map(|event| event.outeq).collect(); + outeqs.sort_unstable(); + outeqs.dedup(); + + // Generate dummy events + let mut new_events = vec![]; + let mut current_time = start_time + interval; // Start from the first interval after the start time + while current_time <= end_time { + current_time = (current_time / interval).round() * interval; // Round to the nearest interval + current_time = decimals(current_time, 4); // Round to 4 decimal places + for outeq in &outeqs { + new_events.push(Event { + id: self.id.clone(), + evid: 0, + time: current_time, + dur: None, + dose: None, + _addl: None, + _ii: None, + input: None, + out: Some(-99.0), + outeq: Some(*outeq), + _c0: None, + _c1: None, + _c2: None, + _c3: None, + covs: HashMap::new(), + }); + } + current_time += interval; + } + + // Combine all_events with new_events + let mut combined_events = all_events; + combined_events.extend(new_events.iter().cloned()); + + // Sort the events by time + combined_events.sort_by(|a, b| a.cmp_by_id_then_time(b)); + // Remove duplicate events based on time and outeq + // In essence, no need to have two predictions at the same time for the same outeq + let time_tolerance = 1e-4; + combined_events.sort_by(|a, b| a.cmp_by_id_then_time(b)); + combined_events.dedup_by(|a, b| { + (a.time - b.time).abs() < time_tolerance && a.outeq == b.outeq && a.evid == b.evid + }); + + Scenario::new(combined_events).unwrap() + } + pub fn reorder_with_lag(&self, lag_inputs: Vec<(f64, usize)>) -> Self { if lag_inputs.is_empty() { return self.clone(); @@ -88,7 +169,7 @@ impl Scenario { obs_times.push(event.time); obs.push(event.out.unwrap()); } else { - log::error!("Error: Unsupported evid"); + tracing::error!("Error: Unsupported evid: {evid}", evid = event.evid); exit(-1); } block.events.push(event); @@ -305,12 +386,12 @@ pub fn parse(path: &String) -> Result, Box> { fn check_dose(event: &Event) -> Result<(), Box> { if event.dose.is_none() { - log::error!("Error: Dose event without dose"); + tracing::error!("Error: Dose event without dose"); //return Err("Error: Dose event without dose".into()); exit(-1); } if event.input.is_none() { - log::error!("Error: Dose event without input"); + tracing::error!("Error: Dose event without input"); //return Err("Error: Dose event without input".into()); exit(-1); } @@ -318,17 +399,17 @@ fn check_dose(event: &Event) -> Result<(), Box> { } fn check_infusion(event: &Event) -> Result<(), Box> { if event.dose.is_none() { - log::error!("Error: Infusion event without dose"); + tracing::error!("Error: Infusion event without dose"); //return Err("Error: Infusion event without dose".into()); exit(-1); } if event.dur.is_none() { - log::error!("Error: Infusion event without duration"); + tracing::error!("Error: Infusion event without duration"); //return Err("Error: Infusion event without duration".into()); exit(-1); } if event.input.is_none() { - log::error!("Error: Infusion event without input"); + tracing::error!("Error: Infusion event without input"); //return Err("Error: Infusion event without input".into()); exit(-1); } @@ -336,14 +417,19 @@ fn check_infusion(event: &Event) -> Result<(), Box> { } fn check_obs(event: &Event) -> Result<(), Box> { if event.out.is_none() { - log::error!("Error: Obs event without out"); + tracing::error!("Error: Obs event without out"); //return Err("Error: Obs event without out".into()); exit(-1); } if event.outeq.is_none() { - log::error!("Error: Obs event without outeq"); + tracing::error!("Error: Obs event without outeq"); //return Err("Error: Obs event without outeq".into()); exit(-1); } Ok(()) } + +fn decimals(value: f64, places: u32) -> f64 { + let multiplier = 10f64.powi(places as i32); + (value * multiplier).round() / multiplier +} diff --git a/src/routines/evaluation/ipm.rs b/src/routines/evaluation/ipm.rs index 7ef291f2a..6a8d0b735 100644 --- a/src/routines/evaluation/ipm.rs +++ b/src/routines/evaluation/ipm.rs @@ -19,7 +19,7 @@ type OneDimArray = ArrayBase, ndarray::Dim<[usize; 1]>>; /// /// A `Result` containing a tuple with two elements: /// -/// * `lam` - An Array1 representing the solution of the optimization problem. +/// * `lam` - An `Array1` representing the solution of the optimization problem. /// * `obj` - A f64 value representing the objective function value at the solution. /// /// # Errors @@ -41,7 +41,7 @@ pub fn burke( // if row>col { // return Err("The matrix PSI has row>col".into()); // } - if psi.min().unwrap() < &0.0 { + if psi.min()? < &0.0 { return Err("PSI contains negative elements".into()); } let ecol: ArrayBase, Dim<[usize; 1]>> = Array::ones(col); @@ -55,7 +55,7 @@ pub fn burke( let mut lam = ecol.clone(); let mut w = 1. / &plam; let mut ptw = psi.t().dot(&w); - let shrink = 2. * *ptw.max().unwrap(); + let shrink = 2. * *ptw.max()?; lam *= shrink; plam *= shrink; w /= shrink; @@ -88,10 +88,10 @@ pub fn burke( let dw = dw_aux.column(0); let dy = -psi.t().dot(&dw); let dlam = smuyinv - &lam - inner * &dy; - let mut alfpri = -1. / ((&dlam / &lam).min().unwrap().min(-0.5)); + let mut alfpri = -1. / ((&dlam / &lam).min()?.min(-0.5)); alfpri = (0.99995 * alfpri).min(1.0); - let mut alfdual = -1. / ((&dy / &y).min().unwrap().min(-0.5)); - alfdual = alfdual.min(-1. / (&dw / &w).min().unwrap().min(-0.5)); + let mut alfdual = -1. / ((&dy / &y).min()?.min(-0.5)); + alfdual = alfdual.min(-1. / (&dw / &w).min()?.min(-0.5)); alfdual = (0.99995 * alfdual).min(1.0); lam = lam + alfpri * dlam; w = w + alfdual * &dw; @@ -111,8 +111,7 @@ pub fn burke( (1. - alfdual).powi(2), (norm_r - mu) / (norm_r + 100. * mu) ]] - .max() - .unwrap() + .max()? .min(0.3); } } diff --git a/src/routines/evaluation/prob.rs b/src/routines/evaluation/prob.rs index bf94daf67..38a9dccdf 100644 --- a/src/routines/evaluation/prob.rs +++ b/src/routines/evaluation/prob.rs @@ -32,7 +32,7 @@ where let sigma = sig.sigma(&yobs); let ll = normal_likelihood(ypred.get((i, j)).unwrap(), &yobs, &sigma); if ll.is_nan() || ll.is_infinite() { - log::info!( + tracing::info!( "NaN or Inf Likelihood detected!\nLL:{:?}\nypred: {:?}\nsubject: {}\nSpp: {}", ll, &ypred.get((i, j)), diff --git a/src/routines/evaluation/sigma.rs b/src/routines/evaluation/sigma.rs index 490f92fbc..8b3525de2 100644 --- a/src/routines/evaluation/sigma.rs +++ b/src/routines/evaluation/sigma.rs @@ -54,7 +54,7 @@ impl<'a> Sigma for ErrorPoly<'a> { res.mapv(|x| { if x.is_nan() || x < 0.0 { - log::error!( + tracing::error!( "The computed standard deviation is either NaN or negative (SD = {}), coercing to 0", x ); diff --git a/src/routines/optimization/expansion.rs b/src/routines/expansion/adaptative_grid.rs similarity index 56% rename from src/routines/optimization/expansion.rs rename to src/routines/expansion/adaptative_grid.rs index f9bc2dbf2..933b15454 100644 --- a/src/routines/optimization/expansion.rs +++ b/src/routines/expansion/adaptative_grid.rs @@ -1,5 +1,14 @@ -use ndarray::{Array, Array1, Array2}; +use ndarray::{Array, Array2}; +use crate::routines::condensation::prune::prune; + +/// Adaptive grid algorithm for support point expansion +/// +/// For each support point, generate up to 2 new support points in each dimension +/// +/// New support points are symmetrically placed around the original support point, at a distance of eps * (range_max - range_min) +/// +/// If the new support point is too close to an existing support point, or it is outside the given range, it is discarded pub fn adaptative_grid( theta: &mut Array2, eps: f64, @@ -14,35 +23,17 @@ pub fn adaptative_grid( let mut plus = Array::zeros(spp.len()); plus[j] = l; plus = plus + spp; - evaluate_spp(theta, plus, ranges, min_dist); + prune(theta, plus, ranges, min_dist); // (n_spp, _) = theta.dim(); } if val - l > ranges[j].0 { let mut minus = Array::zeros(spp.len()); minus[j] = -l; minus = minus + spp; - evaluate_spp(theta, minus, ranges, min_dist); + prune(theta, minus, ranges, min_dist); // (n_spp, _) = theta.dim(); } } } theta.to_owned() } - -fn evaluate_spp( - theta: &mut Array2, - candidate: Array1, - limits: &[(f64, f64)], - min_dist: f64, -) { - for spp in theta.rows() { - let mut dist: f64 = 0.; - for (i, val) in candidate.clone().into_iter().enumerate() { - dist += (val - spp.get(i).unwrap()).abs() / (limits[i].1 - limits[i].0); - } - if dist <= min_dist { - return; - } - } - theta.push_row(candidate.view()).unwrap(); -} diff --git a/src/routines/initialization.rs b/src/routines/initialization.rs index e4262ee7b..0f0ab7698 100644 --- a/src/routines/initialization.rs +++ b/src/routines/initialization.rs @@ -2,13 +2,14 @@ use std::fs::File; use ndarray::Array2; -use crate::prelude::settings::run::Data; +use crate::prelude::settings::Settings; pub mod sobol; -pub fn sample_space(settings: &Data, ranges: &Vec<(f64, f64)>) -> Array2 { - match &settings.parsed.paths.prior_dist { +pub fn sample_space(settings: &Settings, ranges: &Vec<(f64, f64)>) -> Array2 { + match &settings.paths.prior { Some(prior_path) => { + tracing::info!("Reading prior from {}", prior_path); let file = File::open(prior_path).unwrap(); let mut reader = csv::ReaderBuilder::new() .has_headers(true) @@ -28,12 +29,7 @@ pub fn sample_space(settings: &Data, ranges: &Vec<(f64, f64)>) -> Array2 { } // Check and reorder parameters to match names in settings.parsed.random - let random_names: Vec = settings - .parsed - .random - .iter() - .map(|(name, _)| name.clone()) - .collect(); + let random_names: Vec = settings.random.names(); let mut reordered_indices: Vec = Vec::new(); for random_name in &random_names { @@ -76,10 +72,6 @@ pub fn sample_space(settings: &Data, ranges: &Vec<(f64, f64)>) -> Array2 { Array2::from_shape_vec((n_points, n_params), theta_values) .expect("Failed to create theta Array2") } - None => sobol::generate( - settings.parsed.config.init_points, - ranges, - settings.parsed.config.seed, - ), + None => sobol::generate(settings.config.init_points, ranges, settings.config.seed), } } diff --git a/src/routines/initialization/sobol.rs b/src/routines/initialization/sobol.rs index e2ad7b7c0..1eb7e0a00 100644 --- a/src/routines/initialization/sobol.rs +++ b/src/routines/initialization/sobol.rs @@ -8,7 +8,7 @@ use sobol_burley::sample; pub fn generate( n_points: usize, range_params: &Vec<(f64, f64)>, - seed: u32, + seed: usize, ) -> ArrayBase, Dim<[usize; 2]>> { let n_params = range_params.len(); let mut seq = Array::::zeros((n_points, n_params).f()); @@ -16,7 +16,7 @@ pub fn generate( let mut row = seq.slice_mut(s![i, ..]); let mut point: Vec = Vec::new(); for j in 0..n_params { - point.push(sample(i.try_into().unwrap(), j.try_into().unwrap(), seed) as f64) + point.push(sample(i.try_into().unwrap(), j.try_into().unwrap(), seed as u32) as f64) } row.assign(&Array::from(point)); } diff --git a/src/routines/optimization/d_optimizer.rs b/src/routines/optimization/d_optimizer.rs new file mode 100644 index 000000000..982af7f70 --- /dev/null +++ b/src/routines/optimization/d_optimizer.rs @@ -0,0 +1,108 @@ +use argmin::{ + core::{CostFunction, Error, Executor}, + solver::neldermead::NelderMead, +}; +use ndarray::{Array1, Axis}; + +use crate::routines::{ + datafile::Scenario, + simulation::predict::{sim_obs, Engine, Predict}, +}; + +use crate::prelude::{prob, sigma::Sigma}; + +pub struct SppOptimizer<'a, S, P> +where + S: Sigma + Sync, + P: Predict<'static> + Sync + Clone, +{ + engine: &'a Engine

, + scenarios: &'a Vec, + sig: &'a S, + pyl: &'a Array1, +} + +impl<'a, S, P> CostFunction for SppOptimizer<'a, S, P> +where + S: Sigma + Sync, + P: Predict<'static> + Sync + Clone, +{ + type Param = Array1; + type Output = f64; + fn cost(&self, spp: &Self::Param) -> Result { + let theta = spp.to_owned().insert_axis(Axis(0)); + let ypred = sim_obs(&self.engine, &self.scenarios, &theta, true); + let psi = prob::calculate_psi(&ypred, self.scenarios, self.sig); + if psi.ncols() > 1 { + tracing::error!("Psi in SppOptimizer has more than one column"); + } + if psi.nrows() != self.pyl.len() { + tracing::error!( + "Psi in SppOptimizer has {} rows, but spp has {}", + psi.nrows(), + self.pyl.len() + ); + } + let nsub = psi.nrows() as f64; + let mut sum = -nsub; + for (p_i, pyl_i) in psi.iter().zip(self.pyl.iter()) { + sum += nsub + p_i / pyl_i; + } + Ok(-sum) + } +} + +impl<'a, S, P> SppOptimizer<'a, S, P> +where + S: Sigma + Sync, + P: Predict<'static> + Sync + Clone, +{ + pub fn new( + engine: &'a Engine

, + scenarios: &'a Vec, + sig: &'a S, + pyl: &'a Array1, + ) -> Self { + Self { + engine, + scenarios, + sig, + pyl, + } + } + pub fn optimize_point(self, spp: Array1) -> Result, Error> { + let simplex = create_initial_simplex(&spp); + let solver = NelderMead::new(simplex).with_sd_tolerance(1e-2)?; + let res = Executor::new(self, solver) + .configure(|state| state.max_iters(5)) + // .add_observer(SlogLogger::term(), ObserverMode::Always) + .run()?; + Ok(res.state.best_param.unwrap()) + } +} + +fn create_initial_simplex(initial_point: &Array1) -> Vec> { + let num_dimensions = initial_point.len(); + let perturbation_percentage = 0.008; + + // Initialize a Vec to store the vertices of the simplex + let mut vertices = Vec::new(); + + // Add the initial point to the vertices + vertices.push(initial_point.to_owned()); + + // Calculate perturbation values for each component + for i in 0..num_dimensions { + let perturbation = if initial_point[i] == 0.0 { + 0.00025 // Special case for components equal to 0 + } else { + perturbation_percentage * initial_point[i] + }; + + let mut perturbed_point = initial_point.to_owned(); + perturbed_point[i] += perturbation; + vertices.push(perturbed_point); + } + + vertices +} diff --git a/src/routines/output.rs b/src/routines/output.rs index 368d24b1a..219f07c94 100644 --- a/src/routines/output.rs +++ b/src/routines/output.rs @@ -4,7 +4,7 @@ use datafile::Scenario; use ndarray::parallel::prelude::*; use ndarray::{Array, Array1, Array2, Axis}; use predict::{post_predictions, sim_obs, Engine, Predict}; -use settings::run::Data; +use settings::Settings; use std::fs::File; /// Defines the result objects from an NPAG run @@ -19,7 +19,7 @@ pub struct NPResult { pub cycles: usize, pub converged: bool, pub par_names: Vec, - pub settings: Data, + pub settings: Settings, } impl NPResult { @@ -32,16 +32,12 @@ impl NPResult { objf: f64, cycles: usize, converged: bool, - settings: Data, + settings: Settings, ) -> Self { // TODO: Add support for fixed and constant parameters - let par_names = settings - .parsed - .random - .iter() - .map(|(name, _)| name.clone()) - .collect(); + let par_names = settings.random.names(); + Self { scenarios, theta, @@ -55,15 +51,15 @@ impl NPResult { } } - pub fn write_outputs(&self, write: bool, engine: &Engine) + pub fn write_outputs<'a, S>(&self, write: bool, engine: &Engine, idelta: f64, tad: f64) where - S: Predict + std::marker::Sync + 'static + Clone + std::marker::Send, + S: Predict<'static> + std::marker::Sync + 'static + Clone + std::marker::Send, { if write { self.write_theta(); self.write_posterior(); self.write_obs(); - self.write_pred(&engine); + self.write_pred(&engine, idelta, tad); self.write_meta(); } } @@ -77,6 +73,7 @@ impl NPResult { /// Writes theta, which containts the population support points and their associated probabilities /// Each row is one support point, the last column being probability pub fn write_theta(&self) { + tracing::info!("Writing final parameter distribution..."); let result = (|| { let theta: Array2 = self.theta.clone(); let w: Array1 = self.w.clone(); @@ -99,12 +96,13 @@ impl NPResult { })(); if let Err(e) = result { - log::error!("Error while writing theta: {}", e); + tracing::error!("Error while writing theta: {}", e); } } /// Writes the posterior support points for each individual pub fn write_posterior(&self) { + tracing::info!("Writing posterior parameter probabilities..."); let result = (|| { let theta: Array2 = self.theta.clone(); let w: Array1 = self.w.clone(); @@ -143,12 +141,13 @@ impl NPResult { })(); if let Err(e) = result { - log::error!("Error while writing posterior: {}", e); + tracing::error!("Error while writing posterior: {}", e); } } /// Write the observations, which is the reformatted input data pub fn write_obs(&self) { + tracing::info!("Writing (expanded) observations..."); let result = (|| { let scenarios = self.scenarios.clone(); @@ -173,17 +172,25 @@ impl NPResult { })(); if let Err(e) = result { - log::error!("Error while writing observations: {}", e); + tracing::error!("Error while writing observations: {}", e); } } /// Writes the predictions - pub fn write_pred(&self, engine: &Engine) + pub fn write_pred<'a, S>(&self, engine: &Engine, idelta: f64, tad: f64) where - S: Predict + std::marker::Sync + std::marker::Send + 'static + Clone, + S: Predict<'static> + std::marker::Sync + std::marker::Send + 'static + Clone, { + tracing::info!("Writing individual predictions..."); let result = (|| { - let scenarios = self.scenarios.clone(); + let mut scenarios = self.scenarios.clone(); + // Add an event interval to each scenario + if idelta > 0.0 { + scenarios.iter_mut().for_each(|scenario| { + *scenario = scenario.add_event_interval(idelta, tad); + }); + } + let theta: Array2 = self.theta.clone(); let w: Array1 = self.w.clone(); let psi: Array2 = self.psi.clone(); @@ -252,7 +259,7 @@ impl NPResult { })(); if let Err(e) = result { - log::error!("Error while writing predictions: {}", e); + tracing::error!("Error while writing predictions: {}", e); } } } @@ -279,13 +286,21 @@ impl CycleLog { } } +/// Defines the result objects from a run +/// An [NPResult] contains the necessary information to generate predictions and summary statistics +/// It holds the following information: +/// - `cycle`: The cycle number +/// - `objf`: The objective function value +/// - `gamlam`: The assay noise parameter, either gamma or lambda +/// - `theta`: The support points and their associated probabilities +/// - `nspp`: The number of support points +/// - `delta_objf`: The change in objective function value from last cycle #[derive(Debug, Clone)] pub struct NPCycle { pub cycle: usize, pub objf: f64, pub gamlam: f64, pub theta: Array2, - pub stop_text: String, pub nspp: usize, pub delta_objf: f64, } @@ -296,7 +311,6 @@ impl NPCycle { objf: 0.0, gamlam: 0.0, theta: Array2::default((0, 0)), - stop_text: "".to_string(), nspp: 0, delta_objf: 0.0, } @@ -340,7 +354,7 @@ impl CycleWriter { pub fn write(&mut self, cycle: usize, objf: f64, gamma: f64, theta: &Array2) { self.writer.write_field(format!("{}", cycle)).unwrap(); - self.writer.write_field(format!("{}", -2. * objf)).unwrap(); + self.writer.write_field(format!("{}", objf)).unwrap(); self.writer.write_field(format!("{}", gamma)).unwrap(); self.writer .write_field(format!("{}", theta.nrows())) diff --git a/src/routines/settings.rs b/src/routines/settings.rs new file mode 100644 index 000000000..f21bdda26 --- /dev/null +++ b/src/routines/settings.rs @@ -0,0 +1,235 @@ +#![allow(dead_code)] + +use config::Config as eConfig; +use serde::Deserialize; +use serde_derive::Serialize; +use serde_json; +use std::collections::HashMap; + +/// Contains all settings NPcore +#[derive(Debug, Deserialize, Clone, Serialize)] +#[serde(deny_unknown_fields)] +pub struct Settings { + pub paths: Paths, + pub config: Config, + pub random: Random, + pub fixed: Option, + pub constant: Option, + pub error: Error, +} + +/// This struct contains the paths to the data, log and prior files. +#[derive(Debug, Deserialize, Clone, Serialize)] +#[serde(deny_unknown_fields)] +pub struct Paths { + /// Path to the data file, see `datafile::parse` for details. + pub data: String, + /// If provided, the log file will be written to this path. + pub log: Option, + /// If provided, NPcore will use this prior instead of a "uniform" prior, see `sobol::generate` for details. + pub prior: Option, +} + +/// General configuration settings +#[derive(Debug, Deserialize, Clone, Serialize)] +#[serde(deny_unknown_fields)] +pub struct Config { + pub cycles: usize, + pub engine: String, + #[serde(default = "default_seed")] + pub seed: usize, + #[serde(default = "default_10k")] + pub init_points: usize, + #[serde(default = "default_false")] + pub tui: bool, + #[serde(default = "default_true")] + pub output: bool, + #[serde(default = "default_true")] + pub cache: bool, + #[serde(default = "default_idelta")] + pub idelta: f64, + #[serde(default = "default_log_level")] + pub log_level: String, + pub exclude: Option>, + #[serde(default = "default_tad")] + pub tad: f64, +} + +/// Random parameters to be estimated +/// +/// This struct contains the random parameters to be estimated. The parameters are specified as a hashmap, where the key is the name of the parameter, and the value is a tuple containing the upper and lower bounds of the parameter. +/// +/// # Example +/// +/// ```toml +/// [random] +/// alpha = [0.0, 1.0] +/// beta = [0.0, 1.0] +/// ``` +#[derive(Debug, Deserialize, Clone, Serialize)] +pub struct Random { + #[serde(flatten)] + pub parameters: HashMap, +} + +impl Random { + /// Get the upper and lower bounds of a random parameter from its key + pub fn get(&self, key: &str) -> Option<&(f64, f64)> { + self.parameters.get(key) + } + + /// Returns a vector of tuples containing the names and ranges of the random parameters + pub fn names_and_ranges(&self) -> Vec<(String, (f64, f64))> { + let mut pairs: Vec<(String, (f64, f64))> = self + .parameters + .iter() + .map(|(key, &(upper, lower))| (key.clone(), (upper, lower))) + .collect(); + + // Sorting alphabetically by name + pairs.sort_by(|a, b| a.0.cmp(&b.0)); + + pairs + } + /// Returns a vector of the names of the random parameters + pub fn names(&self) -> Vec { + self.names_and_ranges() + .into_iter() + .map(|(name, _)| name) + .collect() + } + + /// Returns a vector of the upper and lower bounds of the random parameters + pub fn ranges(&self) -> Vec<(f64, f64)> { + self.names_and_ranges() + .into_iter() + .map(|(_, range)| range) + .collect() + } + + /// Validate the boundaries of the random parameters + pub fn validate(&self) -> Result<(), String> { + for (key, &(lower, upper)) in &self.parameters { + if lower >= upper { + return Err(format!( + "In key '{}', lower bound ({}) is not less than upper bound ({})", + key, lower, upper + )); + } + } + Ok(()) + } +} + +/// Parameters which are estimated, but fixed for the population +#[derive(Debug, Deserialize, Clone, Serialize)] +pub struct Fixed { + #[serde(flatten)] + pub parameters: HashMap, +} + +/// Parameters which are held constant +#[derive(Debug, Deserialize, Clone, Serialize)] +pub struct Constant { + #[serde(flatten)] + pub parameters: HashMap, +} + +/// Defines the error model and polynomial to be used +#[derive(Debug, Deserialize, Clone, Serialize)] +#[serde(deny_unknown_fields)] +pub struct Error { + pub value: f64, + pub class: String, + pub poly: (f64, f64, f64, f64), +} + +impl Error { + pub fn validate(&self) -> Result<(), String> { + if self.value < 0.0 { + return Err(format!( + "Error value must be non-negative, got {}", + self.value + )); + } + Ok(()) + } +} + +/// Parses the settings from a TOML configuration file +/// +/// This function parses the settings from a TOML configuration file. The settings are validated, and a copy of the settings is written to file. +/// +/// Entries in the TOML file may be overridden by environment variables. The environment variables must be prefixed with `NPCORE_`, and the TOML entry must be in uppercase. For example, the TUI may be disabled by setting the environment variable `NPCORE_TUI=false`. +pub fn read_settings(path: String) -> Result { + let settings_path = path; + + let parsed = eConfig::builder() + .add_source(config::File::with_name(&settings_path).format(config::FileFormat::Toml)) + .add_source(config::Environment::with_prefix("NPCORE").separator("_")) + .build()?; + + // Deserialize settings to the Settings struct + let settings: Settings = parsed.try_deserialize()?; + + // Validate entries + settings + .random + .validate() + .map_err(config::ConfigError::Message)?; + settings + .error + .validate() + .map_err(config::ConfigError::Message)?; + + // Write a copy of the settings to file if output is enabled + if settings.config.output { + write_settings_to_file(&settings).expect("Could not write settings to file"); + } + + Ok(settings) // Return the settings wrapped in Ok +} + +/// Writes a copy of the parsed settings to file +/// +/// This function writes a copy of the parsed settings to file. The file is written to the current working directory, and is named `settings.json`. +pub fn write_settings_to_file(settings: &Settings) -> Result<(), std::io::Error> { + let serialized = serde_json::to_string_pretty(settings) + .map_err(|e| std::io::Error::new(std::io::ErrorKind::Other, e))?; + + let file_path = "settings.json"; + let mut file = std::fs::File::create(file_path)?; + std::io::Write::write_all(&mut file, serialized.as_bytes())?; + Ok(()) +} + +// ********************************* +// Default values for deserializing +// ********************************* +fn default_true() -> bool { + true +} + +fn default_false() -> bool { + false +} + +fn default_log_level() -> String { + "info".to_string() +} + +fn default_seed() -> usize { + 347 +} + +fn default_idelta() -> f64 { + 0.12 +} + +fn default_tad() -> f64 { + 0.0 +} + +fn default_10k() -> usize { + 10_000 +} diff --git a/src/routines/settings/run.rs b/src/routines/settings/run.rs deleted file mode 100644 index 52ce15ac0..000000000 --- a/src/routines/settings/run.rs +++ /dev/null @@ -1,139 +0,0 @@ -use serde_derive::Deserialize; -use std::fs; -use std::process::exit; -use toml::value::Array; -use toml::{self, Table}; - -#[derive(Deserialize, Clone, Debug)] -pub struct Data { - pub computed: Computed, - pub parsed: Parsed, -} - -#[derive(Deserialize, Clone, Debug)] -pub struct Computed { - pub random: Range, - pub constant: Single, - pub fixed: Single, -} - -#[derive(Deserialize, Clone, Debug)] -pub struct Error { - pub value: f64, - pub class: String, - pub poly: (f64, f64, f64, f64), -} - -#[derive(Deserialize, Clone, Debug)] -pub struct Range { - pub names: Vec, - pub ranges: Vec<(f64, f64)>, -} - -#[derive(Deserialize, Clone, Debug)] -pub struct Single { - pub names: Vec, - pub values: Vec, -} - -#[derive(Deserialize, Clone, Debug)] -pub struct Parsed { - pub paths: Paths, - pub config: Config, - pub random: Table, - pub fixed: Option, - pub constant: Option
, - pub error: Error, -} - -#[derive(Deserialize, Clone, Debug)] -pub struct Paths { - pub data: String, - pub log_out: Option, - pub prior_dist: Option, -} - -#[derive(Deserialize, Clone, Debug)] -pub struct Config { - pub cycles: usize, - pub engine: String, - pub init_points: usize, - pub seed: u32, - pub tui: bool, - pub pmetrics_outputs: Option, - pub exclude: Option, - pub cache: Option, -} - -pub fn read(filename: String) -> Data { - let contents = match fs::read_to_string(&filename) { - Ok(c) => c, - Err(e) => { - eprintln!("{}", e); - eprintln!("ERROR: Could not read file {}", &filename); - exit(1); - } - }; - - let parsed: Parsed = match toml::from_str(&contents) { - Ok(d) => d, - Err(e) => { - eprintln!("{}", e); - eprintln!("ERROR: Unable to load data from {}", &filename); - exit(1); - } - }; - //Pri - let mut pr = vec![]; - let mut pn = vec![]; - for (name, range) in &parsed.random { - let range = range.as_array().unwrap(); - if range.len() != 2 { - eprintln!( - "ERROR: Ranges can only have 2 elements, {} found", - range.len() - ); - eprintln!("ERROR: In {:?}: {:?}", name, range); - exit(1); - } - pn.push(name.clone()); - pr.push((range[0].as_float().unwrap(), range[1].as_float().unwrap())); - } - //Constant - let mut cn = vec![]; - let mut cv = vec![]; - if let Some(constant) = &parsed.constant { - for (name, value) in constant { - cn.push(name.clone()); - cv.push(value.as_float().unwrap()); - } - } - - //Randfix - let mut rn = vec![]; - let mut rv = vec![]; - if let Some(randfix) = &parsed.fixed { - for (name, value) in randfix { - rn.push(name.clone()); - rv.push(value.as_float().unwrap()); - } - } - - Data { - computed: Computed { - random: Range { - names: pn, - ranges: pr, - }, - constant: Single { - names: cn, - values: cv, - }, - fixed: Single { - names: rn, - values: rv, - }, - }, - parsed, - } -} diff --git a/src/routines/settings/simulator.rs b/src/routines/settings/simulator.rs deleted file mode 100644 index 73178ba93..000000000 --- a/src/routines/settings/simulator.rs +++ /dev/null @@ -1,40 +0,0 @@ -use serde_derive::Deserialize; -use std::fs; -use std::process::exit; -use toml; - -#[derive(Deserialize, Clone, Debug)] -pub struct Data { - pub paths: Paths, -} - -#[derive(Deserialize, Clone, Debug)] -pub struct Paths { - pub data: String, - pub theta: String, -} - -pub fn read(filename: String) -> Data { - let contents = match fs::read_to_string(&filename) { - Ok(c) => c, - Err(e) => { - eprintln!("{}", e); - eprintln!("ERROR: Could not read file {}", &filename); - exit(1); - } - }; - let parse: Data = match toml::from_str(&contents) { - Ok(d) => d, - Err(e) => { - eprintln!("{}", e); - eprintln!("ERROR: Unable to load data from {}", &filename); - exit(1); - } - }; - Data { - paths: Paths { - data: parse.paths.data, - theta: parse.paths.theta, - }, - } -} diff --git a/src/routines/simulation/predict.rs b/src/routines/simulation/predict.rs index 62152f800..12b06213c 100644 --- a/src/routines/simulation/predict.rs +++ b/src/routines/simulation/predict.rs @@ -1,3 +1,5 @@ +use crate::routines::datafile::CovLine; +use crate::routines::datafile::Infusion; use crate::routines::datafile::Scenario; use dashmap::mapref::entry::Entry; use dashmap::DashMap; @@ -6,36 +8,98 @@ use ndarray::parallel::prelude::*; use ndarray::prelude::*; use ndarray::Array1; use ndarray::{Array, Array2, Axis}; +use std::collections::HashMap; use std::error; use std::hash::{Hash, Hasher}; -const CACHE_SIZE: usize = 1000000; +/// Number of support points to cache for each scenario +const CACHE_SIZE: usize = 1000; + +#[derive(Debug, Clone)] +pub struct Model { + params: HashMap, + _scenario: Scenario, + _infusions: Vec, + _cov: Option>, +} +impl Model { + pub fn get_param(&self, str: &str) -> f64 { + *self.params.get(str).unwrap() + } +} /// return the predicted values for the given scenario and parameters /// where the second element of the tuple is the predicted values /// one per observation time in scenario and in the same order /// it is not relevant the outeq of the specific event. -pub trait Predict { - fn predict(&self, params: Vec, scenario: &Scenario) -> Vec; +pub trait Predict<'a> { + type Model: 'a + Clone; + type State; + fn initial_system(&self, params: &Vec, scenario: Scenario) -> (Self::Model, Scenario); + fn initial_state(&self) -> Self::State; + fn add_covs(&self, system: &mut Self::Model, cov: Option>); + fn add_infusion(&self, system: &mut Self::Model, infusion: Infusion); + fn add_dose(&self, state: &mut Self::State, dose: f64, compartment: usize); + fn get_output(&self, time: f64, state: &Self::State, system: &Self::Model, outeq: usize) + -> f64; + fn state_step(&self, state: &mut Self::State, system: &Self::Model, time: f64, next_time: f64); } #[derive(Clone, Debug)] pub struct Engine where - S: Predict + Clone, + S: Predict<'static> + Clone, { ode: S, } impl Engine where - S: Predict + Clone, + S: Predict<'static> + Clone, { pub fn new(ode: S) -> Self { Self { ode } } - pub fn pred(&self, scenario: &Scenario, params: Vec) -> Vec { - self.ode.predict(params, scenario) + pub fn pred(&self, scenario: Scenario, params: Vec) -> Vec { + let (mut system, scenario) = self.ode.initial_system(¶ms, scenario.clone()); + let mut yout = vec![]; + let mut x = self.ode.initial_state(); + let mut index: usize = 0; + for block in scenario.blocks { + self.ode.add_covs(&mut system, Some(block.covs)); + for event in &block.events { + if event.evid == 1 { + if event.dur.unwrap_or(0.0) > 0.0 { + //infusion + self.ode.add_infusion( + &mut system, + Infusion { + time: event.time, + dur: event.dur.unwrap(), + amount: event.dose.unwrap(), + compartment: event.input.unwrap() - 1, + }, + ); + } else { + // //dose + self.ode + .add_dose(&mut x, event.dose.unwrap(), event.input.unwrap() - 1); + } + } else if event.evid == 0 { + //obs + yout.push( + self.ode + .get_output(event.time, &x, &system, event.outeq.unwrap()), + ) + } + if let Some(next_time) = scenario.times.get(index + 1) { + // TODO: use the last dx as the initial one for the next simulation. + self.ode.state_step(&mut x, &system, event.time, *next_time); + } + index += 1; + } + } + yout } } @@ -61,9 +125,9 @@ lazy_static! { DashMap::with_capacity(CACHE_SIZE); // Adjust cache size as needed } -pub fn get_ypred( +pub fn get_ypred + Sync + Clone>( sim_eng: &Engine, - scenario: &Scenario, + scenario: Scenario, support_point: Vec, i: usize, cache: bool, @@ -96,16 +160,16 @@ pub fn get_ypred( /// /// * `sim_eng` - A reference to the simulation engine implementing the `Predict` trait. /// -/// * `scenarios` - A reference to a Vec containing information about different scenarios. +/// * `scenarios` - A reference to a `Vec` containing information about different scenarios. /// -/// * `support_points` - A 2D Array (Array2) representing the support points. Each row +/// * `support_points` - A 2D Array `(Array2)` representing the support points. Each row /// corresponds to a different support point scenario. /// /// * `cache` - A boolean flag indicating whether to cache predicted values during simulation. /// /// # Returns /// -/// A 2D Array (Array2>) where each element is an Array1 representing the +/// A 2D Array `(Array2>)` where each element is an `Array1` representing the /// simulated observations for a specific scenario and support point. /// /// # Example @@ -124,7 +188,7 @@ pub fn sim_obs( cache: bool, ) -> Array2> where - S: Predict + Sync + Clone, + S: Predict<'static> + Sync + Clone, { let mut pred: Array2> = Array2::default((scenarios.len(), support_points.nrows()).f()); @@ -137,8 +201,13 @@ where .enumerate() .for_each(|(j, mut element)| { let scenario = scenarios.get(i).unwrap(); - let ypred = - get_ypred(sim_eng, scenario, support_points.row(j).to_vec(), i, cache); + let ypred = get_ypred( + sim_eng, + scenario.clone(), + support_points.row(j).to_vec(), + i, + cache, + ); element.fill(ypred); }); }); @@ -147,11 +216,11 @@ where pub fn simple_sim( sim_eng: &Engine, - scenario: &Scenario, + scenario: Scenario, support_point: &Array1, ) -> Vec where - S: Predict + Sync + Clone, + S: Predict<'static> + Sync + Clone, { sim_eng.pred(scenario, support_point.to_vec()) } @@ -162,7 +231,7 @@ pub fn post_predictions( scenarios: &Vec, ) -> Result>, Box> where - S: Predict + Sync + Clone, + S: Predict<'static> + Sync + Clone, { if post.nrows() != scenarios.len() { return Err("Error calculating the posterior predictions, size mismatch.".into()); @@ -176,7 +245,7 @@ where .for_each(|(i, mut pred)| { let scenario = scenarios.get(i).unwrap(); let support_point = post.row(i).to_owned(); - pred.fill(simple_sim(sim_engine, scenario, &support_point)) + pred.fill(simple_sim(sim_engine, scenario.clone(), &support_point)) }); Ok(predictions) diff --git a/src/tests/config.toml b/src/tests/config.toml index ada6f155f..eb1bf733d 100644 --- a/src/tests/config.toml +++ b/src/tests/config.toml @@ -1,5 +1,6 @@ [paths] data = "data.csv" +log = "test.log" [config] cycles = 1024 @@ -7,7 +8,7 @@ engine = "NPAG" init_points = 500 seed = 347 tui = false -pmetrics_outputs = true +output = true [random] ka = [0.1, 0.9] diff --git a/src/tests/mod.rs b/src/tests/mod.rs index 35abac843..e318d1168 100644 --- a/src/tests/mod.rs +++ b/src/tests/mod.rs @@ -33,45 +33,6 @@ fn scaled_sobol() { ) } -#[test] -fn read_mandatory_settings() { - let settings = settings::run::read("src/tests/config.toml".to_string()); - assert_eq!(settings.parsed.paths.data, "data.csv"); - assert_eq!(settings.parsed.config.cycles, 1024); - assert_eq!(settings.parsed.config.engine, "NPAG"); -} - -#[test] -fn read_parameter_names() { - let settings = settings::run::read("src/tests/config.toml".to_string()); - assert_eq!(settings.computed.random.names, vec!["ka", "ke", "v"]); -} - -#[test] -fn read_parameter_ranges() { - let settings = settings::run::read("src/tests/config.toml".to_string()); - - assert_eq!( - settings.computed.random.ranges, - vec![(0.1, 0.9), (0.001, 0.1), (30.0, 120.0)] - ); -} - -#[test] -fn read_randfix() { - let settings = settings::run::read("src/tests/config.toml".to_string()); - assert_eq!(settings.computed.fixed.names, vec!["KCP", "KPC"]); - assert_eq!(settings.computed.fixed.values, vec![5.1, 2.0]); -} - -#[test] -fn read_error() { - let settings = settings::run::read("src/tests/config.toml".to_string()); - assert_eq!(settings.parsed.error.value, 0.5); - assert_eq!(settings.parsed.error.class, "additive"); - assert_eq!(settings.parsed.error.poly, (0.0, 0.5, 0.0, 0.0)) -} - #[test] fn read_test_datafile() { let scenarios = datafile::parse(&"src/tests/test.csv".to_string()); diff --git a/src/tui/actions.rs b/src/tui/actions.rs index 7bf3d3302..4413b2f6d 100644 --- a/src/tui/actions.rs +++ b/src/tui/actions.rs @@ -9,20 +9,22 @@ use super::inputs::key::Key; pub enum Action { Quit, Stop, + Next, } impl Action { /// All available actions pub fn iterator() -> Iter<'static, Action> { - static ACTIONS: [Action; 2] = [Action::Quit, Action::Stop]; + static ACTIONS: [Action; 3] = [Action::Quit, Action::Stop, Action::Next]; ACTIONS.iter() } /// List of key associated to action pub fn keys(&self) -> &[Key] { match self { - Action::Quit => &[Key::Ctrl('c'), Key::Char('q')], + Action::Quit => &[Key::Char('q')], Action::Stop => &[Key::Ctrl('d')], + Action::Next => &[Key::Char('n')], } } } @@ -31,6 +33,7 @@ impl Action { impl Display for Action { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { let str = match self { + Action::Next => "Next", Action::Quit => "Quit", Action::Stop => "Stop", }; diff --git a/src/tui/components.rs b/src/tui/components.rs index 8a6becf01..ebe1e103d 100644 --- a/src/tui/components.rs +++ b/src/tui/components.rs @@ -1,6 +1,21 @@ +use std::time::Duration; + /// This file contains the different components of the TUI /// The purpose is to create common components with generic methods +use ratatui::{ + layout::{Alignment, Constraint}, + style::{Color, Modifier, Style}, + symbols, + text::{Line, Span}, + widgets::{ + Axis, Block, BorderType, Borders, Cell, Chart, Dataset, GraphType, Paragraph, Row, Table, + Tabs, Wrap, + }, +}; + +use super::App; +use crate::prelude::settings::Settings; pub fn draw_title<'a>() -> Paragraph<'a> { Paragraph::new("NPcore Execution") @@ -22,7 +37,7 @@ pub fn draw_status<'a>(app: &App, elapsed_time: Duration) -> Table<'a> { let gamma_text = format!("{:.5}", app.state.gamlam); let spp_text = format!("{}", app.state.nspp); let time_text = format_time(elapsed_time); - let stop_text = app.state.stop_text.to_string(); + let conv_text = "Placeholder".to_string(); // Define the table data let data = vec![ @@ -32,7 +47,7 @@ pub fn draw_status<'a>(app: &App, elapsed_time: Duration) -> Table<'a> { ("Gamma/Lambda", gamma_text), ("Support points", spp_text), ("Elapsed time", time_text), - ("Convergence", stop_text), + ("Convergence", conv_text), // Add more rows as needed ]; @@ -48,7 +63,8 @@ pub fn draw_status<'a>(app: &App, elapsed_time: Duration) -> Table<'a> { .collect(); // Create the table widget - Table::new(rows) + Table::default() + .rows(rows) .block( Block::default() .borders(Borders::ALL) @@ -59,20 +75,19 @@ pub fn draw_status<'a>(app: &App, elapsed_time: Duration) -> Table<'a> { .column_spacing(1) } -pub fn draw_options<'a>(settings: &Data) -> Table<'a> { +pub fn draw_options<'a>(settings: &Settings) -> Table<'a> { // Define the table data - let cycles = settings.parsed.config.cycles.to_string(); - let engine = settings.parsed.config.engine.to_string(); + let cycles = settings.config.cycles.to_string(); + let engine = settings.config.engine.to_string(); let conv_crit = "Placeholder".to_string(); - let indpts = settings.parsed.config.init_points.to_string(); - let error = settings.parsed.error.class.to_string(); - let cache = match settings.parsed.config.cache { - Some(true) => "Yes".to_string(), - Some(false) => "No".to_string(), - None => "Not set".to_string(), + let indpts = settings.config.init_points.to_string(); + let error = settings.error.class.to_string(); + let cache = match settings.config.cache { + true => "Enabled".to_string(), + false => "Disabled".to_string(), }; - let seed = settings.parsed.config.seed.to_string(); + let seed = settings.config.seed.to_string(); let data = vec![ ("Maximum cycles", cycles), @@ -97,7 +112,8 @@ pub fn draw_options<'a>(settings: &Data) -> Table<'a> { .collect(); // Create the table widget - Table::new(rows) + Table::default() + .rows(rows) .block( Block::default() .borders(Borders::ALL) @@ -130,7 +146,8 @@ pub fn draw_commands(app: &App) -> Table { } } - Table::new(rows) + Table::default() + .rows(rows) .block( Block::default() .borders(Borders::ALL) @@ -200,4 +217,54 @@ pub fn draw_plot(norm_data: &mut [(f64, f64)]) -> Chart { .title(" Objective function ") .borders(Borders::ALL), ) -} \ No newline at end of file +} + +pub fn draw_logs<'a>(log_history: &'a Vec, height: u16) -> Paragraph<'a> { + // Convert each String in log_history to a Line + let text: Vec = log_history.iter().map(|s| Line::from(s.as_str())).collect(); + + let to_text = text.len(); + // Prevent underflow with saturating_sub + let from_text = to_text.saturating_sub(height as usize); + + // Create a slice of the text to be displayed + let show_text = if from_text < to_text { + text[from_text..to_text].to_vec() + } else { + Vec::new() + }; + + Paragraph::new(show_text) + .block(Block::default().title(" Logs ").borders(Borders::ALL)) + .style(Style::default().fg(Color::White)) + .alignment(Alignment::Left) + .wrap(Wrap { trim: true }) +} + +pub fn draw_tabs<'a>(app: &App) -> Tabs<'a> { + let titles = app.tab_titles.clone(); + let index = app.tab_index.clone(); + let tabs = Tabs::new(titles.clone()) + .block(Block::default().borders(Borders::ALL)) + .style(Style::default().fg(Color::Cyan)) + .highlight_style(Style::default().fg(Color::Yellow)) + .divider(Span::raw("|")) + .select(index); + + tabs +} + +fn format_time(elapsed_time: std::time::Duration) -> String { + let elapsed_seconds = elapsed_time.as_secs(); + let (elapsed, unit) = if elapsed_seconds < 60 { + (elapsed_seconds, "s") + } else if elapsed_seconds < 3600 { + let elapsed_minutes = elapsed_seconds / 60; + (elapsed_minutes, "m") + } else { + let elapsed_hours = elapsed_seconds / 3600; + (elapsed_hours, "h") + }; + let time_text = format!("{}{}", elapsed, unit); + time_text +} diff --git a/src/tui/mod.rs b/src/tui/mod.rs index aed565d1c..6800b124c 100644 --- a/src/tui/mod.rs +++ b/src/tui/mod.rs @@ -1,10 +1,10 @@ pub mod actions; +pub mod components; pub mod inputs; pub mod state; pub mod ui; use crate::prelude::output::NPCycle; -use log::{debug, trace}; use self::actions::{Action, Actions}; use self::inputs::key::Key; @@ -22,33 +22,54 @@ pub struct App { actions: Actions, /// State state: NPCycle, + /// Index for tab + tab_index: usize, + /// Tab titles + tab_titles: Vec<&'static str>, } impl App { #[allow(clippy::new_without_default)] pub fn new() -> Self { - let actions = vec![Action::Quit, Action::Stop].into(); + let actions = vec![Action::Quit, Action::Stop, Action::Next].into(); let state = NPCycle::new(); + let tab_index = 0; + let tab_titles = vec!["Logs", "Plot", "Parameters"]; - Self { actions, state } + Self { + actions, + state, + tab_index, + tab_titles, + } } /// Handle a user action pub fn do_action(&mut self, key: Key) -> AppReturn { if let Some(action) = self.actions.find(key) { - debug!("Run action [{:?}]", action); + tracing::debug!("Run action [{:?}]", action); match action { Action::Quit => AppReturn::Exit, Action::Stop => { // Write the "stop.txt" file - log::info!("Stop signal received - writing stopfile"); - let filename = "stop"; - File::create(filename).unwrap(); + tracing::info!("Stop signal received, program will stop after current cycle"); + let stopfile = "stop"; + File::create(stopfile).unwrap(); + AppReturn::Continue + } + Action::Next => { + self.tab_index = self.tab_index + 1; + if self.tab_index >= self.tab_titles.len() { + self.tab_index = 0; + } AppReturn::Continue } } } else { - trace!("{} was registered, but it has no associated action", key); + tracing::trace!( + "The {} key was registered, but it has no associated action", + key + ); AppReturn::Continue } } diff --git a/src/tui/state.rs b/src/tui/state.rs index 50a603128..54dff4f51 100644 --- a/src/tui/state.rs +++ b/src/tui/state.rs @@ -1,20 +1,20 @@ use crate::prelude::output::NPCycle; #[derive(Debug, Clone)] -pub struct AppHistory { +pub struct CycleHistory { pub cycles: Vec, } -impl AppHistory { +impl CycleHistory { pub fn new() -> Self { - AppHistory { cycles: Vec::new() } + CycleHistory { cycles: Vec::new() } } pub fn add_cycle(&mut self, cycle: NPCycle) { self.cycles.push(cycle); } } -impl Default for AppHistory { +impl Default for CycleHistory { fn default() -> Self { Self::new() } diff --git a/src/tui/ui.rs b/src/tui/ui.rs index d0953067f..dfc396823 100644 --- a/src/tui/ui.rs +++ b/src/tui/ui.rs @@ -1,38 +1,46 @@ //! Defines the Terminal User Interface (TUI) for NPcore +use crossterm::execute; use eyre::Result; use ratatui::{ - backend::{Backend, CrosstermBackend}, - layout::{Alignment, Constraint, Direction, Layout, Rect}, - style::{Color, Modifier, Style}, - symbols, - text::Span, - widgets::{ - Axis, Block, BorderType, Borders, Cell, Chart, Dataset, GraphType, Paragraph, Row, Table, - }, + backend::CrosstermBackend, + layout::{Constraint, Direction, Layout}, Frame, Terminal, }; use std::{ io::stdout, + process::exit, time::{Duration, Instant}, }; use tokio::sync::mpsc::UnboundedReceiver; use super::{ inputs::{events::Events, InputEvent}, - state::AppHistory, + state::CycleHistory, App, AppReturn, }; -use crate::prelude::{output::NPCycle, settings::run::Data}; +pub enum Comm { + NPCycle(NPCycle), + Message(String), + Stop, + StopUI, + LogMessage(String), +} + +use crate::prelude::{output::NPCycle, settings::Settings}; +use crate::tui::components::*; -pub fn start_ui(mut rx: UnboundedReceiver, settings: Data) -> Result<()> { - let stdout = stdout(); +pub fn start_ui(mut rx: UnboundedReceiver, settings: Settings) -> Result<()> { + initialize_panic_handler(); + let mut stdout = stdout(); + execute!(stdout, crossterm::terminal::EnterAlternateScreen)?; crossterm::terminal::enable_raw_mode()?; let backend = CrosstermBackend::new(stdout); let mut terminal = Terminal::new(backend)?; let mut app = App::new(); - let mut app_history = AppHistory::new(); + let mut cycle_history = CycleHistory::new(); + let mut log_history: Vec = Vec::new(); terminal.clear()?; @@ -40,42 +48,49 @@ pub fn start_ui(mut rx: UnboundedReceiver, settings: Data) -> Result<() let tick_rate = Duration::from_millis(200); let mut events = Events::new(tick_rate); - let mut start_time = Instant::now(); + let start_time = Instant::now(); + #[allow(unused_assignments)] let mut elapsed_time = Duration::from_secs(0); // Main UI loop loop { - app.state = match rx.try_recv() { - Ok(state) => state, - Err(_) => app.state, + let _ = match rx.try_recv() { + Ok(comm) => match comm { + Comm::NPCycle(cycle) => { + app.state = cycle.clone(); + cycle_history.add_cycle(cycle); + } + Comm::Message(_msg) => {} + Comm::Stop => { + terminal.show_cursor()?; + crossterm::terminal::disable_raw_mode()?; + println!(); + exit(0); + } + Comm::StopUI => { + break; + } + Comm::LogMessage(msg) => log_history.push(msg), + }, + Err(_) => {} }; - // Stop incrementing elapsed time if conv is true - if app.state.stop_text.is_empty() { - let now = Instant::now(); - if now.duration_since(start_time) > tick_rate { - elapsed_time += now.duration_since(start_time); - start_time = now; - } - } - - // Break if we receive a stop text - if !app.state.stop_text.is_empty() { - break; - } - - // If we receive a new NPCycle, add it to the app_history - if !app_history - .cycles - .iter() - .any(|state| state.cycle == app.state.cycle) - { - app_history.add_cycle(app.state.clone()); - } + // Update elapsed time + let now = Instant::now(); + elapsed_time = now.duration_since(start_time); // Draw the terminal terminal - .draw(|rect| draw(rect, &app, &app_history, elapsed_time, &settings)) + .draw(|rect| { + draw( + rect, + &app, + &cycle_history, + elapsed_time, + &settings, + &log_history, + ) + }) .unwrap(); // Handle inputs @@ -85,11 +100,34 @@ pub fn start_ui(mut rx: UnboundedReceiver, settings: Data) -> Result<() }; // Check if we should exit if result == AppReturn::Exit { - break; + terminal.clear()?; + terminal.show_cursor()?; + crossterm::terminal::disable_raw_mode()?; + tracing::info!("Exit signal received"); + print!("NPcore was stopped by user"); + exit(0); } } + // Exit alternate screen, and print one last frame + + execute!( + terminal.backend_mut(), + crossterm::terminal::LeaveAlternateScreen + )?; terminal.clear()?; + terminal + .draw(|rect| { + draw( + rect, + &app, + &cycle_history, + elapsed_time, + &settings, + &log_history, + ) + }) + .unwrap(); terminal.show_cursor()?; crossterm::terminal::disable_raw_mode()?; terminal @@ -98,17 +136,15 @@ pub fn start_ui(mut rx: UnboundedReceiver, settings: Data) -> Result<() Ok(()) } -pub fn draw( - rect: &mut Frame, +pub fn draw( + rect: &mut Frame, app: &App, - app_history: &AppHistory, + cycle_history: &CycleHistory, elapsed_time: Duration, - settings: &Data, -) where - B: Backend, -{ + settings: &Settings, + log_history: &Vec, +) { let size = rect.size(); - check_size(&size); // Vertical layout (overall) let chunks = Layout::default() @@ -153,8 +189,19 @@ pub fn draw( let commands = draw_commands(app); rect.render_widget(commands, body_layout[2]); + // Bottom chunk (tabs) + let bottom_chunk = chunks[2]; + let tab_layout = Layout::default() + .direction(Direction::Vertical) + .constraints([Constraint::Percentage(10), Constraint::Percentage(90)].as_ref()) + .split(bottom_chunk); + + let tabs = draw_tabs(&app); + rect.render_widget(tabs, tab_layout[0]); + + // Plot // Prepare the data - let data: Vec<(f64, f64)> = app_history + let data: Vec<(f64, f64)> = cycle_history .cycles .iter() .enumerate() @@ -171,230 +218,33 @@ pub fn draw( .map(|&(x, y)| (x, y)) .collect(); - let plot = draw_plot(&mut norm_data); - rect.render_widget(plot, chunks[2]); -} - -fn draw_title<'a>() -> Paragraph<'a> { - Paragraph::new("NPcore Execution") - .style(Style::default().fg(Color::LightCyan)) - .alignment(Alignment::Center) - .block( - Block::default() - .borders(Borders::ALL) - .style(Style::default().fg(Color::White)) - .border_type(BorderType::Plain), - ) -} - -fn draw_status<'a>(app: &App, elapsed_time: Duration) -> Table<'a> { - // Define (formatted) texts - let cycle_text = format!("{}", app.state.cycle); - let objf_text = format!("{:.5}", app.state.objf); - let delta_objf_text = format!("{:.5}", app.state.delta_objf); - let gamma_text = format!("{:.5}", app.state.gamlam); - let spp_text = format!("{}", app.state.nspp); - let time_text = format_time(elapsed_time); - let stop_text = app.state.stop_text.to_string(); - - // Define the table data - let data = vec![ - ("Current cycle", cycle_text), - ("Objective function", objf_text), - ("Δ Objective function", delta_objf_text), - ("Gamma/Lambda", gamma_text), - ("Support points", spp_text), - ("Elapsed time", time_text), - ("Convergence", stop_text), - // Add more rows as needed - ]; - - // Populate the table rows - let rows: Vec = data - .iter() - .map(|(key, value)| { - let title_style = Style::default().add_modifier(Modifier::BOLD); - let title_cell = Cell::from(Span::styled(format!("{}:", key), title_style)); - let value_cell = Cell::from(value.to_string()); - Row::new(vec![title_cell, value_cell]) - }) - .collect(); - - // Create the table widget - Table::new(rows) - .block( - Block::default() - .borders(Borders::ALL) - .border_type(BorderType::Plain) - .title(" Status "), - ) - .widths(&[Constraint::Percentage(50), Constraint::Percentage(50)]) // Set percentage widths for columns - .column_spacing(1) -} - -fn draw_options<'a>(settings: &Data) -> Table<'a> { - // Define the table data - - let cycles = settings.parsed.config.cycles.to_string(); - let engine = settings.parsed.config.engine.to_string(); - let conv_crit = "Placeholder".to_string(); - let indpts = settings.parsed.config.init_points.to_string(); - let error = settings.parsed.error.class.to_string(); - let cache = match settings.parsed.config.cache { - Some(true) => "Yes".to_string(), - Some(false) => "No".to_string(), - None => "Not set".to_string(), - }; - let seed = settings.parsed.config.seed.to_string(); - - let data = vec![ - ("Maximum cycles", cycles), - ("Engine", engine), - ("Convergence criteria", conv_crit), - ("Initial gridpoints", indpts), - ("Error model", error), - ("Cache", cache), - ("Random seed", seed), - // Add more rows as needed - ]; - - // Populate the table rows - let rows: Vec = data - .iter() - .map(|(key, value)| { - let title_style = Style::default().add_modifier(Modifier::BOLD); - let title_cell = Cell::from(Span::styled(format!("{}:", key), title_style)); - let value_cell = Cell::from(value.to_string()); - Row::new(vec![title_cell, value_cell]) - }) - .collect(); - - // Create the table widget - Table::new(rows) - .block( - Block::default() - .borders(Borders::ALL) - .border_type(BorderType::Plain) - .title(" Options "), - ) - .widths(&[Constraint::Percentage(50), Constraint::Percentage(50)]) // Set percentage widths for columns - .column_spacing(1) -} - -fn draw_commands(app: &App) -> Table { - let key_style = Style::default().fg(Color::LightCyan); - let help_style = Style::default().fg(Color::Gray); - - let mut rows = vec![]; - for action in app.actions.actions().iter() { - let mut first = true; - for key in action.keys() { - let help = if first { - first = false; - action.to_string() - } else { - String::from("") - }; - let row = Row::new(vec![ - Cell::from(Span::styled(key.to_string(), key_style)), - Cell::from(Span::styled(help, help_style)), - ]); - rows.push(row); + // Tab content + let inner_height = tab_layout[1].height; + match app.tab_index { + 0 => { + let logs = draw_logs(log_history, inner_height); + rect.render_widget(logs, tab_layout[1]); } - } - - Table::new(rows) - .block( - Block::default() - .borders(Borders::ALL) - .border_type(BorderType::Plain) - .title(" Commands "), - ) - .widths(&[Constraint::Percentage(50), Constraint::Percentage(50)]) // Set percentage widths for columns - .column_spacing(1) -} - -fn draw_plot(norm_data: &mut [(f64, f64)]) -> Chart { - // Find min and max values - let (x_min, x_max) = norm_data - .iter() - .fold((f64::INFINITY, f64::NEG_INFINITY), |(min, max), (x, _)| { - (min.min(*x), max.max(*x)) - }); - - let (y_min, y_max) = norm_data - .iter() - .fold((f64::INFINITY, f64::NEG_INFINITY), |(min, max), (_, y)| { - (min.min(*y), max.max(*y)) - }); - - // Compute the dynamic step size for the X-labels - let step_size = ((x_max - x_min) / 10.0).max(1.0).ceil(); - - // Generate X-labels using the dynamic step size - let x_labels: Vec = ((x_min as i64)..=(x_max as i64)) - .step_by(step_size as usize) - .map(|x| Span::from(x.to_string())) - .collect(); - - // Generate four Y-labels, evenly from y_min to y_max - let y_step = (y_max - y_min) / 5.0; // To get 4 labels, we need 3 steps - let y_labels: Vec = (0..=3) - .map(|i| { - let y = y_min + y_step * (i as f64); - Span::from(format!("{:.0}", y)) - }) - .collect(); - - // Prepare the dataset - let dataset = vec![Dataset::default() - .name("-2LL") - .marker(symbols::Marker::Dot) - .style(Style::default().fg(Color::Cyan)) - .graph_type(GraphType::Scatter) - .data(norm_data)]; - - // Return the plot - Chart::new(dataset) - .x_axis( - Axis::default() - .title("Cycle") - .bounds([x_min, x_max]) - .labels(x_labels), - ) - .y_axis( - Axis::default() - .title("-2LL") - .bounds([y_min, y_max]) - .labels(y_labels), - ) - .block( - Block::default() - .title(" Objective function ") - .borders(Borders::ALL), - ) -} - -fn check_size(rect: &Rect) { - if rect.width < 52 { - // panic!("Require width >= 52, (got {})", rect.width); - } - if rect.height < 12 { - // panic!("Require height >= 12, (got {})", rect.height); - } + 1 => { + let plot = draw_plot(&mut norm_data); + rect.render_widget(plot, tab_layout[1]); + } + 2 => { + // TODO: Return this to show the parameter boundaries + let plot = draw_plot(&mut norm_data); + rect.render_widget(plot, tab_layout[1]); + } + _ => unreachable!(), + }; } -fn format_time(elapsed_time: std::time::Duration) -> String { - let elapsed_seconds = elapsed_time.as_secs(); - let (elapsed, unit) = if elapsed_seconds < 60 { - (elapsed_seconds, "s") - } else if elapsed_seconds < 3600 { - let elapsed_minutes = elapsed_seconds / 60; - (elapsed_minutes, "m") - } else { - let elapsed_hours = elapsed_seconds / 3600; - (elapsed_hours, "h") - }; - let time_text = format!("{}{}", elapsed, unit); - time_text +// From https://ratatui.rs/how-to/develop-apps/panic-hooks/ +pub fn initialize_panic_handler() { + let original_hook = std::panic::take_hook(); + std::panic::set_hook(Box::new(move |panic_info| { + crossterm::execute!(std::io::stderr(), crossterm::terminal::LeaveAlternateScreen).unwrap(); + crossterm::terminal::disable_raw_mode().unwrap(); + crossterm::terminal::Clear(crossterm::terminal::ClearType::All); + original_hook(panic_info); + })); } diff --git a/examples/drusano/config.toml b/todo/drusano/config.toml similarity index 100% rename from examples/drusano/config.toml rename to todo/drusano/config.toml diff --git a/examples/drusano/main.rs b/todo/drusano/main-old.rs similarity index 100% rename from examples/drusano/main.rs rename to todo/drusano/main-old.rs diff --git a/todo/drusano/main.rs b/todo/drusano/main.rs new file mode 100644 index 000000000..e5c961a75 --- /dev/null +++ b/todo/drusano/main.rs @@ -0,0 +1,477 @@ +#![allow(dead_code)] +#![allow(unused_variables)] +use argmin::core::observers::{ObserverMode, SlogLogger}; +use argmin::core::{CostFunction, Error, Executor, TerminationReason, TerminationStatus}; +use argmin::solver::neldermead::NelderMead; +use eyre::Result; +use npcore::prelude::{ + datafile::{CovLine, Infusion, Scenario}, + predict::{Engine, Predict}, + start, +}; + +const ATOL: f64 = 1e-4; +const RTOL: f64 = 1e-4; +use ode_solvers::*; +use std::{collections::HashMap, process::exit}; +#[derive(Debug, Clone)] +struct Model<'a> { + v1: f64, + cl1: f64, + v2: f64, + cl2: f64, + popmax: f64, + kgs: f64, + kks: f64, + e50_1s: f64, + e50_2s: f64, + alpha_s: f64, + kgr1: f64, + kkr1: f64, + e50_1r1: f64, + alpha_r1: f64, + kgr2: f64, + kkr2: f64, + e50_2r2: f64, + alpha_r2: f64, + init_3: f64, + init_4: f64, + init_5: f64, + h1s: f64, + h2s: f64, + h1r1: f64, + h2r2: f64, + _scenario: &'a Scenario, + infusions: Vec, + cov: Option<&'a HashMap>, +} + +type State = Vector5; +type Time = f64; + +impl ode_solvers::System for Model<'_> { + fn system(&self, t: Time, x: &State, dx: &mut State) { + let mut rateiv = [0.0, 0.0]; + for infusion in &self.infusions { + if t >= infusion.time && t <= (infusion.dur + infusion.time) { + rateiv[infusion.compartment] += infusion.amount / infusion.dur; + } + } + // Sec + let e50_2r1 = self.e50_2s; + let e50_1r2 = self.e50_1s; + let h2r1 = self.h2s; + let h1r2 = self.h1s; + let mut xm0best = 0.0; + + ///////////////////// USER DEFINED /////////////// + + // if x[0] < 0.0 { + // x[0] = 0.0; + // } + // if x[1] < 0.0 { + // x[1] = 0.0; + // } + dx[0] = rateiv[0] - self.cl1 * x[0] / self.v1; + dx[1] = rateiv[1] - self.cl2 * x[1] / self.v2; + + let xns = x[2]; + let xnr1 = x[3]; + let xnr2 = x[4]; + let e = 1.0 - (xns + xnr1 + xnr2) / self.popmax; + let mut d1 = x[0] / self.v1; + let mut d2 = x[1] / self.v2; + let mut u = d1 / self.e50_1s; + let mut v = d2 / self.e50_2s; + let mut w = self.alpha_s * d1 * d2 / (self.e50_1s * self.e50_2s); + let mut h1 = 1.0_f64 / self.h1s; + let mut h2 = 1.0_f64 / self.h2s; + let mut xx = (h1 + h2) / 2.0; + if u < 1.0E-5 && v < 1.0E-5 { + xm0best = 0.0; + } else { + if v < 0.0 { + xm0best = u.powf(1.0 / h1); + } + if u < 0.0 { + xm0best = v.powf(1.0 / h2); + } + + if v > 0.0 && u > 0.0 { + let start = 0.00001; + let tol = 1.0e-10; + let step = -2.0 * start; + // CALL ELDERY(1,START,XM0BEST1,VALMIN1,TOL,STEP,1000,BESTM0,0,ICONV,NITER,ICNT) + let bm0 = BESTM0 { + u, + v, + w, + h1, + h2, + xx, + }; + let (xm0best1, valmin1, iconv) = bm0.get_best(start, step); + if iconv == false { + // Output a message indicating no convergence on the selection of best M0 for s + println!(" NO CONVERGENCE ON SELECTION OF BEST M0 FOR s."); + + // Output a message indicating the XP(3) EQ... + println!(" FOR THE XP(3) EQ.... "); + + // Output the values of XM0BEST1 and VALMIN1 with formatting + println!(" THE EST. FOR M0 FROM ELDERY WAS {:>20.12}", xm0best1); + println!(" AND THIS GAVE A VALMIN OF {:>20.12}", valmin1); + + // Output the values of D1, D2, U, V, W, ALPHA_S, H1, and H2 with formatting + println!(" NOTE THAT D1,D2 = {:>20.12} {:>20.12}", d1, d2); + println!(" U,V = {:>20.12} {:>20.12}", u, v); + println!(" W,ALPHA_S = {:>20.12} {:>20.12}", w, self.alpha_s); + println!(" H1,H2 = {:>20.12} {:>20.12}", h1, h2); + + exit(-1); + } + if valmin1 < 1.0e-10 { + xm0best = xm0best1; + } else { + // CALL FINDM0(U,V,alpha_s,H1,H2,XM0EST) + let xm0est = find_m0(u, v, self.alpha_s, h1, h2); + if xm0est < 0.0 { + xm0best = xm0best1; + } else { + // START(1) = XM0EST + // STEP(1)= -.2D0*START(1) + // CALL ELDERY(1,START,XM0BEST2,VALMIN2,TOL,STEP,1000,BESTM0,0,ICONV,NITER,ICNT) + let bm0 = BESTM0 { + u, + v, + w, + h1, + h2, + xx, + }; + let (xm0best2, valmin2, iconv) = bm0.get_best(xm0est, -2.0 * xm0est); + xm0best = xm0best1; + if valmin2 < valmin1 { + xm0best = xm0best2; + } + if iconv == false { + panic!("NO CONVERGENCE ON SELECTION OF BEST M0 FOR s."); + } //235 + } //237 + } //240 + } //243 + } + let xms = xm0best / (xm0best + 1.0); + dx[2] = xns * (self.kgs * e - self.kks * xms); + + d1 = x[0] / self.v1; + d2 = x[1] / self.v2; + u = d1 / self.e50_1r1; + v = d2 / e50_2r1; + w = self.alpha_r1 * d1 * d2 / (self.e50_1r1 * e50_2r1); + h1 = 1.0_f64 / self.h1r1; + h2 = 1.0_f64 / h2r1; + xx = (h1 + h2) / 2.0; + if u < 1.0e-5 && v < 1.0e-5 { + xm0best = 0.0; + } else { + if v < 0.0 { + xm0best = u.powf(1.0 / h1); + } + if u < 0.0 { + xm0best = v.powf(1.0 / h2); + } + if v > 0.0 && u > 0.0 { + //START(1) = .00001 + let tol = 1.0e-10; + // STEP(1)= -.2D0*START(1) + // CALL ELDERY(1,START,XM0BEST1,VALMIN1,TOL,STEP,1000,BESTM0,0,ICONV,NITER,ICNT) + let bm0 = BESTM0 { + u, + v, + w, + h1, + h2, + xx, + }; + let (xm0best1, valmin1, iconv) = bm0.get_best(0.00001, -2.0 * 0.00001); + if iconv == false { + panic!("NO CONVERGENCE ON SELECTION OF BEST M0 FOR r1."); + } + if valmin1 < 1.0e-10 { + xm0best = xm0best1; + } else { + // CALL FINDM0(U,V,alpha_r1,H1,H2,XM0EST) + let xm0est = find_m0(u, v, self.alpha_s, h1, h2); + if xm0est < 0.0 { + xm0best = xm0best1; + } else { + // START(1) = XM0EST + // STEP(1)= -.2D0*START(1) + // CALL ELDERY(1,START,XM0BEST2,VALMIN2,TOL,STEP,1000,BESTM0,0,ICONV,NITER,ICNT) + let bm0 = BESTM0 { + u, + v, + w, + h1, + h2, + xx, + }; + let (xm0best2, valmin2, iconv) = bm0.get_best(xm0est, -2.0 * xm0est); + xm0best = xm0best1; + if valmin2 < valmin1 { + xm0best = xm0best2; + } + if iconv == false { + panic!("NO CONVERGENCE ON SELECTION OF BEST M0 FOR r1."); + } //235 + } //237 + } //240 + } + } + let xmr1 = xm0best / (xm0best + 1.0); + dx[3] = xnr1 * (self.kgr1 * e - self.kkr1 * xmr1); + + d1 = x[0] / self.v1; + d2 = x[1] / self.v2; + u = d1 / e50_1r2; + v = d2 / self.e50_2r2; + w = self.alpha_r2 * d1 * d2 / (e50_1r2 * self.e50_2r2); + h1 = 1.0_f64 / h1r2; + h2 = 1.0_f64 / self.h2r2; + xx = (h1 + h2) / 2.0; + if u < 1.0e-5 && v < 1.0e-5 { + xm0best = 0.0; + } else { + if v < 0.0 { + xm0best = u.powf(1.0 / h1); + } + if u < 0.0 { + xm0best = v.powf(1.0 / h2); + } + + if v > 0.0 && u > 0.0 { + //START(1) = .00001 + let tol = 1.0e-10; + // STEP(1)= -.2D0*START(1) + // CALL ELDERY(1,START,XM0BEST1,VALMIN1,TOL,STEP,1000,BESTM0,0,ICONV,NITER,ICNT) + let xm0best1 = 0.0; + let valmin1 = 0.0; + let iconv = 0.0; + if iconv == 0.0 { + panic!("NO CONVERGENCE ON SELECTION OF BEST M0 FOR r1."); + } + if valmin1 < 1.0e-10 { + xm0best = xm0best1; + } else { + // CALL FINDM0(U,V,alpha_s,H1,H2,XM0EST) + let xm0est = find_m0(u, v, self.alpha_s, h1, h2); + if xm0est < 0.0 { + xm0best = xm0best1; + } else { + // START(1) = XM0EST + // STEP(1)= -.2D0*START(1) + // CALL ELDERY(1,START,XM0BEST2,VALMIN2,TOL,STEP,1000,BESTM0,0,ICONV,NITER,ICNT) + let xm0best2 = 0.0; + let valmin2 = 0.0; + let iconv = 0.0; + xm0best = xm0best1; + if valmin2 < valmin1 { + xm0best = xm0best2; + } + if iconv == 0.0 { + panic!("NO CONVERGENCE ON SELECTION OF BEST M0 FOR s."); + } //235 + } //237 + } //240 + } //243 + } + let xmr2 = xm0best / (xm0best + 1.0); + dx[4] = xnr2 * (self.kgr2 * e - self.kkr2 * xmr2); + + //////////////// END USER DEFINED //////////////// + } +} + +#[derive(Debug, Clone)] +struct Ode {} + +impl Predict for Ode { + fn predict(&self, params: Vec, scenario: &Scenario) -> Vec { + let mut system = Model { + v1: params[0], + cl1: params[1], + v2: params[2], + cl2: params[3], + popmax: params[4], + kgs: params[5], + kks: params[6], + e50_1s: params[7], + e50_2s: params[8], + alpha_s: params[9], + kgr1: params[10], + kkr1: params[11], + e50_1r1: params[12], + alpha_r1: params[13], + kgr2: params[14], + kkr2: params[15], + e50_2r2: params[16], + alpha_r2: params[17], + init_3: params[18], + init_4: params[19], + init_5: params[20], + h1s: params[21], + h2s: params[22], + h1r1: params[23], + h2r2: params[24], + _scenario: scenario, + infusions: vec![], + cov: None, + }; + let mut yout = vec![]; + let mut x = State::new( + 0.0, + 0.0, + 10.0_f64.powf(1.0), + 10.0_f64.powf(system.init_4), + 10.0_f64.powf(system.init_5), + ); + let mut index: usize = 0; + for block in &scenario.blocks { + system.cov = Some(&block.covs); + for event in &block.events { + if event.evid == 1 { + if event.dur.unwrap_or(0.0) > 0.0 { + //infusion + system.infusions.push(Infusion { + time: event.time, + dur: event.dur.unwrap(), + amount: event.dose.unwrap(), + compartment: event.input.unwrap() - 1, + }); + } else { + //dose + x[event.input.unwrap() - 1] += event.dose.unwrap(); + } + } else if event.evid == 0 { + //obs + let v1 = params[0]; + let v2 = params[2]; + let out = match event.outeq.unwrap() { + 1 => x[0] / v1, + 2 => x[1] / v2, + 3 => (x[2] + x[3] + x[4]).log10(), + 4 => x[3].log10(), + 5 => x[4].log10(), + _ => { + log::error!("Invalid output equation"); + exit(1) + } + }; + yout.push(out); + } + if let Some(next_time) = scenario.times.get(index + 1) { + // let mut stepper = Rk4::new(system.clone(), lag_time, x, *next_time, 0.1); + if event.time < *next_time { + let mut stepper = Dopri5::new( + system.clone(), + event.time, + *next_time, + 1e-3, + x, + RTOL, + ATOL, + ); + let _res = stepper.integrate(); + let y = stepper.y_out(); + x = *y.last().unwrap(); + } else if event.time > *next_time { + log::error!("next time is in the past!"); + log::error!("event_time: {}\nnext_time: {}", event.time, *next_time); + } + } + index += 1; + } + } + yout + } +} + +struct BESTM0 { + u: f64, + v: f64, + w: f64, + h1: f64, + h2: f64, + xx: f64, +} +impl CostFunction for BESTM0 { + type Param = f64; + type Output = f64; + fn cost(&self, xm0: &Self::Param) -> Result { + let t1 = self.u / xm0.powf(self.h1); + let t2 = self.v / xm0.powf(self.h2); + let t3 = self.w / xm0.powf(self.xx); + + Ok((1.0 - t1 - t2 - t3).powi(2)) + } +} + +impl BESTM0 { + fn get_best(self, start: f64, step: f64) -> (f64, f64, bool) { + let other_point = start + step; + let solver = NelderMead::new(vec![start, other_point]) + .with_sd_tolerance(0.0001) + .unwrap(); + let res = Executor::new(self, solver) + .configure(|state| state.max_iters(1000)) + // .add_observer(SlogLogger::term(), ObserverMode::Always) + .run() + .unwrap(); + let converged = match res.state.termination_status { + TerminationStatus::Terminated(reason) => match reason { + TerminationReason::SolverConverged => true, + _ => false, + }, + _ => false, + }; + + ( + res.state.best_param.unwrap(), + res.state.best_cost, + converged, + ) + } +} +fn find_m0(ufinal: f64, v: f64, alpha: f64, h1: f64, h2: f64) -> f64 { + let noint = 1000; + let delu = ufinal / (noint as f64); + let mut xm = v.powf(1.0 / h2); + let mut u = 0.0; + let hh = (h1 + h2) / 2.0; + + for int in 1..=noint { + let top = 1.0 / xm.powf(h1) + alpha * v / xm.powf(hh); + let b1 = u * h1 / xm.powf(h1 + 1.0); + let b2 = v * h2 / xm.powf(h2 + 1.0); + let b3 = alpha * v * u * hh / xm.powf(hh + 1.0); + let xmp = top / (b1 + b2 + b3); + + xm = xm + xmp * delu; + + if xm <= 0.0 { + return -1.0; // Greco equation is not solvable + } + + u = delu * (int as f64); + } + + xm // Return the calculated xm0est +} +fn main() -> Result<()> { + start( + Engine::new(Ode {}), + "examples/drusano/config.toml".to_string(), + )?; + Ok(()) +} diff --git a/examples/faer_qr.rs b/todo/faer_qr.rs similarity index 100% rename from examples/faer_qr.rs rename to todo/faer_qr.rs diff --git a/examples/simulator/main.rs b/todo/simulator/main-old.rs similarity index 100% rename from examples/simulator/main.rs rename to todo/simulator/main-old.rs diff --git a/todo/simulator/main.rs b/todo/simulator/main.rs new file mode 100644 index 000000000..50f38266e --- /dev/null +++ b/todo/simulator/main.rs @@ -0,0 +1,129 @@ +use eyre::Result; +use npcore::prelude::{ + datafile::{CovLine, Infusion, Scenario}, + predict::{Engine, Predict}, + simulate, +}; +use ode_solvers::*; +use std::collections::HashMap; +#[derive(Debug, Clone)] +struct Model<'a> { + ka: f64, + ke: f64, + _v: f64, + lag: f64, + _scenario: &'a Scenario, + infusions: Vec, + cov: Option<&'a HashMap>, +} + +type State = SVector; +type Time = f64; + +impl ode_solvers::System for Model<'_> { + fn system(&self, t: Time, x: &State, dx: &mut State) { + // Random parameters + let ka = self.ka; + let ke = self.ke; + // let lag = self.lag; + // Covariates + let _wt = self.cov.unwrap().get("WT").unwrap().interp(t); + let mut rateiv = [0.0]; + for infusion in &self.infusions { + if t >= infusion.time && t <= (infusion.dur + infusion.time) { + rateiv[infusion.compartment] = infusion.amount / infusion.dur; + } + } + ///////////////////// USER DEFINED /////////////// + dx[0] = -ka * x[0]; + dx[1] = ka * x[0] - ke * x[1]; + //////////////// END USER DEFINED //////////////// + } +} +#[derive(Debug, Clone)] +struct Ode {} + +impl Predict for Ode { + fn predict(&self, params: Vec, scenario: &Scenario) -> Vec { + let mut system = Model { + ka: params[0], + ke: params[1], + _v: params[2], + lag: params[3], + _scenario: scenario, + infusions: vec![], + cov: None, + }; + let lag = system.lag; // or 0.0 + let mut yout = vec![]; + let mut x = State::new(0.0, 0.0); + let mut index = 0; + for block in &scenario.blocks { + system.cov = Some(&block.covs); + for event in &block.events { + let mut event_time = event.time; + if event.evid == 1 { + if event.dur.unwrap_or(0.0) > 0.0 { + //infusion + system.infusions.push(Infusion { + time: event.time + lag, + dur: event.dur.unwrap(), + amount: event.dose.unwrap(), + compartment: event.input.unwrap() - 1, + }); + } else { + //dose + if lag > 0.0 { + // if lag is greater than 0 and we integrate from the current time to the time plus lag + // then we can start the next integration at the correct time + // and we can give the dose directly to the compartment + event_time = event.time + lag; + let mut stepper = + Rk4::new(system.clone(), event.time, x, event_time, 0.1); + let _int = stepper.integrate(); + let y = stepper.y_out(); + x = *y.last().unwrap(); + } + + x[event.input.unwrap() - 1] += event.dose.unwrap(); + } + } else if event.evid == 0 { + //obs + yout.push(x[1] / params[2]); + } + if let Some(next_time) = scenario.times.get(index + 1) { + let mut stepper = Rk4::new(system.clone(), event_time, x, *next_time, 0.1); + let _int = stepper.integrate(); + let y = stepper.y_out(); + x = *y.last().unwrap(); + index += 1; + } + } + } + yout + } +} + +fn main() -> Result<()> { + // let scenarios = parse(&"examples/data/two_eq_lag.csv".to_string()) + // .ok() + // .unwrap(); + // let scenario = scenarios.first().unwrap(); + // let ode = Ode {}; + // let params = vec![ + // 0.10007869720458984, + // 0.0999935963869095, + // 119.99048137664795, + // 0.6458234786987305, + // ]; + // let y = ode.predict(params, scenario); + // println!("{:?}", y); + // println!("{:?}", scenario.obs); + + simulate( + Engine::new(Ode {}), + "examples/simulator/sim_config.toml".to_string(), + )?; + + Ok(()) +} diff --git a/examples/simulator/sim_config.toml b/todo/simulator/sim_config.toml similarity index 100% rename from examples/simulator/sim_config.toml rename to todo/simulator/sim_config.toml diff --git a/todo/two_eq_lag/config.toml b/todo/two_eq_lag/config.toml new file mode 100644 index 000000000..4c07a7470 --- /dev/null +++ b/todo/two_eq_lag/config.toml @@ -0,0 +1,25 @@ +[paths] +data = "examples/data/two_eq_lag.csv" +log_out = "log/two_eq_lag.log" +#prior_dist = "theta_two_eq_lag.csv" + +[config] +cycles = 1000 +engine = "NPOD" +init_points = 1000 +seed = 22 +tui = true +pmetrics_outputs = true +cache = true + +[random] +ka = [0.1, 0.9] +ke = [0.001, 0.1] +lag = [0.0, 4.0] +v = [30.0, 120.0] + + +[error] +value = 0.0 +class = "additive" +poly = [0.1, 0.25, -0.001, 0.0] diff --git a/todo/two_eq_lag/main-old.rs b/todo/two_eq_lag/main-old.rs new file mode 100644 index 000000000..59ff8be43 --- /dev/null +++ b/todo/two_eq_lag/main-old.rs @@ -0,0 +1,125 @@ +use eyre::Result; +use npcore::prelude::{ + datafile::{CovLine, Infusion, Scenario}, + predict::{Engine, Predict}, + start, +}; +use ode_solvers::*; +use std::collections::HashMap; +const ATOL: f64 = 1e-4; +const RTOL: f64 = 1e-4; +#[derive(Debug, Clone)] +struct Model<'a> { + ka: f64, + ke: f64, + lag: f64, + _v: f64, + _scenario: &'a Scenario, + infusions: Vec, + cov: Option<&'a HashMap>, +} + +type State = SVector; +type Time = f64; + +impl ode_solvers::System for Model<'_> { + fn system(&self, t: Time, x: &State, dx: &mut State) { + // Random parameters + let ka = self.ka; + let ke = self.ke; + // let lag = self.lag; + // Covariates + let _wt = self.cov.unwrap().get("WT").unwrap().interp(t); + let mut rateiv = [0.0]; + for infusion in &self.infusions { + if t >= infusion.time && t <= (infusion.dur + infusion.time) { + rateiv[infusion.compartment] += infusion.amount / infusion.dur; + } + } + ///////////////////// USER DEFINED /////////////// + dx[0] = -ka * x[0]; + dx[1] = ka * x[0] - ke * x[1]; + //////////////// END USER DEFINED //////////////// + } +} + +#[derive(Debug, Clone)] +struct Ode {} + +impl Predict for Ode { + fn predict(&self, params: Vec, scenario: &Scenario) -> Vec { + let mut system = Model { + ka: params[0], + ke: params[1], + lag: params[2], + _v: params[3], + _scenario: scenario, + infusions: vec![], + cov: None, + }; + let scenario = scenario.reorder_with_lag(vec![(system.lag, 1)]); + let mut yout = vec![]; + let mut x = State::new(0.0, 0.0); + let mut index = 0; + for block in &scenario.blocks { + system.cov = Some(&block.covs); + for event in &block.events { + if event.evid == 1 { + if event.dur.unwrap_or(0.0) > 0.0 { + //infusion + system.infusions.push(Infusion { + time: event.time, + dur: event.dur.unwrap(), + amount: event.dose.unwrap(), + compartment: event.input.unwrap() - 1, + }); + } else { + //dose + x[event.input.unwrap() - 1] += event.dose.unwrap(); + } + } else if event.evid == 0 { + //obs + yout.push(x[1] / params[3]); + } + if let Some(next_time) = scenario.times.get(index + 1) { + // let mut stepper = Rk4::new(system.clone(), lag_time, x, *next_time, 0.1); + let mut stepper = + Dopri5::new(system.clone(), event.time, *next_time, 1e-3, x, RTOL, ATOL); + let _res = stepper.integrate(); + let y = stepper.y_out(); + x = *y.last().unwrap(); + } + index += 1; + } + } + yout + } +} + +fn main() -> Result<()> { + // let scenarios = parse(&"examples/data/two_eq_lag.csv".to_string()) + // .ok() + // .unwrap(); + // let scenario = scenarios.first().unwrap(); + // let ode = Ode {}; + // let params = vec![ + // 0.10007869720458984, + // 0.0999935963869095, + // 0.6458234786987305, + // 119.99048137664795, + // ]; + // let y = ode.predict(params, scenario); + // println!("{:?}", y); + // println!("{:?}", scenario.obs); + start( + Engine::new(Ode {}), + "examples/two_eq_lag/config.toml".to_string(), + )?; + + // simulate( + // Engine::new(Ode {}), + // "examples/two_eq_lag/sim_config.toml".to_string(), + // )?; + + Ok(()) +} diff --git a/todo/two_eq_lag/main.rs b/todo/two_eq_lag/main.rs new file mode 100644 index 000000000..59ff8be43 --- /dev/null +++ b/todo/two_eq_lag/main.rs @@ -0,0 +1,125 @@ +use eyre::Result; +use npcore::prelude::{ + datafile::{CovLine, Infusion, Scenario}, + predict::{Engine, Predict}, + start, +}; +use ode_solvers::*; +use std::collections::HashMap; +const ATOL: f64 = 1e-4; +const RTOL: f64 = 1e-4; +#[derive(Debug, Clone)] +struct Model<'a> { + ka: f64, + ke: f64, + lag: f64, + _v: f64, + _scenario: &'a Scenario, + infusions: Vec, + cov: Option<&'a HashMap>, +} + +type State = SVector; +type Time = f64; + +impl ode_solvers::System for Model<'_> { + fn system(&self, t: Time, x: &State, dx: &mut State) { + // Random parameters + let ka = self.ka; + let ke = self.ke; + // let lag = self.lag; + // Covariates + let _wt = self.cov.unwrap().get("WT").unwrap().interp(t); + let mut rateiv = [0.0]; + for infusion in &self.infusions { + if t >= infusion.time && t <= (infusion.dur + infusion.time) { + rateiv[infusion.compartment] += infusion.amount / infusion.dur; + } + } + ///////////////////// USER DEFINED /////////////// + dx[0] = -ka * x[0]; + dx[1] = ka * x[0] - ke * x[1]; + //////////////// END USER DEFINED //////////////// + } +} + +#[derive(Debug, Clone)] +struct Ode {} + +impl Predict for Ode { + fn predict(&self, params: Vec, scenario: &Scenario) -> Vec { + let mut system = Model { + ka: params[0], + ke: params[1], + lag: params[2], + _v: params[3], + _scenario: scenario, + infusions: vec![], + cov: None, + }; + let scenario = scenario.reorder_with_lag(vec![(system.lag, 1)]); + let mut yout = vec![]; + let mut x = State::new(0.0, 0.0); + let mut index = 0; + for block in &scenario.blocks { + system.cov = Some(&block.covs); + for event in &block.events { + if event.evid == 1 { + if event.dur.unwrap_or(0.0) > 0.0 { + //infusion + system.infusions.push(Infusion { + time: event.time, + dur: event.dur.unwrap(), + amount: event.dose.unwrap(), + compartment: event.input.unwrap() - 1, + }); + } else { + //dose + x[event.input.unwrap() - 1] += event.dose.unwrap(); + } + } else if event.evid == 0 { + //obs + yout.push(x[1] / params[3]); + } + if let Some(next_time) = scenario.times.get(index + 1) { + // let mut stepper = Rk4::new(system.clone(), lag_time, x, *next_time, 0.1); + let mut stepper = + Dopri5::new(system.clone(), event.time, *next_time, 1e-3, x, RTOL, ATOL); + let _res = stepper.integrate(); + let y = stepper.y_out(); + x = *y.last().unwrap(); + } + index += 1; + } + } + yout + } +} + +fn main() -> Result<()> { + // let scenarios = parse(&"examples/data/two_eq_lag.csv".to_string()) + // .ok() + // .unwrap(); + // let scenario = scenarios.first().unwrap(); + // let ode = Ode {}; + // let params = vec![ + // 0.10007869720458984, + // 0.0999935963869095, + // 0.6458234786987305, + // 119.99048137664795, + // ]; + // let y = ode.predict(params, scenario); + // println!("{:?}", y); + // println!("{:?}", scenario.obs); + start( + Engine::new(Ode {}), + "examples/two_eq_lag/config.toml".to_string(), + )?; + + // simulate( + // Engine::new(Ode {}), + // "examples/two_eq_lag/sim_config.toml".to_string(), + // )?; + + Ok(()) +}