offline oop web

This commit is contained in:
Johan Degraeve 2020-10-18 23:24:24 +02:00
parent c13d329bb4
commit 0fe351699b
13 changed files with 508 additions and 48 deletions

View File

@ -232,6 +232,8 @@
F830992A23C32A98005741DF /* WatlaaView.strings in Resources */ = {isa = PBXBuildFile; fileRef = F830992923C32A98005741DF /* WatlaaView.strings */; };
F830993023C928E0005741DF /* WatlaaBluetoothTransmitterDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F830992F23C928E0005741DF /* WatlaaBluetoothTransmitterDelegate.swift */; };
F856CE5B22EDC8E50083E436 /* ConstantsBluetoothPairing.swift in Sources */ = {isa = PBXBuildFile; fileRef = F856CE5A22EDC8E50083E436 /* ConstantsBluetoothPairing.swift */; };
F857A32A253E2D9E00951BB2 /* LibreAlgorithmThresholds.swift in Sources */ = {isa = PBXBuildFile; fileRef = F857A329253E2D9E00951BB2 /* LibreAlgorithmThresholds.swift */; };
F857A334253F6A7600951BB2 /* LibreCalibrationInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = F857A333253F6A7500951BB2 /* LibreCalibrationInfo.swift */; };
F85DC2ED21CFE2F500B9F74A /* BgReading+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F85DC2E721CFE2F500B9F74A /* BgReading+CoreDataProperties.swift */; };
F85DC2EF21CFE2F500B9F74A /* Sensor+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = F85DC2E921CFE2F500B9F74A /* Sensor+CoreDataProperties.swift */; };
F85DC2F321CFE3D400B9F74A /* Calibration+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = F85DC2F021CFE3D400B9F74A /* Calibration+CoreDataClass.swift */; };
@ -742,6 +744,8 @@
F846CDD523046BAC00DCF016 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/SettingsViews.strings"; sourceTree = "<group>"; };
F846CDD623046BAE00DCF016 /* pt */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pt; path = pt.lproj/SettingsViews.strings; sourceTree = "<group>"; };
F856CE5A22EDC8E50083E436 /* ConstantsBluetoothPairing.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ConstantsBluetoothPairing.swift; sourceTree = "<group>"; };
F857A329253E2D9E00951BB2 /* LibreAlgorithmThresholds.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LibreAlgorithmThresholds.swift; sourceTree = "<group>"; };
F857A333253F6A7500951BB2 /* LibreCalibrationInfo.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LibreCalibrationInfo.swift; sourceTree = "<group>"; };
F85DC2E721CFE2F500B9F74A /* BgReading+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "BgReading+CoreDataProperties.swift"; path = "../Extensions/BgReading+CoreDataProperties.swift"; sourceTree = "<group>"; };
F85DC2E921CFE2F500B9F74A /* Sensor+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Sensor+CoreDataProperties.swift"; path = "../Extensions/Sensor+CoreDataProperties.swift"; sourceTree = "<group>"; };
F85DC2F021CFE3D400B9F74A /* Calibration+CoreDataClass.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Calibration+CoreDataClass.swift"; sourceTree = "<group>"; };
@ -2402,14 +2406,18 @@
F8F971E123A5915900C3F17D /* Utilities */ = {
isa = PBXGroup;
children = (
F80D915B24F06A40006840B5 /* PreLibre2.swift */,
F8F971E823A5915900C3F17D /* CRC.swift */,
F8177024248ED4DE00AA3600 /* Libre1DerivedAlgorithmParameters.swift */,
F857A329253E2D9E00951BB2 /* LibreAlgorithmThresholds.swift */,
F857A333253F6A7500951BB2 /* LibreCalibrationInfo.swift */,
F8F971E923A5915900C3F17D /* LibreDataParser.swift */,
F80D915F24F45EB2006840B5 /* LibreError.swift */,
F89467F724A7C94C00F18424 /* LibreHistoricGlucoseA2.swift */,
F8F971EA23A5915900C3F17D /* LibreMeasurement.swift */,
F8F971E523A5915900C3F17D /* LibreOOPClient.swift */,
F8F971E223A5915900C3F17D /* LibreOOPResponse.swift */,
F8AF11F024B11FD400AE5BA2 /* LibreOOPWebError.swift */,
F8AF11FB24B27A6C00AE5BA2 /* LibreOOPWebServerResponse.swift */,
F8F971EB23A5915900C3F17D /* LibreRawGlucoseData.swift */,
F89467F3249FFFA700F18424 /* LibreRawGlucoseOOPA2Cotent.swift */,
F8177026248ED57000AA3600 /* LibreRawGlucoseOOPA2Data.swift */,
@ -2420,9 +2428,7 @@
F8F971E723A5915900C3F17D /* LibreSensorSerialNumber.swift */,
F8F971E423A5915900C3F17D /* LibreSensorState.swift */,
F8177022248CF78300AA3600 /* LibreSensorType.swift */,
F8AF11F024B11FD400AE5BA2 /* LibreOOPWebError.swift */,
F8AF11FB24B27A6C00AE5BA2 /* LibreOOPWebServerResponse.swift */,
F80D915F24F45EB2006840B5 /* LibreError.swift */,
F80D915B24F06A40006840B5 /* PreLibre2.swift */,
);
path = Utilities;
sourceTree = "<group>";
@ -2900,6 +2906,7 @@
F8F9723123A5915900C3F17D /* M5StackAuthenticateTXMessage.swift in Sources */,
F8F9721223A5915900C3F17D /* FirmwareVersionTxMessage.swift in Sources */,
F80D916824F7086D006840B5 /* Libre2BluetoothPeripheralViewModel.swift in Sources */,
F857A334253F6A7600951BB2 /* LibreCalibrationInfo.swift in Sources */,
F867E2612252ADAB000FD265 /* Calibration+CoreDataProperties.swift in Sources */,
F8025E6B21F7CD7600ECF0C0 /* UIStoryboard.swift in Sources */,
F830991D23C2909E005741DF /* Watlaa+CoreDataProperties.swift in Sources */,
@ -3146,6 +3153,7 @@
F8F9722923A5915900C3F17D /* CGMTransmitter.swift in Sources */,
F8A389ED23342EB10010F405 /* ConstantsNightScout.swift in Sources */,
F85FF3D1252F9FF9004E6FF1 /* SnoozeParameters+CoreDataClass.swift in Sources */,
F857A32A253E2D9E00951BB2 /* LibreAlgorithmThresholds.swift in Sources */,
F890E07A247687AE008FB2EC /* URL.swift in Sources */,
F8B3A856227F28DC004BA588 /* AlertTypeSettingsViewController.swift in Sources */,
F8A1584F22ECB281007F5B5D /* SettingsViewInfoViewModel.swift in Sources */,

View File

@ -432,7 +432,7 @@ class CGMMiaoMiaoTransmitter:BluetoothTransmitter, CGMTransmitter {
}
LibreDataParser.libreDataProcessor(libreSensorSerialNumber: LibreSensorSerialNumber(withUID: Data(rxBuffer.subdata(in: 5..<13))), patchInfo: patchInfo, webOOPEnabled: false, oopWebSite: ConstantsLibre.site, oopWebToken: ConstantsLibre.token, libreData: (rxBuffer.subdata(in: miaoMiaoHeaderLength..<(344 + miaoMiaoHeaderLength))), cgmTransmitterDelegate: nil, timeStampLastBgReading: Date(timeIntervalSince1970: 0), dataIsDecryptedToLibre1Format: dataIsDecryptedToLibre1Format, completionHandler: { (timeStampLastBgReading: Date?, sensorState: LibreSensorState?, xDripError: XdripError?) in
LibreDataParser.libreDataProcessor(libreSensorSerialNumber: LibreSensorSerialNumber(withUID: Data(rxBuffer.subdata(in: 5..<13))), patchInfo: patchInfo, webOOPEnabled: true, oopWebSite: ConstantsLibre.site, oopWebToken: ConstantsLibre.token, libreData: (rxBuffer.subdata(in: miaoMiaoHeaderLength..<(344 + miaoMiaoHeaderLength))), cgmTransmitterDelegate: nil, timeStampLastBgReading: Date(timeIntervalSince1970: 0), dataIsDecryptedToLibre1Format: dataIsDecryptedToLibre1Format, completionHandler: { (timeStampLastBgReading: Date?, sensorState: LibreSensorState?, xDripError: XdripError?) in
if let timeStampLastBgReading = timeStampLastBgReading {
debuglogging("timeStampLastBgReading = " + timeStampLastBgReading.description(with: .current))

View File

@ -45,7 +45,7 @@ final class Crc {
/// - parameter seed: seed for crc
///
/// - returns: crc16
private static func crc16(_ message: [UInt8], seed: UInt16? = nil) -> UInt16 {
public static func crc16(_ message: [UInt8], seed: UInt16? = nil) -> UInt16 {
var crc: UInt16 = seed != nil ? seed! : 0x0000
// calculate crc
@ -74,7 +74,7 @@ final class Crc {
/// - parameter bytes: Array of bytes with a crc in the first two bytes
///
/// - returns: true if crc is valid
private static func hasValidCrc16InFirstTwoBytes(_ bytes: [UInt8]) -> Bool {
public static func hasValidCrc16InFirstTwoBytes(_ bytes: [UInt8]) -> Bool {
// print(Array(bytes.dropFirst(2)))
let calculatedCrc = Crc.crc16(Array(bytes.dropFirst(2)), seed: 0xffff)

View File

@ -18,7 +18,7 @@ public struct Libre1DerivedAlgorithmParameters: Codable, CustomStringConvertible
public var isValidForFooterWithReverseCRCs: Int
public var extraSlope : Double = 1
public var extraOffset: Double = 0
public var serialNumber: String
public var serialNumber: String?
public var description: String {
return "LibreDerivedAlgorithmParameters:: slopeslope: \(slope_slope), slopeoffset: \(slope_offset), offsetoffset: \(offset_offset), offsetSlope: \(offset_slope), extraSlope: \(extraSlope), extraOffset: \(extraOffset), isValidForFooterWithReverseCRCs: \(isValidForFooterWithReverseCRCs)"
@ -36,5 +36,50 @@ public struct Libre1DerivedAlgorithmParameters: Codable, CustomStringConvertible
self.serialNumber = sensorSerialNumber
}
public init(bytes: [UInt8]) {
let thresholds = LibreAlgorithmThresholds(glucoseLowerThreshold: 1000, glucoseUpperThreshold: 3000, temperatureLowerThreshold: 6000, temperatureUpperThreshold: 9000, forSensorIdentifiedBy: 49778)
let libreCalibrationInfo = LibreCalibrationInfo(bytes: bytes)
let responseb1 = LibreMeasurement(rawGlucose: Int(thresholds.glucoseLowerThreshold), rawTemperature: Int(thresholds.temperatureLowerThreshold)).roundedGlucoseValueFromRaw2(libreCalibrationInfo: libreCalibrationInfo)
let responseb2 = LibreMeasurement(rawGlucose: Int(thresholds.glucoseUpperThreshold), rawTemperature: Int(thresholds.temperatureLowerThreshold)).roundedGlucoseValueFromRaw2(libreCalibrationInfo: libreCalibrationInfo)
let slope1 = (responseb2 - responseb1) / (Double(thresholds.glucoseUpperThreshold) - Double(thresholds.glucoseLowerThreshold))
let offset1 = responseb2 - (Double(thresholds.glucoseUpperThreshold) * slope1)
let responsef1 = LibreMeasurement(rawGlucose: Int(thresholds.glucoseLowerThreshold), rawTemperature: Int(thresholds.temperatureUpperThreshold)).roundedGlucoseValueFromRaw2(libreCalibrationInfo: libreCalibrationInfo)
let responsef2 = LibreMeasurement(rawGlucose: Int(thresholds.glucoseUpperThreshold), rawTemperature: Int(thresholds.temperatureUpperThreshold)).roundedGlucoseValueFromRaw2(libreCalibrationInfo: libreCalibrationInfo)
let slope2 = (responsef2 - responsef1) / (Double(thresholds.glucoseUpperThreshold) - Double(thresholds.glucoseLowerThreshold)) // ca 0.09260869565
let offset2 = responsef2 - (Double(thresholds.glucoseUpperThreshold) * slope2) //
slope_slope = (slope1 - slope2) / (Double(thresholds.temperatureLowerThreshold) - Double(thresholds.temperatureUpperThreshold)) // 0.00001562292
offset_slope = slope1 - (slope_slope * Double(thresholds.temperatureLowerThreshold))
slope_offset = (offset1 - offset2) / (Double(thresholds.temperatureLowerThreshold) - Double(thresholds.temperatureUpperThreshold)) //-0.00023267185
offset_offset = offset2 - (slope_offset * Double(thresholds.temperatureUpperThreshold))
// from SensorData and GlucoseFromRaw
let footerRange = 320..<344
let footer = Array(bytes[footerRange])
let b0 = UInt16(footer[1])
let b1 = UInt16(footer[0])
let reverseFooterCRC = (b0 << 8) | UInt16(b1)
isValidForFooterWithReverseCRCs = Int(reverseFooterCRC)
extraSlope = 1
extraOffset = 0
}
}

View File

@ -0,0 +1,15 @@
import Foundation
struct LibreAlgorithmThresholds {
var glucoseLowerThreshold: UInt16
var glucoseUpperThreshold: UInt16
var temperatureLowerThreshold: UInt16
var temperatureUpperThreshold: UInt16
var forSensorIdentifiedBy: UInt16
}

View File

@ -0,0 +1,67 @@
import Foundation
public struct LibreCalibrationInfo: Codable {
var i1: Int
var i2: Int
var i3: Double
var i4: Double
var i5: Double
var i6: Double
init(bytes: [UInt8]) {
i1 = Self.readBits(bytes, 2, 0, 3)
i2 = Self.readBits(bytes, 2, 3, 0xa)
i3 = Double(Self.readBits(bytes, 0x150, 0, 8))
if Self.readBits(bytes, 0x150, 0x21, 1) != 0 {
i3 = -i3
}
i4 = Double(Self.readBits(bytes, 0x150, 8, 0xe))
i5 = Double(Self.readBits(bytes, 0x150, 0x28, 0xc) << 2)
i6 = Double(Self.readBits(bytes, 0x150, 0x34, 0xc) << 2)
}
/// Reads Libredata in bits converts and the result to int
///
/// Makes it possible to read for example 7 bits from a 1 byte (8 bit) buffer.
/// Can be used to read both FRAM and Libre2 Bluetooth buffer data . Buffer is expected to be unencrypted
/// - Returns: bits from buffer
static func readBits(_ buffer: [UInt8], _ byteOffset: Int, _ bitOffset: Int, _ bitCount: Int) -> Int {
guard bitCount != 0 else {
return 0
}
var res = 0
for i in stride(from: 0, to: bitCount, by: 1) {
let totalBitOffset = byteOffset * 8 + bitOffset + i
let abyte = Int(floor(Float(totalBitOffset) / 8))
let abit = totalBitOffset % 8
if totalBitOffset >= 0 && ((buffer[abyte] >> abit) & 0x1) == 1 {
res = res | (1 << i)
}
}
return res
}
static func writeBits(_ buffer: [UInt8], _ byteOffset: Int, _ bitOffset: Int, _ bitCount: Int, _ value: Int) -> [UInt8]{
var res = buffer; // Make a copy
for i in stride(from: 0, to: bitCount, by: 1) {
let totalBitOffset = byteOffset * 8 + bitOffset + i;
let byte = Int(floor(Double(totalBitOffset) / 8))
let bit = totalBitOffset % 8;
let bitValue = (value >> i) & 0x1;
res[byte] = (res[byte] & ~(1 << bit) | (UInt8(bitValue) << bit));
}
return res;
}
}

View File

@ -472,6 +472,13 @@ fileprivate func parseLibre1DataWithOOPWebCalibration(libreData: Data, libre1Der
/// - libreData : either Libre 1 data or decrypted Libre 2 data
fileprivate func libre1DataProcessor(libreSensorSerialNumber: LibreSensorSerialNumber, libreSensorType: LibreSensorType, libreData: Data, timeStampLastBgReading: Date, cgmTransmitterDelegate: CGMTransmitterDelegate?, oopWebSite: String, oopWebToken: String, completionHandler:@escaping ((_ timeStampLastBgReading: Date?, _ sensorState: LibreSensorState?, _ xDripError: XdripError?) -> ())) {
if UserDefaults.standard.oopWebOffline && UserDefaults.standard.libre1DerivedAlgorithmParameters == nil {
trace("in libreDataProcessor, calculate libre1DerivedAlgorithmParameters offline", log: log, category: ConstantsLog.categoryLibreOOPClient, type: .info)
UserDefaults.standard.libre1DerivedAlgorithmParameters = Libre1DerivedAlgorithmParameters(bytes: libreData.bytes)
}
// If the values are already available in userdefaults , then use those values
if let libre1DerivedAlgorithmParameters = UserDefaults.standard.libre1DerivedAlgorithmParameters, libre1DerivedAlgorithmParameters.serialNumber == libreSensorSerialNumber.serialNumber {

View File

@ -1,16 +1,8 @@
//
// Measurement.swift
// LibreMonitor
//
// Created by Uwe Petersen on 25.08.16.
// Copyright © 2016 Uwe Petersen. All rights reserved.
//
import Foundation
/// Structure for one glucose measurement including value, date and raw data bytes
struct LibreMeasurement {
class LibreMeasurement {
/// The date for this measurement
let date: Date
@ -41,7 +33,8 @@ struct LibreMeasurement {
private let temperatureAlgorithmParameterSet: Libre1DerivedAlgorithmParameters?
private let rawTemperatureAdjustment: Int
/// - parameters :
/// - bytes: raw data bytes as read from the sensor
/// - slope: slope to calculate glucose from raw value in (mg/dl)/raw
@ -59,6 +52,10 @@ struct LibreMeasurement {
self.date = date
self.minuteCounter = minuteCounter
let temperatureAdjustment = (LibreCalibrationInfo.readBits(bytes, 0, 0x26, 0x9) << 2)
let negativeAdjustment = LibreCalibrationInfo.readBits(bytes, 0, 0x2f, 0x1) != 0;
self.rawTemperatureAdjustment = negativeAdjustment ? -temperatureAdjustment : temperatureAdjustment
// local algorithm
self.temperatureAlgorithmParameterSet = libre1DerivedAlgorithmParameters
if let libreDerivedAlgorithmParameterSet = self.temperatureAlgorithmParameterSet {
@ -77,4 +74,329 @@ struct LibreMeasurement {
}
}
/// this is the simplified Measurement, not used as real Measurement
init(rawGlucose: Int, rawTemperature: Int) {
self.rawGlucose = rawGlucose
self.rawTemperature = rawTemperature
self.rawTemperatureAdjustment = 0
// default values for following parameters, as they will not be used
date = Date()
minuteCounter = 0
slope = 0.0
offset = 0.0
glucose = 0.0
temperatureAlgorithmGlucose = 0.0
oopSlope = 0.0
oopOffset = 0.0
temperatureAlgorithmParameterSet = nil
}
func roundedGlucoseValueFromRaw(libreCalibrationInfo: LibreCalibrationInfo) -> Int {
Int(round(glucoseValueFromRaw(libreCalibrationInfo: libreCalibrationInfo)))
}
func roundedGlucoseValueFromRaw2(libreCalibrationInfo: LibreCalibrationInfo) -> Double{
round(glucoseValueFromRaw(libreCalibrationInfo: libreCalibrationInfo))
}
func glucoseValueFromRaw(libreCalibrationInfo: LibreCalibrationInfo) -> Double {
let x : Double = 1000 + 71500;
let y : Double = 1000;
let ca = 0.0009180023;
let cb = 0.0001964561;
let cc = 0.0000007061775;
let cd = 0.00000005283566;
let rawTemperature = Double(self.rawTemperature)
let rawTemperatureAdjustment = Double(self.rawTemperatureAdjustment)
let rawGlucose = Double(self.rawGlucose)
let rLeft = rawTemperature * x
let rRight = rawTemperatureAdjustment + libreCalibrationInfo.i6
let R = ( rLeft / rRight ) - y;
let logR = log(R)
let d = pow(logR, 3) * cd + pow(logR, 2) * cc + logR * cb + ca
let temperature = 1 / d - 273.15;
let g1 = 65.0 * (rawGlucose - libreCalibrationInfo.i3) / (libreCalibrationInfo.i4 - libreCalibrationInfo.i3);
let g2 = pow(1.045, 32.5 - temperature);
let g3 = g1 * g2
let v1 = t1[libreCalibrationInfo.i2 - 1]
let v2 = t2[libreCalibrationInfo.i2 - 1]
let res = (g3 - v1) / v2;
return res
}
}
fileprivate let t1 = [
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
0.75, 1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3,
1, 1.25, 1.5, 1.75, 2, 2.25, 2.5, 2.75, 3,
];
fileprivate let t2 = [
0.037744199999999999, 0.037744199999999999, 0.037744199999999999, 0.037744199999999999, 0.037744199999999999, 0.037744199999999999, 0.037744199999999999, 0.037744199999999999,
0.038121700000000001, 0.038121700000000001, 0.038121700000000001, 0.038121700000000001, 0.038121700000000001, 0.038121700000000001, 0.038121700000000001, 0.038121700000000001,
0.0385029, 0.0385029, 0.0385029, 0.0385029, 0.0385029, 0.0385029, 0.0385029, 0.0385029,
0.038887900000000003, 0.038887900000000003, 0.038887900000000003, 0.038887900000000003, 0.038887900000000003, 0.038887900000000003, 0.038887900000000003, 0.038887900000000003,
0.039276800000000001, 0.039276800000000001, 0.039276800000000001, 0.039276800000000001, 0.039276800000000001, 0.039276800000000001, 0.039276800000000001, 0.039276800000000001,
0.039669599999999999, 0.039669599999999999, 0.039669599999999999, 0.039669599999999999, 0.039669599999999999, 0.039669599999999999, 0.039669599999999999, 0.039669599999999999,
0.040066299999999999, 0.040066299999999999, 0.040066299999999999, 0.040066299999999999, 0.040066299999999999, 0.040066299999999999, 0.040066299999999999, 0.040066299999999999,
0.0404669, 0.0404669, 0.0404669, 0.0404669, 0.0404669, 0.0404669, 0.0404669, 0.0404669,
0.040871600000000001, 0.040871600000000001, 0.040871600000000001, 0.040871600000000001, 0.040871600000000001, 0.040871600000000001, 0.040871600000000001, 0.040871600000000001,
0.041280299999999999, 0.041280299999999999, 0.041280299999999999, 0.041280299999999999, 0.041280299999999999, 0.041280299999999999, 0.041280299999999999, 0.041280299999999999,
0.041693099999999997, 0.041693099999999997, 0.041693099999999997, 0.041693099999999997, 0.041693099999999997, 0.041693099999999997, 0.041693099999999997, 0.041693099999999997,
0.042110000000000002, 0.042110000000000002, 0.042110000000000002, 0.042110000000000002, 0.042110000000000002, 0.042110000000000002, 0.042110000000000002, 0.042110000000000002,
0.042531100000000002, 0.042531100000000002, 0.042531100000000002, 0.042531100000000002, 0.042531100000000002, 0.042531100000000002, 0.042531100000000002, 0.042531100000000002,
0.042956500000000002, 0.042956500000000002, 0.042956500000000002, 0.042956500000000002, 0.042956500000000002, 0.042956500000000002, 0.042956500000000002, 0.042956500000000002,
0.043386000000000001, 0.043386000000000001, 0.043386000000000001, 0.043386000000000001, 0.043386000000000001, 0.043386000000000001, 0.043386000000000001, 0.043386000000000001,
0.043819900000000002, 0.043819900000000002, 0.043819900000000002, 0.043819900000000002, 0.043819900000000002, 0.043819900000000002, 0.043819900000000002, 0.043819900000000002,
0.044258100000000002, 0.044258100000000002, 0.044258100000000002, 0.044258100000000002, 0.044258100000000002, 0.044258100000000002, 0.044258100000000002, 0.044258100000000002,
0.044700700000000003, 0.044700700000000003, 0.044700700000000003, 0.044700700000000003, 0.044700700000000003, 0.044700700000000003, 0.044700700000000003, 0.044700700000000003,
0.045147699999999999, 0.045147699999999999, 0.045147699999999999, 0.045147699999999999, 0.045147699999999999, 0.045147699999999999, 0.045147699999999999, 0.045147699999999999,
0.045599099999999997, 0.045599099999999997, 0.045599099999999997, 0.045599099999999997, 0.045599099999999997, 0.045599099999999997, 0.045599099999999997, 0.045599099999999997,
0.046055100000000002, 0.046055100000000002, 0.046055100000000002, 0.046055100000000002, 0.046055100000000002, 0.046055100000000002, 0.046055100000000002, 0.046055100000000002,
0.0465157, 0.0465157, 0.0465157, 0.0465157, 0.0465157, 0.0465157, 0.0465157, 0.0465157,
0.046980800000000003, 0.046980800000000003, 0.046980800000000003, 0.046980800000000003, 0.046980800000000003, 0.046980800000000003, 0.046980800000000003, 0.046980800000000003,
0.047450600000000002, 0.047450600000000002, 0.047450600000000002, 0.047450600000000002, 0.047450600000000002, 0.047450600000000002, 0.047450600000000002, 0.047450600000000002,
0.047925200000000001, 0.047925200000000001, 0.047925200000000001, 0.047925200000000001, 0.047925200000000001, 0.047925200000000001, 0.047925200000000001, 0.047925200000000001,
0.0484044, 0.0484044, 0.0484044, 0.0484044, 0.0484044, 0.0484044, 0.0484044, 0.0484044,
0.048888399999999999, 0.048888399999999999, 0.048888399999999999, 0.048888399999999999, 0.048888399999999999, 0.048888399999999999, 0.048888399999999999, 0.048888399999999999,
0.049377299999999999, 0.049377299999999999, 0.049377299999999999, 0.049377299999999999, 0.049377299999999999, 0.049377299999999999, 0.049377299999999999, 0.049377299999999999,
0.049871100000000002, 0.049871100000000002, 0.049871100000000002, 0.049871100000000002, 0.049871100000000002, 0.049871100000000002, 0.049871100000000002, 0.049871100000000002,
0.050369799999999999, 0.050369799999999999, 0.050369799999999999, 0.050369799999999999, 0.050369799999999999, 0.050369799999999999, 0.050369799999999999, 0.050369799999999999,
0.050873500000000002, 0.050873500000000002, 0.050873500000000002, 0.050873500000000002, 0.050873500000000002, 0.050873500000000002, 0.050873500000000002, 0.050873500000000002,
0.051382299999999999, 0.051382299999999999, 0.051382299999999999, 0.051382299999999999, 0.051382299999999999, 0.051382299999999999, 0.051382299999999999, 0.051382299999999999,
0.051896100000000001, 0.051896100000000001, 0.051896100000000001, 0.051896100000000001, 0.051896100000000001, 0.051896100000000001, 0.051896100000000001, 0.051896100000000001,
0.052415000000000003, 0.052415000000000003, 0.052415000000000003, 0.052415000000000003, 0.052415000000000003, 0.052415000000000003, 0.052415000000000003, 0.052415000000000003,
0.052939199999999999, 0.052939199999999999, 0.052939199999999999, 0.052939199999999999, 0.052939199999999999, 0.052939199999999999, 0.052939199999999999, 0.052939199999999999,
0.053468599999999998, 0.053468599999999998, 0.053468599999999998, 0.053468599999999998, 0.053468599999999998, 0.053468599999999998, 0.053468599999999998, 0.053468599999999998,
0.054003299999999997, 0.054003299999999997, 0.054003299999999997, 0.054003299999999997, 0.054003299999999997, 0.054003299999999997, 0.054003299999999997, 0.054003299999999997,
0.054543300000000003, 0.054543300000000003, 0.054543300000000003, 0.054543300000000003, 0.054543300000000003, 0.054543300000000003, 0.054543300000000003, 0.054543300000000003,
0.055088699999999997, 0.055088699999999997, 0.055088699999999997, 0.055088699999999997, 0.055088699999999997, 0.055088699999999997, 0.055088699999999997, 0.055088699999999997,
0.055639599999999997, 0.055639599999999997, 0.055639599999999997, 0.055639599999999997, 0.055639599999999997, 0.055639599999999997, 0.055639599999999997, 0.055639599999999997,
0.056196000000000003, 0.056196000000000003, 0.056196000000000003, 0.056196000000000003, 0.056196000000000003, 0.056196000000000003, 0.056196000000000003, 0.056196000000000003,
0.056758000000000003, 0.056758000000000003, 0.056758000000000003, 0.056758000000000003, 0.056758000000000003, 0.056758000000000003, 0.056758000000000003, 0.056758000000000003,
0.057325599999999997, 0.057325599999999997, 0.057325599999999997, 0.057325599999999997, 0.057325599999999997, 0.057325599999999997, 0.057325599999999997, 0.057325599999999997,
0.0578988, 0.0578988, 0.0578988, 0.0578988, 0.0578988, 0.0578988, 0.0578988, 0.0578988,
0.058477800000000003, 0.058477800000000003, 0.058477800000000003, 0.058477800000000003, 0.058477800000000003, 0.058477800000000003, 0.058477800000000003, 0.058477800000000003,
0.0590626, 0.0590626, 0.0590626, 0.0590626, 0.0590626, 0.0590626, 0.0590626, 0.0590626,
0.059653200000000003, 0.059653200000000003, 0.059653200000000003, 0.059653200000000003, 0.059653200000000003, 0.059653200000000003, 0.059653200000000003, 0.059653200000000003,
0.060249700000000003, 0.060249700000000003, 0.060249700000000003, 0.060249700000000003, 0.060249700000000003, 0.060249700000000003, 0.060249700000000003, 0.060249700000000003,
0.060852200000000002, 0.060852200000000002, 0.060852200000000002, 0.060852200000000002, 0.060852200000000002, 0.060852200000000002, 0.060852200000000002, 0.060852200000000002,
0.0614607, 0.0614607, 0.0614607, 0.0614607, 0.0614607, 0.0614607, 0.0614607, 0.0614607,
0.062075400000000003, 0.062075400000000003, 0.062075400000000003, 0.062075400000000003, 0.062075400000000003, 0.062075400000000003, 0.062075400000000003, 0.062075400000000003,
0.062696100000000005, 0.062696100000000005, 0.062696100000000005, 0.062696100000000005, 0.062696100000000005, 0.062696100000000005, 0.062696100000000005, 0.062696100000000005,
0.063323099999999993, 0.063323099999999993, 0.063323099999999993, 0.063323099999999993, 0.063323099999999993, 0.063323099999999993, 0.063323099999999993, 0.063323099999999993,
0.063956299999999994, 0.063956299999999994, 0.063956299999999994, 0.063956299999999994, 0.063956299999999994, 0.063956299999999994, 0.063956299999999994, 0.063956299999999994,
0.064595899999999998, 0.064595899999999998, 0.064595899999999998, 0.064595899999999998, 0.064595899999999998, 0.064595899999999998, 0.064595899999999998, 0.064595899999999998,
0.065241800000000003, 0.065241800000000003, 0.065241800000000003, 0.065241800000000003, 0.065241800000000003, 0.065241800000000003, 0.065241800000000003, 0.065241800000000003,
0.0658942, 0.0658942, 0.0658942, 0.0658942, 0.0658942, 0.0658942, 0.0658942, 0.0658942,
0.066553200000000007, 0.066553200000000007, 0.066553200000000007, 0.066553200000000007, 0.066553200000000007, 0.066553200000000007, 0.066553200000000007, 0.066553200000000007,
0.067218700000000006, 0.067218700000000006, 0.067218700000000006, 0.067218700000000006, 0.067218700000000006, 0.067218700000000006, 0.067218700000000006, 0.067218700000000006,
0.067890900000000004, 0.067890900000000004, 0.067890900000000004, 0.067890900000000004, 0.067890900000000004, 0.067890900000000004, 0.067890900000000004, 0.067890900000000004,
0.0685698, 0.0685698, 0.0685698, 0.0685698, 0.0685698, 0.0685698, 0.0685698, 0.0685698,
0.069255499999999998, 0.069255499999999998, 0.069255499999999998, 0.069255499999999998, 0.069255499999999998, 0.069255499999999998, 0.069255499999999998, 0.069255499999999998,
0.069948099999999999, 0.069948099999999999, 0.069948099999999999, 0.069948099999999999, 0.069948099999999999, 0.069948099999999999, 0.069948099999999999, 0.069948099999999999,
0.070647500000000002, 0.070647500000000002, 0.070647500000000002, 0.070647500000000002, 0.070647500000000002, 0.070647500000000002, 0.070647500000000002, 0.070647500000000002,
0.071354000000000001, 0.071354000000000001, 0.071354000000000001, 0.071354000000000001, 0.071354000000000001, 0.071354000000000001, 0.071354000000000001, 0.071354000000000001, 0.071354000000000001,
0.072067599999999996, 0.072067599999999996, 0.072067599999999996, 0.072067599999999996, 0.072067599999999996, 0.072067599999999996, 0.072067599999999996, 0.072067599999999996, 0.072067599999999996,
0.072788199999999997, 0.072788199999999997, 0.072788199999999997, 0.072788199999999997, 0.072788199999999997, 0.072788199999999997, 0.072788199999999997, 0.072788199999999997, 0.072788199999999997,
0.073516100000000001, 0.073516100000000001, 0.073516100000000001, 0.073516100000000001, 0.073516100000000001, 0.073516100000000001, 0.073516100000000001, 0.073516100000000001, 0.073516100000000001,
0.074251300000000006, 0.074251300000000006, 0.074251300000000006, 0.074251300000000006, 0.074251300000000006, 0.074251300000000006, 0.074251300000000006, 0.074251300000000006, 0.074251300000000006,
0.074993799999999999, 0.074993799999999999, 0.074993799999999999, 0.074993799999999999, 0.074993799999999999, 0.074993799999999999, 0.074993799999999999, 0.074993799999999999, 0.074993799999999999,
0.075743699999999997, 0.075743699999999997, 0.075743699999999997, 0.075743699999999997, 0.075743699999999997, 0.075743699999999997, 0.075743699999999997, 0.075743699999999997, 0.075743699999999997,
0.076501200000000005, 0.076501200000000005, 0.076501200000000005, 0.076501200000000005, 0.076501200000000005, 0.076501200000000005, 0.076501200000000005, 0.076501200000000005, 0.076501200000000005,
0.077266199999999993, 0.077266199999999993, 0.077266199999999993, 0.077266199999999993, 0.077266199999999993, 0.077266199999999993, 0.077266199999999993, 0.077266199999999993, 0.077266199999999993,
0.078038800000000005, 0.078038800000000005, 0.078038800000000005, 0.078038800000000005, 0.078038800000000005, 0.078038800000000005, 0.078038800000000005, 0.078038800000000005, 0.078038800000000005,
0.078819200000000006, 0.078819200000000006, 0.078819200000000006, 0.078819200000000006, 0.078819200000000006, 0.078819200000000006, 0.078819200000000006, 0.078819200000000006, 0.078819200000000006,
0.079607399999999995, 0.079607399999999995, 0.079607399999999995, 0.079607399999999995, 0.079607399999999995, 0.079607399999999995, 0.079607399999999995, 0.079607399999999995, 0.079607399999999995,
0.080403500000000003, 0.080403500000000003, 0.080403500000000003, 0.080403500000000003, 0.080403500000000003, 0.080403500000000003, 0.080403500000000003, 0.080403500000000003, 0.080403500000000003,
0.081207500000000002, 0.081207500000000002, 0.081207500000000002, 0.081207500000000002, 0.081207500000000002, 0.081207500000000002, 0.081207500000000002, 0.081207500000000002, 0.081207500000000002,
0.082019599999999998, 0.082019599999999998, 0.082019599999999998, 0.082019599999999998, 0.082019599999999998, 0.082019599999999998, 0.082019599999999998, 0.082019599999999998, 0.082019599999999998,
0.082839800000000005, 0.082839800000000005, 0.082839800000000005, 0.082839800000000005, 0.082839800000000005, 0.082839800000000005, 0.082839800000000005, 0.082839800000000005, 0.082839800000000005,
0.083668199999999998, 0.083668199999999998, 0.083668199999999998, 0.083668199999999998, 0.083668199999999998, 0.083668199999999998, 0.083668199999999998, 0.083668199999999998, 0.083668199999999998,
0.084504899999999994, 0.084504899999999994, 0.084504899999999994, 0.084504899999999994, 0.084504899999999994, 0.084504899999999994, 0.084504899999999994, 0.084504899999999994, 0.084504899999999994,
0.085349900000000006, 0.085349900000000006, 0.085349900000000006, 0.085349900000000006, 0.085349900000000006, 0.085349900000000006, 0.085349900000000006, 0.085349900000000006, 0.085349900000000006,
0.086203399999999999, 0.086203399999999999, 0.086203399999999999, 0.086203399999999999, 0.086203399999999999, 0.086203399999999999, 0.086203399999999999, 0.086203399999999999, 0.086203399999999999,
0.087065500000000004, 0.087065500000000004, 0.087065500000000004, 0.087065500000000004, 0.087065500000000004, 0.087065500000000004, 0.087065500000000004, 0.087065500000000004, 0.087065500000000004,
0.087936100000000003, 0.087936100000000003, 0.087936100000000003, 0.087936100000000003, 0.087936100000000003, 0.087936100000000003, 0.087936100000000003, 0.087936100000000003, 0.087936100000000003,
0.088815500000000006, 0.088815500000000006, 0.088815500000000006, 0.088815500000000006, 0.088815500000000006, 0.088815500000000006, 0.088815500000000006, 0.088815500000000006, 0.088815500000000006,
0.089703599999999994, 0.089703599999999994, 0.089703599999999994, 0.089703599999999994, 0.089703599999999994, 0.089703599999999994, 0.089703599999999994, 0.089703599999999994,
0.090600700000000006, 0.090600700000000006, 0.090600700000000006, 0.090600700000000006, 0.090600700000000006, 0.090600700000000006, 0.090600700000000006, 0.090600700000000006,
0.091506699999999996, 0.091506699999999996, 0.091506699999999996, 0.091506699999999996, 0.091506699999999996, 0.091506699999999996, 0.091506699999999996, 0.091506699999999996,
0.092421699999999996, 0.092421699999999996, 0.092421699999999996, 0.092421699999999996, 0.092421699999999996, 0.092421699999999996, 0.092421699999999996, 0.092421699999999996,
0.093345999999999998, 0.093345999999999998, 0.093345999999999998, 0.093345999999999998, 0.093345999999999998, 0.093345999999999998, 0.093345999999999998, 0.093345999999999998,
0.094279399999999999, 0.094279399999999999, 0.094279399999999999, 0.094279399999999999, 0.094279399999999999, 0.094279399999999999, 0.094279399999999999, 0.094279399999999999,
0.095222200000000007, 0.095222200000000007, 0.095222200000000007, 0.095222200000000007, 0.095222200000000007, 0.095222200000000007, 0.095222200000000007, 0.095222200000000007,
0.096174399999999993, 0.096174399999999993, 0.096174399999999993, 0.096174399999999993, 0.096174399999999993, 0.096174399999999993, 0.096174399999999993, 0.096174399999999993,
0.097136200000000006, 0.097136200000000006, 0.097136200000000006, 0.097136200000000006, 0.097136200000000006, 0.097136200000000006, 0.097136200000000006, 0.097136200000000006,
0.0981075, 0.0981075, 0.0981075, 0.0981075, 0.0981075, 0.0981075, 0.0981075, 0.0981075,
0.099088599999999999, 0.099088599999999999, 0.099088599999999999, 0.099088599999999999, 0.099088599999999999, 0.099088599999999999, 0.099088599999999999, 0.099088599999999999,
0.1000795, 0.1000795, 0.1000795, 0.1000795, 0.1000795, 0.1000795, 0.1000795, 0.1000795,
0.1010803, 0.1010803, 0.1010803, 0.1010803, 0.1010803, 0.1010803, 0.1010803, 0.1010803,
0.1020911, 0.1020911, 0.1020911, 0.1020911, 0.1020911, 0.1020911, 0.1020911, 0.1020911,
0.103112, 0.103112, 0.103112, 0.103112, 0.103112, 0.103112, 0.103112, 0.103112,
0.1041431, 0.1041431, 0.1041431, 0.1041431, 0.1041431, 0.1041431, 0.1041431, 0.1041431,
0.1051846, 0.1051846, 0.1051846, 0.1051846, 0.1051846, 0.1051846, 0.1051846, 0.1051846,
0.10623639999999999, 0.10623639999999999, 0.10623639999999999, 0.10623639999999999, 0.10623639999999999, 0.10623639999999999, 0.10623639999999999, 0.10623639999999999,
0.1072988, 0.1072988, 0.1072988, 0.1072988, 0.1072988, 0.1072988, 0.1072988, 0.1072988,
0.1083718, 0.1083718, 0.1083718, 0.1083718, 0.1083718, 0.1083718, 0.1083718, 0.1083718,
0.1094555, 0.1094555, 0.1094555, 0.1094555, 0.1094555, 0.1094555, 0.1094555, 0.1094555,
0.11055, 0.11055, 0.11055, 0.11055, 0.11055, 0.11055, 0.11055, 0.11055,
0.1116555, 0.1116555, 0.1116555, 0.1116555, 0.1116555, 0.1116555, 0.1116555, 0.1116555,
0.1127721, 0.1127721, 0.1127721, 0.1127721, 0.1127721, 0.1127721, 0.1127721, 0.1127721,
0.1138998, 0.1138998, 0.1138998, 0.1138998, 0.1138998, 0.1138998, 0.1138998, 0.1138998,
0.1150388, 0.1150388, 0.1150388, 0.1150388, 0.1150388, 0.1150388, 0.1150388, 0.1150388,
0.11618920000000001, 0.11618920000000001, 0.11618920000000001, 0.11618920000000001, 0.11618920000000001, 0.11618920000000001, 0.11618920000000001, 0.11618920000000001,
0.1173511, 0.1173511, 0.1173511, 0.1173511, 0.1173511, 0.1173511, 0.1173511, 0.1173511,
0.11852459999999999, 0.11852459999999999, 0.11852459999999999, 0.11852459999999999, 0.11852459999999999, 0.11852459999999999, 0.11852459999999999, 0.11852459999999999,
0.11970989999999999, 0.11970989999999999, 0.11970989999999999, 0.11970989999999999, 0.11970989999999999, 0.11970989999999999, 0.11970989999999999, 0.11970989999999999, 0.11970989999999999,
0.120907, 0.120907, 0.120907, 0.120907, 0.120907, 0.120907, 0.120907, 0.120907, 0.120907,
0.122116, 0.122116, 0.122116, 0.122116, 0.122116, 0.122116, 0.122116, 0.122116, 0.122116,
0.12333719999999999, 0.12333719999999999, 0.12333719999999999, 0.12333719999999999, 0.12333719999999999, 0.12333719999999999, 0.12333719999999999, 0.12333719999999999, 0.12333719999999999,
0.1245706, 0.1245706, 0.1245706, 0.1245706, 0.1245706, 0.1245706, 0.1245706, 0.1245706, 0.1245706,
0.12581629999999999, 0.12581629999999999, 0.12581629999999999, 0.12581629999999999, 0.12581629999999999, 0.12581629999999999, 0.12581629999999999, 0.12581629999999999, 0.12581629999999999,
0.1270744, 0.1270744, 0.1270744, 0.1270744, 0.1270744, 0.1270744, 0.1270744, 0.1270744, 0.1270744,
0.12834519999999999, 0.12834519999999999, 0.12834519999999999, 0.12834519999999999, 0.12834519999999999, 0.12834519999999999, 0.12834519999999999, 0.12834519999999999, 0.12834519999999999,
];

View File

@ -90,7 +90,7 @@ class LibreOOPClient {
}
}
/// get the `Libre1DerivedAlgorithmParameters for Libre1 Sensor, either from UserDefaults (if already fetched earlier for that sensor), or from oopWeb. If oopWeb fetch fails, then default values are used
/// get the `Libre1DerivedAlgorithmParameters for Libre1 Sensor, from oopWeb
/// - Parameters:
/// - bytes: the 344 bytes from Libre sensor
/// - libreSensorSerialNumber: LibreSensorSerialNumber is a structure that hold the serial number

View File

@ -215,8 +215,8 @@ extension UserDefaults {
/// NSLog enabled or not
case NSLogEnabled = "NSLogEnabled"
/// chartDisabled
case chartDisabled = "chartDisabled"
/// off line calculation libre derived algorithm parameters, voor Libre only
case oopWebOffline = "oopWebOffline"
/// OSLogEnabled enabled or not
case OSLogEnabled = "OSLogEnabled"
@ -1154,13 +1154,13 @@ extension UserDefaults {
}
}
/// chartDisabled - default false
var disableChart: Bool {
/// off line calculation libre derived algorithm parameters, voor Libre only
var oopWebOffline: Bool {
get {
return bool(forKey: Key.chartDisabled.rawValue)
return bool(forKey: Key.oopWebOffline.rawValue)
}
set {
set(newValue, forKey: Key.chartDisabled.rawValue)
set(newValue, forKey: Key.oopWebOffline.rawValue)
}
}

View File

@ -145,7 +145,7 @@ public final class GlucoseChartManager {
// startDate is bigger than the the date of the last currently stored ChartPoint, let's reinitialize the glucosechartpoints
reUseExistingChartPointList = false
// use newGlucoseChartPointsToAppend and assign it to new list of chartpoints startDate to endDate
newGlucoseChartPointsToAppend = self.getGlucoseChartPoints(startDate: startDateToUse, endDate: endDate, bgReadingsAccessor: self.data().bgReadingsAccessor)

View File

@ -547,18 +547,14 @@ final class RootViewController: UIViewController {
// setup watchmanager
watchManager = WatchManager(coreDataManager: coreDataManager)
// initialize glucoseChartManager, only if not disableChart
// after disabling chart in settings, app will need to be restarted to effectively disable it
if !UserDefaults.standard.disableChart {
glucoseChartManager = GlucoseChartManager(chartLongPressGestureRecognizer: chartLongPressGestureRecognizerOutlet, coreDataManager: coreDataManager)
// initialize chartGenerator in chartOutlet
self.chartOutlet.chartGenerator = { [weak self] (frame) in
return self?.glucoseChartManager?.glucoseChartWithFrame(frame)?.view
}
}
// initialize glucoseChartManager
glucoseChartManager = GlucoseChartManager(chartLongPressGestureRecognizer: chartLongPressGestureRecognizerOutlet, coreDataManager: coreDataManager)
// initialize chartGenerator in chartOutlet
self.chartOutlet.chartGenerator = { [weak self] (frame) in
return self?.glucoseChartManager?.glucoseChartWithFrame(frame)?.view
}
}
/// process new glucose data received from transmitter.
@ -976,7 +972,7 @@ final class RootViewController: UIViewController {
// watchManager should process new reading
self.watchManager?.processNewReading()
// send also to loopmanager, not interesting for loop probably, but the data is also used for today widget
self.loopManager?.share()

View File

@ -17,8 +17,8 @@ fileprivate enum Setting:Int, CaseIterable {
/// in case Libre 2 users want to use the local calibration algorithm
case overrideWebOOPCalibration = 4
/// if true then chart will not be shown
case disableChart = 5
/// off line calculation libre derived algorithm parameters, voor Libre only
case oopWebOffline = 5
}
@ -60,8 +60,8 @@ struct SettingsViewDevelopmentSettingsViewModel:SettingsViewModelProtocol {
return "Override Web OOP Calibration"
case .disableChart:
return "disable Chart"
case .oopWebOffline:
return "oop web offline"
}
}
@ -81,7 +81,7 @@ struct SettingsViewDevelopmentSettingsViewModel:SettingsViewModelProtocol {
case .webOOPtoken:
return .disclosureIndicator
case .disableChart:
case .oopWebOffline:
return .none
}
@ -115,7 +115,7 @@ struct SettingsViewDevelopmentSettingsViewModel:SettingsViewModelProtocol {
case .overrideWebOOPCalibration:
return nil
case .disableChart:
case .oopWebOffline:
return nil
}
@ -158,11 +158,11 @@ struct SettingsViewDevelopmentSettingsViewModel:SettingsViewModelProtocol {
})
case .disableChart:
return UISwitch(isOn: UserDefaults.standard.disableChart, action: {
case .oopWebOffline:
return UISwitch(isOn: UserDefaults.standard.oopWebOffline, action: {
(isOn:Bool) in
UserDefaults.standard.disableChart = isOn
UserDefaults.standard.oopWebOffline = isOn
})
@ -180,7 +180,7 @@ struct SettingsViewDevelopmentSettingsViewModel:SettingsViewModelProtocol {
switch setting {
case .NSLogEnabled, .OSLogEnabled, .overrideWebOOPCalibration, .disableChart:
case .NSLogEnabled, .OSLogEnabled, .overrideWebOOPCalibration, .oopWebOffline:
return .nothing
case .webOOPsite: