[
  {
    "path": ".gitignore",
    "content": "*.xcuserstate\n\n.DS_Store\n\n*.xcworkspacedata\n\n*.xccheckout\n\nxcuserdata\n\nweb\n\nfastlane\n\ntravis_signing"
  },
  {
    "path": ".gitmodules",
    "content": ""
  },
  {
    "path": ".travis.yml",
    "content": "language: swift\nos: osx\nosx_image: xcode10.1\nbranches:\n  only:\n    - master\ncache: bundler\nxcode_project: Jirassic.xcodeproj # path to your xcodeproj folder\nxcode_scheme: Jirassic macOS\nxcode_destination: platform=macOS\nbefore_script:\n  - chmod a+x ./scripts/add-key.sh\n  - sh ./scripts/add-key.sh\nscript:\n  - xcodebuild clean test CODE_SIGN_IDENTITY=\"\" CODE_SIGNING_REQUIRED=NO CODE_SIGN_ENTITLEMENTS=\"\" CODE_SIGNING_ALLOWED=\"NO\" -project Jirassic.xcodeproj -scheme \"Jirassic macOS\"\n#  - xcodebuild clean test CODE_SIGN_IDENTITY=\"\" CODE_SIGNING_REQUIRED=NO CODE_SIGN_ENTITLEMENTS=\"\" CODE_SIGNING_ALLOWED=\"NO\" -project Jirassic.xcodeproj -scheme \"Jirassic iOS\" -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone XS,OS=12.1'\n  # - xcodebuild clean test -project Jirassic.xcodeproj -scheme \"Jirassic macOS\""
  },
  {
    "path": "App/Entities/Day.swift",
    "content": "//\n//  Day.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 30/12/15.\n//  Copyright © 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\n// Represents a day in the calendar.\nclass Day: CustomStringConvertible {\n\n    /// The date of the first task in the day\n\tlet dateStart: Date\n    /// The date of the last task in the day if it was finished\n    let dateEnd: Date?\n\t\n    init (dateStart: Date, dateEnd: Date?) {\n\t\tself.dateStart = dateStart\n        self.dateEnd = dateEnd\n\t}\n\n    var description: String {\n        return \"<Day dateStart: \\(dateStart), dateEnd: \\(String(describing: dateEnd))>\"\n    }\n}\n"
  },
  {
    "path": "App/Entities/GitCommit.swift",
    "content": "//\n//  CommitResult.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 17/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\n// Git commit read from the command line\nstruct GitCommit {\n    \n    var commitNumber: String\n    var date: Date\n    var authorEmail: String\n    var message: String\n    var branchName: String?\n}\n"
  },
  {
    "path": "App/Entities/GitUser.swift",
    "content": "//\n//  GitUser.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 14/12/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\n// Users that made commits to the project\nstruct GitUser {\n    var name: String\n    var email: String\n}\n"
  },
  {
    "path": "App/Entities/Report.swift",
    "content": "//\n//  Report.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 06/11/2016.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nstruct Report {\n    \n    var taskNumber: String\n    var title: String\n    var notes: [String]\n    var duration: TimeInterval\n}\n"
  },
  {
    "path": "App/Entities/Settings.swift",
    "content": "//\n//  Settings.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 17/09/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nenum TrackingMode: Int {\n    case auto\n    case notif\n}\n\nstruct Settings {\n    \n    var enableBackup: Bool\n    var settingsTracking: SettingsTracking\n    var settingsBrowser: SettingsBrowser\n}\n\nstruct SettingsTracking {\n    \n    var autotrack: Bool\n    var autotrackingMode: TrackingMode\n    var trackLunch: Bool\n    var trackScrum: Bool\n    var trackMeetings: Bool\n    var trackStartOfDay: Bool\n    \n    var startOfDayTime: Date\n    var endOfDayTime: Date\n    var lunchTime: Date\n    var scrumTime: Date\n    var minSleepDuration: Int\n}\n\nstruct SettingsBrowser {\n\n    var trackCodeReviews: Bool\n    var trackWastedTime: Bool\n\n    var minCodeRevDuration: Int\n    var codeRevLink: String\n    var minWasteDuration: Int\n    var wasteLinks: [String]\n}\n"
  },
  {
    "path": "App/Entities/Task.swift",
    "content": "//\n//  Task.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 21/11/15.\n//  Copyright © 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\n// Never change the indexes because they are already stored in the database\nenum TaskType: Int {\n\t\n\tcase issue = 0\n\tcase startDay = 1\n\tcase scrum = 2\n\tcase lunch = 3\n\tcase meeting = 4\n    case gitCommit = 5\n    case waste = 6\n    case learning = 7\n    case coderev = 8\n    case endDay = 9\n    case calendar = 10\n    \n    var defaultNotes: String {\n        switch self {\n        case .startDay: return \"Working day started\"\n        case .endDay: return \"Working day ended\"\n        case .scrum: return \"Scrum meeting\"\n        case .lunch: return \"Lunch break\"\n        case .meeting: return \"Meeting\"\n        case .waste: return \"Social & Media\"\n        case .learning: return \"Learning session\"\n        case .coderev: return \"Reviewing and fixing code\"\n        case .calendar: return \"Calendar event\"\n        default: return \"\"\n        }\n    }\n    \n    // Used to group reports\n    var defaultTaskNumber: String? {\n        switch self {\n        case .scrum: return \"scrum\"\n        case .lunch: return \"lunch\"\n        case .meeting: return \"meeting\"\n        case .waste: return \"waste\"\n        case .learning: return \"learning\"\n        case .coderev: return \"coderev\"\n        case .calendar: return \"meeting\"\n        default: return nil\n        }\n    }\n}\n\n// Object representing a task\nstruct Task {\n    \n    /// Is the date when this object was last modified by the server (iCloud)\n    /// When created locally this field does not have a value.\n    var lastModifiedDate: Date?\n    /// Start date of the task, needed by tasks like meetings which have a known start and end\n    var startDate: Date?\n\tvar endDate: Date\n\tvar notes: String?\n    /// Task number is the issue number from Jira (eg. AA-1234)\n    /// For other type of tasks should be nil\n    var taskNumber: String?\n    /// Task title is usually the title that follows the task number in Jira\n    var taskTitle: String?\n\tvar taskType: TaskType\n    /// Created locally and used for matching with the remote object\n    /// If objectId is missing means the task is not saved to db nor to server (eg. unsaved git and calendar items)\n    var objectId: String?\n}\n\nextension Task {\n\t\n    init () {\n        self.init (endDate: Date(), type: .issue)\n    }\n    \n\tinit (endDate: Date, type: TaskType) {\n\t\t\n\t\tself.endDate = endDate\n        self.taskType = type\n        self.objectId = String.generateId()\n\t}\n    \n    init (startDate: Date?, endDate: Date, type: TaskType) {\n        \n        self.startDate = startDate\n        self.endDate = endDate\n        self.taskType = type\n        self.objectId = String.generateId()\n    }\n}\n\n/// Object used to pass task data to and from the cell, for displaying and editing\ntypealias TaskCreationData = (\n    dateStart: Date?,\n    dateEnd: Date,\n    taskNumber: String?,\n    notes: String?,\n    taskType: TaskType\n)\n"
  },
  {
    "path": "App/Entities/User.swift",
    "content": "//\n//  User.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 21/11/15.\n//  Copyright © 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nstruct User {\n    \n\tvar email: String?\n    var userId: String?\n}\n\ntypealias UserCredentials = (email: String, password: String)\n"
  },
  {
    "path": "App/Entities/Week.swift",
    "content": "//\n//  Week.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 30/12/15.\n//  Copyright © 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\n// Represents a week in the calendar\nclass Week {\n\t\n\tlet date: Date\n\tvar days = [Day]()\n\t\n\tinit (date: Date) {\n\t\tself.date = date\n\t}\n}\n"
  },
  {
    "path": "App/Extensions/Conversions.swift",
    "content": "//\n//  Conversions.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 06/11/2016.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nextension Double {\n    \n    var minToSec: Double {\n        return self * 60\n    }\n\n    var monthsToSec: Double {\n        return self * 30 * 24.hoursToSec\n    }\n\n    var hoursToSec: Double {\n        return self * 3600\n    }\n    \n    var secToHours: Double {\n        return self / 3600\n    }\n    \n    /// Transforms a number of seconds into 'hours minutes'. The hours can be over 24\n    var secToHoursAndMin: String {\n        let h = floor(self / 3600)\n        let secondsRemaining = self - h * 3600\n        let m = secondsRemaining / 60\n        let hours = Int(h)\n        let minutes = Int(m)\n        return \"\\(hours)h \\(minutes)m\"\n    }\n    \n    /// One hour equals to 1 percent\n    var secToPercent: Double {\n        return Double(Darwin.round((self / 3600) * 100) / 100)\n    }\n}\n"
  },
  {
    "path": "App/Extensions/DateExtension.swift",
    "content": "//\n//  DateExtension.swift\n//  Spoto\n//\n//  Created by Baluta Cristian on 05/12/14.\n//  Copyright (c) 2014 Baluta Cristian. All rights reserved.\n//\n\nimport Foundation\n\nlet ymdUnitFlags: Set<Calendar.Component> = [.year, .month, .day]\nlet ymdhmsUnitFlags: Set<Calendar.Component> = [.year, .month, .weekday, .day, .hour, .minute, .second]\nlet gregorian = Calendar(identifier: Calendar.Identifier.gregorian)\n\nextension Date {\n\t\n\tinit (hour: Int, minute: Int, second: Int = 0) {\n\t\tself.init(date: Date(), hour: hour, minute: minute, second: second)\n\t}\n\t\n\tinit (date: Date, hour: Int, minute: Int, second: Int = 0) {\n\t\t\n\t\tvar comps = gregorian.dateComponents(ymdhmsUnitFlags, from: date)\n\t\tcomps.hour = hour\n\t\tcomps.minute = minute\n\t\tcomps.second = 0\n\t\t\n\t\tself.init(timeInterval: 0, since: gregorian.date(from: comps)!)\n\t}\n\t\n\tinit (year: Int, month: Int, day: Int, hour: Int, minute: Int, second: Int = 0) {\n\t\t\n\t\tvar comps = gregorian.dateComponents(ymdhmsUnitFlags, from: Date())\n\t\tcomps.year = year\n\t\tcomps.month = month\n\t\tcomps.day = day\n\t\tcomps.hour = hour\n\t\tcomps.minute = minute\n\t\tcomps.second = second\n\t\t\n\t\tself.init(timeInterval: 0, since: gregorian.date(from: comps)!)\n\t}\n    \n    init (YYYYMMddString: String) {\n        \n        let dateFormatter = DateFormatter()\n        dateFormatter.dateFormat = \"YYYY.MM.dd\"\n        let date = dateFormatter.date(from: YYYYMMddString)\n        \n        self.init(timeInterval: 0, since: date!)\n    }\n}\n\nextension Date {\n\t\n\tfunc HHmmddMM() -> String {\n\t\tlet f = DateFormatter()\n\t\tf.dateFormat = \"HH:mm • dd MMM\"\n\t\treturn f.string(from: self)\n\t}\n\t\n\tfunc MMMMdd() -> String {\n\t\tlet f = DateFormatter()\n\t\tf.dateFormat = \"MMMM dd\"\n\t\treturn f.string(from: self)\n\t}\n\t\n\tfunc HHmm() -> String {\n\t\tlet f = DateFormatter()\n\t\tf.dateFormat = \"HH:mm\"\n\t\treturn f.string(from: self)\n\t}\n\t\n\tfunc HHmmGMT() -> String {\n\t\tlet f = DateFormatter()\n\t\tf.timeZone = TimeZone(abbreviation: \"GMT\")\n\t\tf.dateFormat = \"HH:mm\"\n\t\treturn f.string(from: self)\n\t}\n\t\n\tfunc EEMMMMdd() -> String {\n\t\tlet f = DateFormatter()\n\t\tf.dateFormat = \"EE, MMMM dd\"\n\t\treturn f.string(from: self)\n\t}\n\t\n\tfunc ddEEE() -> String {\n\t\tlet f = DateFormatter()\n\t\tf.dateFormat = \"dd • EEE\"\n\t\treturn f.string(from: self)\n\t}\n\t\n    // eg. Thursday, February 01\n\tfunc EEEEMMMMdd() -> String {\n\t\tlet f = DateFormatter()\n\t\tf.dateFormat = \"EEEE, MMMM dd\"\n\t\treturn f.string(from: self)\n\t}\n    \n    // eg. Thursday, Feb 01\n    func EEEEMMMdd() -> String {\n        let f = DateFormatter()\n        f.dateFormat = \"EEEE, MMM dd\"\n        return f.string(from: self)\n    }\n    \n    func YYYYMMddHHmmss() -> String {\n        let f = DateFormatter()\n        f.dateFormat = \"yyyy-MM-dd HH:mm:ss\"\n        return f.string(from: self)\n    }\n    \n    func YYYYMMddHHmmssGMT() -> String {\n        let f = DateFormatter()\n        f.timeZone = TimeZone(abbreviation: \"GMT\")\n        f.dateFormat = \"yyyy-MM-dd HH:mm:ss\"\n        return f.string(from: self)\n    }\n    \n    #warning(\"if the date is right at the begining of the day the conversion returns the previous day because of the timezone\")\n    func YYYYMMddT00() -> String {\n        let f = DateFormatter()\n//        f.timeZone = TimeZone(abbreviation: \"GMT\")\n        f.dateFormat = \"YYYY-MM-dd\"\n        let day = f.string(from: self)\n//        f.dateFormat = \"HH:mm\"\n        let hour = \"00:00\"//f.string(from: self)\n        return day + \"T\" + hour + \":00.000+0000\"\n    }\n    \n    func YY() -> String {\n        let f = DateFormatter()\n        f.dateFormat = \"YY\"\n        return f.string(from: self)\n    }\n    \n    func YYYY() -> String {\n        let f = DateFormatter()\n        f.dateFormat = \"YYYY\"\n        return f.string(from: self)\n    }\n}\n\nextension Date {\n    \n\tfunc weekInterval() -> String {\n\t\tlet bounds = self.weekBounds()\n\t\tlet f = DateFormatter()\n\t\tf.dateFormat = \"MMM dd\"\n\t\tif bounds.0.isSameMonthAs(bounds.1) {\n\t\t\treturn \"\\(f.string(from: bounds.0)) - \\(bounds.1.day())   '\\(bounds.0.YY())\"\n\t\t}\n\t\treturn \"\\(f.string(from: bounds.0)) - \\(f.string(from: bounds.1))   '\\(bounds.0.YY())\"\n\t}\n}\n\nextension Date {\n    \n\t@inline(__always) func isSameMonthAs (_ month: Date) -> Bool {\n\t\treturn self.year() == month.year() && self.month() == month.month()\n\t}\n\t\n\t@inline(__always) func isSameWeekAs (_ month: Date) -> Bool {\n\t\treturn self.year() == month.year() && self.week() == month.week()\n\t}\n\t\n\t@inline(__always) func isSameDayAs (_ date: Date) -> Bool {\n        return NSCalendar.current.isDate(self, inSameDayAs: date)\n\t}\n    \n    @inline(__always) func isAlmostSameHourAs (_ date: Date, devianceSeconds: Double = 600.0) -> Bool {\n        let timestampDiff = date.timeIntervalSince(self)\n        return abs(timestampDiff) <= devianceSeconds\n    }\n    \n    @inline(__always) func isToday() -> Bool {\n        return isSameDayAs( Date() )\n    }\n    \n    func isWeekend() -> Bool {\n        return gregorian.isDateInWeekend(self)\n    }\n\t\n\tfunc daysInMonth() -> Int {\n\t\t\n\t\tlet daysRange = gregorian.range(of: Calendar.Component.day, in: Calendar.Component.month, for: self)\n\t\t\n\t\treturn daysRange!.count as Int\n\t}\n    \n    func components() -> (hour: Int, minute: Int) {\n        let comps = gregorian.dateComponents(ymdhmsUnitFlags, from: self)\n        return (hour: comps.hour!, minute: comps.minute!)\n    }\n\t\n\t@inline(__always) func year() -> Int {\n\t\tlet comps = gregorian.dateComponents(ymdUnitFlags, from: self)\n\t\treturn comps.year!\n\t}\n\t\n\t@inline(__always) func month() -> Int {\n\t\tlet comps = gregorian.dateComponents(ymdUnitFlags, from: self)\n\t\treturn comps.month!\n\t}\n\t\n\t@inline(__always) func day() -> Int {\n\t\tlet comps = gregorian.dateComponents(ymdUnitFlags, from: self)\n\t\treturn comps.day!\n\t}\n\t\n\t@inline(__always) func week() -> Int {\n\t\tlet comps = gregorian.dateComponents([Calendar.Component.weekOfYear], from: self)\n\t\treturn comps.weekOfYear!\n\t}\n\n    func round (minutesPrecision precision: Int = 6) -> Date {\n\n        var comps = gregorian.dateComponents(ymdhmsUnitFlags, from: self)\n        let hm = minutesToHours(minutes: comps.minute!, resultingMinutesPrecision: precision)\n        comps.hour = comps.hour! + hm.hour\n        comps.minute = hm.min\n        comps.second = 0\n\n        return gregorian.date(from: comps)!\n    }\n\n    func dateByUpdating (hour: Int, minute: Int, second: Int = 0) -> Date {\n\t\t\n\t\tvar comps = gregorian.dateComponents(ymdhmsUnitFlags, from: self)\n\t\tcomps.hour = hour\n\t\tcomps.minute = minute\n\t\tcomps.second = second\n\t\t\n\t\treturn gregorian.date(from: comps)!\n\t}\n    \n    func dateByKeepingTime() -> Date {\n        let comps = gregorian.dateComponents(ymdhmsUnitFlags, from: self)\n        return Date().dateByUpdating(hour: comps.hour!, minute: comps.minute!)\n    }\n\t\n\tstatic func parseHHmm (_ hhmm: String) -> (hour: Int, min: Int) {\n\t\tlet hm = hhmm.components(separatedBy: \":\")\n        let hh = Int(hm[0]) ?? 0\n        let mm = Int(hm[1]) ?? 0\n\t\treturn (hour: hh, min: mm)\n\t}\n}\n\nextension Date {\n    \n    static func getMonthsBetween (startDate: Date, endDate: Date) -> Array<Date> {\n        \n        var dates: [Date] = [Date]()\n        var monthDifference = DateComponents()\n        var monthOffset: Int = 0\n        var nextDate = startDate\n        \n        while nextDate.compare(endDate) == ComparisonResult.orderedAscending {\n            monthOffset += 1\n            monthDifference.month = monthOffset\n            nextDate = gregorian.date(byAdding: monthDifference, to: startDate)!\n            dates.append(nextDate)\n        }\n        \n        return dates;\n    }\n\n    func startOfMonth() -> Date {\n        return gregorian.date(from: gregorian.dateComponents([.year, .month], from: gregorian.startOfDay(for: self)))!\n    }\n\n    func endOfMonth() -> Date {\n        return gregorian.date(byAdding: DateComponents(month: 1, day: -1, hour: 23, minute: 59, second: 59), to: self.startOfMonth())!\n    }\n}\n\nextension Date {\n    \n    func startOfWeek() -> Date {\n        \n        var comps = gregorian.dateComponents(ymdhmsUnitFlags, from: self)\n        comps.day = comps.day! - (comps.weekday! - 1) + 1// 1 because weekday starts with 1, and 1 because weekday starts sunday\n        comps.hour = 0\n        comps.minute = 0\n        comps.second = 0\n        comps.weekday = 1\n        \n        return gregorian.date(from: comps)!\n    }\n    \n    func endOfWeek() -> Date {\n        \n        var comps = gregorian.dateComponents(ymdhmsUnitFlags, from: self)\n        comps.day = comps.day! + (7 - comps.weekday!) + 1\n        comps.hour = 23\n        comps.minute = 59\n        comps.second = 59\n        comps.weekday = 7\n        \n        return gregorian.date(from: comps)!\n    }\n    \n    func weekBounds() -> (Date, Date) {\n        return (self.startOfWeek(), self.endOfWeek())\n    }\n}\n\nextension Date {\n    \n    func startOfDay() -> Date {\n        \n        var comps = gregorian.dateComponents(ymdhmsUnitFlags, from: self)\n        comps.hour = 0\n        comps.minute = 0\n        comps.second = 0\n        \n        return gregorian.date(from: comps)!\n    }\n\n    func startOfNextDay() -> Date {\n\n        var comps = gregorian.dateComponents(ymdhmsUnitFlags, from: self)\n        comps.day = comps.day! + 1\n        comps.hour = 0\n        comps.minute = 0\n        comps.second = 0\n\n        return gregorian.date(from: comps)!\n    }\n\n    func endOfDay() -> Date {\n        \n        var comps = gregorian.dateComponents(ymdhmsUnitFlags, from: self)\n        comps.hour = 23\n        comps.minute = 59\n        comps.second = 59\n        \n        return gregorian.date(from: comps)!\n    }\n    \n    func dayBounds() -> (Date, Date) {\n        return (self.startOfDay(), self.endOfDay())\n    }\n}\n\nextension Date {\n    \n    private func minutesToHours (minutes: Int, resultingMinutesPrecision precision: Int) -> (hour: Int, min: Int) {\n\n        let rest = minutes % precision\n        let newMin = rest == 0 ? minutes : (minutes + precision - rest)\n        \n        return (newMin >= 60 ? 1 : 0, newMin >= 60 ? 0 : newMin)\n    }\n}\n"
  },
  {
    "path": "App/Extensions/DateExtensionTests.swift",
    "content": "//\n//  DateTests.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 01/05/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport XCTest\n@testable import Jirassic_no_cloud\n\nclass DateTests: XCTestCase {\n    \n    func testDateByKeepingTime() {\n        \n        let d1 = Date()\n        let d2 = Date(year: 2016, month: 5, day: 5, hour: 11, minute: 30)\n        let d3 = d2.dateByKeepingTime()\n        let components1 = gregorian.dateComponents(ymdhmsUnitFlags, from: d1)\n        let components2 = gregorian.dateComponents(ymdhmsUnitFlags, from: d2)\n        let components3 = gregorian.dateComponents(ymdhmsUnitFlags, from: d3)\n        \n        XCTAssertTrue(components1.year == components3.year, \"Should keep the ymd from current date d1\")\n        XCTAssertTrue(components1.month == components3.month)\n        XCTAssertTrue(components1.day == components3.day)\n        XCTAssertTrue(components2.hour == components3.hour, \"Should keep the hm from custom date d2\")\n        XCTAssertTrue(components2.minute == components3.minute)\n    }\n    \n    func testFirstDayThisMonth() {\n\t\t\n\t\tlet sndOfMay2015 = Date(timeIntervalSince1970: 1430589737)\n\t\tlet fstOfMay2015 = sndOfMay2015.startOfMonth()\n\t\tlet components = gregorian.dateComponents(ymdhmsUnitFlags, from: fstOfMay2015)\n\t\t\n\t\tXCTAssertTrue(components.year == 2015, \"Test failed, check firstDateThisMonth method\")\n\t\tXCTAssertTrue(components.month == 5, \"Test failed, check firstDateThisMonth method\")\n\t\tXCTAssertTrue(components.day == 1, \"Test failed, check firstDateThisMonth method\")\n\t\tXCTAssertTrue(components.hour == 0, \"Test failed, check firstDateThisMonth method\")\n\t\tXCTAssertTrue(components.minute == 0, \"Test failed, check firstDateThisMonth method\")\n\t\tXCTAssertTrue(components.second == 0, \"Test failed, check firstDateThisMonth method\")\n    }\n\t\n\tfunc testRoundDateUpToNearestQuarter() {\n\t\t\n\t\tvar date = Date(hour: 13, minute: 8)\n\t\tXCTAssertTrue(date.round().compare(Date(hour: 13, minute: 12)) == .orderedSame, \"\")\n\t\t\n\t\tdate = Date(hour: 13, minute: 17)\n\t\tXCTAssertTrue(date.round().compare(Date(hour: 13, minute: 18)) == .orderedSame, \"\")\n\t\t\n\t\tdate = Date(hour: 13, minute: 28)\n\t\tXCTAssertTrue(date.round().compare(Date(hour: 13, minute: 30)) == .orderedSame, \"\")\n        \n        date = Date(hour: 13, minute: 31)\n        XCTAssertTrue(date.round().compare(Date(hour: 13, minute: 36)) == .orderedSame, \"\")\n        \n\t\tdate = Date(hour: 13, minute: 44)\n\t\tXCTAssertTrue(date.round().compare(Date(hour: 13, minute: 48)) == .orderedSame, \"\")\n\t\t\n\t\tdate = Date(hour: 13, minute: 55)\n\t\tXCTAssertTrue(date.round().compare(Date(hour: 14, minute: 0)) == .orderedSame, \"\")\n\t}\n\t\n\tfunc testWeek() {\n\t\tlet date = Date(year: 2016, month: 1, day: 9, hour: 10, minute: 0)\n\t\tlet weekBounds = date.weekBounds()\n\t\tXCTAssertTrue(weekBounds.0.compare(Date(year: 2016, month: 1, day: 4, hour: 0, minute: 0)) == .orderedSame, \"\")\n\t\tXCTAssertTrue(weekBounds.1.compare(Date(year: 2016, month: 1, day: 10, hour: 23, minute: 59, second: 59)) == .orderedSame, \"\")\n\t}\n    \n    func testIsSameDay() {\n        let date1 = Date(year: 2016, month: 1, day: 9, hour: 23, minute: 50)\n        let date2 = Date(year: 2016, month: 1, day: 10, hour: 0, minute: 30)\n        XCTAssertFalse(date1.isSameDayAs(date2))\n    }\n    \n    func testIsAlmostSameHour() {\n        var date1 = Date(year: 2016, month: 1, day: 9, hour: 12, minute: 00)\n        var date2 = Date(year: 2016, month: 1, day: 9, hour: 11, minute: 50)\n        XCTAssert(date1.isAlmostSameHourAs(date2))\n        \n        date1 = Date(year: 2016, month: 1, day: 9, hour: 12, minute: 00)\n        date2 = Date(year: 2016, month: 1, day: 9, hour: 12, minute: 10)\n        XCTAssert(date1.isAlmostSameHourAs(date2))\n        \n        date1 = Date(year: 2016, month: 1, day: 9, hour: 12, minute: 00)\n        date2 = Date(year: 2016, month: 1, day: 9, hour: 12, minute: 11)\n        XCTAssertFalse(date1.isAlmostSameHourAs(date2))\n        \n        date1 = Date(year: 2016, month: 1, day: 9, hour: 12, minute: 00)\n        date2 = Date(year: 2016, month: 1, day: 9, hour: 12, minute: 1)\n        XCTAssert(date1.isAlmostSameHourAs(date2, devianceSeconds: 60.0))\n    }\n\n    func testRoundTo6() {\n        let date = Date(year: 2016, month: 1, day: 9, hour: 12, minute: 14)\n        let roundedDate = date.round()\n        let components = gregorian.dateComponents(ymdhmsUnitFlags, from: roundedDate)\n\n        XCTAssertTrue(components.hour == 12)\n        XCTAssertTrue(components.minute == 18)\n    }\n\n    func testRoundTo30() {\n        let date = Date(year: 2016, month: 1, day: 9, hour: 12, minute: 8)\n        let roundedDate = date.round(minutesPrecision: 30)\n        let components = gregorian.dateComponents(ymdhmsUnitFlags, from: roundedDate)\n\n        XCTAssertTrue(components.hour == 12)\n        XCTAssertTrue(components.minute == 30)\n    }\n\n    func testRoundToNextHour() {\n        let date = Date(year: 2016, month: 1, day: 9, hour: 12, minute: 48)\n        let roundedDate = date.round(minutesPrecision: 30)\n        let components = gregorian.dateComponents(ymdhmsUnitFlags, from: roundedDate)\n\n        XCTAssertTrue(components.hour == 13)\n        XCTAssertTrue(components.minute == 0)\n    }\n}\n"
  },
  {
    "path": "App/Extensions/StringArray.swift",
    "content": "//\n//  StringArray.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 14/05/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nextension String {\n    \n    func toArray() -> [String] {\n        return self.components(separatedBy: \",\")\n    }\n}\n\nextension Array where Iterator.Element == String {\n    \n    func toString() -> String {\n        return self.joined(separator: \",\")\n    }\n}\n"
  },
  {
    "path": "App/Extensions/StringIdGenerator.swift",
    "content": "//\n//  StringIdGenerator.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 03/05/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nextension String {\n    \n    static func generateId (_ length: Int = 20) -> String {\n        \n        let chars = \"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789\"\n        var randomString = \"\"\n        \n        for _ in 0..<length {\n            let randomValue = arc4random_uniform(UInt32(chars.count))\n            randomString += \"\\(chars[chars.index(chars.startIndex, offsetBy: Int(randomValue))])\"\n        }\n        \n        return randomString\n    }\n}\n"
  },
  {
    "path": "App/Extensions/TableViewCell.swift",
    "content": "//\n//  TableView.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 25/03/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\n#if os(iOS)\n    import UIKit\n    typealias TableViewCell = UITableViewCell\n    typealias TableView = UITableView\n#else\n    import Cocoa\n    typealias TableViewCell = NSTableRowView\n    typealias TableView = NSTableView\n#endif\n\nextension TableViewCell {\n    \n    class func register (in tableView: TableView) {\n        return register(in: tableView, type: self)\n    }\n    \n    private class func register<T> (in tableView: TableView, type: T.Type) {\n        #if os(iOS)\n//            return UIStoryboard(name: name, bundle: nil).instantiateViewControllerWithIdentifier(self.className) as! T\n        #else\n            let className = String(describing: self)\n            assert(NSNib(nibNamed: className, bundle: Bundle.main) != nil, \"err\")\n            \n            if let nib = NSNib(nibNamed: className, bundle: Bundle.main) {\n                tableView.register(nib, forIdentifier: NSUserInterfaceItemIdentifier(rawValue: className))\n            }\n        #endif\n    }\n    \n    class func instantiate (in tableView: TableView) -> Self {\n        return instantiate(in: tableView, type: self)\n    }\n    \n    private class func instantiate<T> (in tableView: TableView, type: T.Type) -> T {\n        let className = String(describing: self)\n        #if os(iOS)\n//            return UIStoryboard(name: name, bundle: nil).instantiateViewControllerWithIdentifier(self.className) as! T\n        #else\n            guard let cell = tableView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: className), owner: self) as? T else {\n                fatalError(\"Cell \\(className) might not be registered in thsi tableView\")\n            }\n            return cell\n        #endif\n    }\n}\n"
  },
  {
    "path": "App/Extensions/ViewAutolayout.swift",
    "content": "//\n//  NSViewAutolayout.swift\n//  Spoto\n//\n//  Created by Baluta Cristian on 15/07/15.\n//  Copyright (c) 2015 Baluta Cristian. All rights reserved.\n//\n\n#if os(iOS)\n    import UIKit\n    typealias View = UIView\n#else\n    import Cocoa\n    typealias View = NSView\n#endif\n\nextension View {\n    \n\tfunc removeAutoresizing() {\n\t\tself.translatesAutoresizingMaskIntoConstraints = false\n\t}\n\t\n\tfunc constrainToSuperview() {\n\t\tself.removeAutoresizing()\n\t\tself.constrainToSuperviewWidth()\n\t\tself.constrainToSuperviewHeight()\n\t}\n\t\n\tfunc constrainToSuperviewWidth() {\n\t\tself.removeAutoresizing()\n\t\tlet viewsDictionary = [\"view\": self]\n\t\tself.superview!.addConstraints(NSLayoutConstraint.constraints(\n\t\t\twithVisualFormat: \"H:|-0-[view]-0-|\", options: [], metrics: nil, views: viewsDictionary))\n\t}\n\t\n\tfunc constrainToSuperviewHeight (_ top: CGFloat=0.0, bottom: CGFloat=0.0) {\n\t\tself.removeAutoresizing()\n\t\tlet viewsDictionary = [\"view\": self]\n        let metricsDictionary: [String : NSNumber] = [\"top\": NSNumber(value: Float(top)), \"bottom\": NSNumber(value: Float(bottom))]\n\t\tself.superview!.addConstraints(NSLayoutConstraint.constraints(\n\t\t\twithVisualFormat: \"V:|-top-[view]-bottom-|\", options: [], metrics: metricsDictionary, views: viewsDictionary))\n\t}\n\t\n\tfunc constrainHorizontally (_ leftView: View, rightView: View, distance: CGFloat) {\n\t\tlet viewsDictionary = [\"leftView\": leftView, \"rightView\": rightView]\n\t\tlet metricsDictionary: [String : NSNumber] = [\"distance\": NSNumber(value: Float(distance))]\n\t\tself.addConstraints(NSLayoutConstraint.constraints(\n\t\t\twithVisualFormat: \"H:[leftView]-distance-[rightView]\", options: [], metrics: metricsDictionary, views: viewsDictionary))\n\t}\n\t\n\tfunc constraintVertically (_ topView: View, bottomView: View, distance: CGFloat) {\n\t\tlet viewsDictionary = [\"topView\": topView, \"bottomView\": bottomView]\n\t\tlet metrics: [String : NSNumber] = [\"gap\": NSNumber(value: Float(distance))]\n\t\tself.addConstraints(NSLayoutConstraint.constraints(\n\t\t\twithVisualFormat: \"V:[topView]-gap-[bottomView]\", options: [], metrics: metrics, views: viewsDictionary))\n\t}\n\t\n\tfunc constraintToTop (_ view: View, distance: CGFloat) -> NSLayoutConstraint {\n\t\tlet constraint = NSLayoutConstraint(item: view,\n\t\t\tattribute: topAttribute(), relatedBy: equalRelation(),\n\t\t\ttoItem: self, attribute: topAttribute(), multiplier: 1, constant: distance)\n\t\tself.addConstraint(constraint)\n\t\treturn constraint\n\t}\n\t\n\tfunc constraintToBottom (_ view: View, distance: CGFloat) -> NSLayoutConstraint {\n\t\tlet constraint = NSLayoutConstraint(item: view,\n\t\t\tattribute: bottomAttribute(), relatedBy: equalRelation(),\n\t\t\ttoItem: self, attribute: bottomAttribute(), multiplier: 1, constant: distance)\n\t\tself.addConstraint(constraint)\n\t\treturn constraint\n\t}\n\t\n\tfunc constraintToLeft (_ view: View, distance: CGFloat) -> NSLayoutConstraint {\n\t\tlet constraint = NSLayoutConstraint(item: view,\n\t\t\tattribute: leftAttribute(), relatedBy: equalRelation(),\n\t\t\ttoItem: self, attribute: leftAttribute(), multiplier: 1, constant: distance)\n\t\tself.addConstraint(constraint)\n\t\treturn constraint\n\t}\n\t\n\tfunc constraintToRight (_ view: View, distance: CGFloat) -> NSLayoutConstraint {\n\t\tlet constraint = NSLayoutConstraint(item: view,\n\t\t\tattribute: rightAttribute(), relatedBy: equalRelation(),\n\t\t\ttoItem: self, attribute: rightAttribute(), multiplier: 1, constant: distance)\n\t\tself.addConstraint(constraint)\n\t\treturn constraint\n\t}\n\t\n\tfunc constrainToWidth (_ width: CGFloat) -> NSLayoutConstraint {\n\t\tlet constraint = NSLayoutConstraint(item: self,\n\t\t\tattribute: widthAttribute(), relatedBy: equalRelation(),\n\t\t\ttoItem: nil, attribute: noAttribute(), multiplier: 1, constant: width)\n\t\tself.superview!.addConstraint(constraint)\n\t\treturn constraint\n\t}\n\t\n\tfunc constrainToHeight (_ height: CGFloat) -> NSLayoutConstraint {\n\t\tlet constraint = NSLayoutConstraint(item: self,\n\t\t\tattribute: heightAttribute(), relatedBy: equalRelation(),\n\t\t\ttoItem: nil, attribute: noAttribute(), multiplier: 1, constant: height)\n\t\tself.superview!.addConstraint(constraint)\n\t\treturn constraint\n\t}\n\n    func centerX (_ offset: CGFloat) -> NSLayoutConstraint {\n        let constraint = NSLayoutConstraint(item: self,\n                                            attribute: centerXAttribute(), relatedBy: equalRelation(),\n                                            toItem: self.superview!, attribute: centerXAttribute(), multiplier: 1, constant: offset)\n        self.superview!.addConstraint(constraint)\n        return constraint\n    }\n\n\tfunc centerY (_ offset: CGFloat) -> NSLayoutConstraint {\n\t\tlet constraint = NSLayoutConstraint(item: self,\n\t\t\tattribute: centerYAttribute(), relatedBy: equalRelation(),\n\t\t\ttoItem: self.superview!, attribute: centerYAttribute(), multiplier: 1, constant: offset)\n\t\tself.superview!.addConstraint(constraint)\n\t\treturn constraint\n\t}\n\n    #if os(iOS)\n    func leftAttribute() -> NSLayoutAttribute { return NSLayoutAttribute.left }\n    func rightAttribute() -> NSLayoutAttribute { return NSLayoutAttribute.right }\n    func topAttribute() -> NSLayoutAttribute { return NSLayoutAttribute.top }\n    func bottomAttribute() -> NSLayoutAttribute { return NSLayoutAttribute.bottom }\n    func widthAttribute() -> NSLayoutAttribute { return NSLayoutAttribute.width }\n    func heightAttribute() -> NSLayoutAttribute { return NSLayoutAttribute.height }\n    func centerXAttribute() -> NSLayoutAttribute { return NSLayoutAttribute.centerX }\n    func centerYAttribute() -> NSLayoutAttribute { return NSLayoutAttribute.centerY }\n    func noAttribute() -> NSLayoutAttribute { return NSLayoutAttribute.notAnAttribute }\n    func equalRelation() -> NSLayoutRelation { return NSLayoutRelation.equal }\n    #else\n    func leftAttribute() -> NSLayoutConstraint.Attribute { return NSLayoutConstraint.Attribute.left }\n    func rightAttribute() -> NSLayoutConstraint.Attribute { return NSLayoutConstraint.Attribute.right }\n    func topAttribute() -> NSLayoutConstraint.Attribute { return NSLayoutConstraint.Attribute.top }\n    func bottomAttribute() -> NSLayoutConstraint.Attribute { return NSLayoutConstraint.Attribute.bottom }\n    func widthAttribute() -> NSLayoutConstraint.Attribute { return NSLayoutConstraint.Attribute.width }\n    func heightAttribute() -> NSLayoutConstraint.Attribute { return NSLayoutConstraint.Attribute.height }\n    func centerXAttribute() -> NSLayoutConstraint.Attribute { return NSLayoutConstraint.Attribute.centerX }\n    func centerYAttribute() -> NSLayoutConstraint.Attribute { return NSLayoutConstraint.Attribute.centerY }\n    func noAttribute() -> NSLayoutConstraint.Attribute { return NSLayoutConstraint.Attribute.notAnAttribute }\n    func equalRelation() -> NSLayoutConstraint.Relation { return NSLayoutConstraint.Relation.equal }\n    #endif\n}\n"
  },
  {
    "path": "App/Extensions/ViewController.swift",
    "content": "//\n//  ViewController.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 06/05/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\n\nextension NSViewController {\n    \n    func removeFromSuperview() {\n        self.view.removeFromSuperview()\n    }\n}\n"
  },
  {
    "path": "App/Extensions/ViewControllerStoryboard.swift",
    "content": "//\n//  UIViewControllerStoryboard.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 02/05/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\n#if os(iOS)\n    import UIKit\n    typealias ViewController = UIViewController\n#else\n    import Cocoa\n    typealias ViewController = NSViewController\n#endif\n\nextension ViewController {\n    \n    class func instantiateFromStoryboard (_ name: String) -> Self {\n        return  instantiateFromStoryboard(name, type: self)\n    }\n    \n    private class func instantiateFromStoryboard<T> (_ name: String, type: T.Type) -> T {\n        #if os(iOS)\n            return UIStoryboard(name: name, bundle: nil).instantiateViewControllerWithIdentifier(self.className) as! T\n        #else\n            return NSStoryboard(name: name, bundle: nil).instantiateController(withIdentifier: String(describing: self)) as! T\n        #endif\n    }\n}\n"
  },
  {
    "path": "App/Extensions/ViewXib.swift",
    "content": "//\n//  ViewXib.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 18/04/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\n#if os(iOS)\nimport UIKit\ntypealias AView = UIView\n#else\nimport Cocoa\ntypealias AView = NSView\n#endif\n\nextension AView {\n    \n    class func instantiateFromXib() -> Self {\n        return  instantiateFromXib(type: self)\n    }\n    \n    private class func instantiateFromXib<T> (type: T.Type) -> T {\n        #if os(iOS)\n//        return UIStoryboard(name: name, bundle: nil).instantiateViewControllerWithIdentifier(self.className) as! T\n        #else\n        var view: T?\n        var views: NSArray?\n        Bundle.main.loadNibNamed(String(describing: T.self),\n                                 owner: nil,\n                                 topLevelObjects: &views)\n        if let v = views {\n            for _v in v {\n                if let __v = _v as? T {\n                    view = __v\n                }\n            }\n        }\n        return view!\n        #endif\n    }\n}\n"
  },
  {
    "path": "App/Notifications/ComputerWakeUpInteractor.swift",
    "content": "//\n//  ComputerWakeUpInteractor.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 27/12/15.\n//  Copyright © 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nclass ComputerWakeUpInteractor: RepositoryInteractor {\n    \n    var settings: Settings!\n    let typeEstimator = TaskTypeEstimator()\n    let reader: ReadTasksInteractor!\n    \n    init (repository: Repository, remoteRepository: Repository?, settings: Settings) {\n        self.settings = settings\n        reader = ReadTasksInteractor(repository: repository, remoteRepository: remoteRepository)\n        super.init(repository: repository, remoteRepository: remoteRepository)\n    }\n    \n    func runWith (lastSleepDate: Date?, currentDate: Date) {\n\t\t\n        guard let lastSleepDate = lastSleepDate else {\n            return\n        }\n        if let type = estimationForDate(lastSleepDate, currentDate: currentDate) {\n            if type == .startDay {\n                if settings.settingsTracking.trackStartOfDay {\n                    let startDate = settings.settingsTracking.startOfDayTime.dateByKeepingTime()\n                    if currentDate > startDate {\n                        let task = Task(endDate: currentDate, type: .startDay)\n                        save(task: task)\n                    }\n                }\n            } else if (type == .scrum && settings.settingsTracking.trackScrum) || (type == .lunch && settings.settingsTracking.trackLunch) {\n                \n                var task = Task(endDate: currentDate, type: type)\n                task.startDate = lastSleepDate\n                save(task: task)\n            }\n        }\n    }\n    \n    internal func estimationForDate (_ date: Date, currentDate: Date) -> TaskType? {\n        \n\t\tlet existingTasks = reader.tasksInDay(currentDate)\n        \n        guard existingTasks.count > 0 else {\n            return TaskType.startDay\n        }\n        \n        let estimatedType: TaskType = typeEstimator.taskTypeAroundDate(date, withSettings: settings)\n        \n        switch estimatedType {\n        case .scrum:\n            if !TaskFinder().scrumExists(existingTasks) {\n                return TaskType.scrum\n            }\n        case .lunch:\n            if !TaskFinder().lunchExists(existingTasks) {\n                return TaskType.lunch\n            }\n        case .meeting:\n            if settings.settingsTracking.trackMeetings {\n                return TaskType.meeting\n            }\n        default:\n            return nil\n        }\n        return nil\n\t}\n    \n    internal func save (task: Task) {\n        let saveInteractor = TaskInteractor(repository: localRepository, remoteRepository: self.remoteRepository)\n        saveInteractor.saveTask(task, allowSyncing: true, completion: { savedTask in\n            guard let task = savedTask else {\n                return\n            }\n            InternalNotifications.notifyAboutNewlyAddedTask(task)\n        })\n    }\n}\n"
  },
  {
    "path": "App/Notifications/ComputerWakeUpInteractorTests.swift",
    "content": "//\n//  ComputerWakeUpInteractorTests.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 26/11/2016.\n//  Copyright © 2016 Imagin soft. All rights reserved.\n//\n\nimport XCTest\n@testable import Jirassic_no_cloud\n\nclass ComputerWakeUpInteractorMock: ComputerWakeUpInteractor {\n    var log_called = false\n    var taskType_received: TaskType?\n    override func save (task: Task) {\n        log_called = true\n        taskType_received = task.taskType\n    }\n}\n\nclass ComputerWakeUpInteractorTests: XCTestCase {\n    \n    func testScrumAndLunch() {\n        \n        let repository = InMemoryCoreDataRepository()\n        let settings = Settings(enableBackup: false, settingsTracking: SettingsTracking(autotrack: true, autotrackingMode: TrackingMode.auto, trackLunch: true, trackScrum: true, trackMeetings: true, trackStartOfDay: true, startOfDayTime: Date(hour: 9, minute: 0), endOfDayTime: Date(hour: 17, minute: 0), lunchTime: Date(hour: 12, minute: 30), scrumTime: Date(hour: 10, minute: 30), minSleepDuration: 10), settingsBrowser: SettingsBrowser(trackCodeReviews: true, trackWastedTime: true, minCodeRevDuration: 5, codeRevLink: \"\", minWasteDuration: 5, wasteLinks: []))\n        \n        // Insert start of the day otherwise scrum can't be detected\n        let task = Task(endDate: Date(hour: 9, minute: 0), type: .startDay)\n        let saveInteractor = TaskInteractor(repository: repository, remoteRepository: nil)\n        saveInteractor.saveTask(task, allowSyncing: false, completion: { task in })\n        \n        let interactor = ComputerWakeUpInteractorMock(repository: repository, remoteRepository: nil, settings: settings)\n        \n        interactor.runWith(lastSleepDate: Date(hour: 10, minute: 30), currentDate: Date(hour: 10, minute: 55))\n        XCTAssert(interactor.log_called)\n        XCTAssert(interactor.taskType_received == .scrum)\n        \n        interactor.log_called = false\n        interactor.runWith(lastSleepDate: Date(hour: 12, minute: 45), currentDate: Date(hour: 13, minute: 30))\n        XCTAssert(interactor.log_called)\n        XCTAssert(interactor.taskType_received == .lunch)\n    }\n}\n"
  },
  {
    "path": "App/Parsing/ParseGitBranch.swift",
    "content": "//\n//  ParseGitBranch.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 27/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nclass ParseGitBranch {\n    \n    private let taskIdEreg = \"(([A-Z])+-([0-9])+)\"\n    private let branchFromGitLogEreg = \"origin(/([A-Za-z0-9_-])+)\"\n    private let branchFromGitMergeEreg = \"from ([A-Za-z0-9_-])+ to\"\n    \n    var branchName: String\n    \n    init(branchName: String) {\n\n        self.branchName = branchName\n        \n        if let branch = self.parseGitMerge(branchName) {\n            self.branchName = branch\n        }\n        // Eliminate folders\n        self.branchName = self.branchName.components(separatedBy: \"/\").last?.components(separatedBy: \",\").first ?? self.branchName\n//        else if let branch = self.parseGitLog(branchName) {\n//            self.branchName = branch\n//        }\n    }\n    \n    private func parseGitLog(_ branchName: String) -> String? {\n        \n        guard let regex = try? NSRegularExpression(pattern: self.branchFromGitLogEreg, options: []) else {\n            return nil\n        }\n        let match = regex.firstMatch(in: branchName, options: [], range: NSRange(location: 0, length: branchName.count))\n        if let _ = match {\n            // TODO: try this with ereg to eliminate the folders before a branch name and ignore what follows after spaces\n            return branchName.components(separatedBy: \"/\").last?.components(separatedBy: \", \").first\n//            return (branchName as NSString).substring(with: match.range).replacingOccurrences(of: \"origin/\", with: \"\")\n        }\n        return nil\n    }\n    \n    private func parseGitMerge(_ branchName: String) -> String? {\n        \n        guard let regex = try? NSRegularExpression(pattern: self.branchFromGitMergeEreg, options: []) else {\n            return nil\n        }\n        let match = regex.firstMatch(in: branchName, options: [], range: NSRange(location: 0, length: branchName.count))\n        if let match = match {\n            return (branchName as NSString).substring(with: match.range)\n                    .replacingOccurrences(of: \"from \", with: \"\")\n                    .replacingOccurrences(of: \" to\", with: \"\")\n        }\n        return nil\n    }\n    \n    // Extracts from the branch name the taskNumber if exists\n    func taskNumber() -> String? {\n        \n        var taskNumber: String? = nil\n        guard let regex = try? NSRegularExpression(pattern: self.taskIdEreg, options: []) else {\n            return taskNumber\n        }\n        let match = regex.firstMatch(in: branchName, options: [], range: NSRange(location: 0, length: branchName.count))\n        if let match = match {\n            taskNumber = (branchName as NSString).substring(with: match.range)\n        }\n        \n        return taskNumber\n    }\n    \n    // Extracts from the branch name what is left after taskNumber is extracted, and dashes are removed\n    func taskTitle() -> String {\n        \n        let taskNumber = self.taskNumber()\n        return branchName.replacingOccurrences(of: taskNumber ?? \"\", with: \"\")\n            .replacingOccurrences(of: \"-\", with: \" \")\n            .replacingOccurrences(of: \"_\", with: \" \")\n            .trimmingCharacters(in: NSCharacterSet.whitespaces)\n    }\n}\n"
  },
  {
    "path": "App/Parsing/ParseGitBranchTests.swift",
    "content": "//\n//  ParseGitBranchTests.swift\n//  JirassicTests\n//\n//  Created by Cristian Baluta on 28/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport XCTest\n@testable import Jirassic_no_cloud\n\nclass ParseGitBranchTests: XCTestCase {\n\n    func test() {\n        \n        var parser = ParseGitBranch(branchName: \"AA-1234-branch-name\")\n        XCTAssert(parser.taskNumber() == \"AA-1234\")\n        XCTAssert(parser.taskTitle() == \"branch name\")\n        \n        parser = ParseGitBranch(branchName: \"AA-1234__branch_name\")\n        XCTAssert(parser.taskNumber() == \"AA-1234\")\n        XCTAssert(parser.taskTitle() == \"branch name\")\n        \n        parser = ParseGitBranch(branchName: \"some_branch_name\")\n        XCTAssertNil(parser.taskNumber())\n        XCTAssert(parser.taskTitle() == \"some branch name\")\n    }\n    \n    func testCommitMessage() {\n        \n        let parser = ParseGitBranch(branchName: \"APP-1234 Some commit message\")\n        XCTAssert(parser.taskNumber() == \"APP-1234\")\n        XCTAssert(parser.taskTitle() == \"Some commit message\")\n    }\n    \n    func testMergeCommitMessage() {\n        \n        let parser = ParseGitBranch(branchName: \"Merge pull request #619 in MYAPP/proj from AA-1234_some_branch_name to master;\")\n        XCTAssert(parser.taskNumber() == \"AA-1234\")\n        XCTAssert(parser.taskTitle() == \"some branch name\")\n\n        // TODO: Not sur ethis case exists\n//        parser = ParseGitBranch(branchName: \"Merge pull request #619 in MYAPP/proj from origin/AA-1234_some_branch_name to master;\")\n//        XCTAssert(parser.taskNumber() == \"AA-1234\")\n//        XCTAssert(parser.taskTitle() == \"some branch name\")\n    }\n    \n    func testBranchesGivenByGitLog() {\n        \n        var parser = ParseGitBranch(branchName: \"origin/some_branch_name, some_branch_name\")\n        XCTAssertNil(parser.taskNumber())\n        XCTAssert(parser.taskTitle() == \"some branch name\")\n        \n        parser = ParseGitBranch(branchName: \"origin/AA-1234_some_branch_name\")\n        XCTAssert(parser.taskNumber() == \"AA-1234\")\n        XCTAssert(parser.taskTitle() == \"some branch name\")\n        \n        parser = ParseGitBranch(branchName: \"origin/bugfix/AA-1234_some_branch_name\")\n        XCTAssert(parser.taskNumber() == \"AA-1234\")\n        XCTAssert(parser.taskTitle() == \"some branch name\")\n\n        parser = ParseGitBranch(branchName: \"bugfix/AA-1234_some_branch_name\")\n        XCTAssert(parser.taskNumber() == \"AA-1234\")\n        XCTAssert(parser.taskTitle() == \"some branch name\")\n    }\n}\n"
  },
  {
    "path": "App/Reports/CreateDayReport.swift",
    "content": "//\n//  CreateDayReport.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 13.06.2024.\n//  Copyright © 2024 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nclass CreateDayReport {\n\n    private let createReport = CreateReport()\n\n    func stringReports (_ reports: [Report]) -> String {\n\n        var str = \"\"\n        for report in reports {\n            let notes: [String] = report.notes.compactMap { note in\n                guard note.count > 0 else {\n                    return nil\n                }\n                return \"• \\(note)\"\n            }\n            let notesJoined = notes.joined(separator: \"\\n\")\n            var taskNumber = report.taskNumber == \"coderev\" ? \"Code reviews and fixes\" : report.taskNumber\n            taskNumber = taskNumber == \"learning\" ? \"Learning\" : taskNumber\n            taskNumber = taskNumber == \"meeting\" ? \"Meetings\" : taskNumber\n            var title = report.title\n                .replacingOccurrences(of: \"_\", with: \" \")\n                .trimmingCharacters(in: .whitespacesAndNewlines)\n            if report.taskNumber == \"learning\" || report.taskNumber == \"meeting\" {\n                title = \"\"\n            }\n\n            var note = \"(\\(report.duration.secToHours)) \\(taskNumber) \\(title)\"\n            if report.notes.count > 0 {\n                for n in notes {\n                    note += \"\\n      \\(n)\"\n                }\n            }\n            str += note + \"\\n\"\n        }\n        return str\n    }\n\n}\n"
  },
  {
    "path": "App/Reports/CreateMonthReport.swift",
    "content": "//\n//  CreateMonthReport.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 09/10/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nclass CreateMonthReport {\n\n    private let createReport = CreateReport()\n\n    /// Returns reports collected from all days in the month\n    /// @parameters\n    /// tasks - All tasks in a month\n    /// targetHoursInDay - How many hours in a day\n    /// roundHours - Round the reports to fixed hours\n    func reports (fromTasks tasks: [Task],\n                  targetHoursInDay: Double?,\n                  roundHours: Bool) -> (byDays: [[Report]], byTasks: [Report]) {\n\n        guard tasks.count > 1 else {\n            return (byDays: [], byTasks: [])\n        }\n        // When we find a startDay we keep its date and start adding tasks in that day till endDay found or new startDay found\n        // Tasks between end and start are invalid\n        var startDayDate: Date?\n\n        // Group tasks by days\n        var tasksByDay = [[Task]]()\n        var tasksInDay = [Task]()\n        for task in tasks {\n            if let date = startDayDate {\n                // Start of day already found\n                // Iterate till endDay or new startDay found\n                // Days without a .startDay are ignored\n                if task.taskType == .endDay {\n                    tasksInDay.append(task)\n                    tasksByDay.append(tasksInDay)\n                    tasksInDay = []\n                    startDayDate = nil\n                } else if !date.isSameDayAs(task.endDate) {\n                    // This task is from the next day\n                    tasksByDay.append(tasksInDay)\n                    tasksInDay = [task]\n                    startDayDate = task.taskType == .startDay ? task.endDate : nil\n                } else {\n                    tasksInDay.append(task)\n                }\n            } else {\n                // If no start of day found yet iterate till found\n                if task.taskType == .startDay {\n                    startDayDate = task.endDate\n                    tasksInDay = [task]\n                }\n            }\n            if task.objectId == tasks.last?.objectId && tasksInDay.count > 0 {\n                tasksByDay.append(tasksInDay)\n            }\n        }\n\n        // Iterate over days and create reports\n        var reportsByDay = [[Report]]()\n        for tasks in tasksByDay {\n            let report = createReport.reports(fromTasks: tasks, targetHoursInDay: targetHoursInDay)\n            reportsByDay.append(report)\n        }\n\n        // Group reports by task number\n        // Acumulate durations\n        // Join notes but only for meetings\n        var reportsByTaskNumber = [String: Report]()\n        for day in reportsByDay {\n            var d = 0.0\n            for report in day {\n                d += report.duration\n                var monthReport = reportsByTaskNumber[report.taskNumber]\n                if monthReport == nil {\n                    reportsByTaskNumber[report.taskNumber] = Report(taskNumber: report.taskNumber,\n                                                                    title: report.title,\n                                                                    notes: [\"meeting\", \"learning\"].contains(report.taskNumber) ? report.notes : [],\n                                                                    duration: report.duration)\n                } else {\n                    if [\"meeting\", \"learning\"].contains(report.taskNumber)  {\n                        monthReport!.notes = Array(Set(monthReport!.notes + report.notes))\n                    }\n                    monthReport!.duration += report.duration\n                    reportsByTaskNumber[report.taskNumber] = monthReport\n                }\n            }\n        }\n\n        return (byDays: reportsByDay, byTasks: Array(reportsByTaskNumber.values))\n    }\n\n    // List of reports by task number\n    func joinReports (_ reports: [Report]) -> (notes: String, totalDuration: Double) {\n        \n        var notes = \"\"\n        var totalDuration = 0.0\n        for report in reports {\n            totalDuration += report.duration\n            notes += \"• \\(report.taskNumber)\\(report.title) (\" + report.duration.secToHoursAndMin + \")\\n\"\n            if report.notes.count > 0 {\n                for note in report.notes {\n                    notes += \"    - \\(note)\\n\"\n                }\n            }\n        }\n        return (notes: notes, totalDuration: totalDuration)\n    }\n    \n    func htmlReports (_ reports: [Report]) -> String {\n        \n        var notes = \"\"\n        var totalDuration = 0.0\n        for report in reports {\n            totalDuration += report.duration\n            var note = \"\\(report.taskNumber) \\(report.title)\"\n            if report.notes.count > 0 {\n                note = \"<p>\\(note)</p>\"\n                note += \"<ul>\"\n                for n in report.notes {\n                    note += \"<li>\\(n)</li>\"\n                }\n                note += \"</ul>\"\n            }\n            notes += \"<tr><td style=\\\"text-align: left; padding-left: 10px;\\\">\\(note)</td><td>\\(report.duration.secToHoursAndMin)</td></tr>\\n\"\n        }\n        return notes\n    }\n\n    func csvReports (_ reports: [Report]) -> String {\n\n        let headers = [\n            \"Issue Key\", \"Issue summary\", \"Hours\", \"Work date\", \"Username\", \"Full name\",\n            \"Period\", \"Account Key\", \"Account Name\", \"Activity Name\", \"Component\", \"All Components\",\n            \"Version Name\", \"Issue Type\", \"Issue Status\", \"Project Key\", \"Project Name\",\n            \"Work Description\", \"Parent Key\", \"Reporter\", \"External Hours\", \"Billed Hours\",\n            \"Issue Original Estimate\", \"Issue Remaining Estimate\", \"Epic Link\",\n            \"Account [deprecated, this field is no longer being used]\", \"Office Space\", \"External issue ID\",\n            \"External issue ID\", \"Department\", \"Location\", \"External issue summary\", \"External Issue ID\",\n            \"External Issue ID\"\n        ]\n        var csv = headers.joined(separator: \";\") + \"\\n\"\n        for report in reports {\n            var note = \"\\(report.taskNumber) \\(report.title)\"\n            var component = \"\"\n            if report.notes.count > 0 {\n                for n in report.notes {\n                    csv += \";;\\(report.duration.secToHours);;;;;;;;\\(component);;;;;;GS1.1_BOSCH_eBike;\\(note);;;;;;;;;;;;;;;;\"\n                    csv += \"\\n\"\n                }\n            } else {\n                csv += \";;\\(report.duration.secToHours);;;;;;;;;;;;;;GS1.1_BOSCH_eBike;\\(note);;;;;;;;;;;;;;;;\"\n                csv += \"\\n\"\n            }\n        }\n        return csv\n    }\n}\n"
  },
  {
    "path": "App/Reports/CreateMonthReportTests.swift",
    "content": "//\n//  CreateMonthReportTests.swift\n//  JirassicTests\n//\n//  Created by Cristian Baluta on 09/10/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport XCTest\n@testable import Jirassic_no_cloud\n\nclass CreateMonthReportTests: XCTestCase {\n\n    var tasks = [Task]()\n    let kLunchLength = Double(2760)//46min ~ 45min\n    let targetHoursInDay = 8.0.hoursToSec\n    \n    override func setUp() {\n\n        // day 1\n        let str1 = \"|10.10||||1;\" +\n            \"|10.25|Code reviews part 1|coderev||8;\" +\n            \"10.30|10.47||||2;\" +\n            \"12.45|13.51||||3;\" +\n            \"|14.5|Note 1|TASK-1||0;\" +\n            \"|14.50|Note 2|TASK-2||0;\" +\n            \"16.10|16.36|Some meeting|meeting||4;\" +\n            \"|18.0|Note 3|TASK-3||0;\" +\n            \"|18.0||||9\"// end day\n        tasks = buildTasks(str1, date: \"2018.10.10\")\n        \n        // Add a meeting that is outside the start-end, it should be ignored by reports\n        tasks += buildTasks(\"18.30|19.0|Meeting|calendar meeting||10\", date: \"2018.10.10\")\n        \n        // day 2 - without endDay\n        let str2 = \"|9.20||||1;\" +\n            \"|10.25|Code reviews part 1|coderev||8;\" +\n            \"10.30|10.55||||2;\" +\n            \"12.45|13.51||||3;\" +\n            \"|14.5|Note 1|TASK-1||0;\" +\n            \"|14.50|Note 4|TASK-4||0;\" +\n            \"|17.30|Note 5|TASK-5||0\"\n        tasks += buildTasks(str2, date: \"2018.10.11\")\n        \n        // day 3 - with endDay\n        let str3 = \"|10.20||||1;\" +\n            \"|14.5|Note 1|TASK-1||0;\" +\n            \"|18.30||||9\"\n        tasks += buildTasks(str3, date: \"2018.10.12\")\n    }\n\n    override func tearDown() {\n        tasks = []\n        super.tearDown()\n    }\n\n    func testGroupByTaskNumber() {\n\n        let reports = CreateMonthReport().reports(fromTasks: tasks, targetHoursInDay: targetHoursInDay, roundHours: false)\n        var totalDuration = 0.0\n        XCTAssert(reports.byDays.count == 3, \"There should be only 8 unique task numbers. Lunch and waste are ignored\")\n        XCTAssert(reports.byTasks.count == 8, \"There should be only 8 unique task numbers. Lunch and waste are ignored\")\n        for i1 in 0..<reports.byTasks.count {\n            totalDuration += reports.byTasks[i1].duration\n            for i2 in 0..<reports.byTasks.count {\n                if i1 != i2 {\n                    XCTAssertFalse(reports.byTasks[i1].taskNumber == reports.byTasks[i2].taskNumber, \"Duplicate taskNumber found, they should be unique\")\n                }\n            }\n        }\n        XCTAssert(totalDuration == targetHoursInDay*3, \"Duration should be 8*3 hours\")\n    }\n}\n"
  },
  {
    "path": "App/Reports/CreateReport.swift",
    "content": "//\n//  CreateReport.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 28/03/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nclass CreateReport {\n    \n    func reports (fromTasks tasks: [Task], targetHoursInDay: Double?) -> [Report] {\n\t\t\n        // .endDay task is not part of reports\n        let filteredTasks = tasks.filter({ $0.taskType != .endDay })\n\t\tguard filteredTasks.count > 1 else {\n\t\t\treturn []\n        }\n        var processedTasks = splitOverlappingTasks(filteredTasks)\n        processedTasks = removeUntrackableTasks(processedTasks)\n        guard processedTasks.count > 1 else {\n            return []\n        }\n        processedTasks = addExtraTimeToTasks(processedTasks, targetHoursInDay: targetHoursInDay)\n        let groups = groupByTaskNumber(processedTasks)\n        let reports = reportsFromGroups(groups.groups)\n        \n        return sortReports(reports, withOrder: groups.order)\n\t}\n    \n    func toString (_ reports: [Report]) -> String  {\n        let lines = reports.map({ (_ report: Report) -> String in\n            let title = self.title(from: report)\n            let notes = report.notes.map { (note) -> String in\n                return \"• \\(note)\"\n            }\n            let body = notes.joined(separator: \"\\n\")\n            return title + \"\\n\" + body\n        })\n        return lines.joined(separator: \"\\n\\n\")\n    }\n    \n    private func title (from report: Report) -> String {\n        let taskNumber = report.taskNumber\n        let taskTitle = report.title\n        switch taskNumber {\n        case \"meeting\": return \"Meetings:\"\n        case \"coderev\": return \"\"\n        default:\n            switch taskTitle {\n            case \"\": return taskNumber\n            default: return taskNumber + \" - \" + taskTitle\n            }\n        }\n    }\n}\n\nextension CreateReport {\n    \n    private func splitOverlappingTasks (_ tasks: [Task]) -> [Task] {\n        \n        var arr = [Task]()\n        var task = tasks.first!\n        var previousEndDate = task.endDate\n        arr.append(task)\n        \n        for i in 1..<tasks.count {\n            \n            task = tasks[i]\n            \n            if let startDate = task.startDate {\n                // Tasks with begining and ending defined are inlined tasks.\n                // Extract them in front of the overlapped task. This will take from the time of the actual task\n                let duration = task.endDate.timeIntervalSince(startDate)\n                task.startDate = nil\n                task.endDate = previousEndDate.addingTimeInterval(duration)\n                arr.append(task)\n                previousEndDate = task.endDate\n//                print(\"inlined \\(startDate)\")\n            } else {\n                arr.append(task)\n                previousEndDate = task.endDate\n            }\n        }\n        return arr\n    }\n    \n    private func removeUntrackableTasks (_ tasks: [Task]) -> [Task] {\n        \n        var arr = [Task]()\n        var untrackedDuration = 0.0\n        var previousTaskOriginalEndDate = tasks.first!.endDate\n        \n        for task in tasks {\n            if isTrackingAllowed(taskType: task.taskType) {\n                var tempTask = task\n                tempTask.endDate = task.endDate.addingTimeInterval(-untrackedDuration)\n                arr.append(tempTask)\n            } else {\n                untrackedDuration += task.endDate.timeIntervalSince(previousTaskOriginalEndDate)\n            }\n            previousTaskOriginalEndDate = task.endDate\n        }\n        return arr\n    }\n    \n    private func addExtraTimeToTasks (_ tasks: [Task], targetHoursInDay: Double?) -> [Task] {\n        \n        // How many tasks should be adjusted\n        let numberOfTasksToAdjust = tasks.filter({ isAdjustable(taskType: $0.taskType) }).count\n        \n        guard numberOfTasksToAdjust > 0 else {\n            return tasks\n        }\n        \n        // Calculate the diff to targetHoursInDay\n        let workedTime = tasks.last!.endDate.timeIntervalSince(tasks.first!.endDate)\n        let requiredHours = targetHoursInDay != nil ? targetHoursInDay! : workedTime\n        let missingTime = requiredHours - workedTime\n        let extraTimePerTask = ceil( Double( Int(missingTime) / numberOfTasksToAdjust))\n        \n        var roundedTasks = [Task]()\n        \n        var task = tasks.first!\n        task.endDate = targetHoursInDay == nil ? task.endDate : task.endDate.round()\n        roundedTasks.append(task)\n        var previousDate = task.endDate\n        var extraTimeToAdd = 0.0\n        \n        // First task is start of the day and should not be modified\n        for i in 1..<tasks.count-1 {\n            \n            task = tasks[i]\n            \n            if targetHoursInDay != nil && isAdjustable(taskType: task.taskType) {\n                extraTimeToAdd += extraTimePerTask\n            }\n            \n            task.endDate = targetHoursInDay == nil\n                ? task.endDate.addingTimeInterval(extraTimeToAdd)\n                : task.endDate.addingTimeInterval(extraTimeToAdd).round()\n            task.startDate = previousDate\n            previousDate = task.endDate\n            \n            roundedTasks.append(task)\n        }\n        \n        // Handle the last task separately, add the remaining time till targetHoursInDay\n        task = tasks.last!\n        task.endDate = roundedTasks.first!.endDate.addingTimeInterval(requiredHours)\n        task.startDate = previousDate\n        roundedTasks.append(task)\n        \n        return roundedTasks\n    }\n    \n    private func groupByTaskNumber (_ tasks: [Task]) -> (groups: [String: [Task]], order: [String]) {\n        \n        var order = [String]()\n        var groups = [String: [Task]]()\n        for task in tasks {\n            guard isDisplayingAllowed(taskType: task.taskType) else {\n                continue\n            }\n            let taskNumber = task.taskNumber != nil && task.taskNumber != \"\"\n                ? task.taskNumber!\n                : (task.taskType.defaultTaskNumber ?? \"\")\n            // Save to dictionary\n            var tgroup: [Task]? = groups[taskNumber]\n            if tgroup == nil {\n                tgroup = [Task]()\n                groups[taskNumber] = tgroup\n            }\n            tgroup?.append(task)\n            groups[taskNumber] = tgroup!\n            // Save order\n            if !order.contains(taskNumber) {\n                order.append(taskNumber)\n            }\n        }\n        \n        return (groups: groups, order: order)\n    }\n    \n    private func reportsFromGroups (_ groups: [String: [Task]]) -> [Report] {\n        \n        var reportsMap = [String: Report]()\n        \n        for (taskNumber, tasks) in groups {\n            \n            for task in tasks {\n                \n                guard isTrackingAllowed(taskType: task.taskType) else {\n                    continue\n                }\n                guard let startDate = task.startDate else {\n                    // This shouldn't happen. It can happen only if there's no start of the day\n                    continue\n                }\n                \n                var report = reportsMap[taskNumber]\n                \n                if report == nil {\n                    // New reports\n                    var title = task.taskTitle\n                    let comps = title?.components(separatedBy: taskNumber)\n                    title = comps?.last\n                    title = title?.replacingOccurrences(of: \"_\", with: \" \")\n                    title = title?.replacingOccurrences(of: \"-\", with: \" \")\n                    var notes = [String]()\n                    if let taskNotes = task.notes {\n                        notes = [taskNotes]\n                    }\n                    report = Report(\n                        taskNumber: taskNumber,\n                        title: title ?? \"\",\n                        notes: notes,\n                        duration: task.endDate.timeIntervalSince(startDate)\n                    )\n                } else {\n                    // Update existing reports\n                    report!.duration += task.endDate.timeIntervalSince(task.startDate!)\n                    if let taskNotes = task.notes {\n                        var notes = report!.notes\n                        if !notes.contains(taskNotes) {\n                            notes.append(taskNotes)\n                            report!.notes = notes\n                        }\n                    }\n                }\n                reportsMap[taskNumber] = report\n            }\n        }\n        \n        return Array(reportsMap.values)\n\t}\n    \n    private func sortReports (_ reports: [Report], withOrder order: [String]) -> [Report] {\n        \n        var orderedReports = [Report]()\n        \n        // TODO: sort the array with short lambdas if possible\n//        let arr = reports.sorted { reports.index(of: $0) < order.index(of: $1.1) }\n        \n        for taskNumber in order {\n            for report in reports {\n                if report.taskNumber == taskNumber {\n                    orderedReports.append(report)\n                }\n            }\n        }\n        \n        return orderedReports\n    }\n}\n\nextension CreateReport {\n    \n    private func isTrackingAllowed (taskType: TaskType) -> Bool {\n        switch taskType {\n            case .lunch, .waste: return false\n            default: return true\n        }\n    }\n    \n    /// Returns if the duration of this task type is adjustable\n    private func isAdjustable (taskType: TaskType) -> Bool {\n        switch taskType {\n            case .startDay, .scrum, .meeting, .learning, .calendar: return false\n            default: return true\n        }\n    }\n    \n    private func isDisplayingAllowed (taskType: TaskType) -> Bool {\n        return taskType != .startDay\n    }\n}\n"
  },
  {
    "path": "App/Reports/CreateReportTests.swift",
    "content": "//\n//  CreateReportTests.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 01/06/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport XCTest\n@testable import Jirassic_no_cloud\n\nfunc buildTasks(_ str: String, date: String = \"2018.10.10\") -> [Task] {\n    var tasks = [Task]()\n    // startDate: Date? | endDate: Date | notes: String? | taskNumber: String? | taskTitle: String? | taskType: TaskType\n    let lines =  str.components(separatedBy: \";\")\n    for line in lines {\n        let comps = line.components(separatedBy: \"|\")\n        \n        let dateFormatter = DateFormatter()\n        dateFormatter.dateFormat = \"YYYY.MM.dd.HH.mm\"\n        let endDate = dateFormatter.date(from: date + \".\" + comps[1])\n        \n        var task = Task(endDate: endDate!, type: TaskType(rawValue: Int(comps[5])!)!)\n        \n        if comps[0] != \"\" {\n            task.startDate = dateFormatter.date(from: date + \".\" + comps[0])\n        }\n        // notes\n        if comps[2] != \"\" {\n            task.notes = comps[2]\n        }\n        // taskNumber\n        if comps[3] != \"\" {\n            task.taskNumber = comps[3]\n        }\n        // taskTitle\n        if comps[4] != \"\" {\n            task.taskTitle = comps[4]\n        }\n        tasks.append(task)\n    }\n    return tasks\n}\n\nclass CreateReportTests: XCTestCase {\n    \n    let report = CreateReport()\n\tvar tasks = [Task]()\n\tlet kLunchLength = Double(2760)//46min ~ 45min\n    let targetHoursInDay = 8.0.hoursToSec\n\t\n    override func setUp() {\n        super.setUp()\n        \n        let str = \"|10.10||||1;\" +\n            \"|10.25|Code reviews part 1|coderev||8;\" +\n            \"10.30|10.47||||2;\" +\n            \"12.45|13.51||||3;\" +\n            \"|14.5|Note 2|APP-2||0;\" +// begins before the scrum but ends after the scrum. Subtract the scrum duration\n            \"|14.50|Note 3|APP-3||0;\" +\n            \"|15.6|Code reviews part 2|coderev||8;\" +\n            \"16.10|16.36||||6;\" +//waste\n            \"|18.0|Note 6|APP-4||0;\" +\n            \"|18.0||||9\"\n        tasks = buildTasks(str)\n    }\n    \n    override func tearDown() {\n\t\ttasks = []\n        super.tearDown()\n    }\n    \n    func testGroupByTaskNumber() {\n        \n        let reports = report.reports(fromTasks: tasks, targetHoursInDay: targetHoursInDay)\n        XCTAssert(reports.count == 5, \"There should be only 5 unique task numbers. Lunch and waste are ignored\")\n        for i1 in 0..<reports.count {\n            for i2 in 0..<reports.count {\n                if i1 != i2 {\n                    XCTAssertFalse(reports[i1].taskNumber == reports[i2].taskNumber, \"Duplicate taskNumber found, they should be unique\")\n                }\n            }\n        }\n    }\n    \n    func testRoundLessThan8HoursOfWork() {\n\t\t\n\t\tlet reports = report.reports(fromTasks: tasks, targetHoursInDay: targetHoursInDay)\n        \n        var duration = 0.0\n        for report in reports {\n            duration += report.duration\n        }\n\t\t\n\t\tXCTAssert(duration == targetHoursInDay)\n    }\n    \n\tfunc testRoundMoreThan8HoursOfWork() {\n\t\t\n\t\tvar tasks = self.tasks\n        tasks.removeLast()\n        tasks += buildTasks(\"|19.30||||0\")\n        \n        let reports = report.reports(fromTasks: tasks, targetHoursInDay: targetHoursInDay)\n\t\t\n        var duration = 0.0\n        for report in reports {\n            duration += report.duration\n        }\n        \n        XCTAssert(duration == targetHoursInDay)\n    }\n    \n    func testDoNotRoundMeetings() {\n        \n        var tasks = self.tasks\n        tasks.removeLast()\n        tasks += buildTasks(\"|18.20|Learning time|learning||7\")\n        \n        let reports = report.reports(fromTasks: tasks, targetHoursInDay: targetHoursInDay)\n        \n        XCTAssert(reports.count == 6)\n        \n        XCTAssert(reports[1].taskNumber == \"scrum\")\n        XCTAssert(reports[1].duration == 18.minToSec)\n        \n        XCTAssert(reports[5].taskNumber == \"learning\")\n        XCTAssert(reports[5].duration == 18.minToSec)\n    }\n    \n    func testRealSituationWhereDurationCanBeMessedUp() {\n        \n        let str = \"|8.59||||1;\" +\n            \"10.4|11.10|Meeting 1|meeting||4;\" +\n            \"11.39|12.22||||3;\" +\n            \"|13.4|Note 1|APP-3730||0;\" +\n            \"|13.19|Note 2|APP-3730||0;\" +\n            \"13.20|13.29|coderev 1|coderev||8;\" +\n            \"14.13|14.21|coderev 2|coderev||8;\" +\n            \"16.4|16.7|coderev 3|coderev||8;\" +\n            \"16.56|16.59|coderev 4|coderev||8;\" +\n            \"|17.30|Note 3|APP-3730||0\"\n        tasks = buildTasks(str)\n        \n        let reports = report.reports(fromTasks: tasks, targetHoursInDay: targetHoursInDay)\n        XCTAssert(reports.count == 3, \"There should be only 3 unique task numbers. Lunch is ignored\")\n        XCTAssert(reports[0].duration > 0, \"Duration should always greater than 0\")\n        XCTAssert(reports[1].duration > 0, \"Duration should always greater than 0\")\n        XCTAssert(reports[2].duration > 0, \"Duration should always greater than 0\")\n        var totalDuration = 0.0\n        for report in reports {\n            totalDuration += report.duration\n        }\n        XCTAssert(totalDuration == targetHoursInDay)\n    }\n    \n    func testRealSituation2() {\n        \n        let str = \"|10.00||||1;\" +\n            \"13.0|13.10|socialmedia|waste||6;\" +\n            \"|18.45|task 1|APP-3730||0;\" +\n            \"|18.45||||9\"\n        tasks = buildTasks(str)\n        \n        let reports = report.reports(fromTasks: tasks, targetHoursInDay: nil)\n        XCTAssert(reports.count == 1, \"Only one valid task\")\n        XCTAssert(reports[0].duration == 8 * 3600 + 35 * 60, \"8h 35m\")\n    }\n}\n"
  },
  {
    "path": "App/Statistics/StatisticsInteractor.swift",
    "content": "//\n//  StatisticsInteractor.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 28/05/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nclass StatisticsInteractor {\n    \n    func duration (of tasks: [Task]) -> Double {\n        \n        guard tasks.count > 1 else {\n            return 0.0\n        }\n        let time = tasks.last!.endDate.timeIntervalSince(tasks.first!.endDate)\n        return time\n    }\n    \n    func duration (of reports: [Report]) -> Double {\n        \n        var time = 0.0\n        for report in reports {\n            time += report.duration\n        }\n        return time\n    }\n}\n"
  },
  {
    "path": "App/Tasks/CloseDay.swift",
    "content": "//\n//  CloseDay.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 05/11/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport RCLog\n\nclass CloseDay {\n    \n    func close (with tasks: [Task]) {\n        \n        guard tasks.count > 1 else {\n            return\n        }\n        let interactor = TaskInteractor(repository: localRepository, remoteRepository: remoteRepository)\n        \n        // Find if the day ended already\n        let endDayTask: Task? = tasks.filter({$0.taskType == .endDay}).first\n        // If not, end it now\n        if endDayTask == nil {\n            let endDayDate = tasks.last?.endDate ?? Date()\n            let endDayTask = Task(endDate: endDayDate, type: .endDay)\n            interactor.saveTask(endDayTask, allowSyncing: true) { savedTask in }\n        }\n        // Save to db only the tasks that are not already saved, like git commits and calendar events\n        for task in tasks {\n            if task.objectId == nil {\n                var task = task\n                RCLog(\"Unsaved task found \\(task)\")\n                task.objectId = String.generateId()\n                interactor.saveTask(task, allowSyncing: true) { savedTask in }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "App/Tasks/MergeTasksInteractor.swift",
    "content": "//\n//  MergeTasksInteractor.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 20/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nclass MergeTasksInteractor {\n    \n    private let secondsAllowed = 5.0\n    \n    /// Merge the two list of tasks, remove duplicates, and sort ascending\n    func merge (tasks: [Task], with gitTasks: [Task]) -> [Task] {\n        \n        let all = tasks + gitTasks\n        \n        // Remove duplicates\n        var unique = [Task]()\n        for task in all {\n            var originalHasTaskNumber = false\n            var duplicateHasTaskNumber = false\n            let isUnique = !unique.contains(where: {\n                originalHasTaskNumber = task.taskNumber?.count ?? 0 > 0\n                let isDuplicate = task.taskType == $0.taskType && abs(task.endDate.timeIntervalSince($0.endDate)) < secondsAllowed\n                if isDuplicate {\n                    duplicateHasTaskNumber = $0.taskNumber?.count ?? 0 > 0\n                }\n                return isDuplicate\n            })\n            if isUnique {\n                unique.append(task)\n            } else if originalHasTaskNumber && !duplicateHasTaskNumber {\n                unique.removeAll(where: { abs(task.endDate.timeIntervalSince($0.endDate)) < secondsAllowed })\n                unique.append(task)\n            }\n        }\n        \n        // Sort by date\n        unique.sort(by: {\n            // If tasks have the same date might be the end of the day compared with the last task\n            // In this case endDay should be the latter task\n            guard $0.endDate != $1.endDate else {\n                return $1.taskType == .endDay\n            }\n            return $0.endDate < $1.endDate\n        })\n\n        return unique\n    }\n}\n\n//fileprivate extension Array where Element == Task {\n//\n//    fileprivate mutating func mergeElements<C : Collection>(newElements: C) where C.Iterator.Element == Element {\n//\n//        let filteredList = newElements.filter( {\n//            let gitTask = $0\n//            return !self.contains(where: { gitTask.endDate.compare($0.endDate) == .orderedSame })\n//        })\n//        self += filteredList\n//    }\n//}\n"
  },
  {
    "path": "App/Tasks/MergeTasksInteractorTests.swift",
    "content": "//\n//  MergeTasksInteractorTests.swift\n//  JirassicTests\n//\n//  Created by Cristian Baluta on 20/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport XCTest\n@testable import Jirassic_no_cloud\n\nclass MergeTasksInteractorTests: XCTestCase {\n\n    func testMergedOrder() {\n        \n        var gitWithTaskNumber = Task(endDate: Date(year: 2018, month: 2, day: 20, hour: 16, minute: 30, second: 50), type: .gitCommit)\n        gitWithTaskNumber.taskNumber = \"APP-1\"\n        let gitWithoutTaskNumber = Task(endDate: Date(year: 2018, month: 2, day: 20, hour: 16, minute: 30, second: 50), type: .gitCommit)\n        var scrum = Task(endDate: Date(year: 2018, month: 2, day: 20, hour: 10, minute: 0, second: 0), type: .calendar)\n        scrum.startDate = Date(year: 2018, month: 2, day: 20, hour: 9, minute: 45, second: 0)\n        \n        let tasks = [Task(endDate: Date(year: 2018, month: 2, day: 20, hour: 9, minute: 0, second: 0), type: .startDay),\n                     Task(endDate: Date(year: 2018, month: 2, day: 20, hour: 9, minute: 30, second: 50), type: .issue),\n                     Task(endDate: Date(year: 2018, month: 2, day: 20, hour: 13, minute: 10, second: 0), type: .lunch),\n                     Task(endDate: Date(year: 2018, month: 2, day: 20, hour: 14, minute: 30, second: 30), type: .gitCommit),\n                     gitWithoutTaskNumber,\n                     Task(endDate: Date(year: 2018, month: 2, day: 20, hour: 18, minute: 0, second: 0), type: .endDay)\n        ]\n        let gitTasks = [Task(endDate: Date(year: 2018, month: 2, day: 20, hour: 14, minute: 30, second: 30), type: .gitCommit),// duplicate\n                        gitWithTaskNumber,// duplicate\n                        gitWithoutTaskNumber,// Duplicate provided by git cmd when you have rebase done\n                        Task(endDate: Date(year: 2018, month: 2, day: 20, hour: 18, minute: 0, second: 0), type: .gitCommit)\n        ]\n        let calendarTasks = [scrum]\n        \n        var mergedTasks = MergeTasksInteractor().merge(tasks: tasks, with: gitTasks)\n        mergedTasks = MergeTasksInteractor().merge(tasks: mergedTasks, with: calendarTasks)\n        \n        XCTAssert(mergedTasks.count == 8)\n        XCTAssert(mergedTasks[0].objectId == tasks[0].objectId, \"Should be start of the day\")\n        XCTAssert(mergedTasks[1].objectId == tasks[1].objectId, \"Should be issue 1\")\n        XCTAssert(mergedTasks[2].objectId == scrum.objectId, \"Should be scrum\")\n        XCTAssert(mergedTasks[3].objectId == tasks[2].objectId, \"Should be lunch\")\n        XCTAssert(mergedTasks[4].objectId == tasks[3].objectId, \"Should be first git from tasks\")\n        XCTAssert(mergedTasks[5].objectId == gitWithTaskNumber.objectId, \"Between identical git should be the one with a valid taskNumber\")\n        XCTAssert(mergedTasks[5].taskNumber == \"APP-1\")\n        XCTAssert(mergedTasks[6].objectId == gitTasks[3].objectId, \"Should be last git\")\n        XCTAssert(mergedTasks[7].objectId == tasks[5].objectId, \"Should be end of day\")\n        \n        // Test sorting\n        let _ = mergedTasks.sorted { (t1, t2) -> Bool in\n            // t1 is the second object and t2 the first from the mergedTasks\n            XCTAssert(t1.endDate >= t2.endDate)\n            return true\n        }\n    }\n}\n"
  },
  {
    "path": "App/Tasks/ReadDaysInteractor.swift",
    "content": "//\n//  ReadDaysInteractor.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 21/11/15.\n//  Copyright © 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\n// Interactor responsible for querying and building Days snd Weeks.\n// Only start and end tasks will be queried for performance reasons\nclass ReadDaysInteractor: RepositoryInteractor {\n\t\n\tprivate var tasks = [Task]()\n\t\n    /// Query all startDay and endDay objects from the local repository\n    /// Then do a sync with the remote if enabled and query the local objects again\n    /// @parameters\n    /// completion block will be called once with local tasks and once with updated tasks if remote had any changes to download\n    func queryAll (_ completion: @escaping (_ weeks: [Week]) -> Void) {\n        query(startingDate: Date(timeIntervalSince1970: 0), completion: completion)\n    }\n\n    /// Query all startDay and endDay objects from the local repository\n    /// Then do a sync with the remote if enabled and query the local objects again\n    /// @parameters\n    /// startingDate - Query between this date and current date\n    /// completion block - will be called once with local tasks and once with updated tasks if remote had any changes to download\n    func query (startingDate: Date, completion: @escaping (_ weeks: [Week]) -> Void) {\n\n        queryLocalTasks(startDate: startingDate, endDate: Date()) { [weak self] (tasks: [Task]) in\n            \n            guard let _self = self else {\n                return\n            }\n            _self.tasks = tasks\n            completion(_self.weeks())\n            \n            if let remoteRepository = _self.remoteRepository {\n                \n                let sync = RCSync<Task>(localRepository: _self.repository, remoteRepository: remoteRepository)\n                sync.start { [weak self] hasIncomingChanges in\n                    \n                    guard let _self = self, hasIncomingChanges else {\n                        return\n                    }\n                    // Delete dusplicate start day\n                    RemoveDuplicate(repository: _self.repository, remoteRepository: _self.remoteRepository, date: Date()).execute()\n                    // Fetch again the local tasks if they were updated\n                    _self.queryLocalTasks(startDate: startingDate, endDate: Date()) { (tasks: [Task]) in\n                        _self.tasks = tasks\n                        completion(_self.weeks())\n                    }\n                }\n            }\n        }\n    }\n\n    private func queryLocalTasks (startDate: Date, endDate: Date, _ completion: @escaping (_ tasks: [Task]) -> Void) {\n        \n        let predicateWithStartAndEndDays = NSPredicate(format: \"taskType == %i || taskType == %i\", TaskType.startDay.rawValue, TaskType.endDay.rawValue)\n        \n        repository.queryTasks(startDate: startDate, endDate: endDate, predicate: predicateWithStartAndEndDays, completion: { [weak self] (tasks, error) in\n            \n            guard let _self = self else {\n                return\n            }\n            let tasks = _self.sorted(tasks: tasks)\n            completion(tasks)\n        })\n    }\n\t\n\tprivate func weeks() -> [Week] {\n\t\t\n\t\tvar objects = [Week]()\n\t\tvar referenceDate = Date.distantFuture\n\t\t\n\t\tfor task in tasks {\n            if !task.endDate.isSameWeekAs(referenceDate) {\n                referenceDate = task.endDate\n                let obj = Week(date: task.endDate)\n                obj.days = days(ofWeek: obj)\n                objects.append(obj)\n            }\n\t\t}\n\t\t\n\t\treturn objects\n\t}\n\t\n\tprivate func days() -> [Day] {\n\t\t\n\t\tvar objects = [Day]()\n        var obj: Day?\n\t\tvar referenceDate = Date.distantFuture\n\t\t\n\t\tfor task in tasks {\n            if task.endDate.isSameDayAs(referenceDate) {\n                if task.taskType == .endDay {\n                    let tempObj = objects.removeLast()\n                    obj = Day(dateStart: tempObj.dateStart, dateEnd: task.endDate)\n                    objects.append(obj!)\n                }\n            } else {\n                referenceDate = task.endDate\n                obj = Day(dateStart: task.endDate, dateEnd: nil)\n                objects.append(obj!)\n            }\n\t\t}\n\t\t\n\t\treturn objects\n\t}\n\t\n    private func sorted (tasks: [Task]) -> [Task] {\n        return tasks.sorted { (task1: Task, task2: Task) -> Bool in\n            return task1.endDate.compare(task2.endDate) == .orderedDescending\n        }\n    }\n    \n\tprivate func days (ofWeek week: Week) -> [Day] {\n\t\t\n\t\tvar objects = [Day]()\n        var activeDay: Day?\n\t\tvar referenceDate = Date.distantFuture\n\t\t\n        // Tasks are sorted descending\n\t\tfor task in tasks {\n            if task.endDate.isSameWeekAs(week.date) {\n                if task.endDate.isSameDayAs(referenceDate) {\n                    // Check if we reached the begining of the day and recreate the object with the real startDate\n                    if task.taskType == .startDay {\n                        if objects.count > 0 {\n                            let tempDay = objects.removeLast()\n                            activeDay = Day(dateStart: task.endDate, dateEnd: tempDay.dateEnd)\n                        } else {\n                            activeDay = Day(dateStart: task.endDate, dateEnd: nil)\n                        }\n                        objects.append(activeDay!)\n                    }\n                } else {\n                    var endDate: Date?\n                    if task.taskType == .endDay {\n                        endDate = task.endDate\n                    }\n                    referenceDate = task.endDate\n                    activeDay = Day(dateStart: task.endDate, dateEnd: endDate)\n                    objects.append(activeDay!)\n                }\n            }\n\t\t}\n\t\t\n\t\treturn objects\n\t}\n}\n"
  },
  {
    "path": "App/Tasks/ReadDaysInteractorTests.swift",
    "content": "//\n//  ReadDaysInteractorTests.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 23/05/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport XCTest\n@testable import Jirassic_no_cloud\n\nclass ReadDaysInteractorTests: XCTestCase {\n    \n    func testSplitDays_coredata() {\n        \n        let repository = InMemoryCoreDataRepository()\n        remoteRepository = nil\n        \n        let task1 = Task(endDate: Date(year: 2017, month: 5, day: 23, hour: 23, minute: 50), type: TaskType.startDay)\n        repository.saveTask(task1, completion: { task in })\n        let task2 = Task(endDate: Date(year: 2017, month: 5, day: 24, hour: 0, minute: 30), type: TaskType.startDay)\n        repository.saveTask(task2, completion: { task in })\n        let task3 = Task(endDate: Date(year: 2017, month: 5, day: 24, hour: 10, minute: 0), type: TaskType.startDay)\n        repository.saveTask(task3, completion: { task in })\n        \n        let interactor = ReadDaysInteractor(repository: repository, remoteRepository: nil)\n        // This is synchronous query\n        interactor.queryAll { (weeks) in\n            XCTAssertTrue(weeks.first!.days.count == 2)\n        }\n    }\n\n}\n"
  },
  {
    "path": "App/Tasks/ReadTasksInteractor.swift",
    "content": "//\n//  ReadTasks.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 28/03/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nclass ReadTasksInteractor: RepositoryInteractor {\n\t\n    // Return a list of tasks sorted by date\n    func tasksInDay (_ date: Date) -> [Task] {\n        return self.repository.queryTasks(startDate: date.startOfDay(), endDate: date.endOfDay(), predicate: nil)\n    }\n\n    // Return a list of tasks sorted by date\n    func tasksInMonth (_ date: Date) -> [Task] {\n        return self.repository.queryTasks(startDate: date.startOfMonth(), endDate: date.endOfMonth(), predicate: nil)\n    }\n\n    // Return a list of tasks sorted by date\n    func tasks (between dateStart: Date, and dateEnd: Date) -> [Task] {\n        return self.repository.queryTasks(startDate: dateStart, endDate: dateEnd, predicate: nil)\n    }\n}\n"
  },
  {
    "path": "App/Tasks/RemoveDuplicate.swift",
    "content": "//\n//  RemoveDuplicate.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 26/12/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\n/// Removes the later start day\nclass RemoveDuplicate: RepositoryInteractor {\n    \n    let date: Date\n    \n    init(repository: Repository, remoteRepository: Repository?, date: Date) {\n        self.date = date\n        super.init(repository: repository, remoteRepository: remoteRepository)\n    }\n    \n    func execute() {\n        let predicate = NSPredicate(format: \"taskType == %i\", TaskType.startDay.rawValue)\n        \n        repository.queryTasks(startDate: date.startOfDay(), endDate: date.endOfDay(), predicate: predicate, completion: { [weak self] (tasks, error) in\n            \n            guard let _self = self else {\n                return\n            }\n            guard tasks.count > 1 else {\n                return\n            }\n            let taskInteractor = TaskInteractor(repository: _self.repository, remoteRepository: _self.remoteRepository)\n            for i in 1..<tasks.count {\n                taskInteractor.deleteTask(tasks[i])\n            }\n        })\n    }\n}\n"
  },
  {
    "path": "App/Tasks/TaskFinder.swift",
    "content": "//\n//  TaskTypeFinder.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 09/11/15.\n//  Copyright © 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nclass TaskFinder {\n    \n\tfunc scrumExists (_ tasks: [Task]) -> Bool {\n\t\t\n        return tasks.filter({ $0.taskType == TaskType.scrum }).count > 0\n\t}\n    \n    func lunchExists (_ tasks: [Task]) -> Bool {\n        \n        return tasks.filter({ $0.taskType == TaskType.lunch }).count > 0\n    }\n}\n"
  },
  {
    "path": "App/Tasks/TaskFinderTests.swift",
    "content": "//\n//  TaskFinderTests.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 11/06/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport XCTest\n@testable import Jirassic_no_cloud\n\nclass TaskFinderTests: XCTestCase {\n    \n    func testMissingTasks() {\n        \n        let tasks = [\n            Task(endDate: Date(), type: TaskType.issue),\n            Task(endDate: Date(), type: TaskType.startDay),\n            Task(endDate: Date(), type: TaskType.meeting),\n            Task(endDate: Date(), type: TaskType.gitCommit)\n        ]\n        \n        let taskFinder = TaskFinder()\n        XCTAssertFalse(taskFinder.scrumExists(tasks))\n        XCTAssertFalse(taskFinder.lunchExists(tasks))\n    }\n    \n    func testExistingTasks() {\n        \n        let tasks = [\n            Task(endDate: Date(), type: TaskType.issue),\n            Task(endDate: Date(), type: TaskType.startDay),\n            Task(endDate: Date(), type: TaskType.scrum),\n            Task(endDate: Date(), type: TaskType.lunch),\n            Task(endDate: Date(), type: TaskType.meeting),\n            Task(endDate: Date(), type: TaskType.gitCommit)\n        ]\n        \n        let taskFinder = TaskFinder()\n        XCTAssertTrue(taskFinder.scrumExists(tasks))\n        XCTAssertTrue(taskFinder.lunchExists(tasks))\n    }\n}\n"
  },
  {
    "path": "App/Tasks/TaskInteractor.swift",
    "content": "//\n//  TaskInteractor.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 19/10/15.\n//  Copyright © 2017 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nclass TaskInteractor: RepositoryInteractor {\n\n    func queryTask (withId objectId: String) -> Task? {\n        return repository.queryTask(withId: objectId)\n    }\n    \n    func saveTask (_ task: Task, allowSyncing: Bool, completion: @escaping (_ savedTask: Task?) -> Void) {\n        \n        guard task.objectId != nil else {\n            fatalError(\"Cannot save a task without objectId\")\n        }\n        var task = task\n        task.lastModifiedDate = nil\n        \n        self.repository.saveTask(task, completion: { [weak self] savedTask in\n            guard let localTask = savedTask else {\n                completion(nil)\n                return\n            }\n            if allowSyncing {\n                // We don't care if the task doesn't get saved to server\n                self?.syncTask(localTask, completion: { (task) in })\n            }\n            completion(localTask)\n        })\n    }\n    \n    func deleteTask (_ task: Task) {\n        \n        guard task.objectId != nil else {\n            fatalError(\"Cannot delete a task without objectId\")\n        }\n        self.repository.deleteTask(task, permanently: false, completion: { (success: Bool) -> Void in\n            #if !CMD\n            if let remoteRepository = self.remoteRepository {\n                let sync = RCSync<Task>(localRepository: self.repository, remoteRepository: remoteRepository)\n                sync.deleteTask(task, completion: { (success) in\n                    \n                })\n            }\n            #endif\n        })\n    }\n    \n    private func syncTask (_ task: Task, completion: @escaping (_ uploadedTask: Task) -> Void) {\n        \n        #if !CMD\n        if let remoteRepository = self.remoteRepository {\n            let sync = RCSync<Task>(localRepository: self.repository, remoteRepository: remoteRepository)\n            sync.uploadTask(task, completion: { (success) in\n                DispatchQueue.main.async {\n                    completion(task)\n                }\n            })\n        }\n        #endif\n    }\n}\n"
  },
  {
    "path": "App/Tasks/TaskInteractorTests.swift",
    "content": "//\n//  TaskInteractorTests.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 07/05/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport XCTest\n@testable import Jirassic_no_cloud\n\nclass TaskInteractorTests: XCTestCase {\n\n    func testSaveDelete() {\n        \n        let repository = InMemoryCoreDataRepository()\n        let interactor = TaskInteractor(repository: repository, remoteRepository: nil)\n        \n        let tasksBeforeInsert = repository.queryTasks(startDate: Date().startOfDay(), endDate: Date().endOfDay())\n        XCTAssert(tasksBeforeInsert.count == 0, \"We added one task, we should receive one task\")\n        \n        let task = Task(endDate: Date(), type: TaskType.issue)\n        interactor.saveTask(task, allowSyncing: false, completion: { task in })\n        \n        let tasks = repository.queryTasks(startDate: Date().startOfDay(), endDate: Date().endOfDay())\n        XCTAssert(tasks.count == 1, \"We added one task, we should receive one task\")\n        \n        let taskToDelete = tasks.first!\n        interactor.deleteTask(taskToDelete)\n        \n        let tasksAfterDelete = repository.queryTasks(startDate: Date().startOfDay(), endDate: Date().endOfDay())\n        XCTAssert(tasksAfterDelete.count == 0, \"There should be no tasks left\")\n    }\n}\n"
  },
  {
    "path": "App/Tasks/TaskTypeEstimator.swift",
    "content": "//\n//  TaskTypeEstimator.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 04/05/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nclass TaskTypeEstimator {\n\n\tprivate let scrumVariationAllowed = 20.0.minToSec\n\tprivate let lunchVariationAllowed = 60.0.minToSec\n\t\n    func taskTypeAroundDate (_ date: Date, withSettings settings: Settings) -> TaskType {\n\t\t\n\t\t// Check if the date is around scrum time\n        let settingsScrumTime = gregorian.dateComponents(ymdhmsUnitFlags, from: settings.settingsTracking.scrumTime)\n\n\t\tvar comps = gregorian.dateComponents(ymdhmsUnitFlags, from: date)\n\t\tcomps.hour = settingsScrumTime.hour\n\t\tcomps.minute = settingsScrumTime.minute\n\t\tcomps.second = 0\n\t\tlet scrumDate = gregorian.date(from: comps)\n\t\t\n        if date.isAlmostSameHourAs(scrumDate!, devianceSeconds: scrumVariationAllowed) {\n            return TaskType.scrum\n        }\n\n        // Check if the date is around lunch break\n        let settingsLunchTime = gregorian.dateComponents(ymdhmsUnitFlags, from: settings.settingsTracking.lunchTime)\n\n\t\tcomps.hour = settingsLunchTime.hour\n\t\tcomps.minute = settingsLunchTime.minute\n\t\tcomps.second = 0\n\t\tlet lunchDate = gregorian.date(from: comps)\n\t\t\n\t\tif date.isAlmostSameHourAs(lunchDate!, devianceSeconds: lunchVariationAllowed) {\n\t\t\treturn TaskType.lunch\n\t\t}\n        \n        // Check if enough time to be considered a meeting\n        if abs(date.timeIntervalSinceNow) > Double(settings.settingsTracking.minSleepDuration) {\n            return TaskType.meeting\n        }\n        \n\t\treturn TaskType.issue\n\t}\n}\n"
  },
  {
    "path": "App/Tasks/TaskTypeEstimatorTests.swift",
    "content": "//\n//  TaskTypeEstimatorTests.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 11/06/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport XCTest\n@testable import Jirassic_no_cloud\n\nclass TaskTypeEstimatorTests: XCTestCase {\n\t\n\tlet estimator = TaskTypeEstimator()\n    let settings = Settings(enableBackup: false,\n                            settingsTracking: SettingsTracking(\n                                autotrack: true,\n                                autotrackingMode: TrackingMode(rawValue: TrackingMode.auto.rawValue)!,\n                                trackLunch: true,\n                                trackScrum: true,\n                                trackMeetings: true,\n                                trackStartOfDay: true,\n                                startOfDayTime: Date(hour: 9, minute: 0),\n                                endOfDayTime: Date(hour: 17, minute: 0),\n                                lunchTime: Date(hour: 13, minute: 0),\n                                scrumTime: Date(hour: 10, minute: 30),\n                                minSleepDuration: 20\n                            ),\n                            settingsBrowser: SettingsBrowser(\n                                trackCodeReviews: true,\n                                trackWastedTime: true,\n                                minCodeRevDuration: 5,\n                                codeRevLink: \"bitbucket\",\n                                minWasteDuration: 5,\n                                wasteLinks: [\"facebook.com\", \"twitter.com\"]\n                            )\n    )\n    \n\tfunc testScrumBeginAt10_30() {\n        let date = Date(hour: 10, minute: 30)\n\t\tlet taskType = estimator.taskTypeAroundDate(date, withSettings: settings)\n\t\tXCTAssert(taskType == TaskType.scrum, \"\")\n\t}\n\t\n\tfunc testScrumBeginAt_10_50() {\n\t\tlet date = Date(hour: 10, minute: 50)\n\t\tlet taskType = estimator.taskTypeAroundDate(date, withSettings: settings)\n\t\tXCTAssert(taskType == TaskType.scrum, \"\")\n\t}\n\t\n\tfunc testScrumBeginAt_10_10() {\n\t\tlet date = Date(hour: 10, minute: 10)\n\t\tlet taskType = estimator.taskTypeAroundDate(date, withSettings: settings)\n\t\tXCTAssert(taskType == TaskType.scrum, \"\")\n\t}\n\t\n\tfunc testScrumCantBeginAt_11() {\n\t\tlet date = Date(hour: 11, minute: 0)\n\t\tlet taskType = estimator.taskTypeAroundDate(date, withSettings: settings)\n\t\tXCTAssertFalse(taskType == TaskType.scrum, \"\")\n\t}\n\t\n\tfunc testLunchBeginAt_12() {\n\t\tlet date = Date(hour: 12, minute: 0)\n\t\tlet taskType = estimator.taskTypeAroundDate(date, withSettings: settings)\n\t\tXCTAssert(taskType == TaskType.lunch, \"\")\n\t}\n\t\n\tfunc testLunchBeginAt_12_30() {\n\t\tlet date = Date(hour: 12, minute: 30)\n\t\tlet taskType = estimator.taskTypeAroundDate(date, withSettings: settings)\n\t\tXCTAssert(taskType == TaskType.lunch, \"\")\n\t}\n\t\n\tfunc testLunchBeginAt_14() {\n\t\tlet date = Date(hour: 14, minute: 0)\n\t\tlet taskType = estimator.taskTypeAroundDate(date, withSettings: settings)\n\t\tXCTAssert(taskType == TaskType.lunch, \"\")\n\t}\n\t\n\tfunc testLunchTooLate() {\n\t\tlet date = Date(hour: 15, minute: 0)\n\t\tlet taskType = estimator.taskTypeAroundDate(date, withSettings: settings)\n\t\tXCTAssertFalse(taskType == TaskType.lunch, \"\")\n\t}\n    \n}\n"
  },
  {
    "path": "App/Tasks/TaskTypeSelection.swift",
    "content": "//\n//  TaskTypeSelection.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 20/08/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nclass TaskTypeSelection {\n    \n    fileprivate let kLastSelectedTabKey = \"LastSelectedTabKey\"\n    \n    func setType (_ type: ListType) {\n        UserDefaults.standard.set(type.rawValue, forKey: kLastSelectedTabKey)\n        UserDefaults.standard.synchronize()\n    }\n    \n    func lastType() -> ListType {\n        \n        if let type = ListType(rawValue: UserDefaults.standard.integer(forKey: kLastSelectedTabKey)) {\n            return type\n        }\n        return ListType.allTasks\n    }\n}\n"
  },
  {
    "path": "App/Time/PredictiveTimeTyping.swift",
    "content": "//\n//  PredictiveTimeTyping.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 06/05/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nclass PredictiveTimeTyping {\n\t\n    func timeByAdding (_ string: String, to: String) -> String {\n\t\n\t\tvar returnString = string\n\t\t\n        guard string != \"\" else {\n            // Deal with backspace\n\t\t\tlet charsToDelete = to.count == 3 || to.count == 5 ? 2 : 1\n\t\t\tlet rangeToKeep = to.startIndex..<to.index(to.endIndex, offsetBy: -charsToDelete)\n            return String(to[rangeToKeep])\n        }\n        guard Int(string) != nil else {\n            // New digit is not numeric, return previous string\n            return to\n        }\n\t\t\n        // Separate hours from minutes\n\t\tlet timeComps = to.components(separatedBy: \":\")\n\t\tlet hr: String = timeComps.first!\n\t\t\n\t\t// If it contains minutes\n        if timeComps.count == 2 {\n\t\t\tvar m = 0\n\t\t\tlet min = timeComps.last!\n\t\t\tvar minToAdd = \"\"\n\t\t\t\n\t\t\tif min.count == 2 {\n\t\t\t\tlet rangeToKeep = min.startIndex..<min.index(min.endIndex, offsetBy: -1)\n\t\t\t\treturn \"\\(hr):\\(min[rangeToKeep])\\(string)\"\n\t\t\t} else {\n\t\t\t\tm = decimalValueOf(min, newDigit: string)\n\t\t\t}\n\t\t\t\n\t\t\tif (m >= 10) { minToAdd = \"\\(m)\"\n\t\t\t}\n\t\t\telse if (m >= 6) { minToAdd = \"0\\(m)\"\n\t\t\t}\n\t\t\telse if (m == 0) { minToAdd = \"00\"\n\t\t\t}\n\t\t\telse if (m == 1) { minToAdd = \"15\"\n\t\t\t}\n\t\t\telse if (m == 2) { minToAdd = \"20\"\n\t\t\t}\n\t\t\telse if (m == 3) { minToAdd = \"30\"\n\t\t\t}\n\t\t\telse if (m == 4) { minToAdd = \"45\"\n\t\t\t}\n\t\t\telse if (m == 5) { minToAdd = \"50\"\n\t\t\t}\n\t\t\treturnString = \"\\(hr):\\(minToAdd)\"\n        }\n\t\t// Deal with hours\n\t\telse {\n\t\t\tlet h = decimalValueOf(hr, newDigit: string)\n\t\t\t\n\t\t\tif (h >= 24) {\n\t\t\t\treturnString = \"00:\"\n\t\t\t}\n\t\t\telse if (h >= 10) {\n\t\t\t\t// Do not perform any edit on hours from 10 to 23\n\t\t\t\treturnString = \"\\(h):\"\n\t\t\t}\n\t\t\telse if (h >= 3) {\n\t\t\t\treturnString = \"0\\(h):\"\n\t\t\t}\n\t\t\telse if (hr.count >= 1) {\n\t\t\t\treturnString = \"0\\(h):\"\n\t\t\t}\n\t\t}\n\t\treturn returnString\n\t}\n\t\n    func dateFromStringHHmm (_ string: String) -> Date {\n\t\t\n        let gregorian = Calendar(identifier: Calendar.Identifier.gregorian)\n        var comps = gregorian.dateComponents(ymdhmsUnitFlags, from: Date())\n        let hm = string.components(separatedBy: \":\")\n\t\t\n\t\tif (string.count == 0) {\n\t\t\tcomps.hour = 0\n\t\t\tcomps.minute = 0\n\t\t}\n        else if (hm.count > 1) {\n            comps.hour = Int(hm[0])!\n            comps.minute = Int(hm[1])!\n        }\n        else {\n            comps.hour = (hm.count == 1) ? Int(hm[0])! : 19;\n            comps.minute = 0\n        }\n        return gregorian.date(from: comps)!\n    }\n\t\n\t// This method will combine strings and convert the result to number\n    func decimalValueOf (_ existingText: String, newDigit: String) -> Int {\n\t\t\n        if existingText.count > 0 && newDigit.count > 0 {\n            return Int(existingText)! * 10 + Int(newDigit)!\n        }\n\t\tif let d = Int(newDigit) {\n\t\t\treturn d\n\t\t} else {\n\t\t\treturn 0\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "App/Time/PredictiveTimeTypingTests.swift",
    "content": "//\n//  PredictiveTimeTypingTests.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 28/09/15.\n//  Copyright © 2015 Cristian Baluta. All rights reserved.\n//\n\nimport XCTest\n@testable import Jirassic_no_cloud\n\nclass PredictiveTimeTypingTests: XCTestCase {\n\t\n\tlet predictor = PredictiveTimeTyping()\n\t\n    func testStringToDecimal() {\n\t\t\n\t\tXCTAssertFalse(predictor.decimalValueOf(\"\", newDigit: \"2\") == 1, \"\")\n\t\tXCTAssert(predictor.decimalValueOf(\"\", newDigit: \"2\") == 2, \"\")\n\t\tXCTAssert(predictor.decimalValueOf(\"\", newDigit: \"\") == 0, \"\")\n\t\tXCTAssert(predictor.decimalValueOf(\"1\", newDigit: \"2\") == 12, \"\")\n\t\tXCTAssert(predictor.decimalValueOf(\"59\", newDigit: \"3\") == 593, \"\")\n    }\n\t\n\tfunc testDateFromString() {\n\t\t\n\t\tvar date = predictor.dateFromStringHHmm(\"12:25\")\n\t\tXCTAssert(date.HHmm() == \"12:25\", \"\")\n\t\tdate = predictor.dateFromStringHHmm(\"12\")\n\t\tXCTAssert(date.HHmm() == \"12:00\", \"\")\n\t\tdate = predictor.dateFromStringHHmm(\"\")\n\t\tXCTAssert(date.HHmm() == \"00:00\", \"\")\n\t}\n\t\n\tfunc testHourPredictor() {\n\t\t\n\t\tXCTAssert(predictor.timeByAdding(\"0\", to: \"\") == \"0\", \"\")\n\t\tXCTAssert(predictor.timeByAdding(\"1\", to: \"\") == \"1\", \"\")\n\t\tXCTAssert(predictor.timeByAdding(\"2\", to: \"\") == \"2\", \"\")\n\t\tXCTAssert(predictor.timeByAdding(\"3\", to: \"\") == \"03:\", \"Adding first h digit greater or equal to 3 can mean only 03: in the morning\")\n\t\tXCTAssert(predictor.timeByAdding(\"\", to: \"03:\") == \"0\", \"No char means deleting. Deleting last h digit deletes the : as well\")\n        XCTAssert(predictor.timeByAdding(\"\", to: \"0\") == \"\", \"\")\n        XCTAssert(predictor.timeByAdding(\"0\", to: \"0\") == \"00:\", \"\")\n\t\tXCTAssert(predictor.timeByAdding(\"2\", to: \"0\") == \"02:\", \"\")\n\t\tXCTAssert(predictor.timeByAdding(\"3\", to: \"0\") == \"03:\", \"\")\n\t\tXCTAssert(predictor.timeByAdding(\"0\", to: \"1\") == \"10:\", \"\")\n\t\tXCTAssert(predictor.timeByAdding(\"9\", to: \"2\") == \"00:\", \"Adding more than 24h sets it to 00\")\n\t}\n\t\n\t// Minutes are predicted to the first greater quarter or 10th\n\tfunc testMinutesPredictor() {\n\t\t\n\t\tXCTAssert(predictor.timeByAdding(\"0\", to: \"05:\") == \"05:00\", \"\")\n\t\tXCTAssert(predictor.timeByAdding(\"1\", to: \"05:\") == \"05:15\", \"\")\n\t\tXCTAssert(predictor.timeByAdding(\"2\", to: \"05:\") == \"05:20\", \"\")\n\t\tXCTAssert(predictor.timeByAdding(\"3\", to: \"05:\") == \"05:30\", \"\")\n\t\tXCTAssert(predictor.timeByAdding(\"4\", to: \"05:\") == \"05:45\", \"\")\n\t\tXCTAssert(predictor.timeByAdding(\"5\", to: \"05:\") == \"05:50\", \"\")\n\t\tXCTAssert(predictor.timeByAdding(\"6\", to: \"05:\") == \"05:06\", \"If minutes begins with 6 or greater, use it as final value\")\n\t\tXCTAssert(predictor.timeByAdding(\"9\", to: \"05:\") == \"05:09\", \"\")\n\t\tXCTAssert(predictor.timeByAdding(\"9\", to: \"05:1\") == \"05:19\", \"\")\n\t\tXCTAssert(predictor.timeByAdding(\"9\", to: \"05:18\") == \"05:19\", \"\")\n\t\tXCTAssert(predictor.timeByAdding(\"6\", to: \"05:09\") == \"05:06\", \"When the time is complete but you still add digits, replace the last digit with new value\")\n\t\tXCTAssert(predictor.timeByAdding(\"\", to: \"05:09\") == \"05:\", \"Deleting minutes deletes both digits\")\n\t\tXCTAssert(predictor.timeByAdding(\"\", to: \"05:0\") == \"05:\", \"\")\n\t}\n}\n"
  },
  {
    "path": "App/Time/TimeInteractor.swift",
    "content": "//\n//  TimeInteractor.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 05/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nclass TimeInteractor {\n    \n    let settings: Settings!\n    \n    init(settings: Settings) {\n        self.settings = settings\n    }\n    \n    func workingDayLength() -> TimeInterval {\n        return settings.settingsTracking.endOfDayTime.dateByKeepingTime().timeIntervalSince(\n            settings.settingsTracking.startOfDayTime.dateByKeepingTime())\n    }\n    \n    func workedDayLength() -> TimeInterval {\n        return Date().timeIntervalSince( settings.settingsTracking.startOfDayTime.dateByKeepingTime() )\n    }\n}\n"
  },
  {
    "path": "App/User/RegisterUserInteractor.swift",
    "content": "//\n//  RegisterUserInteractor.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 14/06/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\nimport RCLog\n\nclass RegisterUserInteractor: RepositoryInteractor {\n\n    var onRegisterSuccess: (() -> ())?\n    var onRegisterFailure: (() -> ())?\n\t\n\tfunc registerWithCredentials (_ credentials: UserCredentials) {\n\t\t\n\t\tself.repository.registerWithCredentials(credentials) { [weak self] (error) in\n            if let error = error {\n                let errorString = error.userInfo[\"error\"] as? NSString\n                RCLogO(errorString)\n                self?.onRegisterFailure?()\n            } else {\n                self?.onRegisterSuccess?()\n            }\n        }\n\t}\n}\n"
  },
  {
    "path": "App/User/UserInteractor.swift",
    "content": "//\n//  UserInteractor.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 03/05/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\nimport RCLog\n\nclass UserInteractor: RepositoryInteractor {\n    \n    var onLoginSuccess: (() -> ())?\n    var onLoginFailure: (() -> ())?\n    \n    func getUser(_ completion: @escaping ((_ user: User?) -> Void)) {\n        self.repository.getUser(completion)\n    }\n    \n    func loginWithCredentials (_ credentials: UserCredentials) {\n        \n        self.repository.loginWithCredentials(credentials) { [weak self] (error: NSError?) in\n            \n            if let error = error {\n                let errorString = error.userInfo[\"error\"] as? NSString\n                RCLogO(errorString)\n                self?.register(credentials)\n            } else {\n                self?.onLoginSuccess?()\n            }\n        }\n    }\n    \n    func logout() {\n        self.repository.logout()\n    }\n    \n    fileprivate func register (_ credentials: UserCredentials) {\n        \n        let registerInteractor = RegisterUserInteractor(repository: self.repository, remoteRepository: self.remoteRepository)\n        registerInteractor.onRegisterSuccess = { [weak self] in\n            self?.onLoginSuccess?()\n        }\n        registerInteractor.onRegisterFailure = { [weak self] in\n            self?.onLoginFailure?()\n        }\n        registerInteractor.registerWithCredentials(credentials)\n    }\n    \n}\n"
  },
  {
    "path": "App/User/UserInteractorTests.swift",
    "content": "//\n//  UserInteractorTests.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 03/05/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport XCTest\n@testable import Jirassic_no_cloud\n\nclass UserInteractorTests: XCTestCase {\n    \n//    func testLogout() {\n//        \n//        let repository = InMemoryCoreDataRepository()\n//        \n//        let task = Task(dateEnd: Date(), type: TaskType.issue)\n//        let _ = repository.saveTask(task) { (success) in\n//            \n//        }\n//        \n//        let tasks = repository.queryTasksInDay(Date())\n//        XCTAssert(tasks.count == 1, \"We added one task, we should receive one task\")\n//        \n//        UserInteractor(repository: repository).logout()\n//        \n//        let tasksAfterLogout = repository.queryTasksInDay(Date())\n//        XCTAssert(tasksAfterLogout.count == 0, \"After logging out there should be no task left\")\n//    }\n}\n"
  },
  {
    "path": "Delivery/iOS/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  Jirassic-Scrum\n//\n//  Created by Baluta Cristian on 13/05/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport UIKit\n\nvar localRepository: Repository!\nvar remoteRepository: Repository?\nlet appRed = UIColor(red: 240.0/255, green: 40.0/255, blue: 40.0/255, alpha: 1.0)\n\n@UIApplicationMain\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n\n\tvar window: UIWindow?\n\n    func application (_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {\n        \n//        UserDefaults.standard.localChangeDate = nil\n//        UserDefaults.standard.remoteChangeToken = nil\n        \n\t\tlocalRepository = CoreDataRepository()\n        \n        remoteRepository = CloudKitRepository()\n        remoteRepository?.getUser({ (user) in\n            if user == nil {\n                remoteRepository = nil\n            }\n        })\n        \n        self.window?.tintColor = appRed\n        \n\t\treturn true\n\t}\n\n\tfunc applicationWillResignActive(_ application: UIApplication) {\n\t\t// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.\n\t\t// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.\n\t}\n\n\tfunc applicationDidEnterBackground(_ application: UIApplication) {\n\t\t// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.\n\t\t// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.\n\t}\n\n\tfunc applicationWillEnterForeground(_ application: UIApplication) {\n\t\t// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.\n\t}\n\n\tfunc applicationDidBecomeActive(_ application: UIApplication) {\n\t\t// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.\n\t}\n\n\tfunc applicationWillTerminate(_ application: UIApplication) {\n\t\t// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.\n\t}\n}\n\n"
  },
  {
    "path": "Delivery/iOS/Base.lproj/LaunchScreen.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.XIB\" version=\"3.0\" toolsVersion=\"12121\" systemVersion=\"16D32\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" launchScreen=\"YES\" useTraitCollections=\"YES\" colorMatched=\"YES\">\n    <device id=\"retina4_7\" orientation=\"portrait\">\n        <adaptation id=\"fullscreen\"/>\n    </device>\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"12089\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <customFonts key=\"customFonts\">\n        <array key=\"Avenir.ttc\">\n            <string>Avenir-Medium</string>\n        </array>\n    </customFonts>\n    <objects>\n        <placeholder placeholderIdentifier=\"IBFilesOwner\" id=\"-1\" userLabel=\"File's Owner\"/>\n        <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"-2\" customClass=\"UIResponder\"/>\n        <view contentMode=\"scaleToFill\" id=\"iN0-l3-epB\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"480\" height=\"480\"/>\n            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n            <subviews>\n                <label opaque=\"NO\" clipsSubviews=\"YES\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Time tracking done right\" textAlignment=\"center\" lineBreakMode=\"middleTruncation\" baselineAdjustment=\"alignBaselines\" minimumFontSize=\"18\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"kId-c2-rCX\">\n                    <rect key=\"frame\" x=\"106.5\" y=\"370\" width=\"268.5\" height=\"33\"/>\n                    <fontDescription key=\"fontDescription\" name=\"Avenir-Medium\" family=\"Avenir\" pointSize=\"24\"/>\n                    <color key=\"textColor\" red=\"0.82619418379999998\" green=\"0.18153228830000001\" blue=\"0.1534976841\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"displayP3\"/>\n                    <nil key=\"highlightedColor\"/>\n                </label>\n                <imageView userInteractionEnabled=\"NO\" contentMode=\"scaleToFill\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" image=\"SplashIcon\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"8Co-43-sBV\">\n                    <rect key=\"frame\" x=\"140\" y=\"140\" width=\"200\" height=\"200\"/>\n                    <constraints>\n                        <constraint firstAttribute=\"width\" constant=\"200\" id=\"48U-DK-pCe\"/>\n                        <constraint firstAttribute=\"height\" constant=\"200\" id=\"azM-hT-9yV\"/>\n                    </constraints>\n                </imageView>\n            </subviews>\n            <color key=\"backgroundColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"calibratedWhite\"/>\n            <constraints>\n                <constraint firstAttribute=\"centerY\" secondItem=\"8Co-43-sBV\" secondAttribute=\"centerY\" id=\"3Sg-PJ-Yzv\"/>\n                <constraint firstAttribute=\"centerX\" secondItem=\"kId-c2-rCX\" secondAttribute=\"centerX\" id=\"Koa-jz-hwk\"/>\n                <constraint firstItem=\"kId-c2-rCX\" firstAttribute=\"top\" secondItem=\"8Co-43-sBV\" secondAttribute=\"bottom\" constant=\"30\" id=\"aoI-OR-eUc\"/>\n                <constraint firstAttribute=\"centerX\" secondItem=\"8Co-43-sBV\" secondAttribute=\"centerX\" id=\"oBk-RF-Fqh\"/>\n            </constraints>\n            <nil key=\"simulatedStatusBarMetrics\"/>\n            <freeformSimulatedSizeMetrics key=\"simulatedDestinationMetrics\"/>\n            <point key=\"canvasLocation\" x=\"548\" y=\"455\"/>\n        </view>\n    </objects>\n    <resources>\n        <image name=\"SplashIcon\" width=\"200\" height=\"200\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "Delivery/iOS/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"14313.18\" targetRuntime=\"iOS.CocoaTouch\" propertyAccessControl=\"none\" useAutolayout=\"YES\" useTraitCollections=\"YES\" colorMatched=\"YES\" initialViewController=\"rS3-R9-Ivy\">\n    <device id=\"retina4_7\" orientation=\"portrait\">\n        <adaptation id=\"fullscreen\"/>\n    </device>\n    <dependencies>\n        <deployment identifier=\"iOS\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.IBCocoaTouchPlugin\" version=\"14283.14\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Master-->\n        <scene sceneID=\"cUi-kZ-frf\">\n            <objects>\n                <navigationController title=\"Master\" id=\"rS3-R9-Ivy\" sceneMemberID=\"viewController\">\n                    <navigationBar key=\"navigationBar\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"scaleToFill\" id=\"yXu-0R-QUA\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"20\" width=\"375\" height=\"44\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                    </navigationBar>\n                    <connections>\n                        <segue destination=\"pGT-tt-fL9\" kind=\"relationship\" relationship=\"rootViewController\" id=\"rmv-pN-cet\"/>\n                    </connections>\n                </navigationController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"eq9-QA-ai8\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"-951\" y=\"61\"/>\n        </scene>\n        <!--Login View Controller-->\n        <scene sceneID=\"EsZ-fK-YUx\">\n            <objects>\n                <viewController id=\"pGT-tt-fL9\" customClass=\"LoginViewController\" customModule=\"Jirassic_iOS\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <layoutGuides>\n                        <viewControllerLayoutGuide type=\"top\" id=\"Qls-sY-lCN\"/>\n                        <viewControllerLayoutGuide type=\"bottom\" id=\"H8a-Vv-fAg\"/>\n                    </layoutGuides>\n                    <view key=\"view\" contentMode=\"scaleToFill\" id=\"D52-14-Kez\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <button opaque=\"NO\" contentMode=\"scaleToFill\" contentHorizontalAlignment=\"center\" contentVerticalAlignment=\"center\" buttonType=\"roundedRect\" lineBreakMode=\"middleTruncation\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"b4t-lD-bTw\">\n                                <rect key=\"frame\" x=\"142\" y=\"307\" width=\"91\" height=\"53\"/>\n                                <fontDescription key=\"fontDescription\" name=\"Avenir-BlackOblique\" family=\"Avenir\" pointSize=\"30\"/>\n                                <state key=\"normal\" title=\"iCloud\">\n                                    <color key=\"titleColor\" red=\"0.94117647059999998\" green=\"0.15686274510000001\" blue=\"0.15686274510000001\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                    <color key=\"titleShadowColor\" red=\"0.5\" green=\"0.5\" blue=\"0.5\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                </state>\n                            </button>\n                            <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"You must be logged in to continue\" textAlignment=\"natural\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"fW5-5D-GpD\">\n                                <rect key=\"frame\" x=\"57\" y=\"368\" width=\"261\" height=\"21\"/>\n                                <fontDescription key=\"fontDescription\" type=\"system\" pointSize=\"17\"/>\n                                <nil key=\"textColor\"/>\n                                <nil key=\"highlightedColor\"/>\n                            </label>\n                            <button opaque=\"NO\" contentMode=\"scaleToFill\" contentHorizontalAlignment=\"center\" contentVerticalAlignment=\"center\" buttonType=\"roundedRect\" lineBreakMode=\"middleTruncation\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"F4c-hm-ycU\">\n                                <rect key=\"frame\" x=\"156.5\" y=\"397\" width=\"62\" height=\"30\"/>\n                                <state key=\"normal\" title=\"Continue\"/>\n                                <connections>\n                                    <action selector=\"handleLoginButton:\" destination=\"pGT-tt-fL9\" eventType=\"touchUpInside\" id=\"Ldj-i1-ioz\"/>\n                                </connections>\n                            </button>\n                        </subviews>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <constraints>\n                            <constraint firstItem=\"b4t-lD-bTw\" firstAttribute=\"centerX\" secondItem=\"D52-14-Kez\" secondAttribute=\"centerX\" id=\"A2N-Dx-zHx\"/>\n                            <constraint firstItem=\"F4c-hm-ycU\" firstAttribute=\"top\" secondItem=\"fW5-5D-GpD\" secondAttribute=\"bottom\" constant=\"8\" id=\"EMz-Es-LIe\"/>\n                            <constraint firstItem=\"fW5-5D-GpD\" firstAttribute=\"centerX\" secondItem=\"D52-14-Kez\" secondAttribute=\"centerX\" id=\"OGS-Ja-8J1\"/>\n                            <constraint firstItem=\"b4t-lD-bTw\" firstAttribute=\"centerY\" secondItem=\"D52-14-Kez\" secondAttribute=\"centerY\" id=\"TS4-Nn-TVO\"/>\n                            <constraint firstItem=\"fW5-5D-GpD\" firstAttribute=\"top\" secondItem=\"b4t-lD-bTw\" secondAttribute=\"bottom\" constant=\"8\" id=\"cdG-xq-Ouk\"/>\n                            <constraint firstItem=\"F4c-hm-ycU\" firstAttribute=\"centerX\" secondItem=\"D52-14-Kez\" secondAttribute=\"centerX\" id=\"jcL-IC-LEj\"/>\n                        </constraints>\n                    </view>\n                    <navigationItem key=\"navigationItem\" id=\"Q5D-WZ-kV0\"/>\n                    <connections>\n                        <outlet property=\"butLogin\" destination=\"F4c-hm-ycU\" id=\"I5O-P7-dec\"/>\n                        <outlet property=\"infoTextField\" destination=\"fW5-5D-GpD\" id=\"BVV-vy-291\"/>\n                        <segue destination=\"pGg-6v-bdr\" kind=\"show\" identifier=\"ShowDaysSegue\" id=\"SRI-lJ-09U\"/>\n                    </connections>\n                </viewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"kwp-mQ-Xd2\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"-176\" y=\"61\"/>\n        </scene>\n        <!--Master-->\n        <scene sceneID=\"VgW-fR-Quf\">\n            <objects>\n                <tableViewController title=\"Master\" id=\"pGg-6v-bdr\" customClass=\"DaysViewController\" customModule=\"Jirassic_iOS\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <tableView key=\"view\" opaque=\"NO\" clipsSubviews=\"YES\" clearsContextBeforeDrawing=\"NO\" contentMode=\"scaleToFill\" alwaysBounceVertical=\"YES\" dataMode=\"prototypes\" style=\"grouped\" separatorStyle=\"default\" rowHeight=\"63\" sectionHeaderHeight=\"18\" sectionFooterHeight=\"18\" id=\"mLL-gJ-YKr\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" cocoaTouchSystemColor=\"groupTableViewBackgroundColor\"/>\n                        <prototypes>\n                            <tableViewCell contentMode=\"scaleToFill\" selectionStyle=\"blue\" accessoryType=\"disclosureIndicator\" hidesAccessoryWhenEditing=\"NO\" indentationLevel=\"1\" indentationWidth=\"0.0\" reuseIdentifier=\"DayCell\" textLabel=\"2pz-XF-uhl\" rowHeight=\"63\" style=\"IBUITableViewCellStyleDefault\" id=\"m0d-ak-lc9\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"55.5\" width=\"375\" height=\"63\"/>\n                                <autoresizingMask key=\"autoresizingMask\"/>\n                                <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" tableViewCell=\"m0d-ak-lc9\" id=\"d3P-M7-ByW\">\n                                    <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"341\" height=\"62.5\"/>\n                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                    <subviews>\n                                        <label opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" text=\"Title\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" id=\"2pz-XF-uhl\">\n                                            <rect key=\"frame\" x=\"16\" y=\"0.0\" width=\"324\" height=\"62.5\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                            <fontDescription key=\"fontDescription\" name=\"Avenir-Book\" family=\"Avenir\" pointSize=\"20\"/>\n                                            <color key=\"textColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                            <color key=\"highlightedColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                        </label>\n                                    </subviews>\n                                </tableViewCellContentView>\n                                <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                <connections>\n                                    <segue destination=\"Ne8-5p-NMX\" kind=\"show\" identifier=\"ShowTasksSegue\" id=\"3D0-nZ-6Kj\"/>\n                                </connections>\n                            </tableViewCell>\n                        </prototypes>\n                        <sections/>\n                        <connections>\n                            <outlet property=\"dataSource\" destination=\"pGg-6v-bdr\" id=\"P41-gY-KXY\"/>\n                            <outlet property=\"delegate\" destination=\"pGg-6v-bdr\" id=\"Y6K-Cp-Qkv\"/>\n                        </connections>\n                    </tableView>\n                    <navigationItem key=\"navigationItem\" title=\"Days\" id=\"tQt-TN-PWz\"/>\n                </tableViewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"6Cn-md-YlS\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"607\" y=\"61\"/>\n        </scene>\n        <!--Tasks View Controller-->\n        <scene sceneID=\"iy0-h1-6m5\">\n            <objects>\n                <tableViewController id=\"Ne8-5p-NMX\" customClass=\"TasksViewController\" customModule=\"Jirassic_iOS\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <tableView key=\"view\" clipsSubviews=\"YES\" contentMode=\"scaleToFill\" alwaysBounceVertical=\"YES\" dataMode=\"prototypes\" style=\"plain\" separatorStyle=\"none\" rowHeight=\"-1\" estimatedRowHeight=\"-1\" sectionHeaderHeight=\"22\" sectionFooterHeight=\"22\" id=\"EHJ-KF-bI6\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"667\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                        <prototypes>\n                            <tableViewCell userInteractionEnabled=\"NO\" contentMode=\"scaleToFill\" selectionStyle=\"default\" indentationWidth=\"10\" reuseIdentifier=\"TaskCell\" rowHeight=\"128\" id=\"lba-rR-GTL\" customClass=\"TaskCell\" customModule=\"Jirassic_iOS\" customModuleProvider=\"target\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"22\" width=\"375\" height=\"128\"/>\n                                <autoresizingMask key=\"autoresizingMask\"/>\n                                <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" tableViewCell=\"lba-rR-GTL\" id=\"2tP-Kw-4Mv\">\n                                    <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"128\"/>\n                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                    <subviews>\n                                        <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Task nr\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"4pY-nC-xVt\">\n                                            <rect key=\"frame\" x=\"28\" y=\"20\" width=\"224\" height=\"21\"/>\n                                            <constraints>\n                                                <constraint firstAttribute=\"height\" constant=\"21\" id=\"RqQ-HS-0PD\"/>\n                                            </constraints>\n                                            <fontDescription key=\"fontDescription\" name=\"Avenir-Black\" family=\"Avenir\" pointSize=\"17\"/>\n                                            <color key=\"textColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                            <nil key=\"highlightedColor\"/>\n                                        </label>\n                                        <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" ambiguous=\"YES\" text=\"Task title\" lineBreakMode=\"tailTruncation\" numberOfLines=\"0\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"R8k-VZ-rhw\">\n                                            <rect key=\"frame\" x=\"28\" y=\"41\" width=\"331\" height=\"23.5\"/>\n                                            <fontDescription key=\"fontDescription\" name=\"Avenir-Heavy\" family=\"Avenir\" pointSize=\"17\"/>\n                                            <nil key=\"highlightedColor\"/>\n                                        </label>\n                                        <view contentMode=\"scaleToFill\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"HgI-hl-IWE\">\n                                            <rect key=\"frame\" x=\"10\" y=\"0.0\" width=\"5\" height=\"128\"/>\n                                            <color key=\"backgroundColor\" red=\"0.33333333333333331\" green=\"0.33333333333333331\" blue=\"0.33333333333333331\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                            <constraints>\n                                                <constraint firstAttribute=\"width\" constant=\"5\" id=\"AkL-7W-BoN\"/>\n                                                <constraint firstAttribute=\"width\" constant=\"5\" id=\"GW0-Pk-1KP\"/>\n                                            </constraints>\n                                            <variation key=\"default\">\n                                                <mask key=\"constraints\">\n                                                    <exclude reference=\"AkL-7W-BoN\"/>\n                                                </mask>\n                                            </variation>\n                                        </view>\n                                        <view contentMode=\"scaleToFill\" fixedFrame=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"hkz-za-4XF\">\n                                            <rect key=\"frame\" x=\"6\" y=\"20\" width=\"14\" height=\"14\"/>\n                                            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n                                            <subviews>\n                                                <view contentMode=\"scaleToFill\" fixedFrame=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"8Ze-KE-FbQ\">\n                                                    <rect key=\"frame\" x=\"2\" y=\"2\" width=\"10\" height=\"10\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMaxY=\"YES\"/>\n                                                    <color key=\"backgroundColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                                </view>\n                                            </subviews>\n                                            <color key=\"backgroundColor\" red=\"1\" green=\"1\" blue=\"1\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                        </view>\n                                        <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Time\" textAlignment=\"right\" lineBreakMode=\"tailTruncation\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"f6t-Rd-90h\">\n                                            <rect key=\"frame\" x=\"321\" y=\"20\" width=\"38\" height=\"21\"/>\n                                            <constraints>\n                                                <constraint firstAttribute=\"height\" constant=\"21\" id=\"brM-iV-eYx\"/>\n                                            </constraints>\n                                            <fontDescription key=\"fontDescription\" name=\"Avenir-BookOblique\" family=\"Avenir\" pointSize=\"17\"/>\n                                            <color key=\"textColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                            <nil key=\"highlightedColor\"/>\n                                        </label>\n                                        <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" verticalCompressionResistancePriority=\"751\" ambiguous=\"YES\" text=\"Task description\" lineBreakMode=\"tailTruncation\" numberOfLines=\"0\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"MiG-DV-mZh\">\n                                            <rect key=\"frame\" x=\"28\" y=\"72.5\" width=\"331\" height=\"23.5\"/>\n                                            <fontDescription key=\"fontDescription\" name=\"Avenir-Book\" family=\"Avenir\" pointSize=\"17\"/>\n                                            <color key=\"textColor\" red=\"0.0\" green=\"0.0\" blue=\"0.0\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                            <nil key=\"highlightedColor\"/>\n                                        </label>\n                                    </subviews>\n                                    <constraints>\n                                        <constraint firstItem=\"4pY-nC-xVt\" firstAttribute=\"leading\" secondItem=\"2tP-Kw-4Mv\" secondAttribute=\"leadingMargin\" constant=\"12\" id=\"2Po-v0-Fh6\"/>\n                                        <constraint firstItem=\"R8k-VZ-rhw\" firstAttribute=\"trailing\" secondItem=\"2tP-Kw-4Mv\" secondAttribute=\"trailingMargin\" id=\"2vk-6e-spm\"/>\n                                        <constraint firstItem=\"MiG-DV-mZh\" firstAttribute=\"top\" secondItem=\"R8k-VZ-rhw\" secondAttribute=\"bottom\" constant=\"8\" id=\"5Qw-FZ-tcX\"/>\n                                        <constraint firstItem=\"MiG-DV-mZh\" firstAttribute=\"leading\" secondItem=\"2tP-Kw-4Mv\" secondAttribute=\"leadingMargin\" constant=\"12\" id=\"DqQ-o3-VO3\"/>\n                                        <constraint firstItem=\"HgI-hl-IWE\" firstAttribute=\"top\" secondItem=\"2tP-Kw-4Mv\" secondAttribute=\"topMargin\" id=\"FOX-Lf-PgO\"/>\n                                        <constraint firstItem=\"4pY-nC-xVt\" firstAttribute=\"top\" secondItem=\"2tP-Kw-4Mv\" secondAttribute=\"topMargin\" constant=\"9\" id=\"FwX-mA-tff\"/>\n                                        <constraint firstItem=\"MiG-DV-mZh\" firstAttribute=\"trailing\" secondItem=\"2tP-Kw-4Mv\" secondAttribute=\"trailingMargin\" id=\"M6Q-R1-LUZ\"/>\n                                        <constraint firstAttribute=\"bottom\" secondItem=\"HgI-hl-IWE\" secondAttribute=\"bottom\" id=\"RP0-zG-ueq\"/>\n                                        <constraint firstItem=\"R8k-VZ-rhw\" firstAttribute=\"top\" secondItem=\"4pY-nC-xVt\" secondAttribute=\"bottom\" id=\"Tt7-ah-yBT\"/>\n                                        <constraint firstItem=\"HgI-hl-IWE\" firstAttribute=\"leading\" secondItem=\"2tP-Kw-4Mv\" secondAttribute=\"leadingMargin\" constant=\"2\" id=\"VY5-pN-ARW\"/>\n                                        <constraint firstItem=\"R8k-VZ-rhw\" firstAttribute=\"leading\" secondItem=\"2tP-Kw-4Mv\" secondAttribute=\"leadingMargin\" constant=\"12\" id=\"Xom-cB-hNq\"/>\n                                        <constraint firstAttribute=\"bottom\" secondItem=\"MiG-DV-mZh\" secondAttribute=\"bottom\" constant=\"30\" id=\"Zjo-lo-F0L\"/>\n                                        <constraint firstItem=\"HgI-hl-IWE\" firstAttribute=\"leading\" secondItem=\"2tP-Kw-4Mv\" secondAttribute=\"leading\" constant=\"10\" id=\"cOC-Id-gSF\"/>\n                                        <constraint firstItem=\"HgI-hl-IWE\" firstAttribute=\"top\" secondItem=\"2tP-Kw-4Mv\" secondAttribute=\"top\" id=\"nQb-uV-h9O\"/>\n                                        <constraint firstAttribute=\"bottomMargin\" secondItem=\"HgI-hl-IWE\" secondAttribute=\"bottom\" id=\"sDg-UD-tKC\"/>\n                                        <constraint firstAttribute=\"trailingMargin\" secondItem=\"4pY-nC-xVt\" secondAttribute=\"trailing\" constant=\"107\" id=\"vyD-r3-pJr\"/>\n                                        <constraint firstItem=\"f6t-Rd-90h\" firstAttribute=\"top\" secondItem=\"2tP-Kw-4Mv\" secondAttribute=\"topMargin\" constant=\"9\" id=\"xjP-Qv-Gya\"/>\n                                        <constraint firstItem=\"f6t-Rd-90h\" firstAttribute=\"trailing\" secondItem=\"2tP-Kw-4Mv\" secondAttribute=\"trailingMargin\" id=\"yJC-yy-baZ\"/>\n                                    </constraints>\n                                    <variation key=\"default\">\n                                        <mask key=\"constraints\">\n                                            <exclude reference=\"FOX-Lf-PgO\"/>\n                                            <exclude reference=\"VY5-pN-ARW\"/>\n                                            <exclude reference=\"sDg-UD-tKC\"/>\n                                        </mask>\n                                    </variation>\n                                </tableViewCellContentView>\n                                <connections>\n                                    <outlet property=\"circleDark\" destination=\"8Ze-KE-FbQ\" id=\"T4b-76-EFK\"/>\n                                    <outlet property=\"circleWhite\" destination=\"hkz-za-4XF\" id=\"YnE-57-aLr\"/>\n                                    <outlet property=\"dateLabel\" destination=\"f6t-Rd-90h\" id=\"Z06-h5-ygM\"/>\n                                    <outlet property=\"notesLabel\" destination=\"MiG-DV-mZh\" id=\"BhJ-rl-2WR\"/>\n                                    <outlet property=\"taskNrLabel\" destination=\"4pY-nC-xVt\" id=\"LQm-0a-5LM\"/>\n                                    <outlet property=\"titleLabel\" destination=\"R8k-VZ-rhw\" id=\"T8J-MO-ndH\"/>\n                                </connections>\n                            </tableViewCell>\n                            <tableViewCell userInteractionEnabled=\"NO\" contentMode=\"scaleToFill\" selectionStyle=\"default\" indentationWidth=\"10\" reuseIdentifier=\"NonTaskCell\" id=\"4X7-kF-Wim\" customClass=\"NonTaskCell\" customModule=\"Jirassic_iOS\" customModuleProvider=\"target\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"150\" width=\"375\" height=\"44\"/>\n                                <autoresizingMask key=\"autoresizingMask\"/>\n                                <tableViewCellContentView key=\"contentView\" opaque=\"NO\" clipsSubviews=\"YES\" multipleTouchEnabled=\"YES\" contentMode=\"center\" tableViewCell=\"4X7-kF-Wim\" id=\"yb0-IS-u2w\">\n                                    <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"375\" height=\"44\"/>\n                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                    <subviews>\n                                        <view contentMode=\"scaleToFill\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"T7x-ia-d8x\">\n                                            <rect key=\"frame\" x=\"10\" y=\"0.0\" width=\"5\" height=\"44\"/>\n                                            <color key=\"backgroundColor\" red=\"0.33333333333333331\" green=\"0.33333333333333331\" blue=\"0.33333333333333331\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                            <constraints>\n                                                <constraint firstAttribute=\"width\" constant=\"5\" id=\"42U-gd-MEa\"/>\n                                                <constraint firstAttribute=\"width\" constant=\"5\" id=\"mGd-T1-rUr\"/>\n                                            </constraints>\n                                            <variation key=\"default\">\n                                                <mask key=\"constraints\">\n                                                    <exclude reference=\"mGd-T1-rUr\"/>\n                                                </mask>\n                                            </variation>\n                                        </view>\n                                        <label opaque=\"NO\" userInteractionEnabled=\"NO\" contentMode=\"left\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" text=\"Label\" lineBreakMode=\"tailTruncation\" numberOfLines=\"0\" baselineAdjustment=\"alignBaselines\" adjustsFontSizeToFit=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"rL1-iN-yxg\">\n                                            <rect key=\"frame\" x=\"28\" y=\"6\" width=\"339\" height=\"32\"/>\n                                            <fontDescription key=\"fontDescription\" name=\"Avenir-Roman\" family=\"Avenir\" pointSize=\"17\"/>\n                                            <color key=\"textColor\" white=\"0.59517299107142863\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                            <nil key=\"highlightedColor\"/>\n                                        </label>\n                                    </subviews>\n                                    <constraints>\n                                        <constraint firstItem=\"rL1-iN-yxg\" firstAttribute=\"leading\" secondItem=\"yb0-IS-u2w\" secondAttribute=\"leading\" constant=\"28\" id=\"Keh-j8-meh\"/>\n                                        <constraint firstAttribute=\"bottom\" secondItem=\"T7x-ia-d8x\" secondAttribute=\"bottom\" id=\"WsO-XL-2E1\"/>\n                                        <constraint firstItem=\"T7x-ia-d8x\" firstAttribute=\"top\" secondItem=\"yb0-IS-u2w\" secondAttribute=\"top\" id=\"Y1Y-zs-jGZ\"/>\n                                        <constraint firstItem=\"T7x-ia-d8x\" firstAttribute=\"leading\" secondItem=\"yb0-IS-u2w\" secondAttribute=\"leading\" constant=\"10\" id=\"kVQ-9N-NO2\"/>\n                                        <constraint firstAttribute=\"trailing\" secondItem=\"rL1-iN-yxg\" secondAttribute=\"trailing\" constant=\"8\" id=\"l4Z-xx-FR5\"/>\n                                        <constraint firstItem=\"rL1-iN-yxg\" firstAttribute=\"top\" secondItem=\"yb0-IS-u2w\" secondAttribute=\"top\" constant=\"6\" id=\"rCo-Rj-Cu3\"/>\n                                        <constraint firstAttribute=\"bottom\" secondItem=\"rL1-iN-yxg\" secondAttribute=\"bottom\" constant=\"6\" id=\"xkJ-cE-CcN\"/>\n                                    </constraints>\n                                </tableViewCellContentView>\n                                <connections>\n                                    <outlet property=\"notesLabel\" destination=\"rL1-iN-yxg\" id=\"Cg4-DS-U4t\"/>\n                                </connections>\n                            </tableViewCell>\n                        </prototypes>\n                        <connections>\n                            <outlet property=\"dataSource\" destination=\"Ne8-5p-NMX\" id=\"BHb-07-2Ud\"/>\n                            <outlet property=\"delegate\" destination=\"Ne8-5p-NMX\" id=\"UbZ-cF-jpY\"/>\n                        </connections>\n                    </tableView>\n                </tableViewController>\n                <placeholder placeholderIdentifier=\"IBFirstResponder\" id=\"hpt-xA-0zd\" userLabel=\"First Responder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"1364\" y=\"60.719640179910051\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "Delivery/iOS/DaysViewController.swift",
    "content": "//\n//  MasterViewController.swift\n//  Scrum\n//\n//  Created by Baluta Cristian on 05/05/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport UIKit\n\nclass DaysViewController: UITableViewController {\n\n\tvar weeks = [Week]()\n\t\n\toverride func viewDidLoad() {\n\t\tsuper.viewDidLoad()\n        \n\t\tlet refreshControl = UIRefreshControl()\n        refreshControl.tintColor = appRed\n\t\trefreshControl.addTarget(self, action: #selector(reloadData), for: .valueChanged)\n\t\tself.refreshControl = refreshControl\n        \n\t\treloadData()\n\t}\n\t\n    @objc func reloadData() {\n        \n        let interactor = ReadDaysInteractor(repository: localRepository, remoteRepository: remoteRepository)\n        interactor.queryAll { weeks in\n            \n            self.weeks = weeks\n            DispatchQueue.main.async {\n                self.tableView.reloadData()\n                self.refreshControl?.endRefreshing()\n            }\n        }\n\t}\n\n\t// MARK: - Segues\n\n    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {\n        if segue.identifier == \"ShowTasksSegue\" {\n            if let indexPath = self.tableView.indexPathForSelectedRow {\n                (segue.destination as! TasksViewController).currentDay = weeks[indexPath.section].days[indexPath.row]\n            }\n        }\n    }\n}\n\nextension DaysViewController {\n\t\n    override func numberOfSections(in tableView: UITableView) -> Int {\n        return weeks.count\n    }\n    \n    override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {\n        return weeks[section].date.weekInterval()\n    }\n\t\n\toverride func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {\n\t\treturn weeks[section].days.count\n\t}\n\t\n\toverride func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {\n\t\t\n\t\tlet cell = tableView.dequeueReusableCell(withIdentifier: \"DayCell\", for: indexPath)\n\t\tlet day = weeks[indexPath.section].days[indexPath.row]\n\t\tcell.textLabel!.text = day.dateStart.EEEEMMMMdd()\n\t\treturn cell\n\t}\n}\n"
  },
  {
    "path": "Delivery/iOS/Images.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"size\" : \"20x20\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"logo40.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"20x20\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"logo60.png\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"size\" : \"29x29\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"logo58.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"29x29\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"logo87.png\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"size\" : \"40x40\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"logo80.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"40x40\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"logo120-1.png\",\n      \"scale\" : \"3x\"\n    },\n    {\n      \"size\" : \"60x60\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"logo120.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"60x60\",\n      \"idiom\" : \"iphone\",\n      \"filename\" : \"logo180.png\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Delivery/iOS/Images.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Delivery/iOS/Images.xcassets/SplashIcon.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"logo400.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"logo600.png\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Delivery/iOS/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleDisplayName</key>\n\t<string>Jirassic</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1.0</string>\n\t<key>LSRequiresIPhoneOS</key>\n\t<true/>\n\t<key>UILaunchStoryboardName</key>\n\t<string>LaunchScreen</string>\n\t<key>UIMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>UIRequiredDeviceCapabilities</key>\n\t<array>\n\t\t<string>armv7</string>\n\t</array>\n\t<key>UISupportedInterfaceOrientations</key>\n\t<array>\n\t\t<string>UIInterfaceOrientationPortrait</string>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "Delivery/iOS/Jirassic Scrum.entitlements",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>com.apple.developer.icloud-container-identifiers</key>\n\t<array>\n\t\t<string>iCloud.com.jirassic.macos</string>\n\t</array>\n\t<key>com.apple.developer.icloud-services</key>\n\t<array>\n\t\t<string>CloudKit</string>\n\t</array>\n\t<key>com.apple.developer.ubiquity-kvstore-identifier</key>\n\t<string>$(TeamIdentifierPrefix)$(CFBundleIdentifier)</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Delivery/iOS/LoginViewController.swift",
    "content": "//\n//  LoginViewController.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 25/05/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport UIKit\n\nclass LoginViewController: UIViewController {\n\t\n\t@IBOutlet private var butLogin: UIButton!\n\t@IBOutlet private var infoTextField: UILabel!\n\t\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        self.title = \"Jirassic\"\n        handleLoginButton(butLogin)\n    }\n    \n    @IBAction func handleLoginButton (_ sender: UIButton) {\n        \n        remoteRepository?.getUser({ (user) in\n            if user != nil {\n                self.performSegue(withIdentifier: \"ShowDaysSegue\", sender: nil)\n            }\n        })\n    }\n}\n"
  },
  {
    "path": "Delivery/iOS/NonTaskCell.swift",
    "content": "//\n//  NonTaskCell.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 15/05/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport UIKit\n\nclass NonTaskCell: UITableViewCell {\n\t\n\t@IBOutlet var dateLabel: UILabel?\n\t@IBOutlet var notesLabel: UILabel!\n\t\n\toverride func awakeFromNib() {\n\t\tsuper.awakeFromNib()\n\t}\n\n    override func setSelected (_ selected: Bool, animated: Bool) {\n        super.setSelected(selected, animated: animated)\n\n        // Configure the view for the selected state\n    }\n\n}\n"
  },
  {
    "path": "Delivery/iOS/TaskCell.swift",
    "content": "//\n//  TaskTableViewCell.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 14/05/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport UIKit\n\nclass TaskCell: UITableViewCell {\n\t\n\t@IBOutlet var circleWhite: UIView?\n\t@IBOutlet var circleDark: UIView?\n\t@IBOutlet var taskNrLabel: UILabel?\n    @IBOutlet var dateLabel: UILabel?\n    @IBOutlet var titleLabel: UILabel?\n\t@IBOutlet var notesLabel: UILabel?\n\t\n    override func awakeFromNib() {\n        super.awakeFromNib()\n        // Initialization code\n\t\tcircleWhite?.layer.cornerRadius = circleWhite!.frame.size.width / 2\n\t\tcircleDark?.layer.cornerRadius = circleDark!.frame.size.width / 2\n    }\n}\n"
  },
  {
    "path": "Delivery/iOS/TasksViewController.swift",
    "content": "//\n//  DetailViewController.swift\n//  Scrum\n//\n//  Created by Baluta Cristian on 05/05/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport UIKit\n\nclass TasksViewController: UITableViewController {\n\n\tvar currentDay: Day?\n\tprivate var tasks = [Task]()\n\t\n\toverride func viewDidLoad() {\n\t\tsuper.viewDidLoad()\n\t\t// Do any additional setup after loading the view, typically from a nib.\n\t\t//\t\tself.navigationItem.leftBarButtonItem = self.editButtonItem()\n\t\t\n\t\t//\t\tlet addButton = UIBarButtonItem(barButtonSystemItem: .Add, target: self, action: \"insertNewObject:\")\n\t\t//\t\tself.navigationItem.rightBarButtonItem = addButton\n\t\t\n\t\tself.title = currentDay!.dateStart.EEEEMMMMdd()\n        \n        let reader = ReadTasksInteractor(repository: localRepository, remoteRepository: remoteRepository)\n        tasks = reader.tasksInDay(currentDay!.dateStart)\n        \n        //        let reportInteractor = CreateReport()\n        //        let reports = reportInteractor.reports(fromTasks: currentTasks, targetHoursInDay: nil)\n        //        let currentReports = reports.reversed()\n        //    }\n        \n\t\ttableView.reloadData()\n\t}\n\t\n\t//\tfunc insertNewObject(sender: AnyObject) {\n\t//\t\tobjects.insert(Date(), atIndex: 0)\n\t//\t\tlet indexPath = NSIndexPath(forRow: 0, inSection: 0)\n\t//\t\tself.tableView.insertRowsAtIndexPaths([indexPath], withRowAnimation: .Automatic)\n\t//\t}\n}\n\nextension TasksViewController {\n\t\n    override func numberOfSections(in tableView: UITableView) -> Int {\n        return 1\n    }\n\t\n\toverride func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {\n\t\treturn tasks.count\n\t}\n\t\n\toverride func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {\n\t\treturn UITableViewAutomaticDimension\n\t}\n\t\n\toverride func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {\n\t\t\n\t\tlet theTask = tasks[indexPath.row]\n//        RCLog(theData)\n\t\t\n\t\tif theTask.taskType == .issue || theTask.taskType == .gitCommit {\n\t\t\tlet cell = tableView.dequeueReusableCell(withIdentifier: \"TaskCell\", for: indexPath) as! TaskCell\n\t\t\tcell.taskNrLabel!.text = theTask.taskNumber\n            cell.dateLabel!.text = theTask.endDate.HHmm()\n            cell.titleLabel!.text = (theTask.taskTitle ?? \"\").replacingOccurrences(of: \"_\", with: \" \").replacingOccurrences(of: theTask.taskNumber!, with: \"\").trimmingCharacters(in: .whitespaces)\n\t\t\tcell.notesLabel!.text = theTask.notes?.trimmingCharacters(in: .whitespaces)\n\t\t\treturn cell\n\t\t}\n\t\telse {\n\t\t\tlet cell = tableView.dequeueReusableCell(withIdentifier: \"NonTaskCell\", for: indexPath) as! NonTaskCell\n            var notes = theTask.notes ?? theTask.taskType.defaultNotes\n            if theTask.taskType == .coderev {\n                notes = \"\\(theTask.taskType.defaultNotes): \\(notes)\"\n            }\n            if let startDate = theTask.startDate {\n                cell.notesLabel!.text = \"\\(startDate.HHmm()) - \\(theTask.endDate.HHmm()) \\(notes)\"\n            } else {\n                cell.notesLabel!.text = \"\\(theTask.endDate.HHmm()) \\(notes)\"\n            }\n\t\t\treturn cell\n\t\t}\n\t}\n\t\n//\toverride func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {\n//\t\t// Return false if you do not want the specified item to be editable.\n//\t\treturn true\n//\t}\n//\t\n//\toverride func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {\n//\t\tif editingStyle == .delete {\n//\t\t\ttasks.remove(at: indexPath.row)\n//\t\t\ttableView.deleteRows(at: [indexPath], with: .fade)\n//\t\t} else if editingStyle == .insert {\n//\t\t\t// Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view.\n//\t\t}\n//\t}\n}\n\n"
  },
  {
    "path": "Delivery/macOS/Animations/Animatable.swift",
    "content": "//\n//  Animatable.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 11/12/2016.\n//  Copyright © 2016 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nprotocol Animatable {\n    // Animatable views need a CALayer which should be created in this method\n    func createLayer()\n}\n"
  },
  {
    "path": "Delivery/macOS/Animations/FlipAnimation.swift",
    "content": "//\n//  Flip.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 24/05/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\n\nclass FlipAnimation: NSObject {\n\n\tvar animationReachedMiddle: (() -> ())?\n\tvar animationFinished: (() -> ())?\n\tweak var layer: CALayer?\n\t\n\tfunc startWithLayer (_ layer: CALayer) {\n\t\t\n\t\t// Create CAAnimation\n\t\tlet rotationAnimation = CABasicAnimation(keyPath: \"transform.rotation.y\")\n\t\trotationAnimation.fromValue = 0.0\n\t\trotationAnimation.toValue = 3.14/2\n\t\trotationAnimation.duration = 0.2\n\t\trotationAnimation.repeatCount = 1.0\n        rotationAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeIn)\n        rotationAnimation.fillMode = CAMediaTimingFillMode.forwards\n\t\trotationAnimation.isRemovedOnCompletion = false\n\t\trotationAnimation.setValue(\"flipAnimationInwards\", forKey: \"flip\")\n\t\trotationAnimation.delegate = self\n\t\t\n\t\t// Add perspective\n\t\tvar perpectiveTransform = CATransform3DIdentity\n\t\tperpectiveTransform.m34 = CGFloat(1.0 / 1000)\n\t\tlayer.transform = perpectiveTransform\n        layer.anchorPoint = CGPoint(x: 0.5, y: 0)\n\t\tlayer.add(rotationAnimation, forKey:\"flip\")\n\t\tself.layer = layer\n\t}\n\t\n\tfunc animatePhase2 (_ anim: CAAnimation!) {\n\t\t\n\t\tlet rotationAnimation = CABasicAnimation(keyPath: \"transform.rotation.y\")\n\t\trotationAnimation.fromValue = -3.14/2\n\t\trotationAnimation.toValue = 0.0\n\t\trotationAnimation.duration = 0.2\n\t\trotationAnimation.repeatCount = 1.0\n        rotationAnimation.timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut)\n        rotationAnimation.fillMode = CAMediaTimingFillMode.forwards\n\t\trotationAnimation.isRemovedOnCompletion = false\n\t\trotationAnimation.setValue(\"flipAnimationOutwards\", forKey: \"flip\")\n\t\trotationAnimation.delegate = self\n\t\t\n\t\t// Add perspective\n//        var perpectiveTransform = CATransform3DIdentity\n//        perpectiveTransform.m34 = CGFloat(1.0 / 1000)\n//        self.layer?.transform = perpectiveTransform\n\t\tself.layer?.add(rotationAnimation, forKey:\"flip\")\n\t}\n    \n    func clean() {\n        self.animationReachedMiddle = nil\n        self.animationFinished = nil\n        self.layer = nil\n    }\n}\n\nextension FlipAnimation: CAAnimationDelegate {\n    \n    func animationDidStop (_ anim: CAAnimation, finished flag: Bool) {\n        \n        if anim.value(forKey: \"flip\") as! String == \"flipAnimationInwards\" {\n            \n            self.animationReachedMiddle!()\n            self.animatePhase2(anim)\n        }\n        else if anim.value(forKey: \"flip\") as! String == \"flipAnimationOutwards\" {\n            self.animationFinished!()\n            clean()\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/App/AppDelegate.swift",
    "content": "//\n//  AppDelegate.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 24/03/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\nimport RCPreferences\nimport RCLog\n\nvar localRepository: Repository!\nvar remoteRepository: Repository?\nlet hookup = ModuleHookup()\n\n@NSApplicationMain\nclass AppDelegate: NSObject, NSApplicationDelegate {\n\t\n\t@IBOutlet var window: NSWindow?\n    var activePopover: NSPopover?\n    let appWireframe = AppWireframe()\n    let sleep = SleepNotifications()\n    let theme = AppTheme()\n    let menu = MenuBarController()\n    private let browser = BrowserNotification()\n    private let pref = RCPreferences<LocalPreferences>()\n    private var animatesOpen = true\n\t\n    class func sharedApp() -> AppDelegate {\n        return NSApplication.shared.delegate as! AppDelegate\n    }\n    \n\toverride init() {\n\t\tsuper.init()\n        \n        #if DEBUG\n        // Simulate a freshly installed app by resetting the preferences\n//        localPreferences.reset()\n//        UserDefaults.standard.serverChangeToken = nil\n//        pref.reset(.wizardSteps)\n//        pref.set(\"\", forKey: .appVersion)\n//        UserDefaults.standard.set(5, forKey: \"wizardStep\")\n//        localPreferences.set(false, forKey: .enableGit)\n        #else\n        disableTraces()\n        #endif\n        \n        self.window?.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.floatingWindow)))\n        \n        localRepository = SqliteRepository()\n        #if APPSTORE\n        if SettingsInteractor().getAppSettings().enableBackup {\n            remoteRepository = CloudKitRepository()\n            remoteRepository?.getUser({ (user) in\n                if user == nil {\n                    remoteRepository = nil\n                }\n            })\n        }\n//        _ = Store.shared\n        #else\n        RCLog(\"Icloud is not supported in this target, continuing without...\")\n        #endif\n        \n        menu.isDark = theme.isDark\n\t\tmenu.onOpen = {\n            self.removeActivePopup()\n            let isFirstLaunchOfThisVersion = self.pref.string(.appVersion) != Versioning.appVersion\n            let wizardSteps: [Int] = self.pref.get(.wizardSteps)\n            if isFirstLaunchOfThisVersion {\n                self.presentWelcomePopup()\n            }\n            else if wizardSteps.count < WizardStep.allCases.count {\n                self.presentWizard()\n            }\n            else {\n                self.presentTasksPopup(animated: self.animatesOpen)\n                self.animatesOpen = false\n            }\n        }\n        menu.onClose = {\n            self.removeActivePopup()\n        }\n        \n        theme.onChange = {\n            self.menu.isDark = self.theme.isDark\n        }\n\t\t\n        sleep.computerWentToSleep = {\n            self.menu.triggerClose()\n            self.browser.stop()\n        }\n        sleep.computerWakeUp = {\n            \n            let tasks = ReadTasksInteractor(repository: localRepository, remoteRepository: remoteRepository)\n                        .tasksInDay(Date())\n            let isWeekend = Date().isWeekend()\n            let isDayStarted = tasks.count > 0\n            let isDayEnded = tasks.contains(where: { $0.taskType == .endDay })\n            guard !isWeekend || (isDayStarted && isWeekend) else {\n                RCLog(\">>>>>>> It's weekend, won't track weekends unless the day was started <<<<<<<<\")\n                return\n            }\n            guard !isDayEnded else {\n                RCLog(\">>>>>>> Day ended, won't analyze further <<<<<<<<\")\n                return\n            }\n            self.browser.start()\n            let settings: Settings = SettingsInteractor().getAppSettings()\n            guard settings.settingsTracking.autotrack else {\n                RCLog(\">>>>>>> Autotracking disabled, won't present suggestions to user <<<<<<<<\")\n                return\n            }\n            \n            let sleepDuration = Date().timeIntervalSince(self.sleep.lastSleepDate ?? Date())\n            guard sleepDuration >= Double(settings.settingsTracking.minSleepDuration).minToSec else {\n                RCLog(\">>>>>>> Sleep duration is shorter than the minimum required: \\(sleepDuration) < \\(Double(settings.settingsTracking.minSleepDuration).minToSec) <<<<<<<<\")\n                return\n            }\n            let startDate = settings.settingsTracking.startOfDayTime.dateByKeepingTime()\n            guard Date() > startDate else {\n                RCLog(\">>>>>>> Woke up earlier than the predefined startDay, won't analyze further <<<<<<<<\")\n                return\n            }\n            \n            let timeInteractor = TimeInteractor(settings: settings)\n            let dayDuration = timeInteractor.workingDayLength()\n            let workedDuration = timeInteractor.workedDayLength()\n            guard workedDuration < dayDuration else {\n                // Do not track time exceeded the working duration\n                return\n            }\n            switch settings.settingsTracking.autotrackingMode {\n                case .notif:\n                    self.removeActivePopup()\n                    self.presentTaskSuggestionPopup()\n                    break\n                case .auto:\n                    ComputerWakeUpInteractor(repository: localRepository, remoteRepository: remoteRepository, settings: settings)\n                        .runWith(lastSleepDate: self.sleep.lastSleepDate, currentDate: Date())\n                    break\n            }\n        }\n        \n        browser.codeReviewDidStart = {\n            RCLog(\"Start code review \\(Date())\")\n        }\n        browser.codeReviewDidEnd = {\n            RCLog(\"End code review \\(Date())\")\n            let task = Task(\n                lastModifiedDate: nil,\n                startDate: self.browser.startDate,\n                endDate: self.browser.endDate!,\n                notes: self.browser.reviewedTasks.joined(separator: \", \"),\n                taskNumber: nil,\n                taskTitle: nil,\n                taskType: .coderev,\n                objectId: String.generateId()\n            )\n            let saveInteractor = TaskInteractor(repository: localRepository, remoteRepository: remoteRepository)\n            saveInteractor.saveTask(task, allowSyncing: true, completion: { savedTask in\n                \n            })\n        }\n        browser.wastingTimeDidStart = {\n            RCLog(\"Start wasting time \\(Date())\")\n        }\n        browser.wastingTimeDidEnd = {\n            RCLog(\"End wasting time \\(Date())\")\n            let task = Task(startDate: self.browser.startDate, endDate: self.browser.endDate!, type: .waste)\n            let saveInteractor = TaskInteractor(repository: localRepository, remoteRepository: remoteRepository)\n            saveInteractor.saveTask(task, allowSyncing: true, completion: { savedTask in\n                \n            })\n        }\n\t}\n\t\n    func applicationDidFinishLaunching (_ aNotification: Notification) {\n        \n        self.killLauncher()\n        \n        // Open with a delay because the popup doesn't play well otherwise\n        let dispatchTime: DispatchTime = DispatchTime.now() + Double(Int64(1.0 * Double(NSEC_PER_SEC))) / Double(NSEC_PER_SEC)\n        DispatchQueue.main.asyncAfter(deadline: dispatchTime, execute: {\n            \n            if !UserDefaults.standard.bool(forKey: \"launchedByLauncher\") {\n                self.menu.triggerOpen()\n            } else {\n                self.presentTaskSuggestionPopup()\n            }\n        })\n        \n        NSUserNotificationCenter.default.delegate = self\n        \n        NSEvent.addGlobalMonitorForEvents(matching: .rightMouseDown, handler: { event in\n            self.menu.triggerClose()\n        })\n    }\n\t\n    func applicationWillTerminate (_ aNotification: Notification) {\n        \n    }\n}\n\nextension AppDelegate {\n    \n    private func presentWelcomePopup() {\n        let popover = NSPopover()\n        activePopover = popover\n        popover.contentViewController = appWireframe.appViewController\n        appWireframe.removeCurrentController()\n        _ = appWireframe.presentWelcomeController()\n        appWireframe.showPopover(popover, fromIcon: menu.iconView)\n    }\n    \n    private func presentWizard() {\n        let popover = NSPopover()\n        activePopover = popover\n        popover.contentViewController = appWireframe.appViewController\n        appWireframe.removeCurrentController()\n        _ = appWireframe.presentWizardController()\n        appWireframe.showPopover(popover, fromIcon: menu.iconView)\n    }\n    \n    private func presentTasksPopup (animated: Bool) {\n        let popover = NSPopover()\n        activePopover = popover\n        popover.contentViewController = appWireframe.appViewController\n        popover.animates = true\n        appWireframe.removeCurrentController()\n        _ = appWireframe.presentTasksController()\n        appWireframe.showPopover(popover, fromIcon: menu.iconView)\n    }\n    \n    func removeActivePopup() {\n        if let popover = activePopover {\n            activePopover = nil\n            appWireframe.hidePopover(popover)\n            appWireframe.removeEndDayController()\n            appWireframe.removePlaceholder()\n            appWireframe.removeCurrentController()\n        }\n    }\n    \n    private func presentTaskSuggestionPopup() {\n        let popover = NSPopover()\n        activePopover = popover\n        popover.contentViewController = appWireframe.appViewController\n        _ = appWireframe.presentTaskSuggestionController (startSleepDate: sleep.lastSleepDate,\n                                                          endSleepDate: Date())\n        appWireframe.showPopover(popover, fromIcon: menu.iconView)\n    }\n}\n\nextension AppDelegate: NSUserNotificationCenterDelegate {\n\t\n    func userNotificationCenter (_ center: NSUserNotificationCenter, shouldPresent notification: NSUserNotification) -> Bool {\n        return true\n    }\n}\n\n"
  },
  {
    "path": "Delivery/macOS/App/AppLauncher.swift",
    "content": "//\n//  AppLauncher.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 24/12/2016.\n//  Copyright © 2016 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nlet launcherIdentifier = \"com.jirassic.macos.launcher\"\n\nextension AppDelegate {\n\n//    func launchAtStartup() {\n//        \n//        guard InternalSettings().launchAtStartup else {\n//            return\n//        }\n//        InternalSettings().launchAtStartup = true\n//        killLauncher()\n//    }\n    \n    func killLauncher() {\n        \n        for app in NSWorkspace.shared.runningApplications {\n            if app.bundleIdentifier == launcherIdentifier {\n                DistributedNotificationCenter.default()\n                    .postNotificationName(NSNotification.Name(rawValue: \"killme\"),\n                                          object: Bundle.main.bundleIdentifier!,\n                                          userInfo: nil,\n                                          deliverImmediately: true)\n                break\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/App/AppTheme.swift",
    "content": "//\n//  AppTheme.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 17/05/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport Cocoa\n\nclass AppTheme {\n    \n    var isDark: Bool {\n        get {\n            return UserDefaults.standard.string(forKey: \"AppleInterfaceStyle\") == \"Dark\"\n        }\n    }\n    var onChange: (() -> ())?\n    var textColor: NSColor {\n        get {\n            return isDark\n                    ? NSColor(red: 240/255.0, green: 190/255.0, blue: 80/255.0, alpha: 1.0)\n                    : NSColor(red: 200/255.0, green: 120/255.0, blue: 180/255.0, alpha: 1.0)\n        }\n    }\n    var lineColor: NSColor {\n        get {\n            return isDark\n                ? NSColor(calibratedWhite: 1.0, alpha: 0.2)\n                : NSColor(calibratedWhite: 0.0, alpha: 0.2)\n        }\n    }\n    var highlightLineColor: NSColor {\n        get {\n            return isDark\n                ? NSColor(calibratedWhite: 1.0, alpha: 1.0)\n                : NSColor(calibratedWhite: 0.0, alpha: 1.0)\n        }\n    }\n    \n    init() {\n        DistributedNotificationCenter.default.addObserver(self, \n                                                          selector: #selector(interfaceModeChanged(sender:)), \n                                                          name: NSNotification.Name(rawValue: \"AppleInterfaceThemeChangedNotification\"), \n                                                          object: nil)\n        \n    }\n\n    @objc func interfaceModeChanged (sender: NSNotification) {\n        onChange?()\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/App/AppViewController.swift",
    "content": "//\n//  AppViewController.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 30/11/2016.\n//  Copyright © 2016 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nclass AppViewController: NSViewController {\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        // Do view setup here.\n    }\n    \n}\n"
  },
  {
    "path": "Delivery/macOS/App/AppWireframe.swift",
    "content": "//\n//  AppWireframe.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 06/11/15.\n//  Copyright © 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\n\nenum SplitViewColumn: Int {\n    case calendar = 0\n    case tasks = 1\n}\n\nclass AppWireframe {\n\n    private var _appViewController: AppViewController?\n    private var currentController: NSViewController?\n    private var _placeholderViewController: PlaceholderViewController?\n    private var _worklogsViewController: WorklogsViewController?\n    \n    var appViewController: AppViewController {\n        \n        guard _appViewController == nil else {\n            return _appViewController!\n        }\n        _appViewController = AppViewController.instantiateFromStoryboard(\"Main\")\n        \n        return _appViewController!\n    }\n    \n    private var welcomeViewController: WelcomeViewController {\n        \n        let controller = WelcomeViewController.instantiateFromStoryboard(\"Welcome\")\n        controller.appWireframe = self\n        \n        return controller\n    }\n    \n    private var wizardViewController: WizardViewController {\n        \n        let controller = WizardViewController.instantiateFromStoryboard(\"Welcome\")\n        controller.appWireframe = self\n        \n        return controller\n    }\n    \n    private var loginViewController: LoginViewController {\n        \n        let controller = LoginViewController.instantiateFromStoryboard(\"Login\")\n        let presenter = LoginPresenter()\n        \n        controller.loginPresenter = presenter\n        presenter.userInterface = controller\n        \n        return controller\n    }\n    \n    private var tasksViewController: TasksViewController {\n        \n        let controller = TasksViewController.instantiateFromStoryboard(\"Tasks\")\n        let presenter = TasksPresenter()\n        let interactor = TasksInteractor()\n        \n        presenter.ui = controller\n        presenter.interactor = interactor\n        presenter.appWireframe = self\n        interactor.presenter = presenter\n        controller.presenter = presenter\n        controller.appWireframe = self\n        \n        return controller\n    }\n    \n    private var taskSuggestionViewController: TaskSuggestionViewController {\n        \n        let controller = TaskSuggestionViewController.instantiateFromStoryboard(\"Tasks\")\n        let presenter = TaskSuggestionPresenter()\n        \n        controller.presenter = presenter\n        presenter.userInterface = controller\n        \n        return controller\n    }\n    \n    private var settingsViewController: SettingsViewController {\n        \n        let controller = SettingsViewController.instantiateFromStoryboard(\"Settings\")\n        let presenter = SettingsPresenter()\n        let interactor = SettingsInteractor()\n        \n        presenter.userInterface = controller\n        presenter.interactor = interactor\n        interactor.presenter = presenter\n        controller.view.frame = CGRect(origin: CGPoint.zero, size: CGSize(width: 500, height: 500))\n        controller.presenter = presenter\n        controller.appWireframe = self\n        \n        return controller\n    }\n    \n    private var placeholderViewController: PlaceholderViewController {\n        return PlaceholderViewController.instantiateFromStoryboard(\"Placeholder\")\n    }\n\n    private var worklogsViewController: WorklogsViewController {\n\n        let controller = WorklogsViewController.instantiateFromStoryboard(\"Worklogs\")\n        let presenter = WorklogsPresenter()\n\n        controller.presenter = presenter\n        controller.appWireframe = self\n        presenter.userInterface = controller\n\n        return controller\n    }\n\n}\n\nextension AppWireframe {\n\t\n\tfunc showPopover (_ popover: NSPopover, fromIcon icon: NSView) {\n\t\tlet edge = NSRectEdge.minY\n\t\tlet rect = icon.frame\n\t\tpopover.show(relativeTo: rect, of: icon, preferredEdge: edge)\n\t}\n\t\n\tfunc hidePopover (_ popover: NSPopover) {\n\t\tpopover.close()\n\t}\n    \n    func removeCurrentController() {\n        if let c = currentController {\n            removeController(c)\n            currentController = nil\n        }\n    }\n    \n\tprivate func addController (_ controller: NSViewController) {\n        appViewController.addChild(controller)\n        appViewController.view.addSubview(controller.view)\n        controller.view.constrainToSuperview()\n\t}\n    \n    private func removeController (_ controller: NSViewController) {\n        controller.removeFromParent()\n        controller.view.removeFromSuperview()\n    }\n    \n    private func layerToAnimate() -> CALayer {\n        return appViewController.view.superview!.layer!\n    }\n}\n\nextension AppWireframe {\n    \n    func presentWelcomeController() -> WelcomeViewController {\n        \n        appViewController.view.frame = CGRect(origin: CGPoint.zero, size: CGSize(width: 560, height: 500))\n        let controller = self.welcomeViewController\n        addController(controller)\n        currentController = controller\n        \n        return controller\n    }\n    \n    func presentWizardController() -> WizardViewController {\n        \n        appViewController.view.frame = CGRect(origin: CGPoint.zero, size: CGSize(width: 560, height: 500))\n        let controller = self.wizardViewController\n        addController(controller)\n        currentController = controller\n        \n        return controller\n    }\n    \n    func presentLoginController() -> LoginViewController {\n        \n        let controller = self.loginViewController\n        addController(controller)\n        currentController = controller\n        \n        return controller\n    }\n    \n    func presentTasksController() -> TasksViewController {\n        \n        appViewController.view.frame = CGRect(origin: CGPoint.zero, size: CGSize(width: 560, height: 500))\n        let controller = self.tasksViewController\n        addController(controller)\n        currentController = controller\n        \n        return controller\n    }\n    \n    func presentTaskSuggestionController (startSleepDate: Date?, endSleepDate: Date) -> TaskSuggestionViewController {\n        \n        appViewController.view.frame = CGRect(origin: CGPoint.zero, size: CGSize(width: 450, height: 150))\n        let controller = self.taskSuggestionViewController\n        controller.startSleepDate = startSleepDate\n        controller.endSleepDate = endSleepDate\n        addController(controller)\n        currentController = controller\n        \n        return controller\n    }\n\n    // Placeholder\n    func presentPlaceholder (_ message: MessageViewModel, intoSplitView splitView: NSSplitView) -> PlaceholderViewController {\n        \n        var controller = _placeholderViewController\n        \n        if controller == nil {\n            controller = self.placeholderViewController\n            appViewController.addChild(controller!)\n            _placeholderViewController = controller\n        }\n        splitView.subviews[SplitViewColumn.tasks.rawValue].addSubview(controller!.view)\n        controller!.view.constrainToSuperview()\n        controller!.viewModel = message\n        \n        return controller!\n    }\n    \n    func removePlaceholder() {\n        if let controller = _placeholderViewController {\n            removeController(controller)\n            _placeholderViewController = nil\n        }\n    }\n\n    // EndDay\n    func presentEndDayController (date: Date, tasks: [Task]) -> WorklogsViewController {\n\n        let controller = self.worklogsViewController\n        controller.date = date\n        controller.tasks = tasks\n        addController(controller)\n        controller.view.constrainToSuperview()\n        _worklogsViewController = controller\n\n        return controller\n    }\n\n    func removeEndDayController() {\n        if let controller = _worklogsViewController {\n            removeController(controller)\n            _worklogsViewController = nil\n        }\n    }\n}\n\nextension AppWireframe {\n    \n    func flipToTasksController() {\n        \n        let tasksController = self.tasksViewController\n        let flip = FlipAnimation()\n        flip.animationReachedMiddle = {\n            self.removeCurrentController()\n            self.addController(tasksController)\n            self.currentController = tasksController\n        }\n        flip.animationFinished = {}\n        flip.startWithLayer(layerToAnimate())\n    }\n    \n    func flipToSettingsController() {\n        \n        let settingsController = self.settingsViewController\n        let flip = FlipAnimation()\n        flip.animationReachedMiddle = {\n            self.removeCurrentController()\n            self.removePlaceholder()\n            self.removeEndDayController()\n            self.addController(settingsController)\n            self.currentController = settingsController\n        }\n        flip.animationFinished = {}\n        flip.startWithLayer(layerToAnimate())\n    }\n    \n    func flipToLoginController() {\n        \n        let loginController = self.loginViewController\n        let flip = FlipAnimation()\n        flip.animationReachedMiddle = {\n            self.removeController(self.currentController!)\n            self.addController(loginController)\n            self.currentController = loginController\n        }\n        flip.animationFinished = {}\n        flip.startWithLayer(layerToAnimate())\n    }\n    \n    func flipToWizardController() {\n        \n        let wizardController = self.wizardViewController\n        let flip = FlipAnimation()\n        flip.animationReachedMiddle = {\n            self.removeCurrentController()\n            self.removePlaceholder()\n            self.removeEndDayController()\n            self.addController(wizardController)\n            self.currentController = wizardController\n        }\n        flip.animationFinished = {}\n        flip.startWithLayer(layerToAnimate())\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/App/LocalPreferences.swift",
    "content": "//\n//  LocalPreferences.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 23/04/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport RCPreferences\n\nenum LocalPreferences: String, RCPreferencesProtocol {\n    \n    case launchAtStartup = \"launchAtStartup\"\n    case usePercents = \"usePercents\"\n    case useDuration = \"useDuration\"\n    // Currently installed app version. In case of an update this is the version of the previous app\n    case appVersion = \"appVersion\"\n    case wizardSteps = \"wizardSteps\"\n    case settingsActiveTab = \"settingsActiveTab\"\n    case settingsJiraUrl = \"settingsJiraUrl\"\n    case settingsJiraUser = \"settingsJiraUser\"\n    case settingsJiraProjectId = \"settingsJiraProjectId\"\n    case settingsJiraProjectKey = \"settingsJiraProjectKey\"\n    case settingsJiraProjectIssueKey = \"settingsJiraProjectIssueKey\"\n    case settingsHookupCmdName = \"settingsHookupCmdName\"\n    case settingsHookupAppName = \"settingsHookupAppName\"\n    case settingsGitPaths = \"settingsGitPaths\"\n    case settingsGitAuthors = \"settingsGitAuthors\"\n    case settingsSelectedCalendars = \"settingsSelectedCalendars\"\n    case enableGit = \"enableGit\"\n    case enableJit = \"enableJit\"\n    case enableRoundingDay = \"enableRoundingDay\"\n    case enableHookup = \"enableHookup\"\n    case enableCocoaHookup = \"enableCocoaHookup\"\n    case enableHookupCredentials = \"enableHookupCredentials\"\n    case enableCalendar = \"enableCalendar\"\n    case copyWorklogsAsHtml = \"copyWorklogsAsHtml\"\n    \n    func defaultValue() -> Any {\n        switch self {\n        case .launchAtStartup:          return false\n        case .usePercents:              return true\n        case .useDuration:              return false\n        case .appVersion:               return \"\"\n        case .wizardSteps:              return []\n        case .settingsActiveTab:        return SettingsTab.tracking.rawValue\n        case .settingsJiraUrl:          return \"\"\n        case .settingsJiraUser:         return \"\"\n        case .settingsJiraProjectId:    return \"\"\n        case .settingsJiraProjectKey:   return \"\"\n        case .settingsJiraProjectIssueKey:return \"\"\n        case .settingsHookupCmdName:    return \"\"\n        case .settingsHookupAppName:    return \"\"\n        case .settingsGitPaths:         return \"\"\n        case .settingsGitAuthors:       return \"\"\n        case .settingsSelectedCalendars:return \"Work,Calendar\"\n        case .enableGit:                return false\n        case .enableJit:                return true\n        case .enableRoundingDay:        return false\n        case .enableHookup:             return false\n        case .enableCocoaHookup:        return false\n        case .enableHookupCredentials:  return false\n        case .enableCalendar:           return false\n        case .copyWorklogsAsHtml:       return false\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/App/Versioning.swift",
    "content": "//\n//  Versioning.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 11/02/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\ntypealias Versions = (shellScript: String, browserScript: String, jirassicCmd: String, jitCmd: String)\ntypealias Compatibility = (currentVersion: String, minVersion: String, available: Bool, compatible: Bool)\n\nclass Versioning {\n    \n    static let appVersion = Bundle.main.infoDictionary?[\"CFBundleShortVersionString\"] as! String\n    private let compatibilityMaps: [String: Versions] = [\n        \"17.06.14\": (shellScript: \"1.0\", browserScript: \"1.0\", jirassicCmd: \"17.06.14\", jitCmd: \"17.06.14\"),\n        \"18.04.04\": (shellScript: \"1.0\", browserScript: \"1.1\", jirassicCmd: \"17.06.14\", jitCmd: \"17.06.14\"),\n        \"18.04.25\": (shellScript: \"1.0\", browserScript: \"1.1\", jirassicCmd: \"18.04.25\", jitCmd: \"18.04.25\"),\n        \"18.12.12\": (shellScript: \"1.0\", browserScript: \"1.1\", jirassicCmd: \"18.12.12\", jitCmd: \"18.12.12\")\n        // Add a new compatibility for each app version that needs one\n    ]\n    private let versions: Versions\n    private let minVersions: Versions\n    \n    var shellScript: Compatibility {\n        return (currentVersion: versions.shellScript,\n                minVersion: minVersions.shellScript,\n                available: versions.shellScript != \"\",\n                compatible: versions.shellScript >= minVersions.shellScript)\n    }\n    var jirassic: Compatibility {\n        return (currentVersion: versions.jirassicCmd,\n                minVersion: minVersions.jirassicCmd,\n                available: versions.jirassicCmd != \"\",\n                compatible: versions.jirassicCmd >= minVersions.jirassicCmd)\n    }\n    var jit: Compatibility {\n        return (currentVersion: versions.jitCmd,\n                minVersion: minVersions.jitCmd,\n                available: versions.jitCmd != \"\",\n                compatible: versions.jitCmd >= minVersions.jitCmd)\n    }\n    var browser: Compatibility {\n        return (currentVersion: versions.browserScript,\n                minVersion: minVersions.browserScript,\n                available: versions.browserScript != \"\",\n                compatible: versions.browserScript >= minVersions.browserScript)\n    }\n    \n    init (versions: Versions) {\n        self.versions = versions\n        // Find the current compatibility map\n        var currentCompatibilityMap = compatibilityMaps[Versioning.appVersion]\n        if currentCompatibilityMap == nil {\n            let sortedKeys = compatibilityMaps.keys.sorted()\n            let lastKey = sortedKeys.last!\n            currentCompatibilityMap = compatibilityMaps[lastKey]\n        }\n        self.minVersions = currentCompatibilityMap!\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Base.lproj/Main.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"11762\" systemVersion=\"16D32\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"11762\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Application-->\n        <scene sceneID=\"JPo-4y-FX3\">\n            <objects>\n                <application id=\"hnw-xV-0zn\" sceneMemberID=\"viewController\">\n                    <menu key=\"mainMenu\" title=\"Main Menu\" systemMenu=\"main\" id=\"AYu-sK-qS6\">\n                        <items>\n                            <menuItem title=\"Jirassic\" id=\"1Xt-HY-uBw\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Jirassic\" systemMenu=\"apple\" id=\"uQy-DD-JDr\">\n                                    <items>\n                                        <menuItem title=\"About Jira Logger\" id=\"5kV-Vb-QxS\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"orderFrontStandardAboutPanel:\" target=\"Ady-hI-5gd\" id=\"Exp-CZ-Vem\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"VOq-y0-SEH\"/>\n                                        <menuItem title=\"Preferences…\" keyEquivalent=\",\" id=\"BOF-NM-1cW\"/>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"wFC-TO-SCJ\"/>\n                                        <menuItem title=\"Services\" id=\"NMo-om-nkz\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Services\" systemMenu=\"services\" id=\"hz9-B4-Xy5\"/>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"4je-JR-u6R\"/>\n                                        <menuItem title=\"Hide Jira Logger\" keyEquivalent=\"h\" id=\"Olw-nP-bQN\">\n                                            <connections>\n                                                <action selector=\"hide:\" target=\"Ady-hI-5gd\" id=\"PnN-Uc-m68\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Hide Others\" keyEquivalent=\"h\" id=\"Vdr-fp-XzO\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"hideOtherApplications:\" target=\"Ady-hI-5gd\" id=\"VT4-aY-XCT\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Show All\" id=\"Kd2-mp-pUS\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"unhideAllApplications:\" target=\"Ady-hI-5gd\" id=\"Dhg-Le-xox\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"kCx-OE-vgT\"/>\n                                        <menuItem title=\"Quit Jira Logger\" keyEquivalent=\"q\" id=\"4sb-4s-VLi\">\n                                            <connections>\n                                                <action selector=\"terminate:\" target=\"Ady-hI-5gd\" id=\"Te7-pn-YzF\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"File\" id=\"dMs-cI-mzQ\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"File\" id=\"bib-Uj-vzu\">\n                                    <items>\n                                        <menuItem title=\"New\" keyEquivalent=\"n\" id=\"Was-JA-tGl\">\n                                            <connections>\n                                                <action selector=\"newDocument:\" target=\"Ady-hI-5gd\" id=\"4Si-XN-c54\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Open…\" keyEquivalent=\"o\" id=\"IAo-SY-fd9\">\n                                            <connections>\n                                                <action selector=\"openDocument:\" target=\"Ady-hI-5gd\" id=\"bVn-NM-KNZ\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Open Recent\" id=\"tXI-mr-wws\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Open Recent\" systemMenu=\"recentDocuments\" id=\"oas-Oc-fiZ\">\n                                                <items>\n                                                    <menuItem title=\"Clear Menu\" id=\"vNY-rz-j42\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"clearRecentDocuments:\" target=\"Ady-hI-5gd\" id=\"Daa-9d-B3U\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"m54-Is-iLE\"/>\n                                        <menuItem title=\"Close\" keyEquivalent=\"w\" id=\"DVo-aG-piG\">\n                                            <connections>\n                                                <action selector=\"performClose:\" target=\"Ady-hI-5gd\" id=\"HmO-Ls-i7Q\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Save…\" keyEquivalent=\"s\" id=\"pxx-59-PXV\">\n                                            <connections>\n                                                <action selector=\"saveDocument:\" target=\"Ady-hI-5gd\" id=\"teZ-XB-qJY\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Save As…\" keyEquivalent=\"S\" id=\"Bw7-FT-i3A\">\n                                            <connections>\n                                                <action selector=\"saveDocumentAs:\" target=\"Ady-hI-5gd\" id=\"mDf-zr-I0C\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Revert to Saved\" id=\"KaW-ft-85H\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"revertDocumentToSaved:\" target=\"Ady-hI-5gd\" id=\"iJ3-Pv-kwq\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"aJh-i4-bef\"/>\n                                        <menuItem title=\"Page Setup…\" keyEquivalent=\"P\" id=\"qIS-W8-SiK\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" shift=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"runPageLayout:\" target=\"Ady-hI-5gd\" id=\"Din-rz-gC5\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Print…\" keyEquivalent=\"p\" id=\"aTl-1u-JFS\">\n                                            <connections>\n                                                <action selector=\"print:\" target=\"Ady-hI-5gd\" id=\"qaZ-4w-aoO\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Edit\" id=\"5QF-Oa-p0T\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Edit\" id=\"W48-6f-4Dl\">\n                                    <items>\n                                        <menuItem title=\"Undo\" keyEquivalent=\"z\" id=\"dRJ-4n-Yzg\">\n                                            <connections>\n                                                <action selector=\"undo:\" target=\"Ady-hI-5gd\" id=\"M6e-cu-g7V\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Redo\" keyEquivalent=\"Z\" id=\"6dh-zS-Vam\">\n                                            <connections>\n                                                <action selector=\"redo:\" target=\"Ady-hI-5gd\" id=\"oIA-Rs-6OD\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"WRV-NI-Exz\"/>\n                                        <menuItem title=\"Cut\" keyEquivalent=\"x\" id=\"uRl-iY-unG\">\n                                            <connections>\n                                                <action selector=\"cut:\" target=\"Ady-hI-5gd\" id=\"YJe-68-I9s\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Copy\" keyEquivalent=\"c\" id=\"x3v-GG-iWU\">\n                                            <connections>\n                                                <action selector=\"copy:\" target=\"Ady-hI-5gd\" id=\"G1f-GL-Joy\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Paste\" keyEquivalent=\"v\" id=\"gVA-U4-sdL\">\n                                            <connections>\n                                                <action selector=\"paste:\" target=\"Ady-hI-5gd\" id=\"UvS-8e-Qdg\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Paste and Match Style\" keyEquivalent=\"V\" id=\"WeT-3V-zwk\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"pasteAsPlainText:\" target=\"Ady-hI-5gd\" id=\"cEh-KX-wJQ\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Delete\" id=\"pa3-QI-u2k\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"delete:\" target=\"Ady-hI-5gd\" id=\"0Mk-Ml-PaM\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Select All\" keyEquivalent=\"a\" id=\"Ruw-6m-B2m\">\n                                            <connections>\n                                                <action selector=\"selectAll:\" target=\"Ady-hI-5gd\" id=\"VNm-Mi-diN\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"uyl-h8-XO2\"/>\n                                        <menuItem title=\"Find\" id=\"4EN-yA-p0u\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Find\" id=\"1b7-l0-nxx\">\n                                                <items>\n                                                    <menuItem title=\"Find…\" tag=\"1\" keyEquivalent=\"f\" id=\"Xz5-n4-O0W\">\n                                                        <connections>\n                                                            <action selector=\"performFindPanelAction:\" target=\"Ady-hI-5gd\" id=\"cD7-Qs-BN4\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Find and Replace…\" tag=\"12\" keyEquivalent=\"f\" id=\"YEy-JH-Tfz\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                                        <connections>\n                                                            <action selector=\"performFindPanelAction:\" target=\"Ady-hI-5gd\" id=\"WD3-Gg-5AJ\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Find Next\" tag=\"2\" keyEquivalent=\"g\" id=\"q09-fT-Sye\">\n                                                        <connections>\n                                                            <action selector=\"performFindPanelAction:\" target=\"Ady-hI-5gd\" id=\"NDo-RZ-v9R\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Find Previous\" tag=\"3\" keyEquivalent=\"G\" id=\"OwM-mh-QMV\">\n                                                        <connections>\n                                                            <action selector=\"performFindPanelAction:\" target=\"Ady-hI-5gd\" id=\"HOh-sY-3ay\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Use Selection for Find\" tag=\"7\" keyEquivalent=\"e\" id=\"buJ-ug-pKt\">\n                                                        <connections>\n                                                            <action selector=\"performFindPanelAction:\" target=\"Ady-hI-5gd\" id=\"U76-nv-p5D\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Jump to Selection\" keyEquivalent=\"j\" id=\"S0p-oC-mLd\">\n                                                        <connections>\n                                                            <action selector=\"centerSelectionInVisibleArea:\" target=\"Ady-hI-5gd\" id=\"IOG-6D-g5B\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem title=\"Spelling and Grammar\" id=\"Dv1-io-Yv7\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Spelling\" id=\"3IN-sU-3Bg\">\n                                                <items>\n                                                    <menuItem title=\"Show Spelling and Grammar\" keyEquivalent=\":\" id=\"HFo-cy-zxI\">\n                                                        <connections>\n                                                            <action selector=\"showGuessPanel:\" target=\"Ady-hI-5gd\" id=\"vFj-Ks-hy3\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Check Document Now\" keyEquivalent=\";\" id=\"hz2-CU-CR7\">\n                                                        <connections>\n                                                            <action selector=\"checkSpelling:\" target=\"Ady-hI-5gd\" id=\"fz7-VC-reM\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"bNw-od-mp5\"/>\n                                                    <menuItem title=\"Check Spelling While Typing\" id=\"rbD-Rh-wIN\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleContinuousSpellChecking:\" target=\"Ady-hI-5gd\" id=\"7w6-Qz-0kB\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Check Grammar With Spelling\" id=\"mK6-2p-4JG\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleGrammarChecking:\" target=\"Ady-hI-5gd\" id=\"muD-Qn-j4w\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Correct Spelling Automatically\" id=\"78Y-hA-62v\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleAutomaticSpellingCorrection:\" target=\"Ady-hI-5gd\" id=\"2lM-Qi-WAP\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem title=\"Substitutions\" id=\"9ic-FL-obx\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Substitutions\" id=\"FeM-D8-WVr\">\n                                                <items>\n                                                    <menuItem title=\"Show Substitutions\" id=\"z6F-FW-3nz\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"orderFrontSubstitutionsPanel:\" target=\"Ady-hI-5gd\" id=\"oku-mr-iSq\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"gPx-C9-uUO\"/>\n                                                    <menuItem title=\"Smart Copy/Paste\" id=\"9yt-4B-nSM\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleSmartInsertDelete:\" target=\"Ady-hI-5gd\" id=\"3IJ-Se-DZD\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Smart Quotes\" id=\"hQb-2v-fYv\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleAutomaticQuoteSubstitution:\" target=\"Ady-hI-5gd\" id=\"ptq-xd-QOA\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Smart Dashes\" id=\"rgM-f4-ycn\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleAutomaticDashSubstitution:\" target=\"Ady-hI-5gd\" id=\"oCt-pO-9gS\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Smart Links\" id=\"cwL-P1-jid\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleAutomaticLinkDetection:\" target=\"Ady-hI-5gd\" id=\"Gip-E3-Fov\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Data Detectors\" id=\"tRr-pd-1PS\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleAutomaticDataDetection:\" target=\"Ady-hI-5gd\" id=\"R1I-Nq-Kbl\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Text Replacement\" id=\"HFQ-gK-NFA\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleAutomaticTextReplacement:\" target=\"Ady-hI-5gd\" id=\"DvP-Fe-Py6\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem title=\"Transformations\" id=\"2oI-Rn-ZJC\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Transformations\" id=\"c8a-y6-VQd\">\n                                                <items>\n                                                    <menuItem title=\"Make Upper Case\" id=\"vmV-6d-7jI\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"uppercaseWord:\" target=\"Ady-hI-5gd\" id=\"sPh-Tk-edu\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Make Lower Case\" id=\"d9M-CD-aMd\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"lowercaseWord:\" target=\"Ady-hI-5gd\" id=\"iUZ-b5-hil\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Capitalize\" id=\"UEZ-Bs-lqG\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"capitalizeWord:\" target=\"Ady-hI-5gd\" id=\"26H-TL-nsh\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem title=\"Speech\" id=\"xrE-MZ-jX0\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Speech\" id=\"3rS-ZA-NoH\">\n                                                <items>\n                                                    <menuItem title=\"Start Speaking\" id=\"Ynk-f8-cLZ\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"startSpeaking:\" target=\"Ady-hI-5gd\" id=\"654-Ng-kyl\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Stop Speaking\" id=\"Oyz-dy-DGm\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"stopSpeaking:\" target=\"Ady-hI-5gd\" id=\"dX8-6p-jy9\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Format\" id=\"jxT-CU-nIS\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Format\" id=\"GEO-Iw-cKr\">\n                                    <items>\n                                        <menuItem title=\"Font\" id=\"Gi5-1S-RQB\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Font\" systemMenu=\"font\" id=\"aXa-aM-Jaq\">\n                                                <items>\n                                                    <menuItem title=\"Show Fonts\" keyEquivalent=\"t\" id=\"Q5e-8K-NDq\"/>\n                                                    <menuItem title=\"Bold\" tag=\"2\" keyEquivalent=\"b\" id=\"GB9-OM-e27\"/>\n                                                    <menuItem title=\"Italic\" tag=\"1\" keyEquivalent=\"i\" id=\"Vjx-xi-njq\"/>\n                                                    <menuItem title=\"Underline\" keyEquivalent=\"u\" id=\"WRG-CD-K1S\">\n                                                        <connections>\n                                                            <action selector=\"underline:\" target=\"Ady-hI-5gd\" id=\"FYS-2b-JAY\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"5gT-KC-WSO\"/>\n                                                    <menuItem title=\"Bigger\" tag=\"3\" keyEquivalent=\"+\" id=\"Ptp-SP-VEL\"/>\n                                                    <menuItem title=\"Smaller\" tag=\"4\" keyEquivalent=\"-\" id=\"i1d-Er-qST\"/>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"kx3-Dk-x3B\"/>\n                                                    <menuItem title=\"Kern\" id=\"jBQ-r6-VK2\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <menu key=\"submenu\" title=\"Kern\" id=\"tlD-Oa-oAM\">\n                                                            <items>\n                                                                <menuItem title=\"Use Default\" id=\"GUa-eO-cwY\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"useStandardKerning:\" target=\"Ady-hI-5gd\" id=\"6dk-9l-Ckg\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Use None\" id=\"cDB-IK-hbR\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"turnOffKerning:\" target=\"Ady-hI-5gd\" id=\"U8a-gz-Maa\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Tighten\" id=\"46P-cB-AYj\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"tightenKerning:\" target=\"Ady-hI-5gd\" id=\"hr7-Nz-8ro\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Loosen\" id=\"ogc-rX-tC1\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"loosenKerning:\" target=\"Ady-hI-5gd\" id=\"8i4-f9-FKE\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                            </items>\n                                                        </menu>\n                                                    </menuItem>\n                                                    <menuItem title=\"Ligatures\" id=\"o6e-r0-MWq\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <menu key=\"submenu\" title=\"Ligatures\" id=\"w0m-vy-SC9\">\n                                                            <items>\n                                                                <menuItem title=\"Use Default\" id=\"agt-UL-0e3\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"useStandardLigatures:\" target=\"Ady-hI-5gd\" id=\"7uR-wd-Dx6\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Use None\" id=\"J7y-lM-qPV\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"turnOffLigatures:\" target=\"Ady-hI-5gd\" id=\"iX2-gA-Ilz\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Use All\" id=\"xQD-1f-W4t\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"useAllLigatures:\" target=\"Ady-hI-5gd\" id=\"KcB-kA-TuK\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                            </items>\n                                                        </menu>\n                                                    </menuItem>\n                                                    <menuItem title=\"Baseline\" id=\"OaQ-X3-Vso\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <menu key=\"submenu\" title=\"Baseline\" id=\"ijk-EB-dga\">\n                                                            <items>\n                                                                <menuItem title=\"Use Default\" id=\"3Om-Ey-2VK\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"unscript:\" target=\"Ady-hI-5gd\" id=\"0vZ-95-Ywn\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Superscript\" id=\"Rqc-34-cIF\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"superscript:\" target=\"Ady-hI-5gd\" id=\"3qV-fo-wpU\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Subscript\" id=\"I0S-gh-46l\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"subscript:\" target=\"Ady-hI-5gd\" id=\"Q6W-4W-IGz\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Raise\" id=\"2h7-ER-AoG\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"raiseBaseline:\" target=\"Ady-hI-5gd\" id=\"4sk-31-7Q9\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem title=\"Lower\" id=\"1tx-W0-xDw\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"lowerBaseline:\" target=\"Ady-hI-5gd\" id=\"OF1-bc-KW4\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                            </items>\n                                                        </menu>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"Ndw-q3-faq\"/>\n                                                    <menuItem title=\"Show Colors\" keyEquivalent=\"C\" id=\"bgn-CT-cEk\">\n                                                        <connections>\n                                                            <action selector=\"orderFrontColorPanel:\" target=\"Ady-hI-5gd\" id=\"mSX-Xz-DV3\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"iMs-zA-UFJ\"/>\n                                                    <menuItem title=\"Copy Style\" keyEquivalent=\"c\" id=\"5Vv-lz-BsD\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                                        <connections>\n                                                            <action selector=\"copyFont:\" target=\"Ady-hI-5gd\" id=\"GJO-xA-L4q\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Paste Style\" keyEquivalent=\"v\" id=\"vKC-jM-MkH\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                                        <connections>\n                                                            <action selector=\"pasteFont:\" target=\"Ady-hI-5gd\" id=\"JfD-CL-leO\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem title=\"Text\" id=\"Fal-I4-PZk\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Text\" id=\"d9c-me-L2H\">\n                                                <items>\n                                                    <menuItem title=\"Align Left\" keyEquivalent=\"{\" id=\"ZM1-6Q-yy1\">\n                                                        <connections>\n                                                            <action selector=\"alignLeft:\" target=\"Ady-hI-5gd\" id=\"zUv-R1-uAa\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Center\" keyEquivalent=\"|\" id=\"VIY-Ag-zcb\">\n                                                        <connections>\n                                                            <action selector=\"alignCenter:\" target=\"Ady-hI-5gd\" id=\"spX-mk-kcS\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Justify\" id=\"J5U-5w-g23\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"alignJustified:\" target=\"Ady-hI-5gd\" id=\"ljL-7U-jND\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Align Right\" keyEquivalent=\"}\" id=\"wb2-vD-lq4\">\n                                                        <connections>\n                                                            <action selector=\"alignRight:\" target=\"Ady-hI-5gd\" id=\"r48-bG-YeY\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"4s2-GY-VfK\"/>\n                                                    <menuItem title=\"Writing Direction\" id=\"H1b-Si-o9J\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <menu key=\"submenu\" title=\"Writing Direction\" id=\"8mr-sm-Yjd\">\n                                                            <items>\n                                                                <menuItem title=\"Paragraph\" enabled=\"NO\" id=\"ZvO-Gk-QUH\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                </menuItem>\n                                                                <menuItem id=\"YGs-j5-SAR\">\n                                                                    <string key=\"title\">\tDefault</string>\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"makeBaseWritingDirectionNatural:\" target=\"Ady-hI-5gd\" id=\"qtV-5e-UBP\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem id=\"Lbh-J2-qVU\">\n                                                                    <string key=\"title\">\tLeft to Right</string>\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"makeBaseWritingDirectionLeftToRight:\" target=\"Ady-hI-5gd\" id=\"S0X-9S-QSf\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem id=\"jFq-tB-4Kx\">\n                                                                    <string key=\"title\">\tRight to Left</string>\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"makeBaseWritingDirectionRightToLeft:\" target=\"Ady-hI-5gd\" id=\"5fk-qB-AqJ\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem isSeparatorItem=\"YES\" id=\"swp-gr-a21\"/>\n                                                                <menuItem title=\"Selection\" enabled=\"NO\" id=\"cqv-fj-IhA\">\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                </menuItem>\n                                                                <menuItem id=\"Nop-cj-93Q\">\n                                                                    <string key=\"title\">\tDefault</string>\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"makeTextWritingDirectionNatural:\" target=\"Ady-hI-5gd\" id=\"lPI-Se-ZHp\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem id=\"BgM-ve-c93\">\n                                                                    <string key=\"title\">\tLeft to Right</string>\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"makeTextWritingDirectionLeftToRight:\" target=\"Ady-hI-5gd\" id=\"caW-Bv-w94\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                                <menuItem id=\"RB4-Sm-HuC\">\n                                                                    <string key=\"title\">\tRight to Left</string>\n                                                                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                                    <connections>\n                                                                        <action selector=\"makeTextWritingDirectionRightToLeft:\" target=\"Ady-hI-5gd\" id=\"EXD-6r-ZUu\"/>\n                                                                    </connections>\n                                                                </menuItem>\n                                                            </items>\n                                                        </menu>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"fKy-g9-1gm\"/>\n                                                    <menuItem title=\"Show Ruler\" id=\"vLm-3I-IUL\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"toggleRuler:\" target=\"Ady-hI-5gd\" id=\"FOx-HJ-KwY\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Copy Ruler\" keyEquivalent=\"c\" id=\"MkV-Pr-PK5\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\" control=\"YES\" command=\"YES\"/>\n                                                        <connections>\n                                                            <action selector=\"copyRuler:\" target=\"Ady-hI-5gd\" id=\"71i-fW-3W2\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Paste Ruler\" keyEquivalent=\"v\" id=\"LVM-kO-fVI\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\" control=\"YES\" command=\"YES\"/>\n                                                        <connections>\n                                                            <action selector=\"pasteRuler:\" target=\"Ady-hI-5gd\" id=\"cSh-wd-qM2\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"View\" id=\"H8h-7b-M4v\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"View\" id=\"HyV-fh-RgO\">\n                                    <items>\n                                        <menuItem title=\"Show Toolbar\" keyEquivalent=\"t\" id=\"snW-S8-Cw5\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"toggleToolbarShown:\" target=\"Ady-hI-5gd\" id=\"BXY-wc-z0C\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Customize Toolbar…\" id=\"1UK-8n-QPP\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"runToolbarCustomizationPalette:\" target=\"Ady-hI-5gd\" id=\"pQI-g3-MTW\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Window\" id=\"aUF-d1-5bR\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Window\" systemMenu=\"window\" id=\"Td7-aD-5lo\">\n                                    <items>\n                                        <menuItem title=\"Minimize\" keyEquivalent=\"m\" id=\"OY7-WF-poV\">\n                                            <connections>\n                                                <action selector=\"performMiniaturize:\" target=\"Ady-hI-5gd\" id=\"VwT-WD-YPe\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Zoom\" id=\"R4o-n2-Eq4\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"performZoom:\" target=\"Ady-hI-5gd\" id=\"DIl-cC-cCs\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"eu3-7i-yIM\"/>\n                                        <menuItem title=\"Bring All to Front\" id=\"LE2-aR-0XJ\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"arrangeInFront:\" target=\"Ady-hI-5gd\" id=\"DRN-fu-gQh\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Help\" id=\"wpr-3q-Mcd\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Help\" systemMenu=\"help\" id=\"F2S-fz-NVQ\">\n                                    <items>\n                                        <menuItem title=\"Jira Logger Help\" keyEquivalent=\"?\" id=\"FKE-Sm-Kum\">\n                                            <connections>\n                                                <action selector=\"showHelp:\" target=\"Ady-hI-5gd\" id=\"y7X-2Q-9no\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                        </items>\n                    </menu>\n                    <connections>\n                        <outlet property=\"delegate\" destination=\"Voe-Tx-rLC\" id=\"PrD-fu-P6m\"/>\n                    </connections>\n                </application>\n                <customObject id=\"Voe-Tx-rLC\" customClass=\"AppDelegate\" customModule=\"Jirassic\" customModuleProvider=\"target\"/>\n                <customObject id=\"Ady-hI-5gd\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"75\" y=\"-1039\"/>\n        </scene>\n        <!--App View Controller-->\n        <scene sceneID=\"cm9-ck-QOK\">\n            <objects>\n                <viewController storyboardIdentifier=\"AppViewController\" id=\"iaY-ro-C5e\" customClass=\"AppViewController\" customModule=\"Jirassic\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" id=\"msN-JB-seW\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"450\" height=\"300\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                    </view>\n                </viewController>\n                <customObject id=\"Ub3-7n-fsG\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"77\" y=\"-780\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Bridging-Header.h",
    "content": "//\n//  BridgingHeader.h\n//  Jirassic\n//\n//  Created by Cristian Baluta on 28/03/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\n#ifndef Bridging_Header_h\n#define Bridging_Header_h\n\n#import <sqlite3.h>\n\n#endif /* BridgingHeader_h */\n"
  },
  {
    "path": "Delivery/macOS/BuildScript.sh",
    "content": "#!/bin/sh\n\n#if [ ${CONFIGURATION} == \"Release\" ]; then\n\n    COMMIT_COUNT=$(git rev-list HEAD --count);\n    BUNDLE_VERSION=\"$COMMIT_COUNT\"\n\n    now=\"$(date +'%y.%m.%d')\"\n    SHORT_VERSION_STRING=\"$now\"\n\n    echo \"APP VERSION: $SHORT_VERSION_STRING - BUILD: $COMMIT_COUNT\"\n\n    /usr/libexec/Plistbuddy -c \"Set :CFBundleShortVersionString $SHORT_VERSION_STRING\" \"${INFOPLIST_FILE}\"\n    /usr/libexec/Plistbuddy -c \"Set :CFBundleVersion $BUNDLE_VERSION\" \"${INFOPLIST_FILE}\"\n\n#fi;\n"
  },
  {
    "path": "Delivery/macOS/Components/Components.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14460.31\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Time Box View Controller-->\n        <scene sceneID=\"bf9-Yh-ewM\">\n            <objects>\n                <viewController storyboardIdentifier=\"TimeBoxViewController\" id=\"clr-qn-UDB\" customClass=\"TimeBoxViewController\" customModule=\"Jirassic\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" id=\"DLb-3j-LjV\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"278\" height=\"102\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                        <subviews>\n                            <textField focusRingType=\"none\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Zpe-WX-jdh\">\n                                <rect key=\"frame\" x=\"38\" y=\"55\" width=\"202\" height=\"37\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" focusRingType=\"none\" alignment=\"center\" placeholderString=\"--:--\" id=\"36R-23-SMb\">\n                                    <font key=\"font\" size=\"30\" name=\"HelveticaNeue-Bold\"/>\n                                    <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" white=\"1\" alpha=\"0.40000000000000002\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                </textFieldCell>\n                                <connections>\n                                    <outlet property=\"delegate\" destination=\"clr-qn-UDB\" id=\"l8U-Bq-gJT\"/>\n                                </connections>\n                            </textField>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"hr8-KW-SK0\">\n                                <rect key=\"frame\" x=\"10\" y=\"7\" width=\"53\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"Cancel\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"Rmu-eQ-W98\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleCancelButton:\" target=\"clr-qn-UDB\" id=\"Djc-RP-Xsj\"/>\n                                </connections>\n                            </button>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"cbV-MY-FcK\">\n                                <rect key=\"frame\" x=\"226\" y=\"7\" width=\"42\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"Save\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"z7t-Rn-4ZE\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleSaveButton:\" target=\"clr-qn-UDB\" id=\"Rnq-Um-Qqc\"/>\n                                </connections>\n                            </button>\n                            <textField verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Z2O-sK-4ts\">\n                                <rect key=\"frame\" x=\"8\" y=\"34\" width=\"262\" height=\"13\"/>\n                                <textFieldCell key=\"cell\" enabled=\"NO\" title=\"Time predicting typer:\" id=\"znZ-Ie-Qz2\">\n                                    <font key=\"font\" metaFont=\"system\" size=\"10\"/>\n                                    <color key=\"textColor\" name=\"disabledControlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <button horizontalHuggingPriority=\"750\" verticalHuggingPriority=\"750\" fixedFrame=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"j8b-jG-TNc\">\n                                <rect key=\"frame\" x=\"9\" y=\"55\" width=\"13\" height=\"13\"/>\n                                <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                <buttonCell key=\"cell\" type=\"disclosureTriangle\" bezelStyle=\"disclosure\" imagePosition=\"only\" alignment=\"left\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"qhn-jY-8CD\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" changeBackground=\"YES\" changeGray=\"YES\" lightByContents=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleDisclosureButton:\" target=\"clr-qn-UDB\" id=\"yly-GX-lf6\"/>\n                                </connections>\n                            </button>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"Z2O-sK-4ts\" firstAttribute=\"top\" secondItem=\"Zpe-WX-jdh\" secondAttribute=\"bottom\" constant=\"8\" id=\"4Nv-Sq-eMH\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"Zpe-WX-jdh\" secondAttribute=\"trailing\" constant=\"40\" id=\"AT2-sP-zQ6\"/>\n                            <constraint firstItem=\"hr8-KW-SK0\" firstAttribute=\"top\" secondItem=\"Z2O-sK-4ts\" secondAttribute=\"bottom\" constant=\"8\" id=\"Cnz-P9-ij7\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"cbV-MY-FcK\" secondAttribute=\"trailing\" constant=\"10\" id=\"F0n-2q-Zzh\"/>\n                            <constraint firstItem=\"hr8-KW-SK0\" firstAttribute=\"leading\" secondItem=\"DLb-3j-LjV\" secondAttribute=\"leading\" constant=\"10\" id=\"JUr-Gy-oLJ\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"cbV-MY-FcK\" secondAttribute=\"bottom\" constant=\"8\" id=\"TzT-ud-yab\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"hr8-KW-SK0\" secondAttribute=\"bottom\" constant=\"8\" id=\"Zgn-ac-Fo9\"/>\n                            <constraint firstItem=\"Z2O-sK-4ts\" firstAttribute=\"leading\" secondItem=\"DLb-3j-LjV\" secondAttribute=\"leading\" constant=\"10\" id=\"fdT-o8-rWb\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"Z2O-sK-4ts\" secondAttribute=\"trailing\" constant=\"10\" id=\"ite-f9-kJF\"/>\n                            <constraint firstItem=\"Zpe-WX-jdh\" firstAttribute=\"leading\" secondItem=\"DLb-3j-LjV\" secondAttribute=\"leading\" constant=\"40\" id=\"pyH-iu-1Gy\"/>\n                            <constraint firstItem=\"Zpe-WX-jdh\" firstAttribute=\"top\" secondItem=\"DLb-3j-LjV\" secondAttribute=\"top\" constant=\"10\" id=\"uUO-Cj-HVS\"/>\n                        </constraints>\n                    </view>\n                    <connections>\n                        <outlet property=\"disclosureButton\" destination=\"j8b-jG-TNc\" id=\"wwu-IN-YjU\"/>\n                        <outlet property=\"instructionsTextField\" destination=\"Z2O-sK-4ts\" id=\"FIb-Uz-cHz\"/>\n                        <outlet property=\"timeTextField\" destination=\"Zpe-WX-jdh\" id=\"mRs-16-JYL\"/>\n                    </connections>\n                </viewController>\n                <customObject id=\"XDs-oo-fi2\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"519\" y=\"-164.5\"/>\n        </scene>\n        <!--New Task View Controller-->\n        <scene sceneID=\"fte-Yu-h1Q\">\n            <objects>\n                <viewController storyboardIdentifier=\"NewTaskViewController\" id=\"4kA-nc-Buc\" customClass=\"NewTaskViewController\" customModule=\"Jirassic\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" id=\"Utc-sZ-mvk\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"301\" height=\"207\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                        <subviews>\n                            <textField focusRingType=\"none\" verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"XtI-h1-kcK\">\n                                <rect key=\"frame\" x=\"89\" y=\"64\" width=\"204\" height=\"70\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"70\" id=\"gRi-81-6wN\"/>\n                                </constraints>\n                                <textFieldCell key=\"cell\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" focusRingType=\"none\" alignment=\"left\" placeholderString=\"What did you do in this task?\" id=\"u8b-Z9-qfq\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"textColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" white=\"1\" alpha=\"0.0\" colorSpace=\"deviceWhite\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField focusRingType=\"none\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"1A9-vu-6o0\">\n                                <rect key=\"frame\" x=\"229\" y=\"42\" width=\"64\" height=\"17\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"17\" id=\"9wn-rK-GBC\"/>\n                                    <constraint firstAttribute=\"width\" constant=\"60\" id=\"p1U-gE-6IY\"/>\n                                </constraints>\n                                <textFieldCell key=\"cell\" lineBreakMode=\"truncatingTail\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" focusRingType=\"none\" alignment=\"left\" placeholderString=\"--:--\" id=\"I4V-Qi-gnT\">\n                                    <font key=\"font\" metaFont=\"systemBold\"/>\n                                    <color key=\"textColor\" name=\"textColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" white=\"1\" alpha=\"0.0\" colorSpace=\"deviceWhite\"/>\n                                </textFieldCell>\n                                <connections>\n                                    <outlet property=\"delegate\" destination=\"4kA-nc-Buc\" id=\"0qG-aN-UUV\"/>\n                                </connections>\n                            </textField>\n                            <textField focusRingType=\"none\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"5lm-GW-ctz\">\n                                <rect key=\"frame\" x=\"89\" y=\"42\" width=\"64\" height=\"17\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"60\" id=\"FLw-Wh-xJa\"/>\n                                    <constraint firstAttribute=\"height\" constant=\"17\" id=\"cBk-IQ-vKV\"/>\n                                </constraints>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" focusRingType=\"none\" alignment=\"left\" placeholderString=\"--:--\" id=\"sRl-cm-a06\">\n                                    <font key=\"font\" metaFont=\"systemBold\"/>\n                                    <color key=\"textColor\" name=\"selectedControlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" white=\"1\" alpha=\"0.0\" colorSpace=\"deviceWhite\"/>\n                                </textFieldCell>\n                                <connections>\n                                    <outlet property=\"delegate\" destination=\"4kA-nc-Buc\" id=\"Az9-at-hnS\"/>\n                                </connections>\n                            </textField>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"cs9-1y-9Eu\">\n                                <rect key=\"frame\" x=\"249\" y=\"7\" width=\"42\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"Save\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"hih-Ie-oif\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleSaveButton:\" target=\"4kA-nc-Buc\" id=\"OqK-GL-iF8\"/>\n                                </connections>\n                            </button>\n                            <popUpButton verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"qKo-2H-jn0\">\n                                <rect key=\"frame\" x=\"91\" y=\"178\" width=\"200\" height=\"19\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"200\" id=\"SAU-og-n5W\"/>\n                                </constraints>\n                                <popUpButtonCell key=\"cell\" type=\"roundRect\" title=\"Task\" bezelStyle=\"roundedRect\" alignment=\"left\" lineBreakMode=\"truncatingTail\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" selectedItem=\"Aus-pV-O51\" id=\"J1r-P8-Mbw\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                    <menu key=\"menu\" id=\"NRJ-K6-SBs\">\n                                        <items>\n                                            <menuItem title=\"Task\" state=\"on\" id=\"Aus-pV-O51\"/>\n                                            <menuItem title=\"Item 2\" id=\"ibQ-C2-7A4\"/>\n                                            <menuItem title=\"Item 3\" id=\"WsO-Q3-7Vd\"/>\n                                        </items>\n                                    </menu>\n                                </popUpButtonCell>\n                                <connections>\n                                    <action selector=\"handleTaskTypeSelector:\" target=\"4kA-nc-Buc\" id=\"WYB-dq-MfN\"/>\n                                </connections>\n                            </popUpButton>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"5eK-M8-1cc\">\n                                <rect key=\"frame\" x=\"10\" y=\"7\" width=\"53\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"Cancel\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"rcd-U3-vS7\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleCancelButton:\" target=\"4kA-nc-Buc\" id=\"e87-kL-XMk\"/>\n                                </connections>\n                            </button>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"X9a-6K-rru\">\n                                <rect key=\"frame\" x=\"8\" y=\"179\" width=\"70\" height=\"17\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"66\" id=\"MIk-jm-uUh\"/>\n                                </constraints>\n                                <textFieldCell key=\"cell\" lineBreakMode=\"clipping\" alignment=\"right\" title=\"Type\" id=\"xQP-pJ-NGA\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"odU-e3-gDg\">\n                                <rect key=\"frame\" x=\"8\" y=\"148\" width=\"70\" height=\"17\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"66\" id=\"ZcL-jp-wbT\"/>\n                                </constraints>\n                                <textFieldCell key=\"cell\" lineBreakMode=\"clipping\" alignment=\"right\" title=\"Task id\" id=\"ptB-Xz-2ES\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"PPX-mq-tL3\">\n                                <rect key=\"frame\" x=\"8\" y=\"117\" width=\"70\" height=\"17\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"66\" id=\"KZ9-Ds-9ak\"/>\n                                </constraints>\n                                <textFieldCell key=\"cell\" lineBreakMode=\"clipping\" alignment=\"right\" title=\"Notes\" id=\"Yu0-hE-dMs\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField focusRingType=\"none\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Ufh-DL-87n\">\n                                <rect key=\"frame\" x=\"89\" y=\"148\" width=\"204\" height=\"17\"/>\n                                <string key=\"toolTip\">Usually Jira task ids which are of form LETTER-NUMBER, but can be anything really, important is that same task should have same id</string>\n                                <textFieldCell key=\"cell\" lineBreakMode=\"truncatingTail\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" focusRingType=\"none\" alignment=\"left\" placeholderString=\"AB-1234\" id=\"av7-dW-AXk\">\n                                    <font key=\"font\" metaFont=\"systemBold\"/>\n                                    <color key=\"textColor\" name=\"textColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" white=\"1\" alpha=\"0.0\" colorSpace=\"deviceWhite\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"V8B-Ob-jbo\">\n                                <rect key=\"frame\" x=\"160\" y=\"42\" width=\"58\" height=\"17\"/>\n                                <textFieldCell key=\"cell\" lineBreakMode=\"clipping\" alignment=\"right\" title=\"End date\" id=\"gNl-Bj-Aw2\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Xzx-B3-1Nh\">\n                                <rect key=\"frame\" x=\"10\" y=\"42\" width=\"66\" height=\"17\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"66\" id=\"56f-dI-hFp\"/>\n                                </constraints>\n                                <buttonCell key=\"cell\" type=\"bevel\" title=\"Start date\" bezelStyle=\"rounded\" alignment=\"right\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"kVa-dY-sdW\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleDurationButton:\" target=\"4kA-nc-Buc\" id=\"DD4-u7-Dbd\"/>\n                                </connections>\n                            </button>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"XtI-h1-kcK\" firstAttribute=\"leading\" secondItem=\"PPX-mq-tL3\" secondAttribute=\"trailing\" constant=\"15\" id=\"0cr-fx-NC0\"/>\n                            <constraint firstItem=\"X9a-6K-rru\" firstAttribute=\"top\" secondItem=\"Utc-sZ-mvk\" secondAttribute=\"top\" constant=\"11\" id=\"7mj-6J-8rA\"/>\n                            <constraint firstItem=\"Xzx-B3-1Nh\" firstAttribute=\"centerY\" secondItem=\"5lm-GW-ctz\" secondAttribute=\"centerY\" id=\"8cw-J3-Ytb\"/>\n                            <constraint firstItem=\"odU-e3-gDg\" firstAttribute=\"top\" secondItem=\"X9a-6K-rru\" secondAttribute=\"bottom\" constant=\"14\" id=\"C1i-IY-3q5\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"1A9-vu-6o0\" secondAttribute=\"trailing\" constant=\"10\" id=\"F9Z-GJ-tWM\"/>\n                            <constraint firstItem=\"Xzx-B3-1Nh\" firstAttribute=\"centerY\" secondItem=\"V8B-Ob-jbo\" secondAttribute=\"centerY\" id=\"FvT-Br-f8U\"/>\n                            <constraint firstItem=\"5lm-GW-ctz\" firstAttribute=\"leading\" secondItem=\"Xzx-B3-1Nh\" secondAttribute=\"trailing\" constant=\"15\" id=\"Gg1-PA-Nxl\"/>\n                            <constraint firstItem=\"X9a-6K-rru\" firstAttribute=\"leading\" secondItem=\"Utc-sZ-mvk\" secondAttribute=\"leading\" constant=\"10\" id=\"IJT-Wg-34d\"/>\n                            <constraint firstItem=\"Xzx-B3-1Nh\" firstAttribute=\"top\" secondItem=\"XtI-h1-kcK\" secondAttribute=\"bottom\" constant=\"5\" id=\"LTo-RC-B0h\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"qKo-2H-jn0\" secondAttribute=\"trailing\" constant=\"10\" id=\"Ln0-DU-rpH\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"XtI-h1-kcK\" secondAttribute=\"trailing\" constant=\"10\" id=\"OuL-Ii-FUX\"/>\n                            <constraint firstItem=\"odU-e3-gDg\" firstAttribute=\"centerY\" secondItem=\"Ufh-DL-87n\" secondAttribute=\"centerY\" id=\"PcU-fY-S1s\"/>\n                            <constraint firstItem=\"Ufh-DL-87n\" firstAttribute=\"leading\" secondItem=\"odU-e3-gDg\" secondAttribute=\"trailing\" constant=\"15\" id=\"UwL-S5-IXV\"/>\n                            <constraint firstItem=\"PPX-mq-tL3\" firstAttribute=\"leading\" secondItem=\"Utc-sZ-mvk\" secondAttribute=\"leading\" constant=\"10\" id=\"WgV-bL-2Gj\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"Xzx-B3-1Nh\" secondAttribute=\"bottom\" constant=\"42\" id=\"XWP-Gv-Yln\"/>\n                            <constraint firstItem=\"Xzx-B3-1Nh\" firstAttribute=\"leading\" secondItem=\"Utc-sZ-mvk\" secondAttribute=\"leading\" constant=\"10\" id=\"cG9-OH-DNP\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"5eK-M8-1cc\" secondAttribute=\"bottom\" constant=\"8\" id=\"fWB-3v-bT3\"/>\n                            <constraint firstItem=\"1A9-vu-6o0\" firstAttribute=\"leading\" secondItem=\"V8B-Ob-jbo\" secondAttribute=\"trailing\" constant=\"15\" id=\"ftP-3T-gO7\"/>\n                            <constraint firstItem=\"V8B-Ob-jbo\" firstAttribute=\"centerY\" secondItem=\"1A9-vu-6o0\" secondAttribute=\"centerY\" id=\"goT-Vy-bxl\"/>\n                            <constraint firstItem=\"odU-e3-gDg\" firstAttribute=\"leading\" secondItem=\"Utc-sZ-mvk\" secondAttribute=\"leading\" constant=\"10\" id=\"m2M-Q3-spt\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"cs9-1y-9Eu\" secondAttribute=\"trailing\" constant=\"10\" id=\"mMc-VS-9RC\"/>\n                            <constraint firstItem=\"PPX-mq-tL3\" firstAttribute=\"top\" secondItem=\"XtI-h1-kcK\" secondAttribute=\"top\" id=\"nrF-IJ-stI\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"Ufh-DL-87n\" secondAttribute=\"trailing\" constant=\"10\" id=\"oRc-Bh-0UP\"/>\n                            <constraint firstItem=\"qKo-2H-jn0\" firstAttribute=\"leading\" secondItem=\"X9a-6K-rru\" secondAttribute=\"trailing\" constant=\"15\" id=\"szJ-an-Vef\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"cs9-1y-9Eu\" secondAttribute=\"bottom\" constant=\"8\" id=\"umD-JZ-S4Y\"/>\n                            <constraint firstItem=\"X9a-6K-rru\" firstAttribute=\"centerY\" secondItem=\"qKo-2H-jn0\" secondAttribute=\"centerY\" id=\"vjM-qL-Rgg\"/>\n                            <constraint firstItem=\"5eK-M8-1cc\" firstAttribute=\"leading\" secondItem=\"Utc-sZ-mvk\" secondAttribute=\"leading\" constant=\"10\" id=\"yn3-DJ-jGK\"/>\n                            <constraint firstItem=\"PPX-mq-tL3\" firstAttribute=\"top\" secondItem=\"odU-e3-gDg\" secondAttribute=\"bottom\" constant=\"14\" id=\"yrZ-Fk-Qss\"/>\n                        </constraints>\n                    </view>\n                    <connections>\n                        <outlet property=\"endDateTextField\" destination=\"1A9-vu-6o0\" id=\"eNm-07-zV8\"/>\n                        <outlet property=\"issueIdTextField\" destination=\"Ufh-DL-87n\" id=\"WtP-5e-S4l\"/>\n                        <outlet property=\"notesTextField\" destination=\"XtI-h1-kcK\" id=\"pms-tC-WKf\"/>\n                        <outlet property=\"startDateButton\" destination=\"Xzx-B3-1Nh\" id=\"nf2-op-6Wx\"/>\n                        <outlet property=\"startDateTextField\" destination=\"5lm-GW-ctz\" id=\"4aI-xY-N4r\"/>\n                        <outlet property=\"taskTypeSelector\" destination=\"qKo-2H-jn0\" id=\"xLe-7g-cMn\"/>\n                    </connections>\n                </viewController>\n                <customObject id=\"mAC-5h-QzV\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"531\" y=\"117\"/>\n        </scene>\n        <!--Git Users View Controller-->\n        <scene sceneID=\"5KV-dq-od9\">\n            <objects>\n                <viewController storyboardIdentifier=\"GitUsersViewController\" id=\"wqw-d8-I6w\" customClass=\"GitUsersViewController\" customModule=\"Jirassic\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" id=\"ojp-ke-J79\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"301\" height=\"300\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                        <subviews>\n                            <scrollView borderType=\"none\" autohidesScrollers=\"YES\" horizontalLineScroll=\"19\" horizontalPageScroll=\"10\" verticalLineScroll=\"19\" verticalPageScroll=\"10\" hasHorizontalScroller=\"NO\" usesPredominantAxisScrolling=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"if1-U6-VLS\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"36\" width=\"301\" height=\"264\"/>\n                                <clipView key=\"contentView\" drawsBackground=\"NO\" copiesOnScroll=\"NO\" id=\"vYc-JZ-0xV\">\n                                    <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"301\" height=\"264\"/>\n                                    <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                    <subviews>\n                                        <tableView verticalHuggingPriority=\"750\" allowsExpansionToolTips=\"YES\" columnAutoresizingStyle=\"lastColumnOnly\" columnSelection=\"YES\" multipleSelection=\"NO\" autosaveColumns=\"NO\" headerView=\"b1H-TU-TqX\" id=\"7jd-wx-YVr\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"301\" height=\"239\"/>\n                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                            <size key=\"intercellSpacing\" width=\"0.0\" height=\"2\"/>\n                                            <color key=\"backgroundColor\" white=\"1\" alpha=\"0.0\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                            <color key=\"gridColor\" name=\"gridColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            <tableColumns>\n                                                <tableColumn identifier=\"isSelected\" width=\"20\" minWidth=\"20\" maxWidth=\"20\" id=\"XEU-k7-3lR\">\n                                                    <tableHeaderCell key=\"headerCell\" lineBreakMode=\"truncatingTail\" borderStyle=\"border\">\n                                                        <font key=\"font\" metaFont=\"smallSystem\"/>\n                                                        <color key=\"textColor\" name=\"headerTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                        <color key=\"backgroundColor\" name=\"headerColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                    </tableHeaderCell>\n                                                    <buttonCell key=\"dataCell\" type=\"check\" bezelStyle=\"regularSquare\" imagePosition=\"left\" inset=\"2\" id=\"vLU-ya-qd4\">\n                                                        <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                                                        <font key=\"font\" metaFont=\"system\"/>\n                                                    </buttonCell>\n                                                    <tableColumnResizingMask key=\"resizingMask\" resizeWithTable=\"YES\" userResizable=\"YES\"/>\n                                                </tableColumn>\n                                                <tableColumn identifier=\"email\" editable=\"NO\" width=\"281\" minWidth=\"281\" maxWidth=\"1000\" id=\"IB6-HN-nF1\">\n                                                    <tableHeaderCell key=\"headerCell\" lineBreakMode=\"truncatingTail\" borderStyle=\"border\">\n                                                        <font key=\"font\" metaFont=\"smallSystem\"/>\n                                                        <color key=\"textColor\" name=\"headerTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                        <color key=\"backgroundColor\" name=\"headerColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                    </tableHeaderCell>\n                                                    <textFieldCell key=\"dataCell\" lineBreakMode=\"truncatingTail\" selectable=\"YES\" editable=\"YES\" title=\"email\" id=\"swR-I1-p4C\">\n                                                        <font key=\"font\" metaFont=\"system\"/>\n                                                        <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                        <color key=\"backgroundColor\" name=\"controlBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                    </textFieldCell>\n                                                    <tableColumnResizingMask key=\"resizingMask\" resizeWithTable=\"YES\" userResizable=\"YES\"/>\n                                                </tableColumn>\n                                            </tableColumns>\n                                            <connections>\n                                                <outlet property=\"dataSource\" destination=\"wqw-d8-I6w\" id=\"eve-Vy-iyY\"/>\n                                                <outlet property=\"delegate\" destination=\"wqw-d8-I6w\" id=\"Kak-8g-lpo\"/>\n                                            </connections>\n                                        </tableView>\n                                    </subviews>\n                                    <color key=\"backgroundColor\" white=\"1\" alpha=\"0.0\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                </clipView>\n                                <scroller key=\"horizontalScroller\" hidden=\"YES\" wantsLayer=\"YES\" verticalHuggingPriority=\"750\" horizontal=\"YES\" id=\"ssL-aH-BgC\">\n                                    <rect key=\"frame\" x=\"-100\" y=\"-100\" width=\"223\" height=\"15\"/>\n                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                </scroller>\n                                <scroller key=\"verticalScroller\" hidden=\"YES\" wantsLayer=\"YES\" verticalHuggingPriority=\"750\" doubleValue=\"1\" horizontal=\"NO\" id=\"MxN-W4-mAE\">\n                                    <rect key=\"frame\" x=\"224\" y=\"17\" width=\"15\" height=\"102\"/>\n                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                </scroller>\n                                <tableHeaderView key=\"headerView\" hidden=\"YES\" focusRingType=\"none\" id=\"b1H-TU-TqX\">\n                                    <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"301\" height=\"25\"/>\n                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                </tableHeaderView>\n                            </scrollView>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"po0-Ge-9zb\">\n                                <rect key=\"frame\" x=\"238\" y=\"9\" width=\"44\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"Done\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"J5y-b3-bhy\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleDoneButton:\" target=\"wqw-d8-I6w\" id=\"OZY-Gm-Yh6\"/>\n                                </connections>\n                            </button>\n                        </subviews>\n                        <constraints>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"po0-Ge-9zb\" secondAttribute=\"trailing\" constant=\"19\" id=\"1Og-SK-AGd\"/>\n                            <constraint firstItem=\"po0-Ge-9zb\" firstAttribute=\"top\" secondItem=\"if1-U6-VLS\" secondAttribute=\"bottom\" constant=\"8\" id=\"NdZ-Oj-Hfz\"/>\n                            <constraint firstItem=\"if1-U6-VLS\" firstAttribute=\"leading\" secondItem=\"ojp-ke-J79\" secondAttribute=\"leading\" id=\"Qez-Dc-yO8\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"if1-U6-VLS\" secondAttribute=\"trailing\" id=\"YMI-jA-ACZ\"/>\n                            <constraint firstItem=\"if1-U6-VLS\" firstAttribute=\"top\" secondItem=\"ojp-ke-J79\" secondAttribute=\"top\" id=\"jTq-Ae-QYE\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"po0-Ge-9zb\" secondAttribute=\"bottom\" constant=\"10\" id=\"kbp-zU-ljQ\"/>\n                        </constraints>\n                    </view>\n                    <connections>\n                        <outlet property=\"doneButton\" destination=\"po0-Ge-9zb\" id=\"rI4-XT-VzP\"/>\n                        <outlet property=\"scrollView\" destination=\"if1-U6-VLS\" id=\"bJQ-Hf-sYZ\"/>\n                        <outlet property=\"tableView\" destination=\"7jd-wx-YVr\" id=\"jfY-LI-S3v\"/>\n                    </connections>\n                </viewController>\n                <customObject id=\"rSk-8e-UgR\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"530.5\" y=\"475\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Components/EditableTimeBox.swift",
    "content": "//\n//  EditableTimeBox.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 28/10/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nclass EditableTimeBox: TimeBox {\n    \n    var isEditing = false\n    var wasEdited = false\n    var didBeginEditing: (() -> Void)?\n    var didEndEditing: (() -> Void)?\n    \n    private var partialValue = \"\"\n    private let predictor = PredictiveTimeTyping()\n    \n    override func awakeFromNib() {\n        super.awakeFromNib()\n        timeTextField?.delegate = self\n    }\n}\n\nextension EditableTimeBox: NSTextFieldDelegate {\n    \n    public func control(_ control: NSControl, textShouldBeginEditing fieldEditor: NSText) -> Bool {\n        isEditing = true\n        partialValue = stringValue\n        self.borderColor = NSColor.darkGray\n        timeTextField?.textColor = NSColor.black\n        \n        return true\n    }\n    \n    public func control(_ control: NSControl, textShouldEndEditing fieldEditor: NSText) -> Bool {\n        if wasEdited {\n            wasEdited = false\n            didEndEditing?()\n        }\n        self.borderColor = NSColor.white\n        timeTextField?.textColor = NSColor.darkGray\n        \n        return true\n    }\n    \n    public func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {\n        \n        // Detect Enter key\n        if wasEdited && commandSelector == #selector(NSResponder.insertNewline(_:)) {\n            didEndEditing?()\n            wasEdited = false\n        }\n        return false\n    }\n    \n    //    override func controlTextDidBeginEditing (_ obj: Notification) {\n    //        isEditing = true\n    //        partialValue = stringValue\n    //        self.borderColor = NSColor.darkGray\n    //        timeTextField?.textColor = NSColor.black\n    //    }\n    \n    func controlTextDidChange (_ obj: Notification) {\n        wasEdited = true\n        let comps = stringValue.components(separatedBy: partialValue)\n        let newDigit = (comps.count == 1 && partialValue != \"\") ? \"\" : comps.last\n        partialValue = predictor.timeByAdding(newDigit!, to: partialValue)\n        stringValue = partialValue\n    }\n    \n    //    override func controlTextDidEndEditing (_ obj: Notification) {\n    //        if wasEdited {\n    //            wasEdited = false\n    //            didEndEditing?()\n    //        }\n    //        self.borderColor = NSColor.white\n    //        timeTextField?.textColor = NSColor.darkGray\n    //    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Components/GitUsersViewController.swift",
    "content": "//\n//  GitUsersViewController.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 16/12/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\nimport RCPreferences\n\nclass GitUsersViewController: NSViewController {\n    \n    @IBOutlet private weak var scrollView: NSScrollView!\n    @IBOutlet private weak var tableView: NSTableView!\n    @IBOutlet private weak var doneButton: NSButton!\n    \n    var onDone: (() -> Void)?\n    \n    private let pref = RCPreferences<LocalPreferences>()\n    private let gitModule = ModuleGitLogs()\n    private var users: [GitUser] = []\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        gitModule.fetchUsers { [weak self] users in\n            self?.users = users\n            self?.tableView.reloadData()\n        }\n        tableView.headerView = nil\n    }\n    \n    @IBAction func handleDoneButton(_ sender: NSButton) {\n        onDone?()\n    }\n}\n\nextension GitUsersViewController: NSTableViewDataSource {\n    \n    func numberOfRows (in aTableView: NSTableView) -> Int {\n        return users.count\n    }\n}\n\nextension GitUsersViewController: NSTableViewDelegate {\n    \n    func tableView(_ tableView: NSTableView, objectValueFor tableColumn: NSTableColumn?, row: Int) -> Any? {\n        \n        let user = users[row]\n        \n        if (tableColumn?.identifier)?.rawValue == \"isSelected\" {\n            let allowedAuthors: [String] = pref.string(.settingsGitAuthors).split(separator: \",\").map { String($0) }\n            let isSelected = allowedAuthors.contains(user.email)\n            return NSNumber(booleanLiteral: isSelected)\n        }\n        if (tableColumn?.identifier)?.rawValue == \"email\" {\n            return user.email\n        }\n        return nil\n    }\n    \n    func tableView(_ tableView: NSTableView, setObjectValue object: Any?, for tableColumn: NSTableColumn?, row: Int) {\n        \n        let user = users[row]\n        \n        if (tableColumn?.identifier)?.rawValue == \"isSelected\" {\n            var allowedAuthors: [String] = pref.string(.settingsGitAuthors).split(separator: \",\").map { String($0) }\n            guard let isSelected = (object as? NSNumber)?.boolValue else {\n                return\n            }\n            if isSelected {\n                allowedAuthors.append(user.email)\n            } else {\n                allowedAuthors = allowedAuthors.filter({$0 != user.email})\n            }\n            pref.set(allowedAuthors.joined(separator: \",\"), forKey: .settingsGitAuthors)\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Components/NewTaskViewController.swift",
    "content": "//\n//  NewTaskViewController.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 06/05/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\nimport RCPreferences\n\nclass NewTaskViewController: NSViewController {\n    \n    @IBOutlet private weak var taskTypeSelector: NSPopUpButton!\n\t@IBOutlet private weak var issueIdTextField: NSTextField!\n\t@IBOutlet private weak var notesTextField: NSTextField!\n\t@IBOutlet private weak var endDateTextField: NSTextField!\n    @IBOutlet private weak var startDateTextField: NSTextField!\n    @IBOutlet private weak var startDateButton: NSButton!\n\t\n\tvar onSave: ((_ taskData: TaskCreationData) -> Void)?\n\tvar onCancel: (() -> Void)?\n    private var activeEditingTextFieldContent = \"\"\n    private var issueTypes = [String]()\n    private let predictor = PredictiveTimeTyping()\n    private let pref = RCPreferences<LocalPreferences>()\n\t\n    var dateStart: Date? {\n        get {\n            if pref.bool(.useDuration) {\n                return self.duration > 0 ? self.dateEnd.addingTimeInterval(-self.duration) : nil\n            } else {\n                if self.startDateTextField!.stringValue == \"\" {\n                    return nil\n                }\n                let hm = Date.parseHHmm(self.startDateTextField!.stringValue)\n                return self.initialDate.dateByUpdating(hour: hm.hour, minute: hm.min)\n            }\n        }\n        set {\n            if let startDate = newValue {\n                self.startDateTextField.stringValue = startDate.HHmm()\n            }\n        }\n    }\n    var initialDate = Date()\n\tvar dateEnd: Date {\n\t\tget {\n            let hm = Date.parseHHmm(self.endDateTextField!.stringValue)\n            return self.initialDate.dateByUpdating(hour: hm.hour, minute: hm.min)\n\t\t}\n\t\tset {\n            self.initialDate = newValue\n            self.endDateTextField.stringValue = newValue.HHmm()\n            self.estimateTaskType()\n\t\t}\n\t}\n    var duration: TimeInterval {\n        get {\n            if self.startDateTextField.stringValue == \"\" {\n                return 0.0\n            }\n            let hm = Date.parseHHmm(self.startDateTextField.stringValue)\n            return Double(hm.min).minToSec + Double(hm.hour).hoursToSec\n        }\n    }\n\tvar notes: String {\n\t\tget {\n\t\t\treturn notesTextField.stringValue\n\t\t}\n\t\tset {\n\t\t\tself.notesTextField.stringValue = newValue\n\t\t}\n\t}\n\tvar taskNumber: String {\n\t\tget {\n\t\t\treturn issueIdTextField.stringValue\n\t\t}\n\t\tset {\n\t\t\tself.issueIdTextField.stringValue = newValue\n\t\t}\n\t}\n\t\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        taskTypeSelector.removeAllItems()\n        taskTypeSelector.addItems(withTitles: [\"Task\", \"Scrum\", \"Meeting\", \"Food\", \"Social & Media\", \"Learning\", \"Code review\"])\n        taskTypeSelector.selectItem(at: 0)\n        setupStartDateButtonTitle()\n        startDateTextField.toolTip = \"Predictive Time Typing (use digits and backspace):\\n • First digit if between 2 and 9 means AM hours.\\n • Leaving minutes empty, defaults to 00.\\n • Last digit replaces itself, no need to delete.\"\n        endDateTextField.toolTip = startDateTextField.toolTip\n    }\n    \n    private func selectedTaskType() -> TaskType {\n        \n        switch taskTypeSelector.indexOfSelectedItem {\n            case 0: return .issue\n            case 1: return .scrum\n            case 2: return .meeting\n            case 3: return .lunch\n            case 4: return .waste\n            case 5: return .learning\n            case 6: return .coderev\n            default: return .issue\n        }\n    }\n    \n    private func estimateTaskType() {\n        \n        let typeEstimator = TaskTypeEstimator()\n        let settings = SettingsInteractor().getAppSettings()\n        let estimatedType: TaskType = typeEstimator.taskTypeAroundDate(initialDate, withSettings: settings)\n        if estimatedType == .scrum {\n            taskTypeSelector.selectItem(at: 1)\n            handleTaskTypeSelector(taskTypeSelector)\n            \n            let settingsScrumTime = gregorian.dateComponents(ymdhmsUnitFlags, from: settings.settingsTracking.scrumTime)\n            self.dateStart = self.initialDate.dateByUpdating(hour: settingsScrumTime.hour!, minute: settingsScrumTime.minute!)\n        }\n    }\n    \n    private func setupStartDateButtonTitle() {\n        startDateButton.title = pref.bool(.useDuration) ? \"Duration\" : \"Date start\"\n    }\n}\n\nextension NewTaskViewController: NSTextFieldDelegate {\n    \n    func controlTextDidBeginEditing (_ obj: Notification) {\n        \n        if let textField = obj.object as? NSTextField {\n            guard textField == endDateTextField || textField == startDateTextField else {\n                return\n            }\n            activeEditingTextFieldContent = textField.stringValue\n        }\n    }\n    \n    func controlTextDidChange (_ obj: Notification) {\n        \n        if let textField = obj.object as? NSTextField {\n            guard textField == endDateTextField || textField == startDateTextField else {\n                return\n            }\n            let comps = textField.stringValue.map { String($0) }\n            let newDigit = activeEditingTextFieldContent.count > comps.count ? \"\" : comps.last\n            activeEditingTextFieldContent = predictor.timeByAdding(newDigit!, to: activeEditingTextFieldContent)\n            textField.stringValue = activeEditingTextFieldContent\n        }\n    }\n}\n\nextension NewTaskViewController {\n    \n    @IBAction func handleTaskTypeSelector (_ sender: NSPopUpButton) {\n        issueIdTextField.isEnabled = selectedTaskType() == .issue\n    }\n    \n    @IBAction func handleSaveButton (_ sender: NSButton) {\n        \n        let taskData = TaskCreationData(\n            dateStart: self.dateStart,\n            dateEnd: self.dateEnd,\n            taskNumber: self.taskNumber != \"\" ? self.taskNumber : nil,\n            notes: self.notes != \"\" ? self.notes : nil,\n            taskType: selectedTaskType()\n        )\n        self.onSave?(taskData)\n    }\n    \n    @IBAction func handleCancelButton (_ sender: NSButton) {\n        self.onCancel?()\n    }\n    \n    @IBAction func handleDurationButton (_ sender: NSButton) {\n        \n        pref.set(!pref.bool(.useDuration), forKey: .useDuration)\n        setupStartDateButtonTitle()\n    }\n}\n\nextension NewTaskViewController {\n    \n    override func mouseDown(with event: NSEvent) {\n//        RCLog(event)\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Components/TimeBox.swift",
    "content": "//\n//  TimeBox.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 19/03/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nclass TimeBox: NSBox {\n    \n    internal var timeTextField: NSTextField?\n    \n    var stringValue: String {\n        get {\n            return timeTextField!.stringValue\n        }\n        set {\n            timeTextField!.stringValue = newValue\n        }\n    }\n    var isDark: Bool = false {\n        didSet {\n            let isDark = self.isDark\n            if #available(OSX 10.14, *) {\n                self.fillColor = isDark ? NSColor.white : NSColor.darkGray\n                self.timeTextField?.textColor = isDark ? NSColor.darkGray : NSColor.white\n            } else {\n                self.fillColor = isDark ? NSColor.darkGray : NSColor.white\n//                self.borderColor = isDark ? NSColor.clear : NSColor.white\n                self.timeTextField?.textColor = isDark ? NSColor.white : NSColor.darkGray\n//                self.timeTextField?.backgroundColor = isDark ? NSColor.darkGray : NSColor.darkGray\n            }\n        }\n    }\n    var onClick: (() -> Void)?\n    \n    init() {\n        super.init(frame: NSRect.zero)\n        stringValue = \"\"\n    }\n    \n    required init?(coder decoder: NSCoder) {\n        super.init(coder: decoder)\n    }\n    \n    override func awakeFromNib() {\n        super.awakeFromNib()\n        \n        self.borderType = .noBorder\n        \n        timeTextField = NSTextField()\n        timeTextField?.font = NSFont.boldSystemFont(ofSize: 10)\n        timeTextField?.textColor = NSColor.darkGray\n        timeTextField?.backgroundColor = NSColor.clear\n        timeTextField?.drawsBackground = false\n        timeTextField?.alignment = .center\n        timeTextField?.focusRingType = .none\n        timeTextField?.placeholderString = \"00:00\"\n        timeTextField?.isEnabled = false\n        timeTextField?.isEditable = false\n        \n        self.addSubview(timeTextField!)\n\n        timeTextField?.translatesAutoresizingMaskIntoConstraints = false\n        let viewsDictionary = [\"view\": timeTextField!]\n        self.addConstraints(NSLayoutConstraint.constraints(\n            withVisualFormat: \"H:|-(-5)-[view]-(-5)-|\", options: [], metrics: nil, views: viewsDictionary))\n        self.addConstraints(NSLayoutConstraint.constraints(\n            withVisualFormat: \"V:|-(-3)-[view]-(-5)-|\", options: [], metrics: nil, views: viewsDictionary))\n    }\n    \n    override func mouseDown(with event: NSEvent) {\n        onClick?()\n    }\n    \n    override func updateTrackingAreas() {\n        super.updateTrackingAreas()\n        \n        let trackingArea = NSTrackingArea(rect: NSZeroRect,\n                                          options: [\n                                            NSTrackingArea.Options.inVisibleRect,\n                                            NSTrackingArea.Options.activeAlways,\n                                            NSTrackingArea.Options.mouseEnteredAndExited\n            ],\n                                          owner: self,\n                                          userInfo: nil)\n        if !self.trackingAreas.contains(trackingArea) {\n            self.addTrackingArea(trackingArea)\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Components/TimeBoxViewController.swift",
    "content": "//\n//  TimeBoxViewController.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 27/10/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nclass TimeBoxViewController: NSViewController {\n\n    @IBOutlet private weak var timeTextField: NSTextField!\n    @IBOutlet private weak var instructionsTextField: NSTextField!\n    @IBOutlet private weak var disclosureButton: NSButton!\n    var didCancel: (() -> Void)?\n    var didSave: (() -> Void)?\n    \n    private var partialValue = \"\"\n    private var isEditing = false\n    private var wasEdited = false\n    private let predictor = PredictiveTimeTyping()\n    \n    var stringValue: String {\n        get {\n            return timeTextField.stringValue\n        }\n        set {\n            timeTextField.stringValue = newValue\n        }\n    }\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        disclosureButton.state = .on\n        instructionsTextField.stringValue = \"Predictive Time Typing (use digits and backspace):\\n • First digit if between 2 and 9 means AM hours.\\n • Leaving minutes empty, defaults to 00.\\n • Last digit replaces itself, no need to delete.\"\n    }\n}\n\nextension TimeBoxViewController {\n    \n    @IBAction func handleCancelButton (_ sender: NSButton) {\n        didCancel?()\n    }\n    \n    @IBAction func handleSaveButton (_ sender: NSButton) {\n        didSave?()\n    }\n    \n    @IBAction func handleDisclosureButton (_ sender: NSButton) {\n        instructionsTextField.stringValue = sender.state == .off ? \"\" : \"Predictive time typing:\\n • First digit between 2 and 9 means AM.\\n • Leaving minutes empty defaults to 00.\\n • Last digit replaces itself.\"\n    }\n}\n\nextension TimeBoxViewController: NSTextFieldDelegate {\n    \n    public func control(_ control: NSControl, textShouldBeginEditing fieldEditor: NSText) -> Bool {\n        isEditing = true\n        partialValue = stringValue\n        return true\n    }\n    \n    public func control(_ control: NSControl, textShouldEndEditing fieldEditor: NSText) -> Bool {\n        if wasEdited {\n            wasEdited = false\n        }\n        return true\n    }\n    \n    public func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {\n        \n        // Detect Enter key\n        if wasEdited && commandSelector == #selector(NSResponder.insertNewline(_:)) {\n            wasEdited = false\n        }\n        return false\n    }\n    \n    func controlTextDidChange (_ obj: Notification) {\n        wasEdited = true\n        let comps = stringValue.components(separatedBy: partialValue)\n        // The difference between original string and new string is the last digit\n        var newDigit = comps.last\n        // If textfield was selected, entering a new digit replaces everything and it has the length 1\n        if stringValue.count == 1 && partialValue.count > 2 {\n            partialValue = \"\"\n        }\n        // Detect backspace\n        else if comps.count == 1 && partialValue != \"\" {\n            newDigit = nil\n        }\n        partialValue = predictor.timeByAdding(newDigit ?? \"\", to: partialValue)\n        stringValue = partialValue\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/External/AppleScript.swift",
    "content": "//\n//  AppleScript.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 20/11/2016.\n//  Copyright © 2016 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport CoreServices\nimport Carbon.OpenScripting\nimport RCLog\n\nfileprivate let commandRunShellScript = \"runShellScript\"\nfileprivate let commandGetScriptVersion = \"getScriptVersion\"\nfileprivate let commandGetBrowserInfo = \"getBrowserInfo\"\n\nclass AppleScript: AppleScriptProtocol {\n    \n    private func validateTarget() {\n        #if APPSTORE\n            fatalError(\"For sandboxed apps, SandboxedAppleScript must be used\")\n        #endif\n    }\n    \n    var scriptsDirectory: URL? {\n        validateTarget()\n        return Bundle.main.resourceURL\n    }\n    var binPaths: [String] {\n        // Paths given by the app: /Applications/Xcode.app/Contents/Developer/usr/bin:/usr/bin:/bin:/usr/sbin:/sbin\n        // Paths given by  Terminal echo $PATH: /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin\n        // There is surely something weird here\n        // Lets just remove paths matching xcode and insert usr/local/bin if does not exist\n        let localBin = \"/usr/local/bin\"\n        let envPaths = ProcessInfo.processInfo.environment[\"PATH\"] ?? \"\"\n        var paths = envPaths.split(separator: \":\").map({ String($0) })\n        paths = paths.filter({ !$0.contains(\"Xcode.app\") })\n        if !paths.contains(localBin) {\n            paths.insert(localBin, at: 0)\n        }\n        \n        return paths\n    }\n    \n    func run (command: String, completion: @escaping (String?) -> Void) {\n        \n        RCLog(\"-------------------------------------------------\")\n        RCLog(\"Running command: \\(command)\")\n        let args = NSAppleEventDescriptor.list()\n        args.insert(NSAppleEventDescriptor(string: command), at: 1)\n        \n        run (command: commandRunShellScript, scriptNamed: kShellSupportScriptName, args: args, completion: { descriptor in\n            if let descriptor = descriptor, let result = descriptor.stringValue {\n                RCLog(\"Result: \\(result)\")\n                RCLog(\"-------------------------------------------------\")\n                completion(result)\n            } else {\n                completion(nil)\n            }\n        })\n    }\n    \n    func getScriptVersion (script: String, completion: @escaping (String) -> Void) {\n        \n        run (command: commandGetScriptVersion, scriptNamed: script, args: nil, completion: { descriptor in\n            if let descriptor = descriptor, let result = descriptor.stringValue {\n                completion(result)\n            } else {\n                completion(\"\")\n            }\n        })\n    }\n    \n    func getJitInfo (completion: @escaping ([String: String]) -> Void) {\n        getJitInfo (paths: binPaths, completion: completion)\n    }\n    \n    private func getJitInfo (paths: [String], completion: @escaping ([String: String]) -> Void) {\n        \n        guard paths.count > 0 else {\n            completion([:])\n            return\n        }\n        var remainingPaths = paths\n        let path = remainingPaths.removeFirst()\n        let command = \"\\(path)/jit info\"\n        let args = NSAppleEventDescriptor.list()\n        args.insert(NSAppleEventDescriptor(string: command), at: 1)\n        \n        run (command: commandRunShellScript, scriptNamed: kShellSupportScriptName, args: args, completion: { descriptor in\n            \n            if let descriptor = descriptor, let rawJson = descriptor.stringValue {\n                \n                // json received from jit contains ' instead \" because otherwise is not valid when passed\n                let validJson = rawJson.replacingOccurrences(of: \"'\", with: \"\\\"\")\n                var dict: [String: String] = [:]\n                if let data = validJson.data(using: String.Encoding.utf8) {\n                    if let d = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: String] {\n                        if let _d = d {\n                            dict = _d\n                        }\n                    }\n                }\n                completion(dict)\n            } else {\n                self.getJitInfo (paths: remainingPaths, completion: completion)\n            }\n        })\n    }\n    \n    func getJirassicVersion (completion: @escaping (String) -> Void) {\n        getJirassicVersion(paths: binPaths, completion: completion)\n    }\n    \n    private  func getJirassicVersion (paths: [String], completion: @escaping (String) -> Void) {\n        \n        guard paths.count > 0 else {\n            completion(\"\")\n            return\n        }\n        var remainingPaths = paths\n        let path = remainingPaths.removeFirst()\n        let command = \"\\(path)/jirassic version\"\n        let args = NSAppleEventDescriptor.list()\n        args.insert(NSAppleEventDescriptor(string: command), at: 1)\n        \n        run (command: commandRunShellScript, scriptNamed: kShellSupportScriptName, args: args, completion: { descriptor in\n            if let descriptor = descriptor, let result = descriptor.stringValue {\n                completion(result)\n            } else {\n                self.getJirassicVersion(paths: remainingPaths, completion: completion)\n            }\n        })\n    }\n    \n    func getBrowserInfo (browserId: String, browserName: String, completion: @escaping (String, String) -> Void) {\n        \n        let args = NSAppleEventDescriptor.list()\n        args.insert(NSAppleEventDescriptor(string: browserId), at: 1)\n        args.insert(NSAppleEventDescriptor(string: browserName), at: 2)\n        \n        run (command: commandGetBrowserInfo, scriptNamed: kBrowserSupportScriptName, args: args, completion: { descriptor in\n            if let descriptor = descriptor {\n                let url = descriptor.atIndex(1)?.stringValue ?? \"\"\n                let title = descriptor.atIndex(2)?.stringValue ?? \"\"\n                completion(url, title)\n            } else {\n                RCLog(\"Cannot get browser info\")\n                completion(\"\", \"\")\n            }\n        })\n    }\n    \n    func downloadFile (from: String, to: String, completion: @escaping (Bool) -> Void) {\n        \n        //        let asc = NSAppleScript(source: \"do shell script \\\"sudo cp \\(from) \\(to)\\\" with administrator privileges\")\n        \n        \n        let sessionConfig = URLSessionConfiguration.default\n        let session = URLSession(configuration: sessionConfig)\n        let request = URLRequest(url: URL(string: from)!)\n        \n        let task = session.downloadTask(with: request) { (tempLocalUrl, response, error) in\n            if let tempLocalUrl = tempLocalUrl, error == nil {\n                // Success\n                if let statusCode = (response as? HTTPURLResponse)?.statusCode {\n                    RCLog(\"Success: \\(statusCode)\")\n                }\n                \n                //                do {\n                //                    try FileManager.default.copyItem(at: tempLocalUrl, to: URL(fileURLWithPath: to))\n                //                    completion(true)\n                //                } catch (let writeError) {\n                //                    print(\"error writing file \\(to) : \\(writeError)\")\n                //                    completion(false)\n                //                }\n                \n                RCLog(from)\n                RCLog(to)\n                let asc = NSAppleScript(source: \"do shell script \\\"sudo cp \\(tempLocalUrl.path) \\(to)\\\" with administrator privileges\")\n                if let response = asc?.executeAndReturnError(nil) {\n                    RCLog(response)\n                    let asc = NSAppleScript(source: \"chmod +x \\(to)\")\n                    if let response = asc?.executeAndReturnError(nil) {\n                        RCLog(response)\n                        completion(true)\n                    } else {\n                        RCLog(\"Could not download Jit from \\(from) to \\(to)\")\n                        completion(false)\n                    }\n                } else {\n                    RCLog(\"Could not download Jit from \\(from) to \\(to)\")\n                    completion(false)\n                }\n                \n            } else {\n                RCLog(\"Failure: \\(error!.localizedDescription)\")\n            }\n        }\n        task.resume()\n    }\n    \n    func removeFile (from: String, completion: @escaping (Bool) -> Void) {\n        \n    }\n}\n\nextension AppleScript {\n    \n    fileprivate func run (command: String,\n                          scriptNamed: String,\n                          args: NSAppleEventDescriptor?,\n                          completion: @escaping (NSAppleEventDescriptor?) -> Void) {\n        \n        guard let scriptsDirectory = self.scriptsDirectory else {\n            completion(nil)\n            return\n        }\n        let scriptURL = scriptsDirectory.appendingPathComponent(scriptNamed + \".scpt\")\n        \n        do {\n            var pid = ProcessInfo.processInfo.processIdentifier\n            \n            let targetDescriptor = NSAppleEventDescriptor(descriptorType: typeKernelProcessID,\n                                                          bytes: &pid,\n                                                          length: MemoryLayout.size(ofValue: pid))\n            \n            let theEvent = NSAppleEventDescriptor.appleEvent(withEventClass: AEEventClass(kASAppleScriptSuite),//kCoreEventClass,\n                eventID: AEEventID(kASSubroutineEvent),//kAEOpenDocuments,\n                targetDescriptor: targetDescriptor,\n                returnID: AEReturnID(kAutoGenerateReturnID),\n                transactionID: AETransactionID(kAnyTransactionID))\n            \n            let commandDescriptor = NSAppleEventDescriptor(string: command)\n            theEvent.setDescriptor(commandDescriptor, forKeyword: AEKeyword(keyASSubroutineName))\n            \n            if let args = args {\n                theEvent.setDescriptor(args, forKeyword: keyDirectObject)\n            }\n            \n            let result = try NSUserAppleScriptTask(url: scriptURL)\n            result.execute(withAppleEvent: theEvent, completionHandler: { (descriptor, error) in\n                //RCLogO(descriptor)\n                RCLogErrorO(error)\n                DispatchQueue.main.sync {\n                    completion(descriptor)\n                }\n            })\n        } catch {\n            completion(nil)\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/External/AppleScriptProtocol.swift",
    "content": "//\n//  AppleScriptProtocol.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 24/03/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nprotocol AppleScriptProtocol {\n    \n    var scriptsDirectory: URL? {get}\n    \n    func run (command: String, completion: @escaping (String?) -> Void)\n    \n    func getScriptVersion (script: String, completion: @escaping (String) -> Void)\n    \n    func getJitInfo (completion: @escaping ([String: String]) -> Void)\n    \n    func getJirassicVersion (completion: @escaping (String) -> Void)\n    \n    func getBrowserInfo (browserId: String, browserName: String, completion: @escaping (String, String) -> Void)\n    \n    func downloadFile (from: String, to: String, completion: @escaping (Bool) -> Void)\n    \n    func removeFile (from: String, completion: @escaping (Bool) -> Void)\n    \n}\n"
  },
  {
    "path": "Delivery/macOS/External/ExtensionsInstallerInteractor.swift",
    "content": "//\n//  ExtensionsInstallerInteractor.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 14/05/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport Cocoa\n\nclass ExtensionsInstallerInteractor: ExtensionsInteractor {\n    \n    fileprivate let scripts: AppleScriptProtocol = AppleScript()\n    fileprivate let fileManager = FileManager.default\n    \n//    func saveJiraSettings (_ settings: JiraSettings, completion: @escaping (Bool) -> Void) {\n//        \n//        var values = \"jira_url=\\(settings.url!)\\njira_user=\\(settings.user!)\"\n//        if let password = settings.password {\n//            values += \"\\njira_password=\\(password)\"\n//        }\n//        \n//        scripts.setupJitWithValues(values, completion: { success in\n//            completion(success)\n//        })\n//    }\n    \n    func installJirassic (_ completion: @escaping (Bool) -> Void) {\n        \n        scripts.downloadFile(from: \"https://raw.githubusercontent.com/ralcr/Jit/master/build/jit\", to: \"/usr/local/bin/jirassic\", completion: { success in\n            completion(success)\n        })\n    }\n    \n    func installJit (_ completion: @escaping (Bool) -> Void) {\n        \n        scripts.downloadFile(from: \"https://raw.githubusercontent.com/ralcr/Jit/master/build/jit\", to: \"/usr/local/bin/jit\", completion: { success in\n            completion(success)\n        })\n    }\n    \n    func uninstallTools (_ completion: @escaping (Bool) -> Void) {\n        \n        if isShellSupportInstalled() {\n            uninstallCmds({ success in\n                if success {\n                    \n                    if let bookmark = UserDefaults.standard.object(forKey: kShellSupportScriptName) as? NSData as Data? {\n                        var stale = false\n                        if let url = try? URL(resolvingBookmarkData: bookmark, options: URL.BookmarkResolutionOptions.withSecurityScope,\n                                              relativeTo: nil,\n                                              bookmarkDataIsStale: &stale) {\n                            \n                            let _ = url.startAccessingSecurityScopedResource()\n                            self.uninstallScript(atUrl: url, completion)\n                            url.stopAccessingSecurityScopedResource()\n                        }\n                    }\n                    \n                    //                    let scriptsDirectory = self.scripts.scriptsDirectory!\n                    //                    let scriptUrl = scriptsDirectory.appendingPathComponent(\"\\(self.scriptsName).scpt\")\n                    //                    self.uninstallScript(atUrl: scriptUrl, completion)\n                } else {\n                    completion(false)\n                }\n            })\n        } else {\n            completion(false)\n        }\n    }\n}\n\nextension ExtensionsInstallerInteractor {\n    \n    fileprivate func isShellSupportInstalled() -> Bool {\n        let scriptsDirectory = scripts.scriptsDirectory!\n        return fileManager.fileExists(atPath: scriptsDirectory.appendingPathComponent(\"\\(kShellSupportScriptName).scpt\").path)\n    }\n    \n    fileprivate func isBrowserSupportInstalled() -> Bool {\n        let scriptsDirectory = scripts.scriptsDirectory!\n        return fileManager.fileExists(atPath: scriptsDirectory.appendingPathComponent(\"\\(kBrowserSupportScriptName).scpt\").path)\n    }\n    \n    fileprivate func installScriptAndCmds (_ completion: @escaping (Bool) -> Void) {\n        \n        installScript(script: kShellSupportScriptName, { success in\n            self.installJit(completion)\n        })\n    }\n    \n    fileprivate func installScript (script: String, _ completion: @escaping (Bool) -> Void) {\n        \n        let panel = NSSavePanel()\n        panel.nameFieldStringValue = \"\\(script).scpt\"\n        panel.directoryURL = scripts.scriptsDirectory!\n        panel.message = \"Please select: User / Library / Application Scripts / com.ralcr.Jirassic.osx\"\n        panel.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.maximumWindow)))\n        \n        panel.begin { (result) in\n            \n            if result.rawValue == NSFileHandlingPanelOKButton {\n                \n                let scriptPath = Bundle.main.url(forResource: script, withExtension: \".scpt\")\n                do {\n                    try? self.fileManager.copyItem(at: scriptPath!, to: panel.url!)\n                    \n                    let bookmark = try? panel.url!.bookmarkData(options: URL.BookmarkCreationOptions.withSecurityScope,\n                                                                includingResourceValuesForKeys: nil,\n                                                                relativeTo: nil)\n                    \n                    UserDefaults.standard.set(bookmark, forKey: kShellSupportScriptName)\n                    UserDefaults.standard.synchronize()\n                    \n                    completion(true)\n                }\n            } else {\n                completion(false)\n            }\n        }\n    }\n    \n    fileprivate func uninstallScript (atUrl url: URL, _ completion: @escaping (Bool) -> Void) {\n        try? fileManager.removeItem(at: url)\n        completion(true)\n    }\n    \n//    fileprivate func installJit (_ completion: @escaping (Bool) -> Void) {\n//        \n//        let bundlePath = Bundle.main.url(forResource: \"jit\", withExtension: nil)!.deletingLastPathComponent()\n//        \n//        scripts.downloadFile(from: bundlePath.path + \"/\", to: kLocalBinPath, completion: { success in\n//            completion(success)\n//        })\n//    }\n    \n    fileprivate func uninstallCmds (_ completion: @escaping (Bool) -> Void) {\n        \n        scripts.removeFile(from: kLocalBinPath, completion: { success in\n            completion(success)\n        })\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/External/ExtensionsInteractor.swift",
    "content": "//\n//  CMDToolsInstaller.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 04/09/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nlet kShellSupportScriptName = \"ShellSupport\"\nlet kBrowserSupportScriptName = \"BrowserSupport\"\nlet kLocalBinPath = \"/usr/local/bin/\"\n\nclass ExtensionsInteractor {\n    \n    fileprivate let scripts: AppleScriptProtocol!\n    \n    init() {\n        #if APPSTORE\n            scripts = SandboxedAppleScript()\n        #else\n            scripts = AppleScript()\n        #endif\n    }\n    \n    func getJiraSettings (completion: @escaping ([String: String]) -> Void) {\n        \n        scripts.getJitInfo(completion: { dict in\n            completion(dict)\n        })\n    }\n    \n    func getBrowserInfo (browserId: String, browserName: String, completion: @escaping (String, String) -> Void) {\n        scripts.getBrowserInfo(browserId: browserId, browserName: browserName, completion: completion)\n    }\n    \n    func run (command: String, completion: @escaping (String?) -> Void) {\n        scripts.run(command: command, completion: completion)\n    }\n    \n    func getVersions (completion: @escaping (_ versions: Versions) -> Void) {\n        \n        self.scripts.getScriptVersion (script: kShellSupportScriptName, completion: { shellSupportScriptVersion in\n        self.scripts.getScriptVersion (script: kBrowserSupportScriptName, completion: { browserSupportScriptVersion in\n        self.scripts.getJirassicVersion (completion: { jirassicVersion in\n        self.scripts.getJitInfo (completion: { dict in\n            \n            let jitVersion = dict[\"version\"] ?? \"\"\n            let versions = Versions(shellScript: shellSupportScriptVersion, \n                                    browserScript: browserSupportScriptVersion,\n                                    jirassicCmd: jirassicVersion,\n                                    jitCmd: jitVersion\n            )\n            completion(versions)\n        })\n        })\n        })\n        })\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/External/SandboxedAppleScript.swift",
    "content": "//\n//  SandboxedAppleScriptt.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 20/11/2016.\n//  Copyright © 2016 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nclass SandboxedAppleScript: AppleScript {\n    \n    override var scriptsDirectory: URL? {\n        \n        return try? FileManager.default.url(for: .applicationScriptsDirectory,\n                                            in: FileManager.SearchPathDomainMask.userDomainMask,\n                                            appropriateFor: nil,\n                                            create: true)\n    }\n    \n    override func downloadFile (from: String, to: String, completion: @escaping (Bool) -> Void) {\n        \n        fatalError(\"File manipulation not supported in AppStore\")\n//        let args = NSAppleEventDescriptor.list()\n//        args.insert(NSAppleEventDescriptor(string: from), at: 1)\n//        args.insert(NSAppleEventDescriptor(string: to), at: 2)\n//        \n//        run (command: \"install\", scriptNamed: kShellSupportScriptName, args: args, completion: { descriptor in\n//            completion(descriptor != nil)\n//        })\n    }\n    \n    override func removeFile (from: String, completion: @escaping (Bool) -> Void) {\n        \n        fatalError(\"File manipulation not supported in AppStore\")\n//        let args = NSAppleEventDescriptor.list()\n//        args.insert(NSAppleEventDescriptor(string: from), at: 1)\n//\n//        run (command: \"uninstall\", scriptNamed: kShellSupportScriptName, args: args, completion: { descriptor in\n//            completion(descriptor != nil)\n//        })\n    }\n}\n\n"
  },
  {
    "path": "Delivery/macOS/IAP/IAPHelper.swift",
    "content": "//\n//  IAPHelper.swift\n//  IAPDemo\n//\n//  Created by Jason Zheng on 8/24/16.\n//  Copyright © 2016 Jason Zheng. All rights reserved.\n//\nimport StoreKit\n\nextension SKProduct {\n    public func localizedPrice() -> String? {\n        let formatter = NumberFormatter()\n        formatter.numberStyle = .currency\n        formatter.locale = self.priceLocale\n        return formatter.string(from: self.price)\n    }\n}\n\npublic let IAP = IAPHelper.sharedInstance\n\npublic typealias ProductIdentifier = String\npublic typealias ProductWithExpireDate = [ProductIdentifier: Date]\n\npublic typealias ProductsRequestHandler = (_ response: SKProductsResponse?, _ error: Error?) -> ()\npublic typealias PurchaseHandler = (_ productIdentifier: ProductIdentifier?, _ error: Error?) -> ()\npublic typealias RestoreHandler = (_ productIdentifiers: Set<ProductIdentifier>, _ error: Error?) -> ()\npublic typealias ValidateHandler = (_ statusCode: Int?, _ products: ProductWithExpireDate?, _ json: [String: Any]?) -> ()\n\npublic class IAPHelper: NSObject {\n    \n    private override init() {\n        super.init()\n        \n        addObserver()\n    }\n    static let sharedInstance = IAPHelper()\n    \n    fileprivate var productsRequest: SKProductsRequest?\n    fileprivate var productsRequestHandler: ProductsRequestHandler?\n    \n    fileprivate var purchaseHandler: PurchaseHandler?\n    fileprivate var restoreHandler: RestoreHandler?\n    \n    private var observerAdded = false\n    \n    public func addObserver() {\n        if !observerAdded {\n            observerAdded = true\n            SKPaymentQueue.default().add(self)\n        }\n    }\n    \n    public func removeObserver() {\n        if observerAdded {\n            observerAdded = false\n            SKPaymentQueue.default().remove(self)\n        }\n    }\n}\n\n// MARK: StoreKit API\nextension IAPHelper {\n    \n    public func requestProducts(_ productIdentifiers: Set<ProductIdentifier>, handler: @escaping ProductsRequestHandler) {\n        productsRequest?.cancel()\n        productsRequestHandler = handler\n        \n        productsRequest = SKProductsRequest(productIdentifiers: productIdentifiers)\n        productsRequest?.delegate = self\n        productsRequest?.start()\n    }\n    \n    public func purchaseProduct(_ productIdentifier: ProductIdentifier, handler: @escaping PurchaseHandler) {\n        purchaseHandler = handler\n        \n        let payment = SKMutablePayment()\n        payment.productIdentifier = productIdentifier\n        SKPaymentQueue.default().add(payment)\n    }\n    \n    public func restorePurchases(_ handler: @escaping RestoreHandler) {\n        restoreHandler = handler\n        SKPaymentQueue.default().restoreCompletedTransactions()\n    }\n    \n    /*\n     * password: Only used for receipts that contain auto-renewable subscriptions.\n     *           It's your app’s shared secret (a hexadecimal string) which was generated on iTunesConnect.\n     */\n    public func validateReceipt(_ password: String? = nil, handler: @escaping ValidateHandler) {\n        validateReceiptInternal(true, password: password) { (statusCode, products, json) in\n            \n            if let statusCode = statusCode , statusCode == ReceiptStatus.testReceipt.rawValue {\n                self.validateReceiptInternal(false, password: password, handler: { (statusCode, products, json) in\n                    handler(statusCode, products, json)\n                })\n                \n            } else {\n                handler(statusCode, products, json)\n            }\n        }\n    }\n}\n\n// MARK: SKProductsRequestDelegate\nextension IAPHelper: SKProductsRequestDelegate {\n    public func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {\n        productsRequestHandler?(response, nil)\n        clearRequestAndHandler()\n    }\n    \n    public func request(_ request: SKRequest, didFailWithError error: Error) {\n        productsRequestHandler?(nil, error)\n        clearRequestAndHandler()\n    }\n    \n    private func clearRequestAndHandler() {\n        productsRequest = nil\n        productsRequestHandler = nil\n    }\n}\n\n// MARK: SKPaymentTransactionObserver\nextension IAPHelper: SKPaymentTransactionObserver {\n    \n    public func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {\n        for transaction in transactions {\n            switch (transaction.transactionState) {\n                \n            case SKPaymentTransactionState.purchased:\n                completePurchaseTransaction(transaction)\n                \n            case SKPaymentTransactionState.restored:\n                finishTransaction(transaction)\n                \n            case SKPaymentTransactionState.failed:\n                failedTransaction(transaction)\n                \n            case SKPaymentTransactionState.purchasing,\n                 SKPaymentTransactionState.deferred:\n                break\n            }\n        }\n    }\n    \n    public func paymentQueueRestoreCompletedTransactionsFinished(_ queue: SKPaymentQueue) {\n        completeRestoreTransactions(queue, error: nil)\n    }\n    \n    public func paymentQueue(_ queue: SKPaymentQueue, restoreCompletedTransactionsFailedWithError error: Error) {\n        completeRestoreTransactions(queue, error: error)\n    }\n    \n    private func completePurchaseTransaction(_ transaction: SKPaymentTransaction) {\n        purchaseHandler?(transaction.payment.productIdentifier, transaction.error)\n        purchaseHandler = nil\n        \n        finishTransaction(transaction)\n    }\n    \n    private func completeRestoreTransactions(_ queue: SKPaymentQueue, error: Error?) {\n        var productIdentifiers = Set<ProductIdentifier>()\n        \n        for transaction in queue.transactions {\n            if let productIdentifier = transaction.original?.payment.productIdentifier {\n                productIdentifiers.insert(productIdentifier)\n            }\n            \n            finishTransaction(transaction)\n        }\n        \n        restoreHandler?(productIdentifiers, error)\n        restoreHandler = nil\n    }\n    \n    private func failedTransaction(_ transaction: SKPaymentTransaction) {\n        // NOTE: Both purchase and restore may come to this state. So need to deal with both handlers.\n        \n        purchaseHandler?(nil, transaction.error)\n        purchaseHandler = nil\n        \n        restoreHandler?(Set<ProductIdentifier>(), transaction.error)\n        restoreHandler = nil\n        \n        finishTransaction(transaction)\n    }\n    \n    // MARK: Helper\n    \n    private func finishTransaction(_ transaction: SKPaymentTransaction) {\n        switch transaction.transactionState {\n        case SKPaymentTransactionState.purchased,\n             SKPaymentTransactionState.restored,\n             SKPaymentTransactionState.failed:\n            \n            SKPaymentQueue.default().finishTransaction(transaction)\n            \n        default:\n            break\n        }\n    }\n}\n\n// MARK: Validate Receipt\nextension IAPHelper {\n    \n    fileprivate func validateReceiptInternal(_ isProduction: Bool, password: String?, handler: @escaping ValidateHandler) {\n        \n        let serverURL = isProduction\n            ? \"https://buy.itunes.apple.com/verifyReceipt\"\n            : \"https://sandbox.itunes.apple.com/verifyReceipt\"\n        \n        let appStoreReceiptURL = Bundle.main.appStoreReceiptURL\n        guard let receiptData = receiptData(appStoreReceiptURL, password: password), let url = URL(string: serverURL) else {\n            handler(ReceiptStatus.noRecipt.rawValue, nil, nil)\n            return\n        }\n        \n        let request = NSMutableURLRequest(url: url)\n        request.httpMethod = \"POST\"\n        request.httpBody = receiptData\n        \n        let task = URLSession.shared.dataTask(with: request as URLRequest) { (data, response, error) in\n            \n            guard let data = data, error == nil else {\n                handler(nil, nil, nil)\n                return\n            }\n            \n            do {\n                let json = try JSONSerialization.jsonObject(with: data, options:[]) as? [String: Any]\n                \n                let statusCode = json?[\"status\"] as? Int\n                let products = self.parseValidateResultJSON(json)\n                handler(statusCode, products, json)\n                \n            } catch {\n                handler(nil, nil, nil)\n            }\n        }\n        task.resume()\n    }\n    \n    internal func parseValidateResultJSON(_ json: [String: Any]?) -> ProductWithExpireDate? {\n        \n        var products = ProductWithExpireDate()\n        var canceledProducts = ProductWithExpireDate()\n        var productDateDict = [String: [ProductDateHelper]]()\n        let dateOf5000 = Date(timeIntervalSince1970: 95617584000) // 5000-01-01\n        \n        var totalInAppPurchaseList = [[String: Any]]()\n        if let receipt = json?[\"receipt\"] as? [String: Any],\n            let inAppPurchaseList = receipt[\"in_app\"] as? [[String: Any]] {\n            totalInAppPurchaseList += inAppPurchaseList\n        }\n        if let inAppPurchaseList = json?[\"latest_receipt_info\"] as? [[String: Any]] {\n            totalInAppPurchaseList += inAppPurchaseList\n        }\n        \n        for inAppPurchase in totalInAppPurchaseList {\n            if let productID = inAppPurchase[\"product_id\"] as? String,\n                let purchaseDate = parseDate(inAppPurchase[\"purchase_date_ms\"] as? String) {\n                \n                let expiresDate = parseDate(inAppPurchase[\"expires_date_ms\"] as? String)\n                let cancellationDate = parseDate(inAppPurchase[\"cancellation_date_ms\"] as? String)\n                \n                let productDateHelper = ProductDateHelper(purchaseDate: purchaseDate, expiresDate: expiresDate, canceledDate: cancellationDate)\n                if productDateDict[productID] == nil {\n                    productDateDict[productID] = [productDateHelper]\n                } else {\n                    productDateDict[productID]?.append(productDateHelper)\n                }\n                \n                if let cancellationDate = cancellationDate {\n                    if let lastCanceledDate = canceledProducts[productID] {\n                        if lastCanceledDate.timeIntervalSince1970 < cancellationDate.timeIntervalSince1970 {\n                            canceledProducts[productID] = cancellationDate\n                        }\n                    } else {\n                        canceledProducts[productID] = cancellationDate\n                    }\n                }\n            }\n        }\n        \n        for (productID, productDateHelpers) in productDateDict {\n            var date = Date(timeIntervalSince1970: 0)\n            let lastCanceledDate = canceledProducts[productID]\n            \n            for productDateHelper in productDateHelpers {\n                let validDate = productDateHelper.getValidDate(lastCanceledDate: lastCanceledDate, unlimitedDate: dateOf5000)\n                if date.timeIntervalSince1970 < validDate.timeIntervalSince1970 {\n                    date = validDate\n                }\n            }\n            \n            products[productID] = date\n        }\n        \n        return products.isEmpty ? nil : products\n    }\n    \n    private func receiptData(_ appStoreReceiptURL: URL?, password: String?) -> Data? {\n        guard let receiptURL = appStoreReceiptURL, let receipt = try? Data(contentsOf: receiptURL) else {\n            return nil\n        }\n        \n        do {\n            let receiptData = receipt.base64EncodedString()\n            var requestContents = [\"receipt-data\": receiptData]\n            if let password = password {\n                requestContents[\"password\"] = password\n            }\n            let requestData = try JSONSerialization.data(withJSONObject: requestContents, options: [])\n            return requestData\n            \n        } catch let error {\n            NSLog(\"\\(error)\")\n        }\n        \n        return nil\n    }\n    \n    private func parseDate(_ str: String?) -> Date? {\n        guard let str = str, let msTimeInterval = TimeInterval(str) else {\n            return nil\n        }\n        \n        return Date(timeIntervalSince1970: msTimeInterval / 1000)\n    }\n}\n\ninternal struct ProductDateHelper {\n    var purchaseDate = Date(timeIntervalSince1970: 0)\n    var expiresDate: Date? = nil\n    var canceledDate: Date? = nil\n    \n    func getValidDate(lastCanceledDate: Date?, unlimitedDate: Date) -> Date {\n        if let lastCanceledDate = lastCanceledDate {\n            return (purchaseDate.timeIntervalSince1970 > lastCanceledDate.timeIntervalSince1970)\n                ? (expiresDate ?? unlimitedDate)\n                : lastCanceledDate\n        }\n        \n        if let canceledDate = canceledDate {\n            return canceledDate\n        } else if let expiresDate = expiresDate {\n            return expiresDate\n        } else {\n            return unlimitedDate\n        }\n    }\n}\n\npublic enum ReceiptStatus: Int {\n    case noRecipt = -999\n    case valid = 0\n    case testReceipt = 21007\n}\n"
  },
  {
    "path": "Delivery/macOS/IAP/Store.swift",
    "content": "//\n//  Created by Cristian Baluta on 27/06/2018.\n//  Copyright © 2018 Baluta Cristian. All rights reserved.\n//\n\nimport Foundation\nimport StoreKit\nimport RCPreferences\nimport RCLog\n\nenum StoreProduct: String, RCPreferencesProtocol {\n    \n    case git = \"com.jirassic.macos.git.6months\"\n    case jiraTempo = \"com.jirassic.macos.jiratempo.6months\"\n    case full = \"com.jirassic.macos.full.6months\"\n    \n    func defaultValue() -> Any {\n        switch self {\n        case .git:           return false\n        case .jiraTempo:     return false\n        case .full:          return false\n        }\n    }\n}\n\nclass Store {\n    \n    static let shared = Store()\n    private let localPref = RCPreferences<StoreProduct>()\n    private var products = [SKProduct]()\n    \n    init() {\n//        getProducts { (success) in }\n        \n//        let receiptUrl = Bundle.main.appStoreReceiptURL\n    }\n    \n    var isGitPurchased: Bool {\n        return true\n//        return localPref.bool(.full) || localPref.bool(.git)\n    }\n    \n    var isJiraTempoPurchased: Bool {\n        return true\n//        return localPref.bool(.full) || localPref.bool(.jiraTempo)\n    }\n    \n    func getProduct(_ product: StoreProduct, _ completion: @escaping (SKProduct?) -> Void) {\n        \n        guard let skProduct = products.filter({$0.productIdentifier == product.rawValue}).first else {\n            getProducts { (success) in\n                if success {\n                    self.getProduct(product, completion)\n                } else {\n                    completion(nil)\n                }\n            }\n            return\n        }\n        completion(skProduct)\n    }\n    \n    private func getProducts(_ completion: @escaping (Bool) -> Void) {\n        \n        var productIdentifiers = Set<ProductIdentifier>()\n        productIdentifiers.insert(StoreProduct.git.rawValue)\n        productIdentifiers.insert(StoreProduct.jiraTempo.rawValue)\n        productIdentifiers.insert(StoreProduct.full.rawValue)\n        \n        IAP.requestProducts(productIdentifiers) { (response, error) in\n            if let products = response?.products, !products.isEmpty {\n                self.products = products\n                RCLog(products)\n                completion(true)\n            } else if let _ = response?.invalidProductIdentifiers {\n                completion(false)\n            } else {\n                // Some error happened\n                completion(false)\n            }\n        }\n    }\n    \n    func purchase(product: StoreProduct, _ completion: @escaping (Bool) -> Void) {\n        \n        IAP.purchaseProduct(product.rawValue, handler: { (productIdentifier, error) in\n            \n            if let product = StoreProduct(rawValue: productIdentifier ?? \"\") {\n                \n                self.localPref.set(true, forKey: product)\n                completion(true)\n                \n            } else if let error = error as NSError? {\n                if error.code == SKError.Code.paymentCancelled.rawValue {\n                    // User cancelled\n                    RCLog(\"purchase cancelled\")\n                } else {\n                    // Some error happened\n                }\n                completion(false)\n            }\n        })\n    }\n    \n    func restore(_ completion: @escaping (Bool) -> Void) {\n        \n        IAP.restorePurchases({ (productIdentifiers, error) in\n            \n            RCLog(\"Restored products: \\(productIdentifiers)\")\n            if let error = error as NSError? {\n                if error.code == SKError.Code.paymentCancelled.rawValue {\n                    // User cancelled\n                    RCLog(\"canceled\")\n                } else {\n                    // Some error happened\n                }\n                completion(false)\n            } else {\n                // Reset all products\n                self.localPref.set(false, forKey: .full)\n                // Set purchased to true for purchased items\n                for productIdentifier in productIdentifiers.reversed() {\n                    if let product = StoreProduct(rawValue: productIdentifier) {\n                        self.localPref.set(true, forKey: product)\n                    }\n                }\n                completion(true)\n            }\n        })\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Images.xcassets/AppIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"size\" : \"16x16\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_jirassic_16.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"16x16\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_jirassic_32.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"32x32\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_jirassic_32.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"32x32\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_jirassic_64.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"128x128\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_jirassic_128.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"128x128\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_jirassic_256.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"256x256\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_jirassic_256.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"256x256\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_jirassic_512.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"512x512\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_jirassic_512.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"512x512\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_jirassic_1024.png\",\n      \"scale\" : \"2x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Delivery/macOS/Images.xcassets/AppStoreIcon.appiconset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"size\" : \"16x16\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_jirassic_16.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"16x16\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_jirassic_32.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"32x32\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_jirassic_32.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"32x32\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_jirassic_64.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"128x128\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_jirassic_128.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"128x128\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_jirassic_256.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"256x256\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_jirassic_256.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"256x256\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_jirassic_512.png\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"size\" : \"512x512\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_jirassic_512.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"size\" : \"512x512\",\n      \"idiom\" : \"mac\",\n      \"filename\" : \"icon_jirassic_1024.png\",\n      \"scale\" : \"2x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Delivery/macOS/Images.xcassets/ButClose.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"mac\",\n      \"filename\" : \"ButClose.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"mac\",\n      \"filename\" : \"ButClose@2x.png\",\n      \"scale\" : \"2x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Delivery/macOS/Images.xcassets/ButDisabled.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"mac\",\n      \"filename\" : \"ButDisabled.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"mac\",\n      \"filename\" : \"ButDisabled@2x.png\",\n      \"scale\" : \"2x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Delivery/macOS/Images.xcassets/ButMinimize.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"mac\",\n      \"filename\" : \"ButMinimize.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"mac\",\n      \"filename\" : \"ButMinimize@2x.png\",\n      \"scale\" : \"2x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Delivery/macOS/Images.xcassets/CalendarIcon.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"mac\",\n      \"filename\" : \"Calendar-2.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"mac\",\n      \"filename\" : \"Calendar-3.png\",\n      \"scale\" : \"2x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Delivery/macOS/Images.xcassets/Contents.json",
    "content": "{\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Delivery/macOS/Images.xcassets/GitIcon.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"universal\",\n      \"filename\" : \"GitIcon.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"2x\"\n    },\n    {\n      \"idiom\" : \"universal\",\n      \"scale\" : \"3x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Delivery/macOS/Images.xcassets/MenuBarIcon-Normal.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"mac\",\n      \"filename\" : \"MenuBarIcon-Normal.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"mac\",\n      \"filename\" : \"MenuBarIcon-Normal@2x.png\",\n      \"scale\" : \"2x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}"
  },
  {
    "path": "Delivery/macOS/Images.xcassets/MenuBarIcon-Selected.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"mac\",\n      \"filename\" : \"MenuBarIcon-Selected.png\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"mac\",\n      \"filename\" : \"MenuBarIcon-Selected@2x.png\",\n      \"scale\" : \"2x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Delivery/macOS/Images.xcassets/Plus.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"mac\",\n      \"filename\" : \"AddMailboxTemplate-2.pdf\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  },\n  \"properties\" : {\n    \"template-rendering-intent\" : \"template\"\n  }\n}"
  },
  {
    "path": "Delivery/macOS/Images.xcassets/WarningButton.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"mac\",\n      \"filename\" : \"warning.png\",\n      \"scale\" : \"2x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Delivery/macOS/Images.xcassets/WarningIcon.imageset/Contents.json",
    "content": "{\n  \"images\" : [\n    {\n      \"idiom\" : \"mac\",\n      \"scale\" : \"1x\"\n    },\n    {\n      \"idiom\" : \"mac\",\n      \"filename\" : \"warning.png\",\n      \"scale\" : \"2x\"\n    }\n  ],\n  \"info\" : {\n    \"version\" : 1,\n    \"author\" : \"xcode\"\n  }\n}"
  },
  {
    "path": "Delivery/macOS/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIconFile</key>\n\t<string>Jirassic</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>18.12.12</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleVersion</key>\n\t<string>11</string>\n\t<key>LSApplicationCategoryType</key>\n\t<string>public.app-category.productivity</string>\n\t<key>LSMinimumSystemVersion</key>\n\t<string>$(MACOSX_DEPLOYMENT_TARGET)</string>\n\t<key>LSUIElement</key>\n\t<true/>\n\t<key>NSAppleScriptEnabled</key>\n\t<true/>\n\t<key>NSCalendarsUsageDescription</key>\n\t<string>Needed to list meetings</string>\n\t<key>NSCalendarsFullAccessUsageDescription</key>\n\t<string>Needed to list meetings</string>\n\t<key>NSHumanReadableCopyright</key>\n\t<string>Copyright © 2018 Imagin Soft. All rights reserved.</string>\n\t<key>NSMainStoryboardFile</key>\n\t<string>Main</string>\n\t<key>NSPrincipalClass</key>\n\t<string>NSApplication</string>\n\t<key>OSAScriptingDefinition</key>\n\t<string>jirassic.sdef</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Delivery/macOS/Jirassic.entitlements",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>com.apple.developer.icloud-container-identifiers</key>\n\t<array>\n\t\t<string>iCloud.$(CFBundleIdentifier)</string>\n\t</array>\n\t<key>com.apple.developer.icloud-services</key>\n\t<array>\n\t\t<string>CloudKit</string>\n\t</array>\n\t<key>com.apple.developer.ubiquity-kvstore-identifier</key>\n\t<string>$(TeamIdentifierPrefix)$(CFBundleIdentifier)</string>\n\t<key>com.apple.security.app-sandbox</key>\n\t<true/>\n\t<key>com.apple.security.files.user-selected.read-only</key>\n\t<true/>\n\t<key>com.apple.security.network.client</key>\n\t<true/>\n\t<key>com.apple.security.network.server</key>\n\t<true/>\n\t<key>com.apple.security.personal-information.calendars</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "Delivery/macOS/Menu/MenuBarController.swift",
    "content": "//\n//  MenuBarController.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 26/03/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\n\nclass MenuBarController: NSObject {\n\t\n    fileprivate let bar = NSStatusBar.system\n    fileprivate var item: NSStatusItem!\n\tvar iconView: MenuBarIconView!\n    \n    var onOpen: (() -> ())?\n    var onClose: (() -> ())?\n    \n    var appearsDisabled: Bool? {\n        set {\n            iconView.alphaValue = newValue == true ? 0.4 : 1.0\n        }\n        get {\n            return iconView.alphaValue != 1.0\n        }\n    }\n    var isDark: Bool? {\n        didSet {\n            iconView.isDark = isDark\n        }\n    }\n\t\n\toverride init() {\n\t\tsuper.init()\n\t\t\n\t\tlet length: CGFloat = -1 //NSVariableStatusItemLength\n        item = bar.statusItem(withLength: length)\n\t\t\n\t\ticonView = MenuBarIconView(item: item)\n\t\ticonView.onMouseDown = {\n            if self.iconView.isSelected {\n                self.onOpen?()\n            } else {\n                self.onClose?()\n            }\n\t\t}\n\t\titem.view = iconView\n\t}\n    \n    func handleQuitButton() {\n        NSApplication.shared.terminate(nil)\n    }\n    \n    func triggerOpen() {\n        if iconView.isSelected == false {\n            iconView.mouseDown(with: NSEvent())\n        }\n    }\n    \n    func triggerClose() {\n        if iconView.isSelected == true {\n            iconView.mouseDown(with: NSEvent())\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Menu/MenuBarIconView.swift",
    "content": "//\n//  IconView.swift\n//  SwiftStatusBarApplication\n//\n//  Created by Tommy Leung on 6/7/14.\n//  Copyright (c) 2014 Tommy Leung. All rights reserved.\n//\n\nimport Cocoa\n\nclass MenuBarIconView : NSView {\n\t\n    private(set) var image: NSImage\n    private let item: NSStatusItem\n    \n    var onMouseDown: (() -> ())?\n    \n    var _isSelected = false\n    var isSelected: Bool {\n        get {\n            return _isSelected\n        }\n        set {\n            _isSelected = newValue\n            self.image = NSImage(named: isDark == true || _isSelected ? \"MenuBarIcon-Selected\" : \"MenuBarIcon-Normal\")!\n            self.needsDisplay = true\n        }\n    }\n    var isDark: Bool? {\n        didSet {\n            self.image = NSImage(named: isDark == true ? \"MenuBarIcon-Selected\" : \"MenuBarIcon-Normal\")!\n            self.needsDisplay = true\n        }\n    }\n    \n    init (item: NSStatusItem) {\n        \n        self.item = item\n        self.image = NSImage(named: \"MenuBarIcon-Normal\")!\n        \n        let thickness = NSStatusBar.system.thickness\n        let rect = CGRect(x: 0, y: 0, width: thickness, height: thickness)\n        \n        super.init(frame: rect)\n    }\n\n    required init? (coder: NSCoder) {\n        fatalError(\"init(coder:) has not been implemented\")\n    }\n    \n    override func draw (_ dirtyRect: NSRect) {\n\t\t\n        self.item.drawStatusBarBackground(in: dirtyRect, withHighlight: self.isSelected)\n        \n        let size = self.image.size\n        let rect = CGRect(x: 2, y: 2, width: size.width, height: size.height)\n        \n        image.draw(in: rect)\n    }\n    \n    override func mouseDown (with theEvent: NSEvent) {\n        self.isSelected = !_isSelected\n        onMouseDown?()\n    }\n    \n    override func mouseUp (with theEvent: NSEvent) {\n\t\t\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Modules/CalendarEvents/ModuleCalendar.swift",
    "content": "//\n//  ModuleCalendar.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 04/07/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport EventKit\nimport RCPreferences\n\nclass ModuleCalendar {\n\n    private var eventStore = EKEventStore()\n    private let pref = RCPreferences<LocalPreferences>()\n    \n    var isAuthorizationDetermined: Bool {\n        return EKEventStore.authorizationStatus(for: .event) != .notDetermined\n    }\n    \n    var isAuthorized: Bool {\n        if #available(macOS 14.0, *) {\n            return EKEventStore.authorizationStatus(for: .event) == .fullAccess\n        } else {\n            return EKEventStore.authorizationStatus(for: .event) == .authorized\n        }\n    }\n    \n    var selectedCalendars: [String] {\n        get {\n            return pref.string(.settingsSelectedCalendars).split(separator: \",\").map({String($0)})\n        }\n        set {\n            pref.set(newValue.joined(separator: \",\"), forKey: .settingsSelectedCalendars)\n        }\n    }\n    \n    func authorize(_ completion: @escaping (Bool) -> Void) {\n        if #available(macOS 14.0, *) {\n            eventStore.requestFullAccessToEvents { granted, error in\n                self.eventStore = EKEventStore()\n                completion(granted)\n            }\n        } else {\n            eventStore.requestAccess(to: .event) { granted, error in\n                self.eventStore = EKEventStore()\n                completion(granted)\n            }\n        }\n    }\n    \n    func allCalendars() -> [EKCalendar] {\n        return eventStore.calendars(for: .event)\n    }\n\n    func allCalendarsTitles() -> [String] {\n        return allCalendars().map({$0.title})\n    }\n\n    func events (dateStart: Date, dateEnd: Date, completion: @escaping (([Task]) -> Void)) {\n        \n        guard isAuthorized else {\n            completion([])\n            return\n        }\n        \n        var tasks = [Task]()\n\n        authorize { (granted) in\n            \n            guard granted else {\n                completion([])\n                return\n            }\n            for calendar in self.allCalendars() {\n                \n                if self.selectedCalendars.contains(calendar.title) {\n                    \n                    let eventsPredicate = self.eventStore.predicateForEvents(withStart: dateStart, end: dateEnd, calendars: [calendar])\n                    let events: [EKEvent] = self.eventStore.events(matching: eventsPredicate)\n                    \n                    for event in events {\n                        // Create a task without id, this will tell the app that is not saved in db\n                        let task = Task(lastModifiedDate: nil,\n                                        startDate: event.startDate,\n                                        endDate: event.endDate,\n                                        notes: event.title,\n                                        taskNumber: nil,\n                                        taskTitle: event.title,\n                                        taskType: .calendar,\n                                        objectId: nil)\n                        tasks.append(task)\n                    }\n                    DispatchQueue.main.async {\n                        completion(tasks)\n                    }\n                }\n            }\n        }\n    }\n\n}\n"
  },
  {
    "path": "Delivery/macOS/Modules/GitLogs/GitBranchParser.swift",
    "content": "//\n//  GitBranchParser.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 19/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nclass GitBranchParser {\n    \n    private var raw: String\n    \n    init (raw: String) {\n        self.raw = raw\n    }\n    \n    func firstBranchName() -> String {\n        return branches().first ?? \"\"\n    }\n    \n    func branches() -> [String] {\n        \n        var arr = [String]()\n        \n        let r = raw.replacingOccurrences(of: \"\\r\", with: \"\\n\")\n            .replacingOccurrences(of: \"*\", with: \"\")\n            .replacingOccurrences(of: \" \", with: \"\")\n        \n        let results = r.split(separator: \"\\n\").map { String($0) }\n        \n        for result in results {\n            if result.count > 0 {\n                arr.append(result)\n            }\n        }\n        \n        return arr\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Modules/GitLogs/GitBranchParserTests.swift",
    "content": "//\n//  GitBranchParserTests.swift\n//  JirassicTests\n//\n//  Created by Cristian Baluta on 20/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport XCTest\n@testable import Jirassic_no_cloud\n\nclass GitBranchParserTests: XCTestCase {\n\n    let raw = \"   branch1\\r\" +\n        \"branch2\\n\" +\n        \"* branch3\\r\\n\" +\n        \" \\r\" +\n        \"  branch4\"\n    \n    func testBranches() {\n        \n        let parser = GitBranchParser(raw: raw)\n        let branches = parser.branches()\n        \n        \n        XCTAssert(branches.count == 4)\n        XCTAssert(branches[0] == \"branch1\")\n        XCTAssert(branches[1] == \"branch2\")\n        XCTAssert(branches[2] == \"branch3\")\n        XCTAssert(branches[3] == \"branch4\")\n    }\n    \n    func testBranchName() {\n        \n        let parser = GitBranchParser(raw: raw)\n        let branchName = parser.firstBranchName()\n        XCTAssert(branchName == \"branch1\")\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Modules/GitLogs/GitCommitsParser.swift",
    "content": "//\n//  GitCommitsParser.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 17/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nclass GitCommitsParser {\n    \n    private var raw: String\n    \n    init (raw: String) {\n        self.raw = raw\n    }\n    \n    func toGitCommits() -> [GitCommit] {\n        \n        var commits = [GitCommit]()\n        \n        let r = raw.replacingOccurrences(of: \"\\r\", with: \"\\n\")\n        let results = r.split(separator: \"\\n\").map { String($0) }\n        for result in results {\n            if result != \"\" {\n                commits.append( self.parseCommit(result) )\n            }\n        }\n        \n        return commits\n    }\n    \n    private func parseCommit (_ commit: String) -> GitCommit {\n        \n        var comps = commit.split(separator: \";\").map { String($0) }\n        let commitNumber = comps.count > 0 ? comps.removeFirst() : \"\"\n        let timestamp = comps.count > 0 ? comps.removeFirst() : \"0\"\n        let date = Date(timeIntervalSince1970: TimeInterval(timestamp)!)\n        let email = comps.count > 0 ? comps.removeFirst() : \"\"\n        let message = comps.count > 0 ? comps.removeFirst() : \"\"\n        let branchName = comps.count > 0 ? comps.removeFirst() : nil\n        \n        return GitCommit(commitNumber: commitNumber,\n                         date: date,\n                         authorEmail: email,\n                         message: message,\n                         branchName: branchName)\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Modules/GitLogs/GitCommitsParserTests.swift",
    "content": "//\n//  GitCommitsParserTests.swift\n//  JirassicTests\n//\n//  Created by Cristian Baluta on 17/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport XCTest\n@testable import Jirassic_no_cloud\n\nclass GitCommitsParserTests: XCTestCase {\n\n    func testParser() {\n        \n        let raw = \"0;1517923183;me@email.com;AAA-3007 Refactor;\\n\" +\n        \"0;1517922963;you@email.com;AAA-3007 Refactor;\\r\" +\n        \"0;1517922230;me@email.com;AAA-3007 Refactor;(AAA-3007_Branchname)\\r\\n\" +\n        \"0;1517922230;me@email.com;AAA-3007 Refactor;(AAA-3007_Branchname)\\n\\r\" +\n        \"0;1517922230;me@email.com;AAA-3007 Refactor;(AAA-3007_Branchname)\"\n        \n        let parser = GitCommitsParser(raw: raw)\n        let commits = parser.toGitCommits()\n        \n        XCTAssert(commits.count == 5)\n        \n        let commit1 = commits[0]\n        XCTAssert(commit1.authorEmail == \"me@email.com\")\n        XCTAssert(commit1.message == \"AAA-3007 Refactor\")\n        XCTAssertNil(commit1.branchName)\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Modules/GitLogs/GitUserParser.swift",
    "content": "//\n//  GitUserParser.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 14/12/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nclass GitUserParser {\n    \n    private var raw: String\n\n    init (raw: String) {\n        self.raw = raw\n    }\n\n    func toGitUsers() -> [GitUser] {\n\n        var users = [GitUser]()\n\n        let r = raw.replacingOccurrences(of: \"\\r\", with: \"\\n\")\n        let results = r.split(separator: \"\\n\").map { String($0) }\n        for result in results {\n            if result != \"\" {\n                users.append( self.parseUser(result) )\n            }\n        }\n\n        return users\n    }\n\n    private func parseUser (_ user: String) -> GitUser {\n\n        var comps = user.split(separator: \";\").map { String($0) }\n        let name = comps.count > 0 ? comps.removeFirst() : \"\"\n        let email = comps.count > 0 ? comps.removeFirst() : \"\"\n\n        return GitUser(name: name, email: email)\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Modules/GitLogs/ModuleGitLogs.swift",
    "content": "//\n//  ModuleGitLogs.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 16/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport RCPreferences\nimport RCLog\n\nclass ModuleGitLogs {\n    \n    private let extensions = ExtensionsInteractor()\n    private let pref = RCPreferences<LocalPreferences>()\n    \n//    func isReachable (completion: @escaping (Bool) -> Void) {\n//        checkIfGitInstalled(completion: completion)\n//    }\n    \n    func fetchLogs (dateStart: Date, dateEnd: Date, completion: @escaping (([Task]) -> Void)) {\n        // Because of a bug in applescripts split the call into smaller chunks for months\n        if dateEnd.timeIntervalSince(dateStart) > 7*24.hoursToSec {\n            let chunks = ceil(dateEnd.timeIntervalSince(dateStart) / (7*24.hoursToSec))\n            var dates = [(dateStart: Date, dateEnd: Date)]()\n            for i in 0..<Int(chunks) {\n                var date = (dateStart: dateStart.addingTimeInterval(Double(i*7)*24.hoursToSec),\n                            dateEnd: dateStart.addingTimeInterval(Double((i+1)*7)*24.hoursToSec))\n                if date.dateEnd > dateEnd {\n                    date.dateEnd = dateEnd\n                }\n                dates.append(date)\n            }\n            logsChunk(dates: dates, completion: completion)\n        } else {\n            logsChunk(dates: [(dateStart: dateStart, dateEnd: dateEnd)], completion: completion)\n        }\n    }\n\n    /// Returns a list of commiters emails\n    func fetchUsers(completion: @escaping (([GitUser]) -> Void)) {\n\n        let paths = pref.string(.settingsGitPaths).split(separator: \",\").map { String($0) }\n        users(paths: paths, previousUsers: []) { gitUsers in\n            completion(gitUsers)\n        }\n    }\n\n    private func users (paths: [String], previousUsers: [GitUser], completion: @escaping (([GitUser]) -> Void)) {\n\n        var gitUsers = previousUsers\n        var paths = paths\n\n        guard let path = paths.first else {\n            completion(gitUsers)\n            return\n        }\n        paths.removeFirst()\n\n        getGitUsers(at: path) { rawResults in\n            let parser = GitUserParser(raw: rawResults)\n            gitUsers += parser.toGitUsers()\n            self.users(paths: paths, previousUsers: gitUsers, completion: completion)\n        }\n    }\n\n    private func logsChunk (dates: [(dateStart: Date, dateEnd: Date)], previousTasks: [Task] = [], completion: @escaping (([Task]) -> Void)) {\n\n        var tasks = previousTasks\n        var dates = dates\n        guard dates.count > 0 else {\n            completion(tasks)\n            return\n        }\n        let interval = dates.removeFirst()\n        \n        let paths = pref.string(.settingsGitPaths).split(separator: \",\").map { String($0) }\n        logs(dateStart: interval.dateStart, dateEnd: interval.dateEnd, paths: paths, previousCommits: []) { commits in\n            for commit in commits {\n                // Sometimes git returns commits that are not in the provided interval, filter them out\n                guard interval.dateStart <= commit.date && commit.date <= interval.dateEnd else {\n                    RCLog(\"This commit is not in the provided interval, ignoring... \\(commit)\")\n                    continue\n                }\n                // If the branch sounds like invalid (empty or master) try to obtain the task number from commit message\n                let str = commit.branchName != \"\" && commit.branchName != \"master\" ? commit.branchName : commit.message\n                let branchParser = ParseGitBranch(branchName: str ?? \"\")\n                let taskTitle = branchParser.taskTitle()\n                let taskNumber = branchParser.taskNumber() ?? taskTitle\n                // Remove task number from the beginning of a commit message\n                var notes = \"\"\n                if commit.message.contains(\"Merge pull request #\") {\n                    notes = \"Merge pull request\"\n                } else {\n                    notes = commit.message\n                        .replacingOccurrences(of: taskNumber, with: \"\")\n                        .trimmingCharacters(in: NSCharacterSet.whitespaces)\n                }\n\n                // Create a task without id, this will tell the app that is not saved in db\n                let task = Task(lastModifiedDate: nil,\n                                startDate: nil,\n                                endDate: commit.date,\n                                notes: notes,\n                                taskNumber: taskNumber,\n                                taskTitle: taskTitle,\n                                taskType: .gitCommit,\n                                objectId: nil)\n                tasks.append(task)\n            }\n            self.logsChunk(dates: dates, previousTasks: tasks, completion: completion)\n            \n        }\n    }\n    \n    private func logs (dateStart: Date, dateEnd: Date, paths: [String], previousCommits: [GitCommit], completion: @escaping (([GitCommit]) -> Void)) {\n        \n        var commits = previousCommits\n        var paths = paths\n        \n        guard let path = paths.first else {\n            completion(commits)\n            return\n        }\n        paths.removeFirst()\n        \n        let allowedAuthors: [String] = pref.string(.settingsGitAuthors).split(separator: \",\").map { String($0) }\n        \n        getGitLogs(at: path, dateStart: dateStart, dateEnd: dateEnd, completion: { rawResults in\n            \n            let parser = GitCommitsParser(raw: rawResults)\n            var rawCommits: [GitCommit] = parser.toGitCommits()\n            // Filter out commits that don't belong to my users\n            rawCommits = rawCommits.filter({ allowedAuthors.contains($0.authorEmail) })\n            \n            // Obtain branch names where missing\n            self.getBranchName(at: path, previousCommits: rawCommits, completion: { commitsWithBranches in\n                commits += commitsWithBranches\n                self.logs(dateStart: dateStart, dateEnd: dateEnd, paths: paths, previousCommits: commits, completion: completion)\n            })\n            \n        })\n    }\n    \n    private func getBranchName (at path: String, previousCommits: [GitCommit], completion: @escaping (([GitCommit]) -> Void)) {\n        \n        var i: Int = -1, j = 0\n        var commits = previousCommits\n        for c in commits {\n            if c.branchName == nil {\n                i = j\n                break\n            }\n            j += 1\n        }\n        if i > -1 {\n            var commitToFix = commits[i]\n            getGitBranch(at: path, containing: commitToFix.commitNumber, completion: { rawBranches in\n                let parser = GitBranchParser(raw: rawBranches)\n                commitToFix.branchName = parser.firstBranchName()\n                commits[i] = commitToFix\n                self.getBranchName(at: path, previousCommits: commits, completion: completion)\n            })\n        } else {\n            completion(commits)\n        }\n    }\n}\n\nextension ModuleGitLogs {\n    \n    func checkIfGitInstalled (completion: @escaping (Bool) -> Void) {\n        \n        let command = \"command -v git\"// Returns the path to git if exists\n        extensions.run (command: command, completion: { result in\n            completion(result != nil)\n        })\n    }\n    \n//    private func checkGitRepository (at path: String, completion: @escaping (Bool) -> Void) {\n//\n//        let command = \"git -C \\(path) rev-parse --is-inside-work-tree\"\n//        extensions.run (command: command, completion: { result in\n//            completion(result == \"true\")\n//        })\n//    }\n    \n    private func getGitLogs (at path: String, dateStart: Date, dateEnd: Date, completion: @escaping (String) -> Void) {\n        // https://www.kernel.org/pub/software/scm/git/docs/git-log.html#_pretty_formats\n        // error \"fatal: Not a git repository (or any of the parent directories): .git\" number 128\n        // do shell script git -C ~/Documents/proj log --after=\"2018-2-6\" --before=\"2018-2-7\" --pretty=format:\"%at;%ae;%s;%D\"\n        \n        // Getting git logs based on dates looks unreliable, fetch all logs in a day and filter later\n        let startDate = dateStart.startOfDay().YYYYMMddT00()\n        let endDate = dateEnd.endOfDay().addingTimeInterval(1).YYYYMMddT00()\n        let command = \"git -C \\(path) log --reflog --after=\\\"\\(startDate)\\\" --before=\\\"\\(endDate)\\\" --pretty=format:\\\"%h;%at;%ae;%s;%D\\\"\"\n        extensions.run (command: command, completion: { result in\n            if let result = result {\n                if result.contains(\"fatal: Not a git repository (or any of the parent directories): .git\") {\n                    completion(\"\")\n                } else {\n                    completion(result)\n                }\n            } else {\n                completion(\"\")\n            }\n        })\n    }\n    \n    private func getGitBranch (at path: String, containing commitNumber: String, completion: @escaping (String) -> Void) {\n        \n        // let command = \"git -C \\(path) log \\(commitNumber)..HEAD --ancestry-path --merges --oneline | tail -n 1\"\n        let command = \"git -C \\(path) branch --contains \\(commitNumber)\"\n        extensions.run (command: command, completion: { result in\n            if let result = result {\n                completion(result)\n            } else {\n                completion(\"\")\n            }\n        })\n    }\n\n    // Returns the raw response for users\n    private func getGitUsers (at path: String, completion: @escaping (String) -> Void) {\n        // git log --pretty=\"%an %ae%n%cn %ce\" | sort | uniq\n        let command = \"git -C \\(path) log --pretty=format:\\\"%cn;%ce\\\" | sort | uniq\"\n        extensions.run (command: command, completion: { result in\n            if let result = result {\n                if result.contains(\"fatal: Not a git repository (or any of the parent directories): .git\") {\n                    completion(\"\")\n                } else {\n                    completion(result)\n                }\n            } else {\n                completion(\"\")\n            }\n        })\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Modules/Hookup/ModuleHookup.swift",
    "content": "//\n//  Hookup.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 26/11/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport RCPreferences\nimport RCLog\n\nclass ModuleHookup {\n    \n    private let extensions = ExtensionsInteractor()\n    private let localPreferences = RCPreferences<LocalPreferences>()\n    \n    func isCmdReachable (completion: @escaping (Bool) -> Void) {\n        \n        let cmd = localPreferences.string(.settingsHookupCmdName)\n        checkIfCommandInstalled(cmd: cmd, completion: completion)\n    }\n    \n    func isAppReachable (completion: @escaping (Bool) -> Void) {\n        \n        let appName = localPreferences.string(.settingsHookupAppName)\n        checkIfAppInstalled(appName: appName, completion: completion)\n    }\n    \n    func insert (task: Task, completion: ((_ success: Bool) -> Void)? = nil) {\n        \n        let isHookupEnabled = localPreferences.bool(.enableHookup)\n        let isCocoaHookupEnabled = localPreferences.bool(.enableCocoaHookup)\n        \n        // Call cli hookup\n        if isHookupEnabled {\n            let cliName = localPreferences.string(.settingsHookupCmdName)\n            let json = buildJson (task: task)\n            let command = \"\\(cliName) insert \\\"\\(json)\\\"\"\n            \n            extensions.run (command: command, completion: { result in\n                \n                guard let validJson = result else {\n                    completion?(false)\n                    return\n                }\n                guard let data = validJson.data(using: String.Encoding.utf8) else {\n                    completion?(false)\n                    return\n                }\n                guard let jdict = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: String],\n                    let dict = jdict else {\n                    completion?(false)\n                    return\n                }\n                RCLog(dict)\n                completion?(dict[\"success\"] == \"true\")\n            })\n        }\n        \n        // Call cocoa hookups\n        // Only start/end types are supported\n        if isCocoaHookupEnabled {\n            let appName = localPreferences.string(.settingsHookupAppName)\n            var command = \"\"\n            if task.taskType == .startDay {\n                command = \"osascript -e \\\"tell application \\\\\\\"\\(appName)\\\\\\\" to start\\\"\"\n            } else if task.taskType == .endDay {\n                command = \"osascript -e \\\"tell application \\\\\\\"\\(appName)\\\\\\\" to stop\\\"\"\n            }\n            if command != \"\" {\n                extensions.run (command: command, completion: { result in\n                    // Do nothing\n                })\n            }\n        }\n    }\n    \n    /// Json sent to shell to be valid must be a string with ' instead of \" and no breaklines\n    private func buildJson (task: Task) -> String {\n        \n        var jsonCredentials = \"'credentials':{}\"\n        if localPreferences.bool(.enableHookupCredentials) {\n            let url = localPreferences.string(.settingsJiraUrl)\n            let user = localPreferences.string(.settingsJiraUser)\n            let password = Keychain.getPassword()\n            jsonCredentials = \"'credentials':{'url':'\\(url)', 'user':'\\(user)', 'password':'\\(password)'}\"\n        }\n        let jsonTask = \"'task':{'taskType':\\(task.taskType.rawValue)}\"\n        \n        return \"{\\(jsonCredentials), \\(jsonTask)}\"\n    }\n}\n\nextension ModuleHookup {\n    \n    func checkIfCommandInstalled (cmd: String, completion: @escaping (Bool) -> Void) {\n        \n        let command = \"command -v \\(cmd)\"// Returns the path to git if exists\n        extensions.run (command: command, completion: { result in\n            completion(result != nil)\n        })\n    }\n    \n    func checkIfAppInstalled (appName: String, completion: @escaping (Bool) -> Void) {\n        \n        //let command = \"command -v \\(cmd)\"// Returns the path to git if exists\n        //extensions.run (command: command, completion: { result in\n            completion(true)\n        //})\n    }\n    \n}\n"
  },
  {
    "path": "Delivery/macOS/Modules/JiraTempo/ModuleJiraTempo.swift",
    "content": "//\n//  JiraTempo.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 24/01/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport RCPreferences\n\nclass ModuleJiraTempo {\n    \n    private var repository: JiraRepository?\n    private let pref = RCPreferences<LocalPreferences>()\n    /// Returns true if credentials are all setup\n    var isConfigured: Bool {\n        return pref.string(.settingsJiraUrl) != \"\"\n            && pref.string(.settingsJiraUser) != \"\"\n            && Keychain.getPassword() != \"\"\n    }\n    var isProjectConfigured: Bool {\n        return pref.string(.settingsJiraProjectKey) != \"\"\n            && pref.string(.settingsJiraProjectIssueKey) != \"\"\n    }\n    \n    func initRepository() {\n        repository = JiraRepository(url: pref.string(.settingsJiraUrl),\n                                    user: pref.string(.settingsJiraUser),\n                                    password: Keychain.getPassword())\n    }\n    \n    func fetchProjects (success: @escaping ([JProject]) -> Void, failure: @escaping (Error) -> Void) {\n        initRepository()\n        repository!.fetchProjects(success: success, failure: failure)\n    }\n    \n    func fetchProjectIssues (projectKey: String, success: @escaping ([JProjectIssue]) -> Void, failure: @escaping (Error) -> Void) {\n        initRepository()\n        repository!.fetchProjectIssues(projectKey: projectKey, success: success, failure: failure)\n    }\n    \n    func postWorklog (worklog: String,\n                      duration: Double,\n                      date: Date,\n                      success: @escaping () -> Void,\n                      failure: @escaping (Error) -> Void) {\n        \n        let project = JProject(id: pref.string(.settingsJiraProjectId),\n                               key: pref.string(.settingsJiraProjectKey),\n                               name: \"\",\n                               url: \"\")\n        let projectIssue = JProjectIssue(id: \"\",\n                                         key: pref.string(.settingsJiraProjectIssueKey),\n                                         url: \"\")\n\n        initRepository()\n        repository!.postWorklog(worklog, duration: duration, in: project, to: projectIssue, date: date, success: {\n            success()\n        }, failure: { error in\n            failure(error)\n        })\n    }\n\n//    func upload (reports: [Report]) {\n//        var comment = \"\"\n//        var duration = 0.0\n//        for report in reports {\n//            comment += report.taskNumber + \" - \" + report.title + \"\\n\" + report.notes + \"\\n\\n\"\n//            duration += report.duration\n//        }\n//    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Notifications/BrowserNotification.swift",
    "content": "//\n//  BrowserNotifications.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 09/05/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\nimport RCLog\n\nclass BrowserNotification {\n    \n    var codeReviewDidStart: (() -> Void)?\n    var codeReviewDidEnd: (() -> Void)?\n    var wastingTimeDidStart: (() -> Void)?\n    var wastingTimeDidEnd: (() -> Void)?\n    \n    var startDate: Date?\n    var endDate: Date?\n    var reviewedTasks = [String]()\n    var taskType: TaskType?\n    \n    fileprivate let delay = 15.0\n    fileprivate let stashUrlEreg = \"(http|https)://(.+)/projects/(.+)/repos/(.+)/pull-requests\"\n    fileprivate let browsersIds = [\"com.apple.Safari\", \"com.apple.SafariTechnologyPreview\",\n                                   \"com.google.Chrome\", \"com.google.Chrome.canary\", \"org.chromium.Chromium\", \"com.vivaldi.Vivaldi\"]\n    fileprivate var timer: Timer?\n    fileprivate var extensionsInteractor = ExtensionsInteractor()\n    fileprivate var reader: ReadTasksInteractor?\n    \n    init() {\n        start()\n    }\n    \n    func start() {\n        stop()\n        timer = Timer.scheduledTimer(timeInterval: delay,\n                                     target: self,\n                                     selector: #selector(handleTimer),\n                                     userInfo: nil,\n                                     repeats: true)\n    }\n    \n    func stop() {\n        timer?.invalidate()\n        timer = nil\n    }\n    \n    @objc func handleTimer (timer: Timer) {\n        \n        guard let app: NSRunningApplication = NSWorkspace.shared.frontmostApplication,\n              let appId = app.bundleIdentifier,\n              var appName = app.localizedName else {\n            return\n        }\n        // Google Chrome Canary does not return the correct localizedName, so override it\n        if appId == \"com.google.Chrome.canary\" {\n            appName = \"Google Chrome Canary\"\n        }\n//        RCLogO(appId)\n//        RCLogO(appName)\n        \n        guard browsersIds.contains(appId) else {\n            if let taskType = self.taskType {\n                switch taskType {\n                case .waste:\n                    handleWastingTimeEnd()\n                    break\n                case .coderev:\n                    handleCodeRevEnd()\n                    break\n                default:\n                    break\n                }\n            }\n            return\n        }\n        \n        reader = ReadTasksInteractor(repository: localRepository, remoteRepository: remoteRepository)\n        let existingTasks = reader!.tasksInDay(Date())\n        let isDayStarted = existingTasks.count > 0\n        let isDayEnded = existingTasks.contains(where: { $0.taskType == .endDay })\n        \n        guard let startDayTask = existingTasks.first else {\n            return\n        }\n        guard isDayStarted && !isDayEnded else {\n            RCLog(\"Day started but also ended, won't continue analyzing the url\")\n            return\n        }\n        let settings: Settings = SettingsInteractor().getAppSettings()\n        let maxDuration = TimeInteractor(settings: settings).workingDayLength()\n        let workedDuration = Date().timeIntervalSince( startDayTask.endDate )\n        guard workedDuration < maxDuration else {\n            // Do not track browser events past working duration\n            return\n        }\n        \n        extensionsInteractor.getBrowserInfo(browserId: appId, browserName: appName, completion: { (url, title) in\n            \n            RCLog(\"Analyzing url: \\(url), title: \\(title)\")\n            \n            if self.isCodeRevLink(url) {\n                if self.isWastingTime() {\n                    self.handleWastingTimeEnd()\n                }\n                if !self.isInCodeRev() {\n                    self.handleCodeRevStart()\n                }\n                // Find the taskNumber of the branch you're reviewing\n                let branchParser = ParseGitBranch(branchName: title)\n                if let taskNumber = branchParser.taskNumber() {\n                    if !self.reviewedTasks.contains(taskNumber) {\n                        self.reviewedTasks.append(taskNumber)\n                    }\n                }\n            }\n            else if self.isWastingTimeLink(url) {\n                if self.isInCodeRev() {\n                    self.handleCodeRevEnd()\n                }\n                if !self.isWastingTime() {\n                    self.handleWastingTimeStart()\n                }\n            }\n            else {\n                if self.isInCodeRev() {\n                    self.handleCodeRevEnd()\n                }\n                if self.isWastingTime() {\n                    self.handleWastingTimeEnd()\n                }\n            }\n        })\n    }\n}\n\nextension BrowserNotification {\n    \n    fileprivate func handleCodeRevStart() {\n        \n        guard !isInCodeRev() else {\n            return\n        }\n        taskType = .coderev\n        startDate = Date()\n        reviewedTasks = [String]()\n        codeReviewDidStart?()\n    }\n    \n    fileprivate func handleCodeRevEnd() {\n        \n        guard isInCodeRev() else {\n            return\n        }\n        self.endDate = Date()\n        let settings = localRepository.settings()\n        let duration = self.endDate!.timeIntervalSince(startDate!)\n        if duration >= Double(settings.settingsBrowser.minCodeRevDuration).minToSec {\n            self.codeReviewDidEnd?()\n        } else {\n            RCLog(\"Discard code review session with duration \\(duration) < \\(Double(settings.settingsBrowser.minCodeRevDuration).minToSec)\")\n        }\n        startDate = nil\n    }\n    \n    fileprivate func isCodeRevLink (_ url: String) -> Bool {\n        \n        let settings = localRepository.settings()\n        let coderevLink = settings.settingsBrowser.codeRevLink != \"\" ? settings.settingsBrowser.codeRevLink : self.stashUrlEreg\n        guard let coderevRegex = try? NSRegularExpression(pattern: coderevLink, options: []) else {\n            return false\n        }\n        let matches = coderevRegex.matches(in: url, options: [], range: NSRange(location: 0, length: url.count))\n        \n        return matches.count > 0\n    }\n    \n    fileprivate func isInCodeRev() -> Bool {\n        return startDate != nil && taskType == .coderev\n    }\n}\n\nextension BrowserNotification {\n    \n    fileprivate func handleWastingTimeStart() {\n        \n        guard !isWastingTime() else {\n            return\n        }\n        taskType = .waste\n        startDate = Date()\n        wastingTimeDidStart?()\n    }\n    \n    fileprivate func handleWastingTimeEnd() {\n        \n        guard isWastingTime() else {\n            return\n        }\n        self.endDate = Date()\n        let settings: Settings = SettingsInteractor().getAppSettings()\n        let duration = self.endDate!.timeIntervalSince(startDate!)\n        if duration >= Double(settings.settingsBrowser.minWasteDuration).minToSec {\n            self.wastingTimeDidEnd?()\n        } else {\n            RCLog(\"Discard wasting time session with duration \\(duration) < \\(Double(settings.settingsBrowser.minWasteDuration).minToSec)\")\n        }\n        startDate = nil\n    }\n    \n    fileprivate func isWastingTimeLink (_ url: String) -> Bool {\n        \n        let settings = localRepository.settings()\n        for link in settings.settingsBrowser.wasteLinks {\n            guard link != \"\" else {\n                continue\n            }\n            let regex = try! NSRegularExpression(pattern: link, options: [])\n            let matches = regex.matches(in: url, options: [], range: NSRange(location: 0, length: url.count))\n            if matches.count > 0 {\n                return true\n            }\n        }\n        return false\n    }\n    \n    fileprivate func isWastingTime() -> Bool {\n        return startDate != nil && taskType == .waste\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Notifications/InternalNotifications.swift",
    "content": "//\n//  InternalNotifications.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 13/12/15.\n//  Copyright © 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nlet kNewTaskWasAddedNotification = \"NewTaskWasAddedNotification\"\n\nclass InternalNotifications: NSObject {\n\n\tclass func notifyAboutNewlyAddedTask (_ task: Task) {\n\t\tNotificationCenter.default.post(name: Notification.Name(rawValue: kNewTaskWasAddedNotification), object: nil)\n\t}\n}\n"
  },
  {
    "path": "Delivery/macOS/Notifications/SleepNotifications.swift",
    "content": "//\n//  SleepNotifications.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 10/05/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\nimport RCLog\n\nclass SleepNotifications: NSObject {\n\n\tvar computerWentToSleep: (() -> ())?\n\tvar computerWakeUp: (() -> ())?\n\tvar lastSleepDate: Date?\n    var lastWakeDate: Date?\n\t\n\toverride init() {\n\t\tsuper.init()\n\t\t\n//        NSWorkspace.shared().notificationCenter.addObserver(\n//            self,\n//            selector: #selector(SleepNotifications.receiveSleepNotification(_:)),\n//\t\t\tname: NSNotification.Name.NSWorkspaceWillSleep,\n//\t\t\tobject: nil)\n        \n        NSWorkspace.shared.notificationCenter.addObserver(\n            self,\n            selector: #selector(SleepNotifications.receiveSleepNotification(_:)),\n\t\t\tname: NSWorkspace.screensDidSleepNotification,\n\t\t\tobject: nil)\n\t\t\n//        NSWorkspace.shared().notificationCenter.addObserver(\n//            self,\n//            selector: #selector(SleepNotifications.receiveWakeNotification(_:)),\n//\t\t\tname: NSNotification.Name.NSWorkspaceDidWake,\n//\t\t\tobject: nil)\n        \n        NSWorkspace.shared.notificationCenter.addObserver(\n            self,\n            selector: #selector(SleepNotifications.receiveWakeNotification(_:)),\n\t\t\tname: NSWorkspace.screensDidWakeNotification,\n\t\t\tobject: nil)\n\t}\n\t\n\tdeinit {\n\t\tNSWorkspace.shared.notificationCenter.removeObserver(self)\n\t}\n\t\n\t@objc func receiveSleepNotification (_ notif: Notification) {\n\t\tRCLogO(notif)\n\t\tlastSleepDate = Date()\n\t\tcomputerWentToSleep?()\n\t}\n\t\n\t@objc func receiveWakeNotification (_ notif: Notification) {\n\t\tRCLogO(notif)\n        lastWakeDate = Date()\n\t\tcomputerWakeUp?()\n\t}\n}\n"
  },
  {
    "path": "Delivery/macOS/Notifications/UserNotifications.swift",
    "content": "//\n//  LocalNotifications.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 12/12/15.\n//  Copyright © 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nclass UserNotifications {\n\n\tfunc showNotification (_ title: String, informativeText: String) {\n\t\t\n\t\tlet notification = NSUserNotification()\n\t\tnotification.title = title\n\t\tnotification.informativeText = informativeText\n\t\t\n\t\tNSUserNotificationCenter.default.deliver(notification)\n\t}\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Account/AccountViewController.swift",
    "content": "//\n//  AccountViewController.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 25/11/2016.\n//  Copyright © 2016 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nclass AccountViewController: NSViewController {\n    \n    @IBOutlet fileprivate var emailTextField: NSTextField?\n    @IBOutlet fileprivate var passwordTextField: NSTextField?\n    @IBOutlet fileprivate var butLogin: NSButton?\n    @IBOutlet fileprivate var progressIndicator: NSProgressIndicator?\n    \n    var credentials: UserCredentials {\n        get {\n            return (email: self.emailTextField!.stringValue,\n                    password: self.passwordTextField!.stringValue)\n        }\n        set {\n            self.emailTextField!.stringValue = newValue.email\n            self.passwordTextField!.stringValue = newValue.password\n        }\n    }\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        \n        //        let container = CKContainer.default()\n        //        container.requestApplicationPermission(.userDiscoverability) { (status, error) in\n        //            guard error == nil else { return }\n        //\n        //            if status == CKApplicationPermissionStatus.granted {\n        //                container.fetchUserRecordID { (recordID, error) in\n        //                    guard error == nil else { return }\n        //                    guard let recordID = recordID else { return }\n        //\n        //                    container.discoverUserInfo(withUserRecordID: recordID) { (info, fetchError) in\n        //                        // use info.firstName and info.lastName however you need\n        //                        print(info)\n        //                    }\n        //                }\n        //            }\n        //        }\n    }\n    \n    override func viewDidAppear() {\n        super.viewDidAppear()\n        //\t\tlet user = UserInteractor().currentUser()\n        //        butLogin?.title = user.isLoggedIn ? \"Logout\" : \"Login\"\n        //        emailTextField?.stringValue = user.email!\n    }\n    \n    @IBAction func handleLoginButton (_ sender: NSButton) {\n//        presenter!.login(credentials)\n    }\n    \n    func login (_ credentials: UserCredentials) {\n        \n        //        let interactor = UserInteractor(data: localRepository)\n        //        interactor.onLoginSuccess = {\n        //            self.userInterface?.showLoadingIndicator(false)\n        //        }\n        //        let user = interactor.currentUser()\n        //        user.isLoggedIn ? interactor.logout() : interactor.loginWithCredentials(credentials)\n    }\n    \n    func showLoadingIndicator (_ show: Bool) {\n        if show {\n            progressIndicator!.startAnimation(nil)\n        } else {\n            progressIndicator!.stopAnimation(nil)\n        }\n    }\n    \n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Account/CloudKitLoginViewController.swift",
    "content": "//\n//  CloudKitLoginViewController.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 13/06/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\n\nclass CloudKitLoginViewController: NSViewController {\n\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        \n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Account/Login.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"19529\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" initialViewController=\"MZm-Jd-s4c\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"19529\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Login View Controller-->\n        <scene sceneID=\"dbB-kx-1Q6\">\n            <objects>\n                <viewController storyboardIdentifier=\"LoginViewController\" id=\"MZm-Jd-s4c\" customClass=\"LoginViewController\" customModule=\"Jirassic\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" id=\"04v-5T-U8P\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"490\" height=\"414\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                        <subviews>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" setsMaxLayoutWidthAtFirstLayout=\"YES\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Y7W-i2-lic\">\n                                <rect key=\"frame\" x=\"42\" y=\"223\" width=\"407\" height=\"68\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"403\" id=\"Gl3-mF-3dh\"/>\n                                    <constraint firstAttribute=\"height\" constant=\"68\" id=\"zBR-M9-6Rd\"/>\n                                </constraints>\n                                <textFieldCell key=\"cell\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" id=\"U4x-co-B8z\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <string key=\"title\">You are currently using the app in annonymous mode. By logging in you ensure you never lose the data and you can sync with the phone. Preferably to register with your work e-mail</string>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"tUo-Ah-uoO\">\n                                <rect key=\"frame\" x=\"150\" y=\"81\" width=\"191\" height=\"19\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"18\" id=\"d20-lI-rgT\"/>\n                                    <constraint firstAttribute=\"width\" constant=\"191\" id=\"vi6-0b-qYR\"/>\n                                </constraints>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"Login\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"kA3-PN-Vv6\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleLoginButton:\" target=\"MZm-Jd-s4c\" id=\"bgH-9j-ztD\"/>\n                                </connections>\n                            </button>\n                            <secureTextField verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"FS0-uf-Nwq\">\n                                <rect key=\"frame\" x=\"150\" y=\"118\" width=\"191\" height=\"22\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"22\" id=\"2K3-5Y-SFu\"/>\n                                    <constraint firstAttribute=\"width\" constant=\"191\" id=\"BPU-P6-lM1\"/>\n                                </constraints>\n                                <secureTextFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" borderStyle=\"bezel\" placeholderString=\"Password\" drawsBackground=\"YES\" usesSingleLineMode=\"YES\" id=\"NYs-Oa-9bc\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <allowedInputSourceLocales>\n                                        <string>NSAllRomanInputSourcesLocaleIdentifier</string>\n                                    </allowedInputSourceLocales>\n                                </secureTextFieldCell>\n                            </secureTextField>\n                            <textField verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"5oq-we-289\">\n                                <rect key=\"frame\" x=\"150\" y=\"155\" width=\"191\" height=\"22\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"22\" id=\"FXC-uG-TSu\"/>\n                                    <constraint firstAttribute=\"width\" constant=\"191\" id=\"hcQ-3O-OzP\"/>\n                                </constraints>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" borderStyle=\"bezel\" placeholderString=\"Email\" drawsBackground=\"YES\" id=\"ijq-0x-1OO\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <progressIndicator horizontalHuggingPriority=\"750\" verticalHuggingPriority=\"750\" maxValue=\"100\" displayedWhenStopped=\"NO\" bezeled=\"NO\" indeterminate=\"YES\" controlSize=\"small\" style=\"spinning\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"SzE-hz-CAA\">\n                                <rect key=\"frame\" x=\"349\" y=\"83\" width=\"16\" height=\"16\"/>\n                            </progressIndicator>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"Y7W-i2-lic\" firstAttribute=\"top\" secondItem=\"04v-5T-U8P\" secondAttribute=\"top\" constant=\"123\" id=\"0Rn-PI-9n9\"/>\n                            <constraint firstAttribute=\"centerX\" secondItem=\"tUo-Ah-uoO\" secondAttribute=\"centerX\" constant=\"-0.5\" id=\"2aw-X6-x72\"/>\n                            <constraint firstItem=\"tUo-Ah-uoO\" firstAttribute=\"top\" secondItem=\"FS0-uf-Nwq\" secondAttribute=\"bottom\" constant=\"18\" id=\"Pui-VW-fmA\"/>\n                            <constraint firstItem=\"SzE-hz-CAA\" firstAttribute=\"centerY\" secondItem=\"tUo-Ah-uoO\" secondAttribute=\"centerY\" id=\"Q9L-Fb-mhI\"/>\n                            <constraint firstAttribute=\"centerX\" secondItem=\"FS0-uf-Nwq\" secondAttribute=\"centerX\" constant=\"-0.5\" id=\"UpD-sR-Bu9\"/>\n                            <constraint firstItem=\"FS0-uf-Nwq\" firstAttribute=\"top\" secondItem=\"5oq-we-289\" secondAttribute=\"bottom\" constant=\"15\" id=\"Z3x-Pc-RVi\"/>\n                            <constraint firstAttribute=\"centerX\" secondItem=\"5oq-we-289\" secondAttribute=\"centerX\" constant=\"-0.5\" id=\"gfz-Uw-eQu\"/>\n                            <constraint firstItem=\"SzE-hz-CAA\" firstAttribute=\"leading\" secondItem=\"tUo-Ah-uoO\" secondAttribute=\"trailing\" constant=\"8\" id=\"hjB-QW-AVi\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"tUo-Ah-uoO\" secondAttribute=\"bottom\" constant=\"82\" id=\"k5c-8V-rJY\"/>\n                            <constraint firstAttribute=\"centerX\" secondItem=\"Y7W-i2-lic\" secondAttribute=\"centerX\" constant=\"-0.5\" id=\"xTz-7e-FaQ\"/>\n                        </constraints>\n                    </view>\n                    <connections>\n                        <outlet property=\"_butLogin\" destination=\"tUo-Ah-uoO\" id=\"3Ew-AO-jjZ\"/>\n                        <outlet property=\"_emailTextField\" destination=\"5oq-we-289\" id=\"HdF-u9-PS2\"/>\n                        <outlet property=\"_label\" destination=\"Y7W-i2-lic\" id=\"rF6-8I-CtZ\"/>\n                        <outlet property=\"_passwordTextField\" destination=\"FS0-uf-Nwq\" id=\"Fy3-lY-2rJ\"/>\n                        <outlet property=\"_progressIndicator\" destination=\"SzE-hz-CAA\" id=\"tpe-ZX-9Ko\"/>\n                    </connections>\n                </viewController>\n                <customObject id=\"vlD-nS-0PC\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"1072\" y=\"1014\"/>\n        </scene>\n        <!--View Controller-->\n        <scene sceneID=\"PKn-Zj-Cgy\">\n            <objects>\n                <viewController storyboardIdentifier=\"Logged\" id=\"3cW-7h-cFs\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" id=\"QLL-MG-Amm\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"490\" height=\"300\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                        <subviews>\n                            <box autoresizesSubviews=\"NO\" fixedFrame=\"YES\" borderType=\"line\" title=\"Jirassic user\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Tpc-NR-1xm\">\n                                <rect key=\"frame\" x=\"20\" y=\"123\" width=\"458\" height=\"62\"/>\n                                <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                <view key=\"contentView\" id=\"Wxo-uA-Fm9\">\n                                    <rect key=\"frame\" x=\"3\" y=\"3\" width=\"452\" height=\"44\"/>\n                                    <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                    <subviews>\n                                        <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" fixedFrame=\"YES\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"ZPV-O2-4j4\">\n                                            <rect key=\"frame\" x=\"10\" y=\"17\" width=\"130\" height=\"17\"/>\n                                            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                            <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"You are logged in as:\" id=\"aBX-fe-7j6\">\n                                                <font key=\"font\" metaFont=\"system\"/>\n                                                <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            </textFieldCell>\n                                        </textField>\n                                        <textField verticalHuggingPriority=\"750\" fixedFrame=\"YES\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"CGc-LR-7yv\">\n                                            <rect key=\"frame\" x=\"144\" y=\"12\" width=\"231\" height=\"22\"/>\n                                            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                            <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" allowsUndo=\"NO\" sendsActionOnEndEditing=\"YES\" state=\"on\" alignment=\"left\" placeholderString=\"Email\" id=\"KvH-d0-7bI\">\n                                                <font key=\"font\" metaFont=\"systemBold\"/>\n                                                <color key=\"textColor\" name=\"textColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            </textFieldCell>\n                                        </textField>\n                                        <button verticalHuggingPriority=\"750\" fixedFrame=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"1W7-56-xGE\">\n                                            <rect key=\"frame\" x=\"375\" y=\"6\" width=\"75\" height=\"32\"/>\n                                            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                            <buttonCell key=\"cell\" type=\"push\" title=\"Logout\" bezelStyle=\"rounded\" alignment=\"center\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"ca5-nF-Q29\">\n                                                <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                                <font key=\"font\" metaFont=\"system\"/>\n                                            </buttonCell>\n                                        </button>\n                                    </subviews>\n                                </view>\n                            </box>\n                        </subviews>\n                    </view>\n                </viewController>\n                <customObject id=\"P9G-yE-X56\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"1072\" y=\"1438\"/>\n        </scene>\n        <!--Cloud Kit Login View Controller-->\n        <scene sceneID=\"OlU-zA-EKc\">\n            <objects>\n                <viewController storyboardIdentifier=\"CloudKitLoginViewController\" id=\"oJ3-lT-MEh\" customClass=\"CloudKitLoginViewController\" customModule=\"Jirassic\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" id=\"m2C-3F-pNA\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"490\" height=\"300\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                        <subviews>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" setsMaxLayoutWidthAtFirstLayout=\"YES\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"bYg-Nz-mL6\">\n                                <rect key=\"frame\" x=\"21\" y=\"88\" width=\"451\" height=\"85\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"85\" id=\"Uwn-kO-T42\"/>\n                                    <constraint firstAttribute=\"width\" constant=\"447\" id=\"aLX-2o-IO7\"/>\n                                </constraints>\n                                <textFieldCell key=\"cell\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" id=\"scf-qH-cFe\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <string key=\"title\">Sign in to your iCloud account to keep the data in sync with other devices. Launch Settings, tap iCloud, and enter your Apple ID. Turn iCloud Drive on. If you don't have an iCloud account, tap Create a new Apple ID.</string>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Y07-EW-Axq\">\n                                <rect key=\"frame\" x=\"-2\" y=\"191\" width=\"494\" height=\"24\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"24\" id=\"W9f-vT-XoD\"/>\n                                </constraints>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" title=\"Sign in to iCloud\" id=\"PuS-2C-gl1\">\n                                    <font key=\"font\" metaFont=\"system\" size=\"20\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" fixedFrame=\"YES\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"urH-Bk-tis\">\n                                <rect key=\"frame\" x=\"33\" y=\"63\" width=\"214\" height=\"17\"/>\n                                <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Continue in annonymous mode\" id=\"jWQ-ra-kto\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" fixedFrame=\"YES\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Xpq-Ka-MAe\">\n                                <rect key=\"frame\" x=\"33\" y=\"19\" width=\"214\" height=\"17\"/>\n                                <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"right\" title=\"Sign in to iCloud\" id=\"sWA-ZK-MAK\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <button verticalHuggingPriority=\"750\" fixedFrame=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"pvQ-wI-DdQ\">\n                                <rect key=\"frame\" x=\"253\" y=\"48\" width=\"52\" height=\"46\"/>\n                                <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                <buttonCell key=\"cell\" type=\"smallSquare\" bezelStyle=\"smallSquare\" image=\"NSUserGuest\" imagePosition=\"overlaps\" alignment=\"center\" lineBreakMode=\"truncatingTail\" state=\"on\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"g1y-vl-dUk\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                </buttonCell>\n                            </button>\n                            <button verticalHuggingPriority=\"750\" fixedFrame=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"NZa-Vx-0yB\">\n                                <rect key=\"frame\" x=\"253\" y=\"8\" width=\"52\" height=\"39\"/>\n                                <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                <buttonCell key=\"cell\" type=\"smallSquare\" bezelStyle=\"smallSquare\" image=\"NSMobileMe\" imagePosition=\"overlaps\" alignment=\"center\" lineBreakMode=\"truncatingTail\" state=\"on\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"Nrn-vE-t3s\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                </buttonCell>\n                            </button>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"bYg-Nz-mL6\" firstAttribute=\"leading\" secondItem=\"m2C-3F-pNA\" secondAttribute=\"leading\" constant=\"23\" id=\"8sb-w7-OK7\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"Y07-EW-Axq\" secondAttribute=\"trailing\" id=\"C2w-qp-Ij7\"/>\n                            <constraint firstItem=\"Y07-EW-Axq\" firstAttribute=\"leading\" secondItem=\"m2C-3F-pNA\" secondAttribute=\"leading\" id=\"V2s-IC-Hxk\"/>\n                            <constraint firstItem=\"bYg-Nz-mL6\" firstAttribute=\"top\" secondItem=\"Y07-EW-Axq\" secondAttribute=\"bottom\" constant=\"18\" id=\"csP-f8-ATE\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"bYg-Nz-mL6\" secondAttribute=\"trailing\" constant=\"20\" id=\"p72-zb-bzT\"/>\n                            <constraint firstItem=\"Y07-EW-Axq\" firstAttribute=\"top\" secondItem=\"m2C-3F-pNA\" secondAttribute=\"top\" constant=\"85\" id=\"tF6-WQ-wso\"/>\n                        </constraints>\n                    </view>\n                </viewController>\n                <customObject id=\"lpO-KK-F0t\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"1072\" y=\"585\"/>\n        </scene>\n    </scenes>\n    <resources>\n        <image name=\"NSMobileMe\" width=\"32\" height=\"32\"/>\n        <image name=\"NSUserGuest\" width=\"32\" height=\"32\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Account/LoginPresenter.swift",
    "content": "//\n//  LoginPresenter.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 01/05/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nprotocol LoginPresenterInput {\n    \n    func loginWithCredentials (_ credentials: UserCredentials)\n    func cancelScreen()\n}\n\nprotocol LoginPresenterOutput {\n    \n    func showLoadingIndicator (_ show: Bool)\n}\n\nclass LoginPresenter {\n    \n    var userInterface: LoginPresenterOutput?\n    var appWireframe: AppWireframe?\n}\n\nextension LoginPresenter: LoginPresenterInput {\n    \n    func loginWithCredentials (_ credentials: UserCredentials) {\n        \n        userInterface?.showLoadingIndicator(true)\n        \n        if let repository = remoteRepository {\n            let login = UserInteractor(repository: repository, remoteRepository: remoteRepository)\n            login.onLoginSuccess = {\n                self.userInterface?.showLoadingIndicator(false)\n                _ = self.appWireframe?.presentTasksController()\n            }\n            login.onLoginFailure = {\n                self.userInterface?.showLoadingIndicator(false)\n            }\n            login.loginWithCredentials(credentials)\n        }\n    }\n    \n    func cancelScreen() {\n        _ = appWireframe?.presentTasksController()\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Account/LoginViewController.swift",
    "content": "//\n//  LoginViewController.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 07/05/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\n\nclass LoginViewController: NSViewController {\n\t\n\t@IBOutlet fileprivate var _label: NSTextField?\n\t@IBOutlet fileprivate var _emailTextField: NSTextField?\n\t@IBOutlet fileprivate var _passwordTextField: NSTextField?\n\t@IBOutlet fileprivate var _butLogin: NSButton?\n\t@IBOutlet fileprivate var _butCancel: NSButton?\n\t@IBOutlet fileprivate var _progressIndicator: NSProgressIndicator?\n\t\n    var loginPresenter: LoginPresenterInput?\n    \n\tvar credentials: UserCredentials {\n\t\tget {\n\t\t\treturn (email: self._emailTextField!.stringValue,\n\t\t\t\tpassword: self._passwordTextField!.stringValue)\n\t\t}\n\t\tset {\n\t\t\tself._emailTextField!.stringValue = newValue.email\n\t\t\tself._passwordTextField!.stringValue = newValue.password\n\t\t}\n\t}\n\tvar isLoggedIn: Bool = false\n\t\n    override func viewDidLoad() {\n        super.viewDidLoad()\n\t\t\n        if let repository = remoteRepository {\n            UserInteractor(repository: repository, remoteRepository: remoteRepository).getUser({ (user) in\n                \n            })\n//            if user.isLoggedIn {\n//                _butLogin?.title = \"Logout\"\n//                _label?.stringValue = \"You are already logged in.\"\n//                self.credentials = (email: user.email!, password: \"\")\n//            } else {\n//                _butLogin?.title = \"Login or Signup\"\n//                _label?.stringValue = \"You are currently using the app in annonymous mode. By logging in you ensure you never lose the data and you can sync with the phone. Preferably to register with your work e-mail\"\n//            }\n        }\n    }\n    \n    // MARK: Actions\n    \n    @IBAction func handleLoginButton (_ sender: NSButton) {\n        loginPresenter?.loginWithCredentials(credentials)\n    }\n    \n    @IBAction func handleCancelButton (_ sender: NSButton) {\n        loginPresenter?.cancelScreen()\n    }\n}\n\nextension LoginViewController: LoginPresenterOutput {\n\n    func showLoadingIndicator (_ show: Bool) {\n\t\tif show {\n\t\t\t_progressIndicator?.startAnimation(nil)\n\t\t} else {\n\t\t\t_progressIndicator?.stopAnimation(nil)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Calendar/CalendarScrollView.swift",
    "content": "//\n//  DatesScrollView.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 30/12/15.\n//  Copyright © 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\n\nclass CalendarScrollView: NSScrollView {\n\t\n\t@IBOutlet fileprivate var outlineView: NSOutlineView?\n    var _weeks = [Week]()\n    var weeks: [Week] {\n        get {\n            return _weeks\n        }\n        set {\n            _weeks = newValue\n            guard let firstWeek = _weeks.first else {\n                return\n            }\n            let now = Date()\n            if firstWeek.date.isSameWeekAs(now) {\n                if let firstDay = firstWeek.days.first {\n                    if !firstDay.dateStart.isSameDayAs(now) {\n                        _weeks[0].days.insert(Day(dateStart: now, dateEnd: nil), at: 0)\n                    }\n                }\n            } else {\n                let week = Week(date: now)\n                week.days.append( Day(dateStart: now, dateEnd: nil) )\n                _weeks.insert(week, at: 0)\n            }\n        }\n    }\n\tvar didSelectDay: ((_ day: Day) -> ())?\n    var selectedDay: Day?\n\t\n\toverride func awakeFromNib() {\n        super.awakeFromNib()\n\t\toutlineView?.dataSource = self\n\t\toutlineView?.delegate = self\n\t}\n\t\n\tfunc reloadData() {\n\t\tself.outlineView?.reloadData()\n\t\tself.outlineView?.expandItem(nil, expandChildren: true)\n\t}\n    \n    func selectDay (_ dayToSelect: Day) {\n        \n        var i = -1\n        for week in weeks {\n            i += 1\n            for day in week.days {\n                i += 1\n                if day.dateStart.isSameDayAs(dayToSelect.dateStart) {\n                    let indexSet = IndexSet(integer: i)\n                    outlineView?.selectRowIndexes(indexSet, byExtendingSelection: true)\n                    break\n                }\n            }\n        }\n    }\n}\n\nextension CalendarScrollView: NSOutlineViewDataSource {\n\t\n\tfunc outlineView (_ outlineView: NSOutlineView, child index: Int, ofItem item: Any?) -> Any {\n\t\t\n\t\tif let item: AnyObject = item as AnyObject? {\n\t\t\tswitch item {\n\t\t\tcase let week as Week:\n\t\t\t\treturn week.days[index]\n\t\t\tdefault:\n\t\t\t\treturn self\n\t\t\t}\n\t\t} else {\n\t\t\treturn weeks[index]\n\t\t}\n\t}\n\t\n\tfunc outlineView (_ outlineView: NSOutlineView, isItemExpandable item: Any) -> Bool {\n\t\t\n\t\tswitch item {\n\t\tcase let week as Week:\n\t\t\treturn week.days.count > 0\n\t\tdefault:\n\t\t\treturn false\n\t\t}\n\t}\n\t\n\tfunc outlineView (_ outlineView: NSOutlineView, numberOfChildrenOfItem item: Any?) -> Int {\n\t\t\n\t\tif let item: AnyObject = item as AnyObject? {\n\t\t\tswitch item {\n            case let week as Week:\n                return week.days.count\n\t\t\tdefault:\n\t\t\t\treturn 0\n\t\t\t}\n\t\t} else {\n\t\t\treturn weeks.count\n\t\t}\n\t}\n}\n\nextension CalendarScrollView: NSOutlineViewDelegate {\n\t\n\tfunc outlineView (_ outlineView: NSOutlineView, viewFor viewForTableColumn: NSTableColumn?, item: Any) -> NSView? {\n        \n\t\tswitch item {\n\t\tcase let week as Week:\n            \n\t\t\tlet view = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: \"HeaderCell\"), owner: self) as! NSTableCellView\n\t\t\tif let textField = view.textField {\n                textField.font = NSFont.boldSystemFont(ofSize: 14)\n                textField.stringValue = week.date.weekInterval()\n\t\t\t}\n\t\t\treturn view\n            \n\t\tcase let day as Day:\n            \n\t\t\tlet view = outlineView.makeView(withIdentifier: NSUserInterfaceItemIdentifier(rawValue: \"DataCell\"), owner: self) as! NSTableCellView\n\t\t\tif let textField = view.textField {\n                textField.font = NSFont.boldSystemFont(ofSize: 12)\n                textField.textColor = day.dateEnd == nil ? NSColor.lightGray : NSColor.darkGray\n                textField.stringValue = day.dateStart.isToday() ? \"Today\" : day.dateStart.ddEEE()\n\t\t\t}\n\t\t\t\n            return view\n            \n\t\tdefault:\n\t\t\treturn nil\n\t\t}\n\t}\n\t\n\tfunc outlineView (_ outlineView: NSOutlineView, isGroupItem item: Any) -> Bool {\n\t\treturn item is Week\n\t}\n\t\n\tfunc outlineViewSelectionDidChange (_ notification: Notification) {\n\t\t\n        if let outlineView = notification.object as? NSOutlineView {\n            let selectedRow = outlineView.selectedRow\n\n            if let selectedObject = outlineView.item(atRow: selectedRow) as? Day {\n                selectedDay = selectedObject\n                didSelectDay?(selectedObject)\n            }\n        }\n\t}\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Onboarding/Welcome.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14460.31\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Welcome View Controller-->\n        <scene sceneID=\"Yv7-iM-REW\">\n            <objects>\n                <viewController storyboardIdentifier=\"WelcomeViewController\" id=\"JD0-O4-EsS\" customClass=\"WelcomeViewController\" customModule=\"Jirassic\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" id=\"vMb-6z-kGp\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"558\" height=\"485\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                        <subviews>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Pcq-Wr-CsI\">\n                                <rect key=\"frame\" x=\"-2\" y=\"391\" width=\"562\" height=\"34\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"34\" id=\"spB-Wd-GCS\"/>\n                                </constraints>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" title=\"Welcome to Jirassic!\" id=\"cXr-rb-dGq\">\n                                    <font key=\"font\" metaFont=\"systemBold\" size=\"30\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"3oK-tV-cbq\">\n                                <rect key=\"frame\" x=\"-2\" y=\"359\" width=\"562\" height=\"22\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"22\" id=\"0mT-gu-djT\"/>\n                                </constraints>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" title=\"A time tracker for employees\" id=\"KDj-HR-P0x\">\n                                    <font key=\"font\" metaFont=\"system\" size=\"18\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"epJ-lR-g9d\">\n                                <rect key=\"frame\" x=\"-2\" y=\"332\" width=\"562\" height=\"17\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" title=\"You are about to save lots of time and neurons, track your time at work automatically\" id=\"xdp-k7-dJy\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"systemGrayColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <box boxType=\"custom\" cornerRadius=\"4\" title=\"Box\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"ERS-BC-qGc\">\n                                <rect key=\"frame\" x=\"97\" y=\"191\" width=\"364\" height=\"104\"/>\n                                <view key=\"contentView\" id=\"vE6-Oq-Bat\">\n                                    <rect key=\"frame\" x=\"1\" y=\"1\" width=\"362\" height=\"102\"/>\n                                    <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                    <subviews>\n                                        <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"5x2-Pv-4ob\">\n                                            <rect key=\"frame\" x=\"18\" y=\"60\" width=\"326\" height=\"22\"/>\n                                            <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"left\" title=\"Setup  for programmers\" id=\"YNw-0f-yrD\">\n                                                <font key=\"font\" metaFont=\"systemBold\" size=\"18\"/>\n                                                <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            </textFieldCell>\n                                        </textField>\n                                        <textField verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"IAt-rC-AWM\">\n                                            <rect key=\"frame\" x=\"18\" y=\"20\" width=\"326\" height=\"34\"/>\n                                            <textFieldCell key=\"cell\" sendsActionOnEndEditing=\"YES\" title=\"Enable shell support to create reports from Git commits and detect code review sessions\" id=\"g8z-Mj-eKj\">\n                                                <font key=\"font\" metaFont=\"system\"/>\n                                                <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            </textFieldCell>\n                                        </textField>\n                                        <button translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"ukh-Na-jV3\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"362\" height=\"102\"/>\n                                            <buttonCell key=\"cell\" type=\"square\" bezelStyle=\"shadowlessSquare\" imagePosition=\"overlaps\" alignment=\"center\" imageScaling=\"proportionallyUpOrDown\" inset=\"2\" id=\"1ny-3B-8rA\">\n                                                <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                                <font key=\"font\" metaFont=\"system\"/>\n                                            </buttonCell>\n                                            <connections>\n                                                <action selector=\"handleSetupProgrammersButton:\" target=\"JD0-O4-EsS\" id=\"AeD-j5-diP\"/>\n                                            </connections>\n                                        </button>\n                                        <button translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"eSq-Dj-8s9\">\n                                            <rect key=\"frame\" x=\"322\" y=\"22\" width=\"30\" height=\"30\"/>\n                                            <constraints>\n                                                <constraint firstAttribute=\"width\" constant=\"30\" id=\"6Hu-TV-xuS\"/>\n                                                <constraint firstAttribute=\"height\" constant=\"30\" id=\"RNy-FE-XfI\"/>\n                                            </constraints>\n                                            <buttonCell key=\"cell\" type=\"square\" bezelStyle=\"shadowlessSquare\" image=\"NSFollowLinkFreestandingTemplate\" imagePosition=\"only\" alignment=\"center\" imageScaling=\"proportionallyUpOrDown\" inset=\"2\" id=\"lI3-bB-9i7\">\n                                                <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                                <font key=\"font\" metaFont=\"system\"/>\n                                            </buttonCell>\n                                            <connections>\n                                                <action selector=\"handleSetupProgrammersButton:\" target=\"JD0-O4-EsS\" id=\"gAt-uU-8lI\"/>\n                                            </connections>\n                                        </button>\n                                    </subviews>\n                                    <constraints>\n                                        <constraint firstAttribute=\"trailing\" secondItem=\"IAt-rC-AWM\" secondAttribute=\"trailing\" constant=\"20\" id=\"1Ke-G4-Sy7\"/>\n                                        <constraint firstItem=\"5x2-Pv-4ob\" firstAttribute=\"leading\" secondItem=\"vE6-Oq-Bat\" secondAttribute=\"leading\" constant=\"20\" id=\"1pV-bd-vVB\"/>\n                                        <constraint firstAttribute=\"trailing\" secondItem=\"5x2-Pv-4ob\" secondAttribute=\"trailing\" constant=\"20\" id=\"8mI-Eb-5bM\"/>\n                                        <constraint firstAttribute=\"trailing\" secondItem=\"ukh-Na-jV3\" secondAttribute=\"trailing\" id=\"AYZ-k4-UUQ\"/>\n                                        <constraint firstItem=\"ukh-Na-jV3\" firstAttribute=\"leading\" secondItem=\"vE6-Oq-Bat\" secondAttribute=\"leading\" id=\"RZq-bQ-4Mg\"/>\n                                        <constraint firstItem=\"ukh-Na-jV3\" firstAttribute=\"top\" secondItem=\"vE6-Oq-Bat\" secondAttribute=\"top\" id=\"SBb-1p-3gj\"/>\n                                        <constraint firstAttribute=\"bottom\" secondItem=\"ukh-Na-jV3\" secondAttribute=\"bottom\" id=\"WeL-yd-dk2\"/>\n                                        <constraint firstItem=\"IAt-rC-AWM\" firstAttribute=\"leading\" secondItem=\"vE6-Oq-Bat\" secondAttribute=\"leading\" constant=\"20\" id=\"Zbv-hV-QHb\"/>\n                                        <constraint firstAttribute=\"trailing\" secondItem=\"eSq-Dj-8s9\" secondAttribute=\"trailing\" constant=\"10\" id=\"fd2-mp-Aw6\"/>\n                                        <constraint firstAttribute=\"bottom\" secondItem=\"eSq-Dj-8s9\" secondAttribute=\"bottom\" constant=\"22\" id=\"hyU-4I-sCh\"/>\n                                        <constraint firstAttribute=\"bottom\" secondItem=\"IAt-rC-AWM\" secondAttribute=\"bottom\" constant=\"20\" id=\"ioQ-Ya-RZE\"/>\n                                        <constraint firstItem=\"IAt-rC-AWM\" firstAttribute=\"top\" secondItem=\"5x2-Pv-4ob\" secondAttribute=\"bottom\" constant=\"6\" id=\"ta0-xX-iYe\"/>\n                                        <constraint firstItem=\"5x2-Pv-4ob\" firstAttribute=\"top\" secondItem=\"vE6-Oq-Bat\" secondAttribute=\"top\" constant=\"20\" id=\"zZA-4M-Tux\"/>\n                                    </constraints>\n                                </view>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"364\" id=\"98u-y3-sPK\"/>\n                                </constraints>\n                                <color key=\"borderColor\" white=\"0.66666666669999997\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                            </box>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"LIy-LY-WEx\">\n                                <rect key=\"frame\" x=\"12\" y=\"444\" width=\"38\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"Quit\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"K5I-qP-jKc\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleQuitAppButton:\" target=\"JD0-O4-EsS\" id=\"niC-MV-r7t\"/>\n                                </connections>\n                            </button>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"PmU-1L-wKw\">\n                                <rect key=\"frame\" x=\"60\" y=\"444\" width=\"20\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"^\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"jSj-Fb-RVz\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleMinimizeAppButton:\" target=\"JD0-O4-EsS\" id=\"91u-66-h8l\"/>\n                                </connections>\n                            </button>\n                            <box boxType=\"custom\" cornerRadius=\"4\" title=\"Box\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"mlH-It-Zam\">\n                                <rect key=\"frame\" x=\"97\" y=\"71\" width=\"364\" height=\"104\"/>\n                                <view key=\"contentView\" id=\"Off-R5-DBq\">\n                                    <rect key=\"frame\" x=\"1\" y=\"1\" width=\"362\" height=\"102\"/>\n                                    <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                    <subviews>\n                                        <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"MYs-HJ-sfw\">\n                                            <rect key=\"frame\" x=\"18\" y=\"60\" width=\"326\" height=\"22\"/>\n                                            <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"left\" title=\"Setup for others\" id=\"6bz-2O-qfJ\">\n                                                <font key=\"font\" metaFont=\"systemBold\" size=\"18\"/>\n                                                <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            </textFieldCell>\n                                        </textField>\n                                        <textField verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Gum-Jb-IVQ\">\n                                            <rect key=\"frame\" x=\"18\" y=\"20\" width=\"326\" height=\"34\"/>\n                                            <textFieldCell key=\"cell\" sendsActionOnEndEditing=\"YES\" title=\"Enable the Calendar.app events to appear in your reports\" id=\"kyY-gF-4lC\">\n                                                <font key=\"font\" metaFont=\"system\"/>\n                                                <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            </textFieldCell>\n                                        </textField>\n                                        <button translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Lq3-Tx-L59\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"362\" height=\"102\"/>\n                                            <buttonCell key=\"cell\" type=\"square\" bezelStyle=\"shadowlessSquare\" imagePosition=\"only\" alignment=\"center\" imageScaling=\"proportionallyUpOrDown\" inset=\"2\" id=\"YYt-yj-JsG\">\n                                                <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                                <font key=\"font\" metaFont=\"system\"/>\n                                            </buttonCell>\n                                            <connections>\n                                                <action selector=\"handleSetupOthersButton:\" target=\"JD0-O4-EsS\" id=\"gss-G6-8Z6\"/>\n                                            </connections>\n                                        </button>\n                                        <button translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"o9l-77-QKP\">\n                                            <rect key=\"frame\" x=\"322\" y=\"22\" width=\"30\" height=\"30\"/>\n                                            <constraints>\n                                                <constraint firstAttribute=\"height\" constant=\"30\" id=\"aJ8-g1-rcW\"/>\n                                                <constraint firstAttribute=\"width\" constant=\"30\" id=\"aNN-zc-AY1\"/>\n                                            </constraints>\n                                            <buttonCell key=\"cell\" type=\"square\" bezelStyle=\"shadowlessSquare\" image=\"NSFollowLinkFreestandingTemplate\" imagePosition=\"only\" alignment=\"center\" imageScaling=\"proportionallyUpOrDown\" inset=\"2\" id=\"U2P-ca-UK3\">\n                                                <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                                <font key=\"font\" metaFont=\"system\"/>\n                                            </buttonCell>\n                                            <connections>\n                                                <action selector=\"handleSetupOthersButton:\" target=\"JD0-O4-EsS\" id=\"wMX-dr-5CC\"/>\n                                            </connections>\n                                        </button>\n                                    </subviews>\n                                    <constraints>\n                                        <constraint firstAttribute=\"bottom\" secondItem=\"Gum-Jb-IVQ\" secondAttribute=\"bottom\" constant=\"20\" id=\"4H8-7p-FrP\"/>\n                                        <constraint firstAttribute=\"trailing\" secondItem=\"Lq3-Tx-L59\" secondAttribute=\"trailing\" id=\"6vD-Eb-e9Y\"/>\n                                        <constraint firstItem=\"Lq3-Tx-L59\" firstAttribute=\"leading\" secondItem=\"Off-R5-DBq\" secondAttribute=\"leading\" id=\"Duh-ao-LnG\"/>\n                                        <constraint firstAttribute=\"trailing\" secondItem=\"o9l-77-QKP\" secondAttribute=\"trailing\" constant=\"10\" id=\"JjS-8E-jBz\"/>\n                                        <constraint firstAttribute=\"bottom\" secondItem=\"Lq3-Tx-L59\" secondAttribute=\"bottom\" id=\"KgH-ER-JYd\"/>\n                                        <constraint firstItem=\"MYs-HJ-sfw\" firstAttribute=\"leading\" secondItem=\"Off-R5-DBq\" secondAttribute=\"leading\" constant=\"20\" id=\"Kms-ay-Ibb\"/>\n                                        <constraint firstItem=\"MYs-HJ-sfw\" firstAttribute=\"top\" secondItem=\"Off-R5-DBq\" secondAttribute=\"top\" constant=\"20\" id=\"Mm3-Vk-BSM\"/>\n                                        <constraint firstItem=\"Lq3-Tx-L59\" firstAttribute=\"top\" secondItem=\"Off-R5-DBq\" secondAttribute=\"top\" id=\"Mpw-JM-S7Z\"/>\n                                        <constraint firstItem=\"Gum-Jb-IVQ\" firstAttribute=\"top\" secondItem=\"MYs-HJ-sfw\" secondAttribute=\"bottom\" constant=\"6\" id=\"PHR-oP-2RF\"/>\n                                        <constraint firstItem=\"Gum-Jb-IVQ\" firstAttribute=\"leading\" secondItem=\"Off-R5-DBq\" secondAttribute=\"leading\" constant=\"20\" id=\"PyA-Gw-ZGk\"/>\n                                        <constraint firstAttribute=\"trailing\" secondItem=\"Gum-Jb-IVQ\" secondAttribute=\"trailing\" constant=\"20\" id=\"egc-nS-3ne\"/>\n                                        <constraint firstAttribute=\"bottom\" secondItem=\"o9l-77-QKP\" secondAttribute=\"bottom\" constant=\"22\" id=\"y4i-UG-jhI\"/>\n                                        <constraint firstAttribute=\"trailing\" secondItem=\"MYs-HJ-sfw\" secondAttribute=\"trailing\" constant=\"20\" id=\"zSf-qy-7hG\"/>\n                                    </constraints>\n                                </view>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"364\" id=\"zR7-wD-f9V\"/>\n                                </constraints>\n                                <color key=\"borderColor\" white=\"0.66666666669999997\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                            </box>\n                            <box boxType=\"custom\" cornerRadius=\"4\" title=\"Box\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"p4S-ON-7S6\">\n                                <rect key=\"frame\" x=\"97\" y=\"139\" width=\"364\" height=\"87\"/>\n                                <view key=\"contentView\" id=\"GfQ-OY-qPo\">\n                                    <rect key=\"frame\" x=\"1\" y=\"1\" width=\"362\" height=\"85\"/>\n                                    <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                    <subviews>\n                                        <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"yfK-3g-ZSB\">\n                                            <rect key=\"frame\" x=\"18\" y=\"43\" width=\"326\" height=\"22\"/>\n                                            <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"left\" title=\"What's new\" id=\"rJM-JN-Qub\">\n                                                <font key=\"font\" metaFont=\"systemBold\" size=\"18\"/>\n                                                <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            </textFieldCell>\n                                        </textField>\n                                        <textField verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"e4P-1j-Pwp\">\n                                            <rect key=\"frame\" x=\"18\" y=\"20\" width=\"326\" height=\"17\"/>\n                                            <textFieldCell key=\"cell\" sendsActionOnEndEditing=\"YES\" title=\"what's new \" id=\"44P-Lb-sys\">\n                                                <font key=\"font\" metaFont=\"system\"/>\n                                                <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            </textFieldCell>\n                                        </textField>\n                                        <button translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"yFw-iW-0pS\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"362\" height=\"85\"/>\n                                            <buttonCell key=\"cell\" type=\"square\" bezelStyle=\"shadowlessSquare\" imagePosition=\"overlaps\" alignment=\"center\" imageScaling=\"proportionallyUpOrDown\" inset=\"2\" id=\"pgH-Tb-psY\">\n                                                <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                                <font key=\"font\" metaFont=\"system\"/>\n                                            </buttonCell>\n                                            <connections>\n                                                <action selector=\"handleWhatsNewButton:\" target=\"JD0-O4-EsS\" id=\"K1g-IV-k8g\"/>\n                                            </connections>\n                                        </button>\n                                        <button translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"uBO-pP-xIA\">\n                                            <rect key=\"frame\" x=\"322\" y=\"22\" width=\"30\" height=\"30\"/>\n                                            <constraints>\n                                                <constraint firstAttribute=\"height\" constant=\"30\" id=\"5VC-gZ-BsQ\"/>\n                                                <constraint firstAttribute=\"width\" constant=\"30\" id=\"Ohs-rE-TPE\"/>\n                                            </constraints>\n                                            <buttonCell key=\"cell\" type=\"square\" bezelStyle=\"shadowlessSquare\" image=\"NSFollowLinkFreestandingTemplate\" imagePosition=\"only\" alignment=\"center\" imageScaling=\"proportionallyUpOrDown\" inset=\"2\" id=\"vjY-WF-xG1\">\n                                                <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                                <font key=\"font\" metaFont=\"system\"/>\n                                            </buttonCell>\n                                            <connections>\n                                                <action selector=\"handleWhatsNewButton:\" target=\"JD0-O4-EsS\" id=\"h6c-Rh-HPv\"/>\n                                            </connections>\n                                        </button>\n                                    </subviews>\n                                    <constraints>\n                                        <constraint firstItem=\"e4P-1j-Pwp\" firstAttribute=\"top\" secondItem=\"yfK-3g-ZSB\" secondAttribute=\"bottom\" constant=\"6\" id=\"0sg-5C-VYI\"/>\n                                        <constraint firstItem=\"yfK-3g-ZSB\" firstAttribute=\"top\" secondItem=\"GfQ-OY-qPo\" secondAttribute=\"top\" constant=\"20\" id=\"5B4-qu-Q79\"/>\n                                        <constraint firstItem=\"yFw-iW-0pS\" firstAttribute=\"leading\" secondItem=\"GfQ-OY-qPo\" secondAttribute=\"leading\" id=\"8Pr-Pz-KnT\"/>\n                                        <constraint firstItem=\"e4P-1j-Pwp\" firstAttribute=\"leading\" secondItem=\"GfQ-OY-qPo\" secondAttribute=\"leading\" constant=\"20\" id=\"CMp-0v-bfl\"/>\n                                        <constraint firstAttribute=\"trailing\" secondItem=\"e4P-1j-Pwp\" secondAttribute=\"trailing\" constant=\"20\" id=\"JSj-Jm-ODA\"/>\n                                        <constraint firstItem=\"yfK-3g-ZSB\" firstAttribute=\"leading\" secondItem=\"GfQ-OY-qPo\" secondAttribute=\"leading\" constant=\"20\" id=\"MHX-p2-Trz\"/>\n                                        <constraint firstAttribute=\"bottom\" secondItem=\"e4P-1j-Pwp\" secondAttribute=\"bottom\" constant=\"20\" id=\"V0u-g5-u0E\"/>\n                                        <constraint firstItem=\"yFw-iW-0pS\" firstAttribute=\"top\" secondItem=\"GfQ-OY-qPo\" secondAttribute=\"top\" id=\"a4O-0B-VNK\"/>\n                                        <constraint firstAttribute=\"bottom\" secondItem=\"yFw-iW-0pS\" secondAttribute=\"bottom\" id=\"cf6-XI-oHJ\"/>\n                                        <constraint firstAttribute=\"trailing\" secondItem=\"uBO-pP-xIA\" secondAttribute=\"trailing\" constant=\"10\" id=\"hLt-NI-cg5\"/>\n                                        <constraint firstAttribute=\"trailing\" secondItem=\"yFw-iW-0pS\" secondAttribute=\"trailing\" id=\"mtf-Un-IAK\"/>\n                                        <constraint firstAttribute=\"bottom\" secondItem=\"uBO-pP-xIA\" secondAttribute=\"bottom\" constant=\"22\" id=\"pi6-tG-IeR\"/>\n                                        <constraint firstAttribute=\"trailing\" secondItem=\"yfK-3g-ZSB\" secondAttribute=\"trailing\" constant=\"20\" id=\"vQZ-ae-iNr\"/>\n                                    </constraints>\n                                </view>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"364\" id=\"M83-sz-H4R\"/>\n                                </constraints>\n                                <color key=\"borderColor\" white=\"0.66666666669999997\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                            </box>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"p4S-ON-7S6\" firstAttribute=\"centerX\" secondItem=\"vMb-6z-kGp\" secondAttribute=\"centerX\" id=\"6SP-1H-vVk\"/>\n                            <constraint firstItem=\"ERS-BC-qGc\" firstAttribute=\"centerY\" secondItem=\"vMb-6z-kGp\" secondAttribute=\"centerY\" id=\"86N-e6-fiH\"/>\n                            <constraint firstItem=\"Pcq-Wr-CsI\" firstAttribute=\"leading\" secondItem=\"vMb-6z-kGp\" secondAttribute=\"leading\" id=\"9Z5-QL-WIS\"/>\n                            <constraint firstItem=\"mlH-It-Zam\" firstAttribute=\"centerX\" secondItem=\"vMb-6z-kGp\" secondAttribute=\"centerX\" id=\"COc-Wj-roy\"/>\n                            <constraint firstItem=\"PmU-1L-wKw\" firstAttribute=\"centerY\" secondItem=\"LIy-LY-WEx\" secondAttribute=\"centerY\" id=\"CzS-uM-RhZ\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"epJ-lR-g9d\" secondAttribute=\"trailing\" id=\"MnE-uW-Gt6\"/>\n                            <constraint firstItem=\"LIy-LY-WEx\" firstAttribute=\"top\" secondItem=\"vMb-6z-kGp\" secondAttribute=\"top\" constant=\"22\" id=\"O4Y-tp-HIS\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"Pcq-Wr-CsI\" secondAttribute=\"trailing\" id=\"QS6-Pg-5Qg\"/>\n                            <constraint firstItem=\"ERS-BC-qGc\" firstAttribute=\"centerX\" secondItem=\"vMb-6z-kGp\" secondAttribute=\"centerX\" id=\"TGh-GL-ErM\"/>\n                            <constraint firstItem=\"PmU-1L-wKw\" firstAttribute=\"leading\" secondItem=\"LIy-LY-WEx\" secondAttribute=\"trailing\" constant=\"10\" id=\"TVS-2P-2X5\"/>\n                            <constraint firstItem=\"3oK-tV-cbq\" firstAttribute=\"leading\" secondItem=\"vMb-6z-kGp\" secondAttribute=\"leading\" id=\"Ta5-iV-ryj\"/>\n                            <constraint firstItem=\"Pcq-Wr-CsI\" firstAttribute=\"top\" secondItem=\"vMb-6z-kGp\" secondAttribute=\"top\" constant=\"60\" id=\"Z82-jA-C7G\"/>\n                            <constraint firstItem=\"3oK-tV-cbq\" firstAttribute=\"top\" secondItem=\"Pcq-Wr-CsI\" secondAttribute=\"bottom\" constant=\"10\" id=\"hMl-O3-Wo5\"/>\n                            <constraint firstItem=\"mlH-It-Zam\" firstAttribute=\"centerY\" secondItem=\"vMb-6z-kGp\" secondAttribute=\"centerY\" constant=\"120\" id=\"hQz-Xz-cXp\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"3oK-tV-cbq\" secondAttribute=\"trailing\" id=\"jb9-dB-DyB\"/>\n                            <constraint firstItem=\"epJ-lR-g9d\" firstAttribute=\"leading\" secondItem=\"vMb-6z-kGp\" secondAttribute=\"leading\" id=\"nxL-FW-UWH\"/>\n                            <constraint firstItem=\"LIy-LY-WEx\" firstAttribute=\"leading\" secondItem=\"vMb-6z-kGp\" secondAttribute=\"leading\" constant=\"12\" id=\"qMQ-qh-wOO\"/>\n                            <constraint firstItem=\"epJ-lR-g9d\" firstAttribute=\"top\" secondItem=\"3oK-tV-cbq\" secondAttribute=\"bottom\" constant=\"10\" id=\"xn7-VU-d12\"/>\n                            <constraint firstItem=\"p4S-ON-7S6\" firstAttribute=\"centerY\" secondItem=\"vMb-6z-kGp\" secondAttribute=\"centerY\" constant=\"60\" id=\"yf4-Ob-EeX\"/>\n                        </constraints>\n                    </view>\n                    <connections>\n                        <outlet property=\"boxSetupOthers\" destination=\"mlH-It-Zam\" id=\"9hJ-im-VTf\"/>\n                        <outlet property=\"boxSetupProgrammers\" destination=\"ERS-BC-qGc\" id=\"ExP-1C-iJl\"/>\n                        <outlet property=\"boxWhatsNew\" destination=\"p4S-ON-7S6\" id=\"8z4-7p-K1v\"/>\n                        <outlet property=\"whatsNewTextField\" destination=\"e4P-1j-Pwp\" id=\"3eu-6x-VPs\"/>\n                    </connections>\n                </viewController>\n                <customObject id=\"uLi-kL-Wm3\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"75\" y=\"206.5\"/>\n        </scene>\n        <!--Wizard View Controller-->\n        <scene sceneID=\"Fil-uR-thy\">\n            <objects>\n                <viewController storyboardIdentifier=\"WizardViewController\" id=\"DoA-87-gY5\" customClass=\"WizardViewController\" customModule=\"Jirassic\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" id=\"hxG-ku-CMn\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"558\" height=\"484\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                        <subviews>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"cHg-Ny-SMJ\">\n                                <rect key=\"frame\" x=\"-2\" y=\"378\" width=\"562\" height=\"34\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"34\" id=\"rKd-Gz-JT5\"/>\n                                </constraints>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" title=\"Shell support\" id=\"7GE-dW-QsF\">\n                                    <font key=\"font\" metaFont=\"systemBold\" size=\"23\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <box boxType=\"custom\" cornerRadius=\"4\" title=\"Box\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"b3I-CK-kNW\">\n                                <rect key=\"frame\" x=\"97\" y=\"145\" width=\"364\" height=\"114\"/>\n                                <view key=\"contentView\" id=\"YWu-lk-2KH\">\n                                    <rect key=\"frame\" x=\"1\" y=\"1\" width=\"362\" height=\"112\"/>\n                                    <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                </view>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"364\" id=\"5XS-B5-QlH\"/>\n                                    <constraint firstAttribute=\"height\" priority=\"250\" constant=\"114\" id=\"aiA-vp-zhY\"/>\n                                </constraints>\n                            </box>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"LWS-Sc-Yau\">\n                                <rect key=\"frame\" x=\"386\" y=\"30\" width=\"74\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"Skip setup\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"U4c-wv-yEQ\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleSkipButton:\" target=\"DoA-87-gY5\" id=\"rYx-ag-mhA\"/>\n                                </connections>\n                            </button>\n                            <levelIndicator verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"bul-Rz-Luj\">\n                                <rect key=\"frame\" x=\"98\" y=\"34\" width=\"48\" height=\"12\"/>\n                                <levelIndicatorCell key=\"cell\" alignment=\"left\" doubleValue=\"1\" maxValue=\"4\" levelIndicatorStyle=\"rating\" id=\"Zn3-qo-pvX\"/>\n                                <color key=\"fillColor\" name=\"systemBlueColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            </levelIndicator>\n                            <textField verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"jEi-lE-OZv\">\n                                <rect key=\"frame\" x=\"38\" y=\"341\" width=\"482\" height=\"17\"/>\n                                <textFieldCell key=\"cell\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" title=\"Multiline Label\" id=\"Bu7-35-0yU\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"dLe-ZF-F9D\">\n                                <rect key=\"frame\" x=\"12\" y=\"443\" width=\"38\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"Quit\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"JFI-fO-QQm\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleQuitAppButton:\" target=\"DoA-87-gY5\" id=\"9Hr-AF-E4y\"/>\n                                </connections>\n                            </button>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"MOy-l9-bU0\">\n                                <rect key=\"frame\" x=\"60\" y=\"443\" width=\"20\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"^\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"ino-VC-Wlu\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleMinimizeAppButton:\" target=\"DoA-87-gY5\" id=\"bce-jb-BPy\"/>\n                                </connections>\n                            </button>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"MOy-l9-bU0\" firstAttribute=\"centerY\" secondItem=\"dLe-ZF-F9D\" secondAttribute=\"centerY\" id=\"76t-qy-APB\"/>\n                            <constraint firstItem=\"dLe-ZF-F9D\" firstAttribute=\"leading\" secondItem=\"hxG-ku-CMn\" secondAttribute=\"leading\" constant=\"12\" id=\"AmE-Bf-5NB\"/>\n                            <constraint firstItem=\"cHg-Ny-SMJ\" firstAttribute=\"top\" secondItem=\"hxG-ku-CMn\" secondAttribute=\"top\" constant=\"72\" id=\"B4v-et-YoF\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"cHg-Ny-SMJ\" secondAttribute=\"trailing\" id=\"D5U-S7-6KS\"/>\n                            <constraint firstItem=\"MOy-l9-bU0\" firstAttribute=\"leading\" secondItem=\"dLe-ZF-F9D\" secondAttribute=\"trailing\" constant=\"10\" id=\"ECg-kQ-rrG\"/>\n                            <constraint firstItem=\"b3I-CK-kNW\" firstAttribute=\"centerY\" secondItem=\"hxG-ku-CMn\" secondAttribute=\"centerY\" constant=\"40\" id=\"Hxf-pq-YtM\"/>\n                            <constraint firstItem=\"dLe-ZF-F9D\" firstAttribute=\"top\" secondItem=\"hxG-ku-CMn\" secondAttribute=\"top\" constant=\"22\" id=\"K0J-ZJ-U1I\"/>\n                            <constraint firstItem=\"cHg-Ny-SMJ\" firstAttribute=\"leading\" secondItem=\"hxG-ku-CMn\" secondAttribute=\"leading\" id=\"Lku-ei-MQQ\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"jEi-lE-OZv\" secondAttribute=\"trailing\" constant=\"40\" id=\"UdE-lA-jyr\"/>\n                            <constraint firstItem=\"jEi-lE-OZv\" firstAttribute=\"top\" secondItem=\"cHg-Ny-SMJ\" secondAttribute=\"bottom\" constant=\"20\" id=\"aHQ-hF-vH5\"/>\n                            <constraint firstItem=\"bul-Rz-Luj\" firstAttribute=\"leading\" secondItem=\"YWu-lk-2KH\" secondAttribute=\"leading\" id=\"c8f-7P-QWA\"/>\n                            <constraint firstItem=\"bul-Rz-Luj\" firstAttribute=\"centerY\" secondItem=\"LWS-Sc-Yau\" secondAttribute=\"centerY\" id=\"ciP-7m-NEa\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"bul-Rz-Luj\" secondAttribute=\"bottom\" constant=\"34\" id=\"ehx-sS-Qdi\"/>\n                            <constraint firstItem=\"b3I-CK-kNW\" firstAttribute=\"centerX\" secondItem=\"hxG-ku-CMn\" secondAttribute=\"centerX\" id=\"ewW-OA-mJG\"/>\n                            <constraint firstItem=\"LWS-Sc-Yau\" firstAttribute=\"trailing\" secondItem=\"YWu-lk-2KH\" secondAttribute=\"trailing\" id=\"off-JS-LUp\"/>\n                            <constraint firstItem=\"jEi-lE-OZv\" firstAttribute=\"leading\" secondItem=\"hxG-ku-CMn\" secondAttribute=\"leading\" constant=\"40\" id=\"xl4-LI-2BX\"/>\n                        </constraints>\n                    </view>\n                    <connections>\n                        <outlet property=\"butSkip\" destination=\"LWS-Sc-Yau\" id=\"7jf-MB-lj7\"/>\n                        <outlet property=\"containerView\" destination=\"YWu-lk-2KH\" id=\"5Zd-ED-Y0m\"/>\n                        <outlet property=\"containerViewHeightConstrain\" destination=\"aiA-vp-zhY\" id=\"FkF-jy-JQV\"/>\n                        <outlet property=\"levelIndicator\" destination=\"bul-Rz-Luj\" id=\"glc-Bt-tWg\"/>\n                        <outlet property=\"subtitleLabel\" destination=\"jEi-lE-OZv\" id=\"azY-kd-UNL\"/>\n                        <outlet property=\"titleLabel\" destination=\"cHg-Ny-SMJ\" id=\"9OH-fm-DtA\"/>\n                    </connections>\n                </viewController>\n                <customObject id=\"eif-UW-1sQ\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"729\" y=\"206.5\"/>\n        </scene>\n    </scenes>\n    <resources>\n        <image name=\"NSFollowLinkFreestandingTemplate\" width=\"14\" height=\"14\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Onboarding/WelcomeViewController.swift",
    "content": "//\n//  WelcomeViewController.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 10/12/2016.\n//  Copyright © 2016 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\nimport RCPreferences\nimport RCLog\n\nclass WelcomeViewController: NSViewController {\n    \n    weak var appWireframe: AppWireframe?\n    @IBOutlet var boxSetupProgrammers: NSBox!\n    @IBOutlet var boxSetupOthers: NSBox!\n    @IBOutlet var boxWhatsNew: NSBox!\n    @IBOutlet var whatsNewTextField: NSTextField!\n    private let pref = RCPreferences<LocalPreferences>()\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        createLayer()\n       // if AppTheme().isDark {\n         //   box.fillColor = NSColor.clear\n       // }\n        \n        // Do we need to display  what's new box?\n        // When app is an update from previous version\n        let isFirstLaunchOfThisVersion = pref.string(.appVersion) != Versioning.appVersion\n        // Deprecated userdefault, keep it for few versions, needed to present what's new screen\n        let wizardStep = UserDefaults.standard.integer(forKey: \"RCPreferences-wizardStep\")\n        let isAnUpdateFromAnotherVersion = pref.string(.appVersion) != \"\" || wizardStep > 0\n        if isFirstLaunchOfThisVersion && isAnUpdateFromAnotherVersion {\n            boxWhatsNew.isHidden = false\n            boxSetupProgrammers.isHidden = true\n            boxSetupOthers.isHidden = true\n            whatsNewTextField.stringValue = \"• Import meetings from Calendar.app\\n• Create monthly reports\\n• Fixes bug in editing tasks. Git commits and calendar meetings can be edited after the day is closed\\n• Extended calendar history to one year\\n• Various UI improvements and fixes\"\n        } else {\n            boxWhatsNew.isHidden = true\n            boxSetupProgrammers.isHidden = false\n            boxSetupOthers.isHidden = false\n        }\n    }\n    \n    deinit {\n        RCLog(\"deinit\")\n    }\n    \n    @IBAction func handleSetupProgrammersButton (_ sender: NSButton) {\n        // Set that we saw this version of the app launch\n        pref.set(Versioning.appVersion, forKey: .appVersion)\n        let stepsToSave: [Int] = []\n        pref.set(stepsToSave, forKey: .wizardSteps)\n        appWireframe!.flipToWizardController()\n    }\n    \n    @IBAction func handleSetupOthersButton (_ sender: NSButton) {\n        pref.set(Versioning.appVersion, forKey: .appVersion)\n        let stepsSeen = [WizardStep.shell, WizardStep.browser, WizardStep.git]\n        let stepsToSave: [Int] = stepsSeen.map({ $0.rawValue })\n        pref.set(stepsToSave, forKey: .wizardSteps)\n        appWireframe!.flipToWizardController()\n    }\n    \n    @IBAction func handleWhatsNewButton (_ sender: NSButton) {\n        pref.set(Versioning.appVersion, forKey: .appVersion)\n        let stepsSeen = [WizardStep.shell, WizardStep.browser, WizardStep.git, WizardStep.jira]\n        let stepsToSave: [Int] = stepsSeen.map({ $0.rawValue })\n        pref.set(stepsToSave, forKey: .wizardSteps)\n        // Remove deprecated userdefault\n        UserDefaults.standard.removeObject(forKey: \"RCPreferences-wizardStep\")\n        appWireframe!.flipToWizardController()\n    }\n    \n    @IBAction func handleQuitAppButton (_ sender: NSButton) {\n        NSApplication.shared.terminate(nil)\n    }\n    \n    @IBAction func handleMinimizeAppButton (_ sender: NSButton) {\n        AppDelegate.sharedApp().menu.triggerClose()\n    }\n}\n\nextension WelcomeViewController: Animatable {\n    \n    func createLayer() {\n        view.layer = CALayer()\n        view.wantsLayer = true\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Onboarding/WizardAppleScriptView.swift",
    "content": "//\n//  WizardAppleScriptView.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 18/04/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\nimport RCLog\n\nclass WizardAppleScriptView: NSView {\n    \n    @IBOutlet var titleLabel: NSTextField!\n    @IBOutlet var subtitleLabel: NSTextField!\n    @IBOutlet var butLink: NSButton!\n    @IBOutlet var butSkip: NSButton!\n    @IBOutlet var progressIndicator: NSProgressIndicator!\n    var onSkip: (() -> Void)?\n    var scriptName: String? {\n        didSet {\n            handleTimer()\n        }\n    }\n    var subtitle: String? {\n        didSet {\n            subtitleLabel.stringValue = subtitle ?? \"\"\n        }\n    }\n    private var timer: Timer?\n    private let scripts: AppleScriptProtocol = SandboxedAppleScript()\n    \n    override func awakeFromNib() {\n        super.awakeFromNib()\n        \n    }\n    \n    func invalidate() {\n        timer?.invalidate()\n        timer = nil\n    }\n    \n    deinit {\n        invalidate()\n        RCLog(\"deinit\")\n    }\n    \n    @objc func handleTimer() {\n        guard let scriptName = self.scriptName else {\n            return\n        }\n        timer = WeakTimer.scheduledTimer(timeInterval: 1,\n                                         target: self,\n                                         repeats: true) { [weak self] timer in\n                                            // Place your action code here.\n                                            self?.scripts.getScriptVersion(script: scriptName, completion: { [weak self] scriptVersion in\n                                                RCLog(scriptVersion)\n                                                if scriptVersion != \"\" {\n                                                    self?.progressIndicator.stopAnimation(nil)\n                                                    self?.butLink.isHidden = true\n                                                    self?.subtitleLabel.textColor = NSColor.green\n                                                    self?.subtitleLabel.stringValue = \"Installed successfully!\"\n                                                    self?.subtitleLabel.font = NSFont.systemFont(ofSize: 26)\n                                                } else {\n                                                    self?.progressIndicator.startAnimation(nil)\n                                                    self?.butLink.isHidden = false\n                                                    self?.subtitleLabel.textColor = NSColor.black\n                                                    self?.subtitleLabel.stringValue = self?.subtitle ?? \"\"\n                                                    self?.subtitleLabel.font = NSFont.systemFont(ofSize: 13)\n                                                }\n                                            })\n        }\n    }\n    \n    @IBAction func handleInstructionsButton (_ sender: NSButton) {\n        #if APPSTORE\n        NSWorkspace.shared.open( URL(string: \"http://www.jirassic.com/#extensions\")!)\n        #else\n        NSWorkspace.shared.open( URL(string: \"http://www.jirassic.com/#extensions\")!)\n        #endif\n    }\n\n    @IBAction func handleSkipButton (_ sender: NSButton) {\n        onSkip?()\n    }\n}\n\nfinal class WeakTimer {\n    \n    fileprivate weak var timer: Timer?\n    fileprivate weak var target: AnyObject?\n    fileprivate let action: (Timer) -> Void\n    \n    fileprivate init(timeInterval: TimeInterval,\n                     target: AnyObject,\n                     repeats: Bool,\n                     action: @escaping (Timer) -> Void) {\n        self.target = target\n        self.action = action\n        self.timer = Timer.scheduledTimer(timeInterval: timeInterval,\n                                          target: self,\n                                          selector: #selector(fire),\n                                          userInfo: nil,\n                                          repeats: repeats)\n    }\n    \n    class func scheduledTimer(timeInterval: TimeInterval,\n                              target: AnyObject,\n                              repeats: Bool,\n                              action: @escaping (Timer) -> Void) -> Timer {\n        return WeakTimer(timeInterval: timeInterval,\n                         target: target,\n                         repeats: repeats,\n                         action: action).timer!\n    }\n    \n    @objc fileprivate func fire(timer: Timer) {\n        if target != nil {\n            action(timer)\n        } else {\n            timer.invalidate()\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Onboarding/WizardAppleScriptView.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"14109\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14109\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView id=\"c22-O7-iKe\" customClass=\"WizardAppleScriptView\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"364\" height=\"143\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"YaX-Kg-JaV\">\n                    <rect key=\"frame\" x=\"18\" y=\"96\" width=\"328\" height=\"17\"/>\n                    <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"left\" title=\"Install ShellSupport.scpt\" id=\"6qk-B1-qkH\">\n                        <font key=\"font\" metaFont=\"systemBold\"/>\n                        <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                    </textFieldCell>\n                </textField>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"D80-Ry-3Af\">\n                    <rect key=\"frame\" x=\"20\" y=\"19\" width=\"112\" height=\"19\"/>\n                    <buttonCell key=\"cell\" type=\"roundRect\" title=\"View instructions\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"t8d-oT-UYR\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"cellTitle\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleInstructionsButton:\" target=\"c22-O7-iKe\" id=\"uCk-l1-ezT\"/>\n                    </connections>\n                </button>\n                <progressIndicator wantsLayer=\"YES\" horizontalHuggingPriority=\"750\" verticalHuggingPriority=\"750\" maxValue=\"100\" displayedWhenStopped=\"NO\" bezeled=\"NO\" indeterminate=\"YES\" controlSize=\"small\" style=\"spinning\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"EOg-KL-gzY\">\n                    <rect key=\"frame\" x=\"144\" y=\"21\" width=\"16\" height=\"16\"/>\n                </progressIndicator>\n                <textField verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Clu-5X-6dd\">\n                    <rect key=\"frame\" x=\"18\" y=\"58\" width=\"328\" height=\"34\"/>\n                    <textFieldCell key=\"cell\" sendsActionOnEndEditing=\"YES\" title=\"Go to this page, copy the script and run it in Terminal, we'll wait!\" id=\"Ee9-gZ-rdQ\">\n                        <font key=\"font\" metaFont=\"system\"/>\n                        <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                    </textFieldCell>\n                </textField>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"RQ5-jO-LoT\">\n                    <rect key=\"frame\" x=\"303\" y=\"19\" width=\"41\" height=\"19\"/>\n                    <buttonCell key=\"cell\" type=\"roundRect\" title=\"Next\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"gQo-3q-4FU\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"cellTitle\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleSkipButton:\" target=\"c22-O7-iKe\" id=\"Kc6-8Q-vqL\"/>\n                    </connections>\n                </button>\n            </subviews>\n            <constraints>\n                <constraint firstItem=\"YaX-Kg-JaV\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" constant=\"30\" id=\"AcE-VY-CmF\"/>\n                <constraint firstItem=\"D80-Ry-3Af\" firstAttribute=\"top\" secondItem=\"Clu-5X-6dd\" secondAttribute=\"bottom\" constant=\"20\" id=\"BZD-u7-HX2\"/>\n                <constraint firstItem=\"EOg-KL-gzY\" firstAttribute=\"leading\" secondItem=\"D80-Ry-3Af\" secondAttribute=\"trailing\" constant=\"12\" id=\"D4H-vR-qpA\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"D80-Ry-3Af\" secondAttribute=\"bottom\" constant=\"20\" id=\"GQc-BZ-0V0\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"Clu-5X-6dd\" secondAttribute=\"trailing\" constant=\"20\" id=\"IE0-nd-NsH\"/>\n                <constraint firstItem=\"EOg-KL-gzY\" firstAttribute=\"centerY\" secondItem=\"D80-Ry-3Af\" secondAttribute=\"centerY\" id=\"OUW-QJ-fqV\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"YaX-Kg-JaV\" secondAttribute=\"trailing\" constant=\"20\" id=\"PWl-XP-Bsi\"/>\n                <constraint firstItem=\"D80-Ry-3Af\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"20\" id=\"a7D-Yt-6Mq\"/>\n                <constraint firstItem=\"RQ5-jO-LoT\" firstAttribute=\"centerY\" secondItem=\"D80-Ry-3Af\" secondAttribute=\"centerY\" id=\"cz3-Iw-lCl\"/>\n                <constraint firstItem=\"Clu-5X-6dd\" firstAttribute=\"top\" secondItem=\"YaX-Kg-JaV\" secondAttribute=\"bottom\" constant=\"4\" id=\"gOD-Tm-Glw\"/>\n                <constraint firstItem=\"Clu-5X-6dd\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"20\" id=\"hn7-AF-wKf\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"RQ5-jO-LoT\" secondAttribute=\"trailing\" constant=\"20\" id=\"pWV-uL-B04\"/>\n                <constraint firstItem=\"YaX-Kg-JaV\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"20\" id=\"tXC-og-bof\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"butLink\" destination=\"D80-Ry-3Af\" id=\"5ns-DL-xLI\"/>\n                <outlet property=\"butSkip\" destination=\"RQ5-jO-LoT\" id=\"Rls-jd-Hso\"/>\n                <outlet property=\"progressIndicator\" destination=\"EOg-KL-gzY\" id=\"XD2-sn-Pms\"/>\n                <outlet property=\"subtitleLabel\" destination=\"Clu-5X-6dd\" id=\"Y3N-vu-6Zj\"/>\n                <outlet property=\"titleLabel\" destination=\"YaX-Kg-JaV\" id=\"KZi-YJ-EZi\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"81\" y=\"90\"/>\n        </customView>\n    </objects>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Onboarding/WizardCalendarView.swift",
    "content": "//\n//  WizardCalendarView.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 15/07/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\nimport RCPreferences\n\nclass WizardCalendarView: NSView {\n    \n    @IBOutlet private var scrollView: NSScrollView!\n    @IBOutlet private var butAuthorize: NSButton!\n    @IBOutlet var butSkip: NSButton!\n    var onSkip: (() -> Void)?\n    private let pref = RCPreferences<LocalPreferences>()\n    private var calendarsButtons = [NSButton]()\n    private var presenter: CalendarPresenterInput = CalendarPresenter()\n    \n    override func awakeFromNib() {\n        super.awakeFromNib()\n        (presenter as! CalendarPresenter).userInterface = self\n        (presenter as! CalendarPresenter).refresh()\n    }\n    \n    func save() {\n    }\n    \n    @IBAction func handleSkipButton (_ sender: NSButton) {\n        save()\n        onSkip?()\n    }\n    \n    @IBAction func handleAuthorizeButton (_ sender: NSButton) {\n        // Enable the calendar so when it gets authorized will be able to read and display the list of calendars\n        presenter.enable(true)\n        presenter.authorize()\n    }\n    \n    override func layout() {\n        super.layout()\n        \n        var x = CGFloat(0)\n        var y = CGFloat(0)\n        for but in calendarsButtons {\n            if x + but.frame.size.width > scrollView.frame.size.width {\n                y += 26\n                x = CGFloat(0)\n            }\n            but.frame = CGRect(x: x, y: y, width: but.frame.size.width, height: but.frame.size.height)\n            x += but.frame.size.width + 10\n        }\n        scrollView.documentView?.setFrameSize(NSSize(width: 0, height: y + 26))\n    }\n}\n\nextension WizardCalendarView: CalendarPresenterOutput {\n    \n    func enable (_ enabled: Bool) {\n        butAuthorize.isHidden = enabled\n    }\n    \n    func setStatusImage (_ imageName: NSImage.Name) {\n    }\n    \n    func setStatusText (_ text: String) {\n    }\n    \n    func setDescriptionText (_ text: String) {\n    }\n    \n    func setCalendarStatus (authorized: Bool, enabled: Bool) {\n    }\n    \n    func setCalendars (_ calendars: [String], selected: [String]) {\n        \n        for but in calendarsButtons {\n            but.removeFromSuperview()\n        }\n        calendarsButtons = []\n        \n        for title in calendars {\n            let but = NSButton()\n            but.setButtonType(.switch)\n            but.title = title\n            but.sizeToFit()\n            but.state = selected.contains(title) ? .on : .off\n            but.target = self\n            but.action = #selector(didClickCalendarButton)\n            scrollView.addSubview(but)\n            self.calendarsButtons.append(but)\n        }\n        self.needsLayout = true\n    }\n    \n    @objc func didClickCalendarButton (_ sender: NSButton) {\n        if sender.state == .on {\n            presenter.enableCalendar(sender.title)\n        } else {\n            presenter.disableCalendar(sender.title)\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Onboarding/WizardCalendarView.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"14313.18\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14313.18\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView id=\"c22-O7-iKe\" customClass=\"WizardCalendarView\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"480\" height=\"152\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"EFe-aL-uim\">\n                    <rect key=\"frame\" x=\"419\" y=\"19\" width=\"41\" height=\"19\"/>\n                    <buttonCell key=\"cell\" type=\"roundRect\" title=\"Next\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"uQq-TS-Ljt\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"cellTitle\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleSkipButton:\" target=\"c22-O7-iKe\" id=\"ITv-rh-tAh\"/>\n                    </connections>\n                </button>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"K2r-LN-bzz\">\n                    <rect key=\"frame\" x=\"20\" y=\"19\" width=\"147\" height=\"19\"/>\n                    <buttonCell key=\"cell\" type=\"roundRect\" title=\"Authorize Calendar.app\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"OlI-1R-HHR\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"cellTitle\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleAuthorizeButton:\" target=\"c22-O7-iKe\" id=\"jXT-gz-HoS\"/>\n                    </connections>\n                </button>\n                <scrollView borderType=\"none\" horizontalLineScroll=\"10\" horizontalPageScroll=\"10\" verticalLineScroll=\"10\" verticalPageScroll=\"10\" usesPredominantAxisScrolling=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"NF3-oE-rpO\">\n                    <rect key=\"frame\" x=\"20\" y=\"46\" width=\"440\" height=\"86\"/>\n                    <clipView key=\"contentView\" drawsBackground=\"NO\" copiesOnScroll=\"NO\" id=\"0Gi-4W-AIk\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"440\" height=\"86\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <view fixedFrame=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"job-an-2QI\">\n                                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"425\" height=\"71\"/>\n                                <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                            </view>\n                        </subviews>\n                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"0.0\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                    </clipView>\n                    <scroller key=\"horizontalScroller\" verticalHuggingPriority=\"750\" horizontal=\"YES\" id=\"cHo-H6-4gr\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"70\" width=\"440\" height=\"16\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                    </scroller>\n                    <scroller key=\"verticalScroller\" verticalHuggingPriority=\"750\" doubleValue=\"1\" horizontal=\"NO\" id=\"4Bu-Xk-nYr\">\n                        <rect key=\"frame\" x=\"424\" y=\"0.0\" width=\"16\" height=\"86\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                    </scroller>\n                </scrollView>\n            </subviews>\n            <constraints>\n                <constraint firstAttribute=\"trailing\" secondItem=\"EFe-aL-uim\" secondAttribute=\"trailing\" constant=\"20\" id=\"1FC-DL-Rr6\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"K2r-LN-bzz\" secondAttribute=\"bottom\" constant=\"20\" id=\"8Lj-1W-Hb5\"/>\n                <constraint firstItem=\"K2r-LN-bzz\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"20\" id=\"QQi-EM-VaD\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"EFe-aL-uim\" secondAttribute=\"bottom\" constant=\"20\" id=\"TSa-PY-HiA\"/>\n                <constraint firstItem=\"EFe-aL-uim\" firstAttribute=\"top\" secondItem=\"NF3-oE-rpO\" secondAttribute=\"bottom\" constant=\"8\" id=\"Xy5-Sa-As5\"/>\n                <constraint firstItem=\"NF3-oE-rpO\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"20\" id=\"g8b-E9-1pe\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"NF3-oE-rpO\" secondAttribute=\"trailing\" constant=\"20\" id=\"iNN-aZ-Jvn\"/>\n                <constraint firstItem=\"NF3-oE-rpO\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" constant=\"20\" id=\"jkl-me-0L2\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"butAuthorize\" destination=\"K2r-LN-bzz\" id=\"j7Y-Jl-18X\"/>\n                <outlet property=\"butSkip\" destination=\"EFe-aL-uim\" id=\"2CE-Pd-av3\"/>\n                <outlet property=\"scrollView\" destination=\"NF3-oE-rpO\" id=\"LKo-sz-ESh\"/>\n            </connections>\n        </customView>\n    </objects>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Onboarding/WizardGitView.swift",
    "content": "//\n//  WizardGitView.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 18/04/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\nimport RCPreferences\n\nclass WizardGitView: NSView {\n    \n    @IBOutlet fileprivate var emailsTextField: NSTextField!\n    @IBOutlet fileprivate var pathsTextField: NSTextField!\n    @IBOutlet fileprivate var butPick: NSButton!\n    @IBOutlet var butSkip: NSButton!\n    var onSkip: (() -> Void)?\n    private let pref = RCPreferences<LocalPreferences>()\n    private var emailClickGestureRecognizer: NSClickGestureRecognizer?\n    private var gitUsersPopover: NSPopover?\n    \n    var presenter: GitPresenterInput = GitPresenter()\n    \n    override func awakeFromNib() {\n        super.awakeFromNib()\n        // Git is disabled by default, we need to enable in order to be able to make changes\n        pref.set(true, forKey: .enableGit)\n        (presenter as! GitPresenter).userInterface = self\n        presenter.isShellScriptInstalled = true\n        \n        let emailClickGestureRecognizer = NSClickGestureRecognizer(target: self, action: #selector(GitCell.emailTextFieldClicked))\n        emailsTextField.addGestureRecognizer(emailClickGestureRecognizer)\n        self.emailClickGestureRecognizer = emailClickGestureRecognizer\n    }\n    \n    deinit {\n        if  let gesture = emailClickGestureRecognizer {\n            emailsTextField.removeGestureRecognizer(gesture)\n        }\n    }\n    \n    func save() {\n        presenter.save(emails: emailsTextField.stringValue, paths: pathsTextField.stringValue)\n    }\n    \n    @IBAction func handlePickButton (_ sender: NSButton) {\n        presenter.pickPath()\n    }\n    \n    @IBAction func handleSkipButton (_ sender: NSButton) {\n        // If git was not setup completely, disable it\n        if emailsTextField.stringValue == \"\" || pathsTextField.stringValue == \"\" {\n            pref.set(false, forKey: .enableGit)\n        }\n        save()\n        onSkip?()\n    }\n    \n    @objc func emailTextFieldClicked() {\n        guard gitUsersPopover == nil else {\n            return\n        }\n        let popover = NSPopover()\n        let view = GitUsersViewController.instantiateFromStoryboard(\"Components\")\n        view.onDone = {\n            self.gitUsersPopover?.performClose(nil)\n            self.gitUsersPopover = nil\n            self.presenter.isShellScriptInstalled = true\n        }\n        popover.contentViewController = view\n        let rect = CGRect(origin: CGPoint(x: emailsTextField.frame.origin.x, y: emailsTextField.frame.origin.y), size: emailsTextField.frame.size)\n        popover.show(relativeTo: rect, of: self, preferredEdge: NSRectEdge.minY)\n        gitUsersPopover = popover\n    }\n}\n\nextension WizardGitView: GitPresenterOutput {\n    \n    func setStatusImage (_ imageName: NSImage.Name) {}\n    func setStatusText (_ text: String) {}\n    func setDescriptionText (_ text: String) {}\n    func setButInstall (enabled: Bool) {}\n    func setButPurchase(enabled: Bool) {}\n    func setButEnable (on: Bool?, enabled: Bool?) {}\n    func setPaths (_ paths: String?, enabled: Bool?) {\n        if let paths = paths {\n            pathsTextField.stringValue = paths\n        }\n        if let enabled = enabled {\n            pathsTextField.isEnabled = enabled\n            butPick.isEnabled = enabled\n        }\n    }\n    func setEmails (_ emails: String?, enabled: Bool?) {\n        if let emails = emails {\n            emailsTextField.stringValue = emails\n        }\n        if let enabled = enabled {\n            emailsTextField.isEnabled = enabled\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Onboarding/WizardGitView.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14460.31\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView id=\"c22-O7-iKe\" customClass=\"WizardGitView\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"480\" height=\"152\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"EFe-aL-uim\">\n                    <rect key=\"frame\" x=\"419\" y=\"19\" width=\"41\" height=\"19\"/>\n                    <buttonCell key=\"cell\" type=\"roundRect\" title=\"Next\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"uQq-TS-Ljt\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"cellTitle\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleSkipButton:\" target=\"c22-O7-iKe\" id=\"ITv-rh-tAh\"/>\n                    </connections>\n                </button>\n                <textField verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"heA-pk-yTN\">\n                    <rect key=\"frame\" x=\"20\" y=\"68\" width=\"440\" height=\"22\"/>\n                    <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" borderStyle=\"bezel\" placeholderString=\"Commiter's Email\" bezelStyle=\"round\" id=\"344-jC-08b\">\n                        <font key=\"font\" metaFont=\"system\"/>\n                        <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                    </textFieldCell>\n                </textField>\n                <textField verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"KmP-MI-NIp\">\n                    <rect key=\"frame\" x=\"20\" y=\"100\" width=\"440\" height=\"22\"/>\n                    <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" borderStyle=\"bezel\" placeholderString=\"Project's path\" bezelStyle=\"round\" id=\"oqg-Jp-NXL\">\n                        <font key=\"font\" metaFont=\"system\"/>\n                        <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                    </textFieldCell>\n                </textField>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"K2r-LN-bzz\">\n                    <rect key=\"frame\" x=\"20\" y=\"19\" width=\"93\" height=\"19\"/>\n                    <buttonCell key=\"cell\" type=\"roundRect\" title=\"Select project\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"OlI-1R-HHR\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"cellTitle\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handlePickButton:\" target=\"c22-O7-iKe\" id=\"vNF-6E-rRC\"/>\n                    </connections>\n                </button>\n            </subviews>\n            <constraints>\n                <constraint firstAttribute=\"trailing\" secondItem=\"EFe-aL-uim\" secondAttribute=\"trailing\" constant=\"20\" id=\"1FC-DL-Rr6\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"KmP-MI-NIp\" secondAttribute=\"trailing\" constant=\"20\" id=\"49l-Lb-wij\"/>\n                <constraint firstItem=\"KmP-MI-NIp\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"20\" id=\"64j-RB-RZF\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"K2r-LN-bzz\" secondAttribute=\"bottom\" constant=\"20\" id=\"8Lj-1W-Hb5\"/>\n                <constraint firstItem=\"heA-pk-yTN\" firstAttribute=\"top\" secondItem=\"KmP-MI-NIp\" secondAttribute=\"bottom\" constant=\"10\" id=\"M10-OX-18s\"/>\n                <constraint firstItem=\"heA-pk-yTN\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"20\" id=\"MXu-h4-5Fk\"/>\n                <constraint firstItem=\"K2r-LN-bzz\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"20\" id=\"QQi-EM-VaD\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"EFe-aL-uim\" secondAttribute=\"bottom\" constant=\"20\" id=\"TSa-PY-HiA\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"heA-pk-yTN\" secondAttribute=\"trailing\" constant=\"20\" id=\"fpc-k9-coL\"/>\n                <constraint firstItem=\"EFe-aL-uim\" firstAttribute=\"top\" secondItem=\"heA-pk-yTN\" secondAttribute=\"bottom\" constant=\"30\" id=\"lei-JE-pId\"/>\n                <constraint firstItem=\"KmP-MI-NIp\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" constant=\"30\" id=\"y4H-EL-Zsl\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"butPick\" destination=\"K2r-LN-bzz\" id=\"6rU-dQ-JLU\"/>\n                <outlet property=\"butSkip\" destination=\"EFe-aL-uim\" id=\"2CE-Pd-av3\"/>\n                <outlet property=\"emailsTextField\" destination=\"heA-pk-yTN\" id=\"HbJ-2I-1YX\"/>\n                <outlet property=\"pathsTextField\" destination=\"KmP-MI-NIp\" id=\"RjP-Ha-jJq\"/>\n            </connections>\n        </customView>\n    </objects>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Onboarding/WizardJiraView.swift",
    "content": "//\n//  WizardJiraView.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 18/04/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\nimport RCPreferences\n\nclass WizardJiraView: NSView {\n    \n    @IBOutlet var butLogin: NSButton!\n    @IBOutlet var butSkip: NSButton!\n    @IBOutlet fileprivate var baseUrlTextField: NSTextField!\n    @IBOutlet fileprivate var userTextField: NSTextField!\n    @IBOutlet fileprivate var passwordTextField: NSTextField!\n    @IBOutlet fileprivate var errorTextField: NSTextField!\n    @IBOutlet fileprivate var projectNamePopup: NSPopUpButton!\n    @IBOutlet fileprivate var projectIssueNamePopup: NSPopUpButton!\n    @IBOutlet fileprivate var progressIndicator: NSProgressIndicator!\n    \n    fileprivate let localPreferences = RCPreferences<LocalPreferences>()\n    var presenter: JiraTempoPresenterInput = JiraTempoPresenter()\n    \n    var onSkip: (() -> Void)?\n    \n    override func awakeFromNib() {\n        super.awakeFromNib()\n        \n        baseUrlTextField.stringValue = localPreferences.string(.settingsJiraUrl)\n        userTextField.stringValue = localPreferences.string(.settingsJiraUser)\n        passwordTextField.stringValue = Keychain.getPassword()\n        \n        projectNamePopup.target = self\n        projectNamePopup.action = #selector(projectNamePopupSelected(_:))\n        \n        projectIssueNamePopup.target = self\n        projectIssueNamePopup.action = #selector(projectIssueNamePopupSelected(_:))\n        \n        (presenter as! JiraTempoPresenter).userInterface = self\n        presenter.setupUserInterface()\n        handleLoginButton(butLogin)\n    }\n    \n    func save() {\n        presenter.save(url: baseUrlTextField.stringValue,\n                       user: userTextField.stringValue,\n                       password: passwordTextField.stringValue)\n    }\n    \n    @IBAction func handleLoginButton (_ sender: NSButton) {\n        save()\n        guard baseUrlTextField.stringValue != \"\",\n            userTextField.stringValue != \"\",\n            passwordTextField.stringValue != \"\" else {\n                return\n        }\n        presenter.checkCredentials()\n    }\n    \n    @IBAction func handleSkipButton (_ sender: NSButton) {\n        onSkip?()\n    }\n\n    @IBAction func projectNamePopupSelected (_ sender: NSPopUpButton) {\n        if let title = sender.selectedItem?.title {\n            localPreferences.set(title, forKey: .settingsJiraProjectKey)\n            presenter.loadProjectIssues(for: title)\n        }\n    }\n\n    @IBAction func projectIssueNamePopupSelected (_ sender: NSPopUpButton) {\n        localPreferences.set(sender.selectedItem?.title ?? \"\", forKey: .settingsJiraProjectIssueKey)\n    }\n}\n\nextension WizardJiraView: JiraTempoPresenterOutput {\n    \n    func setPurchased (_ purchased: Bool) {\n        \n    }\n    \n    func enableProgressIndicator (_ enabled: Bool) {\n        enabled\n            ? progressIndicator.startAnimation(nil)\n            : progressIndicator.stopAnimation(nil)\n        butLogin.isHidden = enabled\n    }\n    \n    func showProjects (_ projects: [String], selectedProject: String) {\n        projectNamePopup.removeAllItems()\n        projectNamePopup.addItems(withTitles: projects)\n        projectNamePopup.selectItem(withTitle: selectedProject)\n    }\n    \n    func showProjectIssues (_ issues: [String], selectedIssue: String) {\n        projectIssueNamePopup.removeAllItems()\n        projectIssueNamePopup.addItems(withTitles: issues)\n        projectIssueNamePopup.selectItem(withTitle: selectedIssue)\n    }\n    \n    func showErrorMessage (_ message: String) {\n        errorTextField.stringValue = message\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Onboarding/WizardJiraView.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"14109\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14109\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView id=\"c22-O7-iKe\" customClass=\"WizardJiraView\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"480\" height=\"193\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"FZB-Ef-4w6\">\n                    <rect key=\"frame\" x=\"20\" y=\"19\" width=\"45\" height=\"19\"/>\n                    <constraints>\n                        <constraint firstAttribute=\"width\" constant=\"45\" id=\"WW9-WH-elc\"/>\n                    </constraints>\n                    <buttonCell key=\"cell\" type=\"roundRect\" title=\"Login\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"8Ov-Ce-h1l\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"cellTitle\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleLoginButton:\" target=\"c22-O7-iKe\" id=\"y8c-he-X1O\"/>\n                    </connections>\n                </button>\n                <textField verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"ddN-ch-8MV\">\n                    <rect key=\"frame\" x=\"20\" y=\"141\" width=\"440\" height=\"22\"/>\n                    <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" borderStyle=\"bezel\" placeholderString=\"Jira url\" bezelStyle=\"round\" id=\"rVI-cb-kZN\">\n                        <font key=\"font\" metaFont=\"system\"/>\n                        <color key=\"textColor\" name=\"textColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                    </textFieldCell>\n                </textField>\n                <textField verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"909-Gm-xsJ\">\n                    <rect key=\"frame\" x=\"20\" y=\"109\" width=\"202\" height=\"22\"/>\n                    <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" borderStyle=\"bezel\" placeholderString=\"User\" bezelStyle=\"round\" id=\"iE3-Kn-2xo\">\n                        <font key=\"font\" metaFont=\"system\"/>\n                        <color key=\"textColor\" name=\"textColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                    </textFieldCell>\n                </textField>\n                <secureTextField verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"bE1-V5-9RC\">\n                    <rect key=\"frame\" x=\"259\" y=\"109\" width=\"201\" height=\"22\"/>\n                    <secureTextFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" borderStyle=\"bezel\" placeholderString=\"Password\" usesSingleLineMode=\"YES\" bezelStyle=\"round\" id=\"rxY-N0-6kh\">\n                        <font key=\"font\" metaFont=\"system\"/>\n                        <color key=\"textColor\" name=\"textColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <allowedInputSourceLocales>\n                            <string>NSAllRomanInputSourcesLocaleIdentifier</string>\n                        </allowedInputSourceLocales>\n                    </secureTextFieldCell>\n                </secureTextField>\n                <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"LPO-Ts-9kO\">\n                    <rect key=\"frame\" x=\"21\" y=\"70\" width=\"47\" height=\"17\"/>\n                    <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Project\" id=\"Lvu-lS-Vzz\">\n                        <font key=\"font\" metaFont=\"system\"/>\n                        <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                    </textFieldCell>\n                </textField>\n                <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"43i-u2-ZdK\">\n                    <rect key=\"frame\" x=\"313\" y=\"70\" width=\"36\" height=\"17\"/>\n                    <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Issue\" id=\"0LZ-HY-cPi\">\n                        <font key=\"font\" metaFont=\"system\"/>\n                        <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                    </textFieldCell>\n                </textField>\n                <popUpButton verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"ILK-Rr-ee4\">\n                    <rect key=\"frame\" x=\"79\" y=\"65\" width=\"105\" height=\"26\"/>\n                    <constraints>\n                        <constraint firstAttribute=\"width\" constant=\"100\" id=\"glB-Eh-1Hs\"/>\n                    </constraints>\n                    <popUpButtonCell key=\"cell\" type=\"push\" title=\"Item 1\" bezelStyle=\"rounded\" alignment=\"left\" lineBreakMode=\"truncatingTail\" state=\"on\" borderStyle=\"borderAndBezel\" imageScaling=\"proportionallyDown\" inset=\"2\" selectedItem=\"kwi-uS-QTc\" id=\"wSO-Fl-fdA\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"menu\"/>\n                        <menu key=\"menu\" id=\"kid-YB-bmS\">\n                            <items>\n                                <menuItem title=\"Item 1\" state=\"on\" id=\"kwi-uS-QTc\"/>\n                                <menuItem title=\"Item 2\" id=\"8ID-vb-hL5\"/>\n                                <menuItem title=\"Item 3\" id=\"lDy-3Y-BWl\"/>\n                            </items>\n                        </menu>\n                    </popUpButtonCell>\n                </popUpButton>\n                <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"lkx-YZ-zP5\">\n                    <rect key=\"frame\" x=\"71\" y=\"22\" width=\"411\" height=\"14\"/>\n                    <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Error\" id=\"qKv-oP-ffO\">\n                        <font key=\"font\" metaFont=\"smallSystem\"/>\n                        <color key=\"textColor\" red=\"0.82619418379999998\" green=\"0.18153228830000001\" blue=\"0.1534976841\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"displayP3\"/>\n                        <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                    </textFieldCell>\n                </textField>\n                <progressIndicator wantsLayer=\"YES\" horizontalHuggingPriority=\"750\" verticalHuggingPriority=\"750\" maxValue=\"100\" displayedWhenStopped=\"NO\" bezeled=\"NO\" indeterminate=\"YES\" controlSize=\"small\" style=\"spinning\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"WuL-5R-q9B\">\n                    <rect key=\"frame\" x=\"20\" y=\"21\" width=\"16\" height=\"16\"/>\n                </progressIndicator>\n                <popUpButton verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"sx8-DD-0di\">\n                    <rect key=\"frame\" x=\"358\" y=\"65\" width=\"105\" height=\"26\"/>\n                    <constraints>\n                        <constraint firstAttribute=\"height\" constant=\"21\" id=\"0pl-5G-y0H\"/>\n                        <constraint firstAttribute=\"width\" constant=\"100\" id=\"OFp-of-JC3\"/>\n                    </constraints>\n                    <popUpButtonCell key=\"cell\" type=\"push\" title=\"Item 1\" bezelStyle=\"rounded\" alignment=\"left\" lineBreakMode=\"truncatingTail\" state=\"on\" borderStyle=\"borderAndBezel\" imageScaling=\"proportionallyDown\" inset=\"2\" selectedItem=\"Lph-M9-kly\" id=\"UiG-Nf-mO0\">\n                        <behavior key=\"behavior\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"menu\"/>\n                        <menu key=\"menu\" id=\"drN-ez-MdR\">\n                            <items>\n                                <menuItem title=\"Item 1\" state=\"on\" id=\"Lph-M9-kly\"/>\n                                <menuItem title=\"Item 2\" id=\"EJE-fS-B9u\"/>\n                                <menuItem title=\"Item 3\" id=\"ZrO-Q1-NBm\"/>\n                            </items>\n                        </menu>\n                    </popUpButtonCell>\n                </popUpButton>\n            </subviews>\n            <constraints>\n                <constraint firstItem=\"FZB-Ef-4w6\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"20\" id=\"030-d2-11o\"/>\n                <constraint firstItem=\"LPO-Ts-9kO\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"23\" id=\"07b-eY-oes\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"ddN-ch-8MV\" secondAttribute=\"trailing\" constant=\"20\" id=\"1Fc-3C-yiL\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"lkx-YZ-zP5\" secondAttribute=\"trailing\" id=\"AIg-OJ-iM4\"/>\n                <constraint firstItem=\"ddN-ch-8MV\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" constant=\"30\" id=\"D3D-nc-sPo\"/>\n                <constraint firstItem=\"909-Gm-xsJ\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"20\" id=\"F2a-YY-36G\"/>\n                <constraint firstItem=\"ILK-Rr-ee4\" firstAttribute=\"centerY\" secondItem=\"LPO-Ts-9kO\" secondAttribute=\"centerY\" id=\"Fnt-EG-4CO\"/>\n                <constraint firstItem=\"bE1-V5-9RC\" firstAttribute=\"leading\" secondItem=\"909-Gm-xsJ\" secondAttribute=\"trailing\" constant=\"37\" id=\"Hyg-Tf-P9p\"/>\n                <constraint firstItem=\"FZB-Ef-4w6\" firstAttribute=\"centerY\" secondItem=\"lkx-YZ-zP5\" secondAttribute=\"centerY\" id=\"MBf-GQ-HC8\"/>\n                <constraint firstItem=\"43i-u2-ZdK\" firstAttribute=\"centerY\" secondItem=\"ILK-Rr-ee4\" secondAttribute=\"centerY\" id=\"RZx-Eg-tI5\"/>\n                <constraint firstItem=\"ddN-ch-8MV\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"20\" id=\"Syt-uM-nNm\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"FZB-Ef-4w6\" secondAttribute=\"bottom\" constant=\"20\" id=\"Ug3-V3-kWE\"/>\n                <constraint firstItem=\"bE1-V5-9RC\" firstAttribute=\"top\" secondItem=\"ddN-ch-8MV\" secondAttribute=\"bottom\" constant=\"10\" id=\"aCH-82-sCE\"/>\n                <constraint firstItem=\"ILK-Rr-ee4\" firstAttribute=\"leading\" secondItem=\"LPO-Ts-9kO\" secondAttribute=\"trailing\" constant=\"15\" id=\"dyv-NP-Jtb\"/>\n                <constraint firstItem=\"FZB-Ef-4w6\" firstAttribute=\"top\" secondItem=\"ILK-Rr-ee4\" secondAttribute=\"bottom\" constant=\"30\" id=\"eXh-H2-awc\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"sx8-DD-0di\" secondAttribute=\"trailing\" constant=\"20\" id=\"gJu-Ed-yi5\"/>\n                <constraint firstItem=\"lkx-YZ-zP5\" firstAttribute=\"leading\" secondItem=\"FZB-Ef-4w6\" secondAttribute=\"trailing\" constant=\"8\" id=\"gnw-Jj-Mfu\"/>\n                <constraint firstItem=\"909-Gm-xsJ\" firstAttribute=\"top\" secondItem=\"ddN-ch-8MV\" secondAttribute=\"bottom\" constant=\"10\" id=\"hR2-Yd-evk\"/>\n                <constraint firstItem=\"43i-u2-ZdK\" firstAttribute=\"centerY\" secondItem=\"sx8-DD-0di\" secondAttribute=\"centerY\" id=\"jWM-gK-e7p\"/>\n                <constraint firstItem=\"WuL-5R-q9B\" firstAttribute=\"leading\" secondItem=\"FZB-Ef-4w6\" secondAttribute=\"leading\" id=\"mxC-1X-Cxq\"/>\n                <constraint firstItem=\"909-Gm-xsJ\" firstAttribute=\"width\" secondItem=\"bE1-V5-9RC\" secondAttribute=\"width\" id=\"q2q-FG-mO2\"/>\n                <constraint firstItem=\"sx8-DD-0di\" firstAttribute=\"leading\" secondItem=\"43i-u2-ZdK\" secondAttribute=\"trailing\" constant=\"13\" id=\"sL8-Sz-37C\"/>\n                <constraint firstItem=\"ILK-Rr-ee4\" firstAttribute=\"top\" secondItem=\"909-Gm-xsJ\" secondAttribute=\"bottom\" constant=\"20\" id=\"sk8-o7-oKe\"/>\n                <constraint firstItem=\"WuL-5R-q9B\" firstAttribute=\"centerY\" secondItem=\"FZB-Ef-4w6\" secondAttribute=\"centerY\" id=\"sxT-jP-hb0\"/>\n                <constraint firstItem=\"sx8-DD-0di\" firstAttribute=\"top\" secondItem=\"bE1-V5-9RC\" secondAttribute=\"bottom\" constant=\"20\" id=\"uZh-wH-Zk7\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"bE1-V5-9RC\" secondAttribute=\"trailing\" constant=\"20\" id=\"vBk-01-KTt\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"baseUrlTextField\" destination=\"ddN-ch-8MV\" id=\"bGE-VI-UL1\"/>\n                <outlet property=\"butLogin\" destination=\"FZB-Ef-4w6\" id=\"385-UD-kQJ\"/>\n                <outlet property=\"errorTextField\" destination=\"lkx-YZ-zP5\" id=\"60C-mi-ae1\"/>\n                <outlet property=\"passwordTextField\" destination=\"bE1-V5-9RC\" id=\"8VL-kp-PaL\"/>\n                <outlet property=\"progressIndicator\" destination=\"WuL-5R-q9B\" id=\"dgC-FY-8wh\"/>\n                <outlet property=\"projectIssueNamePopup\" destination=\"sx8-DD-0di\" id=\"Tu1-lH-fLY\"/>\n                <outlet property=\"projectNamePopup\" destination=\"ILK-Rr-ee4\" id=\"oj3-MZ-eCG\"/>\n                <outlet property=\"userTextField\" destination=\"909-Gm-xsJ\" id=\"dVj-Rp-XZO\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"139\" y=\"130.5\"/>\n        </customView>\n    </objects>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Onboarding/WizardViewController.swift",
    "content": "//\n//  WizardViewController.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 16/04/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\nimport RCPreferences\nimport RCLog\n\nenum WizardStep: Int, CaseIterable {\n    case shell = 0\n    case browser = 1\n    case git = 2\n    case calendar = 3\n    case jira = 4\n}\n\nclass WizardViewController: NSViewController {\n    \n    weak var appWireframe: AppWireframe?\n    @IBOutlet private var titleLabel: NSTextField!\n    @IBOutlet private var subtitleLabel: NSTextField!\n    @IBOutlet private var containerView: NSView!\n    @IBOutlet private var containerViewHeightConstrain: NSLayoutConstraint!\n    private var contentView: NSView?\n    @IBOutlet private var butSkip: NSButton!\n    @IBOutlet private var levelIndicator: NSLevelIndicator!\n    private let pref = RCPreferences<LocalPreferences>()\n    private var step: WizardStep = WizardStep.shell\n    private let steps: [WizardStep] = [.shell, .browser, .git, .calendar, .jira]\n    private var stepsUnseen: [WizardStep] {\n        let stepsSaved: [Int] = pref.get(.wizardSteps)\n        let stepsSeen: [WizardStep] = stepsSaved.map({ WizardStep(rawValue: $0)! })\n        let unseen: [WizardStep] = steps.filter({ !stepsSeen.contains($0) })\n        return unseen\n    }\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        \n        createLayer()\n        levelIndicator.maxValue = Double(WizardStep.allCases.count)\n        if let wizardStep = stepsUnseen.first {\n            goTo(step: wizardStep)\n        }\n    }\n    \n    override func viewDidDisappear() {\n        super.viewDidDisappear()\n        removeCurrentContent()\n    }\n\n    deinit {\n        RCLog(\"deinit\")\n    }\n    \n    func goTo (step: WizardStep) {\n\n        removeCurrentContent()\n        self.step = step\n        levelIndicator.intValue = Int32(step.rawValue + 1)\n        switch step {\n        case .shell:\n            titleLabel.stringValue = \"Shell Support\"\n            subtitleLabel.stringValue = \"Jirassic needs shell support to communicate with Git and the Browser.\\nThe shell is accessed through an AppleScript which for security reasons you need to install manually.\"\n            let applescriptView = WizardAppleScriptView.instantiateFromXib()\n            applescriptView.titleLabel.stringValue = \"Install ShellSupport.scpt\"\n            applescriptView.subtitle = \"Go to jirassic.com, copy the install script and run it in your Terminal.app. We'll wait!\"\n            applescriptView.scriptName = kShellSupportScriptName\n            applescriptView.onSkip = { [weak self] in\n                if let wself = self {\n                    wself.handleNextButton(wself.butSkip)\n                }\n            }\n            containerView.addSubview(applescriptView)\n            applescriptView.constrainToSuperview()\n            contentView = applescriptView\n            containerViewHeightConstrain.constant = 114\n            break\n        case .browser:\n            titleLabel.stringValue = \"Browser Support\"\n            subtitleLabel.stringValue = \"Jirassic will be able to read the url of the active browser and it will detect when you do code reviews and when you waste time on social media.\"\n            let applescriptView = WizardAppleScriptView.instantiateFromXib()\n            applescriptView.titleLabel.stringValue = \"Install BrowserSupport.scpt\"\n            applescriptView.subtitle = \"Go to jirassic.com, copy the install script and run it in your Terminal. We'll wait!\"\n            applescriptView.scriptName = kBrowserSupportScriptName\n            applescriptView.onSkip = { [weak self] in\n                if let wself = self {\n                    wself.handleNextButton(wself.butSkip)\n                }\n            }\n            containerView.addSubview(applescriptView)\n            applescriptView.constrainToSuperview()\n            contentView = applescriptView\n            containerViewHeightConstrain.constant = 114\n            break\n        case .git:\n            titleLabel.stringValue = \"Git\"\n            subtitleLabel.stringValue = \"Include git commits in reports, to help you write more accurate worklogs. Chose the users and projects you want to track!\"\n            let gitView = WizardGitView.instantiateFromXib()\n            gitView.onSkip = { [weak self] in\n                if let wself = self {\n                    wself.handleNextButton(wself.butSkip)\n                }\n            }\n            containerView.addSubview(gitView)\n            gitView.constrainToSuperview()\n            contentView = gitView\n            containerViewHeightConstrain.constant = 114\n            break\n        case .calendar:\n            titleLabel.stringValue = \"Calendar.app\"\n            subtitleLabel.stringValue = \"Include calendar events in the reports and treat them as meetings. Please enable and select the calendars you use!\"\n            let calendarView = WizardCalendarView.instantiateFromXib()\n            calendarView.onSkip = { [weak self] in\n                if let wself = self {\n                    wself.handleNextButton(wself.butSkip)\n                }\n            }\n            containerView.addSubview(calendarView)\n            calendarView.constrainToSuperview()\n            contentView = calendarView\n            containerViewHeightConstrain.constant = 200\n            break\n        case .jira:\n            titleLabel.stringValue = \"Jira Tempo\"\n            subtitleLabel.stringValue = \"Jirassic can post your worklogs directly to Jira Tempo, very convenient and very fast. Please login then select the project and issue you want to post the worklogs to.\"\n            let jiraView = WizardJiraView.instantiateFromXib()\n            jiraView.onSkip = { [weak self] in\n                if let wself = self {\n                    wself.handleNextButton(wself.butSkip)\n                }\n            }\n            containerView.addSubview(jiraView)\n            jiraView.constrainToSuperview()\n            contentView = jiraView\n            containerViewHeightConstrain.constant = 114\n            butSkip.title = \"Finish setup\"\n            break\n        }\n    }\n\n    private func removeCurrentContent() {\n        if let view = contentView {\n            view.removeFromSuperview()\n            if let v = view as? WizardAppleScriptView {\n                v.invalidate()\n            }\n            contentView = nil\n        }\n    }\n    \n    @IBAction func handleNextButton (_ sender: NSButton) {\n        var stepsUnseen = self.stepsUnseen\n        let stepSeen = stepsUnseen.removeFirst()\n        if let nextStep = stepsUnseen.first {\n            goTo(step: nextStep)\n            let stepsSaved: [Int] = pref.get(.wizardSteps)\n            var stepsSeen: [WizardStep] = stepsSaved.map({ WizardStep(rawValue: $0)! })\n            stepsSeen.append(stepSeen)\n            stepsSeen.sort { (w1, w2) -> Bool in\n                w1.rawValue < w2.rawValue\n            }\n            let stepsToSave: [Int] = stepsSeen.map({ $0.rawValue })\n            pref.set(stepsToSave, forKey: .wizardSteps)\n        } else {\n            handleSkipButton(sender)\n        }\n    }\n    \n    @IBAction func handleSkipButton (_ sender: NSButton) {\n        let stepsToSave: [Int] = WizardStep.allCases.map({ $0.rawValue })\n        pref.set(stepsToSave, forKey: .wizardSteps)\n        appWireframe!.flipToTasksController()\n    }\n    \n    @IBAction func handleQuitAppButton (_ sender: NSButton) {\n        NSApplication.shared.terminate(nil)\n    }\n    \n    @IBAction func handleMinimizeAppButton (_ sender: NSButton) {\n        AppDelegate.sharedApp().menu.triggerClose()\n    }\n}\n\nextension WizardViewController: Animatable {\n    \n    func createLayer() {\n        view.layer = CALayer()\n        view.wantsLayer = true\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Placeholder/Placeholder.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14460.31\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Placeholder View Controller-->\n        <scene sceneID=\"GmZ-gD-vCb\">\n            <objects>\n                <customObject id=\"UqC-ap-ctp\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n                <viewController storyboardIdentifier=\"PlaceholderViewController\" id=\"eiK-MM-LiK\" customClass=\"PlaceholderViewController\" customModule=\"Jirassic\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" id=\"o3K-nw-a6h\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"450\" height=\"300\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                        <subviews>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"vXy-HK-p1X\">\n                                <rect key=\"frame\" x=\"183\" y=\"88\" width=\"84\" height=\"31\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"84\" id=\"U3c-3g-yGf\"/>\n                                    <constraint firstAttribute=\"height\" constant=\"30\" id=\"dy9-u4-0of\"/>\n                                </constraints>\n                                <buttonCell key=\"cell\" type=\"inline\" title=\"Start day\" bezelStyle=\"inline\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"FGE-Fq-6Z5\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"smallSystemBold\"/>\n                                </buttonCell>\n                                <color key=\"contentTintColor\" name=\"systemBlueColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                <connections>\n                                    <action selector=\"handleStartButton:\" target=\"eiK-MM-LiK\" id=\"Pxp-zE-b0E\"/>\n                                </connections>\n                            </button>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Icp-io-OfB\">\n                                <rect key=\"frame\" x=\"18\" y=\"139\" width=\"414\" height=\"22\"/>\n                                <textFieldCell key=\"cell\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" title=\"Ready to start working today?\" id=\"4yf-MA-WY8\">\n                                    <font key=\"font\" metaFont=\"system\" size=\"18\"/>\n                                    <color key=\"textColor\" name=\"windowFrameColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"pqi-kL-eQt\">\n                                <rect key=\"frame\" x=\"-2\" y=\"169\" width=\"454\" height=\"31\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"center\" title=\"Good morning!\" id=\"bZw-Ma-Ra6\">\n                                    <font key=\"font\" metaFont=\"system\" size=\"26\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                        </subviews>\n                        <constraints>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"pqi-kL-eQt\" secondAttribute=\"trailing\" id=\"EqZ-EB-3Hd\"/>\n                            <constraint firstAttribute=\"centerX\" secondItem=\"vXy-HK-p1X\" secondAttribute=\"centerX\" id=\"Jjz-id-Bhj\"/>\n                            <constraint firstItem=\"Icp-io-OfB\" firstAttribute=\"bottom\" secondItem=\"vXy-HK-p1X\" secondAttribute=\"bottom\" constant=\"-50\" id=\"QXN-Xc-iD9\"/>\n                            <constraint firstItem=\"Icp-io-OfB\" firstAttribute=\"leading\" secondItem=\"o3K-nw-a6h\" secondAttribute=\"leading\" constant=\"20\" id=\"Qwy-xs-YxL\"/>\n                            <constraint firstItem=\"Icp-io-OfB\" firstAttribute=\"top\" secondItem=\"pqi-kL-eQt\" secondAttribute=\"bottom\" constant=\"8\" id=\"c0N-1H-Xrc\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"Icp-io-OfB\" secondAttribute=\"trailing\" constant=\"20\" id=\"nab-tg-Fuv\"/>\n                            <constraint firstAttribute=\"centerY\" secondItem=\"Icp-io-OfB\" secondAttribute=\"centerY\" id=\"oiz-ur-I8h\"/>\n                            <constraint firstItem=\"pqi-kL-eQt\" firstAttribute=\"leading\" secondItem=\"o3K-nw-a6h\" secondAttribute=\"leading\" id=\"pyI-Nn-O1j\"/>\n                        </constraints>\n                    </view>\n                    <connections>\n                        <outlet property=\"button\" destination=\"vXy-HK-p1X\" id=\"p0f-i7-UEO\"/>\n                        <outlet property=\"messageLabel\" destination=\"Icp-io-OfB\" id=\"3ky-bK-VSS\"/>\n                        <outlet property=\"titleLabel\" destination=\"pqi-kL-eQt\" id=\"LBk-cK-a7e\"/>\n                    </connections>\n                </viewController>\n            </objects>\n            <point key=\"canvasLocation\" x=\"77\" y=\"-395\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Placeholder/PlaceholderViewController.swift",
    "content": "//\n//  PlaceholderViewController.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 06/05/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\nimport RCLog\n\ntypealias MessageViewModel = (title: String?, message: String?, buttonTitle: String?)\n\nclass PlaceholderViewController: NSViewController {\n\n    @IBOutlet fileprivate weak var titleLabel: NSTextField!\n    @IBOutlet fileprivate weak var messageLabel: NSTextField!\n    @IBOutlet fileprivate weak var button: NSButton!\n\t\n\tvar didPressButton: (() -> ())?\n\t\n    var viewModel: MessageViewModel? {\n        \n        didSet {\n            guard self.titleLabel != nil else {\n                fatalError(\"viewModel should be set after the VC is presented\")\n            }\n            if let title = viewModel?.title {\n                self.titleLabel?.stringValue = title\n            }\n            if let message = viewModel?.message {\n                self.messageLabel?.stringValue = message\n            }\n            if let buttonTitle = viewModel?.buttonTitle {\n                button?.isHidden = false\n                self.button?.title = buttonTitle\n            } else {\n                button?.isHidden = true\n            }\n        }\n    }\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n    }\n}\n\nextension PlaceholderViewController {\n\t\n\t@IBAction func handleStartButton (_ sender: NSButton) {\n        RCLog(sender)\n\t\tself.didPressButton?()\n\t}\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Input/Browser/BrowserCell.swift",
    "content": "//\n//  BrowserCell.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 01/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nclass BrowserCell: NSTableRowView {\n\n    static let height = CGFloat(270)\n    \n    @IBOutlet private var coderevImageView: NSImageView!\n    @IBOutlet private var coderevTextField: NSTextField!\n    @IBOutlet private var butInstallCoderev: NSButton!\n    @IBOutlet private var butTrackCodeReviews: NSButton!\n    @IBOutlet private var butTrackWastedTime: NSButton!\n    @IBOutlet private var codeReviewsLinkTextField: NSTextField!\n    @IBOutlet private var minCodeRevDurationLabel: NSTextField!\n    @IBOutlet private var minCodeRevDurationSlider: NSSlider!\n    @IBOutlet private var wastedTimeLinksTextField: NSTextField!\n    @IBOutlet private var minWasteDurationLabel: NSTextField!\n    @IBOutlet private var minWasteDurationSlider: NSSlider!\n    \n    func showSettings (_ settings: SettingsBrowser) {\n\n        butTrackCodeReviews.state = settings.trackCodeReviews ? NSControl.StateValue.on : NSControl.StateValue.off\n        butTrackWastedTime.state = settings.trackWastedTime ? NSControl.StateValue.on : NSControl.StateValue.off\n        codeReviewsLinkTextField.stringValue = settings.codeRevLink\n        wastedTimeLinksTextField.stringValue = settings.wasteLinks.toString()\n        minCodeRevDurationSlider.integerValue = settings.minCodeRevDuration\n        minWasteDurationSlider.integerValue = settings.minWasteDuration\n        handleMinCodeRevDuration( minCodeRevDurationSlider )\n        handleMinWasteDuration( minWasteDurationSlider )\n        enableCodeReview( settings.trackCodeReviews )\n        enableWastedTime( settings.trackWastedTime )\n    }\n\n    func settings() -> SettingsBrowser {\n        return SettingsBrowser(\n            trackCodeReviews: butTrackCodeReviews.state == NSControl.StateValue.on,\n            trackWastedTime: butTrackWastedTime.state == NSControl.StateValue.on,\n            minCodeRevDuration: minCodeRevDurationSlider.integerValue,\n            codeRevLink: codeReviewsLinkTextField.stringValue,\n            minWasteDuration: minWasteDurationSlider.integerValue,\n            wasteLinks: wastedTimeLinksTextField.stringValue.toArray()\n        )\n    }\n\n    func save() {\n\n    }\n    \n    func setBrowserStatus (compatibility: Compatibility) {\n        \n        if compatibility.available {\n            coderevImageView.image = NSImage(named: compatibility.compatible\n                ? NSImage.statusAvailableName\n                : NSImage.statusUnavailableName)\n            coderevTextField.stringValue = compatibility.compatible\n                ? \"Jirassic can read the url of your browser and it will log time based on it\"\n                : (compatibility.available\n                    ? \"Browser support installed but outdated, please update!\"\n                    : \"Browser support not installed, please install!\")\n        } else {\n            coderevImageView.image = NSImage(named: NSImage.statusUnavailableName)\n            coderevTextField.stringValue = \"Not installed yet\"\n        }\n        butInstallCoderev.isHidden = compatibility.available && compatibility.compatible\n    }\n    \n    func enableCodeReview (_ enable: Bool) {\n        codeReviewsLinkTextField.isEnabled = enable\n        minCodeRevDurationSlider.isEnabled = enable\n    }\n\n    func enableWastedTime (_ enable: Bool) {\n        wastedTimeLinksTextField.isEnabled = enable\n        minWasteDurationSlider.isEnabled = enable\n    }\n\n    @IBAction func handleCodeReviewButton (_ sender: NSButton) {\n        enableCodeReview(sender.state == NSControl.StateValue.on)\n    }\n\n    @IBAction func handleWastedTimeButton (_ sender: NSButton) {\n        enableWastedTime(sender.state == NSControl.StateValue.on)\n    }\n\n    @IBAction func handleInstallBrowserSupportButton (_ sender: NSButton) {\n        NSWorkspace.shared.open( URL(string: \"http://www.jirassic.com/#extensions\")!)\n    }\n\n    @IBAction func handleMinCodeRevDuration (_ sender: NSSlider) {\n        minCodeRevDurationLabel.stringValue = \"\\(sender.integerValue) min\"\n    }\n\n    @IBAction func handleMinWasteDuration (_ sender: NSSlider) {\n        minWasteDurationLabel.stringValue = \"\\(sender.integerValue) min\"\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Input/Browser/BrowserCell.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"14313.18\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14313.18\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView identifier=\"BrowserCell\" id=\"c22-O7-iKe\" customClass=\"BrowserCell\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"480\" height=\"269\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <box autoresizesSubviews=\"NO\" borderType=\"line\" title=\"Browser plugin\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"x9z-3V-m6f\">\n                    <rect key=\"frame\" x=\"-3\" y=\"-4\" width=\"486\" height=\"273\"/>\n                    <view key=\"contentView\" id=\"yhf-nW-mNO\">\n                        <rect key=\"frame\" x=\"1\" y=\"1\" width=\"484\" height=\"257\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <imageView horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"UMH-Mo-8NK\">\n                                <rect key=\"frame\" x=\"8\" y=\"219\" width=\"18\" height=\"18\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"18\" id=\"OSg-JO-JRc\"/>\n                                    <constraint firstAttribute=\"height\" constant=\"18\" id=\"XP0-Tv-H2T\"/>\n                                </constraints>\n                                <imageCell key=\"cell\" refusesFirstResponder=\"YES\" alignment=\"left\" imageScaling=\"proportionallyDown\" image=\"NSStatusNone\" id=\"IK4-2n-Z8e\"/>\n                            </imageView>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"SDw-Zo-fFC\">\n                                <rect key=\"frame\" x=\"30\" y=\"220\" width=\"189\" height=\"17\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Checking code review support\" id=\"G0Y-TN-r82\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"vGY-13-5C7\">\n                                <rect key=\"frame\" x=\"393\" y=\"219\" width=\"81\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"Instructions\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"uiK-GJ-cFU\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleInstallBrowserSupportButton:\" target=\"c22-O7-iKe\" id=\"fFv-nu-DAg\"/>\n                                </connections>\n                            </button>\n                            <button translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"jf7-bI-xVD\">\n                                <rect key=\"frame\" x=\"11\" y=\"112\" width=\"124\" height=\"18\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"120\" id=\"T9H-wE-jTQ\"/>\n                                </constraints>\n                                <buttonCell key=\"cell\" type=\"check\" title=\"Code reviews\" bezelStyle=\"regularSquare\" imagePosition=\"left\" state=\"on\" inset=\"2\" id=\"OHE-XF-4Xm\">\n                                    <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleCodeReviewButton:\" target=\"c22-O7-iKe\" id=\"HpS-Rd-uun\"/>\n                                </connections>\n                            </button>\n                            <button translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"HAL-xr-Jo3\">\n                                <rect key=\"frame\" x=\"11\" y=\"48\" width=\"124\" height=\"18\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"120\" id=\"wHy-Sq-kbz\"/>\n                                </constraints>\n                                <buttonCell key=\"cell\" type=\"check\" title=\"Social &amp; Media\" bezelStyle=\"regularSquare\" imagePosition=\"left\" state=\"on\" inset=\"2\" id=\"497-Wz-hcA\">\n                                    <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleWastedTimeButton:\" target=\"c22-O7-iKe\" id=\"1SW-PO-ViW\"/>\n                                </connections>\n                            </button>\n                            <box verticalHuggingPriority=\"750\" boxType=\"separator\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"yt9-eY-Kha\">\n                                <rect key=\"frame\" x=\"32\" y=\"145\" width=\"437\" height=\"5\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"1\" id=\"9gC-MV-EGQ\"/>\n                                </constraints>\n                            </box>\n                            <slider verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"GeU-aa-ZaF\">\n                                <rect key=\"frame\" x=\"11\" y=\"89\" width=\"82\" height=\"19\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"15\" id=\"HLn-h4-yEW\"/>\n                                </constraints>\n                                <sliderCell key=\"cell\" continuous=\"YES\" state=\"on\" alignment=\"left\" minValue=\"1\" maxValue=\"10\" doubleValue=\"2\" tickMarkPosition=\"above\" sliderType=\"linear\" id=\"oTh-a3-gDg\"/>\n                                <connections>\n                                    <action selector=\"handleMinCodeRevDuration:\" target=\"c22-O7-iKe\" id=\"Utf-L9-O8n\"/>\n                                </connections>\n                            </slider>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Soi-9n-x1W\">\n                                <rect key=\"frame\" x=\"97\" y=\"91\" width=\"36\" height=\"16\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"5 min\" id=\"QNH-dX-J72\">\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <slider verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Mfq-fM-cOv\">\n                                <rect key=\"frame\" x=\"11\" y=\"23\" width=\"82\" height=\"19\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"15\" id=\"8G5-pv-mgY\"/>\n                                </constraints>\n                                <sliderCell key=\"cell\" continuous=\"YES\" state=\"on\" alignment=\"left\" minValue=\"1\" maxValue=\"10\" doubleValue=\"5\" tickMarkPosition=\"above\" sliderType=\"linear\" id=\"eR2-ny-v3K\"/>\n                                <connections>\n                                    <action selector=\"handleMinWasteDuration:\" target=\"c22-O7-iKe\" id=\"DFD-k3-Jzq\"/>\n                                </connections>\n                            </slider>\n                            <textField verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"eFD-1x-dMu\">\n                                <rect key=\"frame\" x=\"139\" y=\"24\" width=\"330\" height=\"40\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"40\" id=\"uXa-Xv-xsD\"/>\n                                </constraints>\n                                <textFieldCell key=\"cell\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" borderStyle=\"border\" placeholderString=\"URLs separated by comma\" id=\"6Kj-ij-uTX\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"E42-ax-52b\">\n                                <rect key=\"frame\" x=\"30\" y=\"163\" width=\"445\" height=\"42\"/>\n                                <textFieldCell key=\"cell\" sendsActionOnEndEditing=\"YES\" id=\"hH6-QD-v2h\">\n                                    <font key=\"font\" metaFont=\"smallSystem\"/>\n                                    <string key=\"title\">When one of the supported browsers is active, Jirassic reads the url and when matches one defined below for at least the minimum defined duration, tracks the time accordingly. A spinner will show next to the app icon when url is read</string>\n                                    <color key=\"textColor\" name=\"disabledControlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"ygP-CN-aYt\">\n                                <rect key=\"frame\" x=\"140\" y=\"88\" width=\"329\" height=\"40\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"40\" id=\"ZYV-c3-3Fd\"/>\n                                </constraints>\n                                <textFieldCell key=\"cell\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" borderStyle=\"border\" placeholderString=\"URLs and REGEXs matching code reviews pages separated by comma\" id=\"04D-75-WRj\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"ben-v1-cTm\">\n                                <rect key=\"frame\" x=\"95\" y=\"25\" width=\"43\" height=\"16\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"23 min\" id=\"ueG-WU-Myh\">\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"SDw-Zo-fFC\" firstAttribute=\"leading\" secondItem=\"UMH-Mo-8NK\" secondAttribute=\"trailing\" constant=\"6\" id=\"04V-Zv-IRg\"/>\n                            <constraint firstItem=\"yt9-eY-Kha\" firstAttribute=\"top\" secondItem=\"E42-ax-52b\" secondAttribute=\"bottom\" constant=\"15\" id=\"1DH-Zv-aQl\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"vGY-13-5C7\" secondAttribute=\"trailing\" constant=\"10\" id=\"465-QI-Fsw\"/>\n                            <constraint firstItem=\"HAL-xr-Jo3\" firstAttribute=\"leading\" secondItem=\"yhf-nW-mNO\" secondAttribute=\"leading\" constant=\"13\" id=\"BFT-1O-ZkR\"/>\n                            <constraint firstItem=\"GeU-aa-ZaF\" firstAttribute=\"top\" secondItem=\"jf7-bI-xVD\" secondAttribute=\"bottom\" constant=\"8\" id=\"E1R-Pb-Wzg\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"eFD-1x-dMu\" secondAttribute=\"trailing\" constant=\"15\" id=\"HFo-go-uRv\"/>\n                            <constraint firstItem=\"E42-ax-52b\" firstAttribute=\"top\" secondItem=\"SDw-Zo-fFC\" secondAttribute=\"bottom\" constant=\"15\" id=\"HSr-dh-FLk\"/>\n                            <constraint firstItem=\"GeU-aa-ZaF\" firstAttribute=\"leading\" secondItem=\"yhf-nW-mNO\" secondAttribute=\"leading\" constant=\"13\" id=\"Kaa-5v-vJj\"/>\n                            <constraint firstItem=\"E42-ax-52b\" firstAttribute=\"leading\" secondItem=\"yhf-nW-mNO\" secondAttribute=\"leading\" constant=\"32\" id=\"LIq-iO-OH6\"/>\n                            <constraint firstItem=\"ben-v1-cTm\" firstAttribute=\"centerY\" secondItem=\"Mfq-fM-cOv\" secondAttribute=\"centerY\" id=\"M2y-Dd-BzX\"/>\n                            <constraint firstItem=\"SDw-Zo-fFC\" firstAttribute=\"centerY\" secondItem=\"UMH-Mo-8NK\" secondAttribute=\"centerY\" id=\"MLW-hH-Qaj\"/>\n                            <constraint firstItem=\"eFD-1x-dMu\" firstAttribute=\"leading\" secondItem=\"HAL-xr-Jo3\" secondAttribute=\"trailing\" constant=\"6\" id=\"UDV-QL-5bX\"/>\n                            <constraint firstItem=\"Mfq-fM-cOv\" firstAttribute=\"top\" secondItem=\"HAL-xr-Jo3\" secondAttribute=\"bottom\" constant=\"10\" id=\"WFp-dA-96I\"/>\n                            <constraint firstItem=\"vGY-13-5C7\" firstAttribute=\"centerY\" secondItem=\"SDw-Zo-fFC\" secondAttribute=\"centerY\" id=\"Wf0-8a-hx7\"/>\n                            <constraint firstItem=\"UMH-Mo-8NK\" firstAttribute=\"top\" secondItem=\"yhf-nW-mNO\" secondAttribute=\"top\" constant=\"20\" id=\"aCa-L7-EV1\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"E42-ax-52b\" secondAttribute=\"trailing\" constant=\"11\" id=\"aWp-uV-gmf\"/>\n                            <constraint firstItem=\"eFD-1x-dMu\" firstAttribute=\"leading\" secondItem=\"ben-v1-cTm\" secondAttribute=\"trailing\" constant=\"3\" id=\"b6o-HO-Tkh\"/>\n                            <constraint firstItem=\"HAL-xr-Jo3\" firstAttribute=\"top\" secondItem=\"jf7-bI-xVD\" secondAttribute=\"bottom\" constant=\"50\" id=\"bAq-Y3-GQA\"/>\n                            <constraint firstItem=\"Soi-9n-x1W\" firstAttribute=\"leading\" secondItem=\"GeU-aa-ZaF\" secondAttribute=\"trailing\" constant=\"8\" id=\"blG-Di-3Pd\"/>\n                            <constraint firstItem=\"GeU-aa-ZaF\" firstAttribute=\"centerY\" secondItem=\"Soi-9n-x1W\" secondAttribute=\"centerY\" id=\"cN8-RV-PnO\"/>\n                            <constraint firstItem=\"yt9-eY-Kha\" firstAttribute=\"leading\" secondItem=\"yhf-nW-mNO\" secondAttribute=\"leading\" constant=\"32\" id=\"edr-VI-1fg\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"ygP-CN-aYt\" secondAttribute=\"trailing\" constant=\"15\" id=\"f01-X6-1e0\"/>\n                            <constraint firstItem=\"ben-v1-cTm\" firstAttribute=\"leading\" secondItem=\"Mfq-fM-cOv\" secondAttribute=\"trailing\" constant=\"6\" id=\"j6z-3R-Wgr\"/>\n                            <constraint firstItem=\"Mfq-fM-cOv\" firstAttribute=\"leading\" secondItem=\"yhf-nW-mNO\" secondAttribute=\"leading\" constant=\"13\" id=\"lCd-8a-pvV\"/>\n                            <constraint firstItem=\"ygP-CN-aYt\" firstAttribute=\"leading\" secondItem=\"jf7-bI-xVD\" secondAttribute=\"trailing\" constant=\"7\" id=\"ldJ-jc-5Tb\"/>\n                            <constraint firstItem=\"ygP-CN-aYt\" firstAttribute=\"top\" secondItem=\"jf7-bI-xVD\" secondAttribute=\"top\" id=\"ong-mj-xD7\"/>\n                            <constraint firstItem=\"ygP-CN-aYt\" firstAttribute=\"leading\" secondItem=\"Soi-9n-x1W\" secondAttribute=\"trailing\" constant=\"9\" id=\"pAM-cU-i3l\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"yt9-eY-Kha\" secondAttribute=\"trailing\" constant=\"15\" id=\"rJw-XN-mbG\"/>\n                            <constraint firstItem=\"jf7-bI-xVD\" firstAttribute=\"leading\" secondItem=\"yhf-nW-mNO\" secondAttribute=\"leading\" constant=\"13\" id=\"t2A-1G-aOg\"/>\n                            <constraint firstItem=\"UMH-Mo-8NK\" firstAttribute=\"leading\" secondItem=\"yhf-nW-mNO\" secondAttribute=\"leading\" constant=\"8\" id=\"uzD-bx-KdP\"/>\n                            <constraint firstItem=\"jf7-bI-xVD\" firstAttribute=\"top\" secondItem=\"yt9-eY-Kha\" secondAttribute=\"bottom\" constant=\"19\" id=\"vdZ-Mq-ecG\"/>\n                            <constraint firstItem=\"eFD-1x-dMu\" firstAttribute=\"top\" secondItem=\"HAL-xr-Jo3\" secondAttribute=\"top\" id=\"yc8-pv-o7g\"/>\n                        </constraints>\n                    </view>\n                </box>\n            </subviews>\n            <constraints>\n                <constraint firstItem=\"x9z-3V-m6f\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" id=\"3LM-Bg-0If\"/>\n                <constraint firstItem=\"x9z-3V-m6f\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" id=\"8e5-Pm-cQv\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"x9z-3V-m6f\" secondAttribute=\"bottom\" id=\"lvN-Yp-YZs\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"x9z-3V-m6f\" secondAttribute=\"trailing\" id=\"vlA-0C-XeH\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"butInstallCoderev\" destination=\"vGY-13-5C7\" id=\"eid-CY-eD1\"/>\n                <outlet property=\"butTrackCodeReviews\" destination=\"jf7-bI-xVD\" id=\"PWl-MC-Zdy\"/>\n                <outlet property=\"butTrackWastedTime\" destination=\"HAL-xr-Jo3\" id=\"dnX-y4-L74\"/>\n                <outlet property=\"codeReviewsLinkTextField\" destination=\"ygP-CN-aYt\" id=\"Wq1-0G-3Ev\"/>\n                <outlet property=\"coderevImageView\" destination=\"UMH-Mo-8NK\" id=\"xes-N0-uN6\"/>\n                <outlet property=\"coderevTextField\" destination=\"SDw-Zo-fFC\" id=\"Vb0-ip-kRo\"/>\n                <outlet property=\"minCodeRevDurationLabel\" destination=\"Soi-9n-x1W\" id=\"1HR-tC-Psz\"/>\n                <outlet property=\"minCodeRevDurationSlider\" destination=\"GeU-aa-ZaF\" id=\"JWv-92-EFw\"/>\n                <outlet property=\"minWasteDurationLabel\" destination=\"ben-v1-cTm\" id=\"3Tf-ed-s8J\"/>\n                <outlet property=\"minWasteDurationSlider\" destination=\"Mfq-fM-cOv\" id=\"MBz-zQ-A2x\"/>\n                <outlet property=\"wastedTimeLinksTextField\" destination=\"eFD-1x-dMu\" id=\"mmY-Xc-DIY\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"139\" y=\"218.5\"/>\n        </customView>\n    </objects>\n    <resources>\n        <image name=\"NSStatusNone\" width=\"16\" height=\"16\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Input/Browser/BrowserPresenter.swift",
    "content": "//\n//  BrowserPresenter.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 01/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Input/Calendar/CalendarCell.swift",
    "content": "//\n//  CalendarCell.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 05/07/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nclass CalendarCell: NSTableRowView {\n    \n    static let height = CGFloat(200)\n    \n    @IBOutlet private var statusImageView: NSImageView!\n    @IBOutlet private var statusTextField: NSTextField!\n    @IBOutlet private var descriptionTextField: NSTextField!\n    @IBOutlet private var butAuthorize: NSButton!\n    @IBOutlet private var butEnable: NSButton!\n    @IBOutlet private var scrollView: NSScrollView!\n    private var calendarsButtons = [NSButton]()\n    \n    private var  presenter: CalendarPresenterInput = CalendarPresenter()\n    \n    override func awakeFromNib() {\n        super.awakeFromNib()\n        (presenter as! CalendarPresenter).userInterface = self\n        presenter.refresh()\n    }\n    \n    func save() {\n        // Nothing to save\n    }\n    \n    @IBAction func handleAuthorizeButton (_ sender: NSButton) {\n        presenter.authorize()\n    }\n    \n    @IBAction func handleEnableButton (_ sender: NSButton) {\n        presenter.enable(sender.state == .on)\n    }\n    \n    override func layout() {\n        super.layout()\n        \n        var x = CGFloat(0)\n        var y = CGFloat(0)\n        for but in calendarsButtons {\n            if x + but.frame.size.width > scrollView.frame.size.width {\n                y += 26\n                x = CGFloat(0)\n            }\n            but.frame = CGRect(x: x, y: y, width: but.frame.size.width, height: but.frame.size.height)\n            x += but.frame.size.width + 10\n        }\n        scrollView.documentView?.setFrameSize(NSSize(width: 0, height: y + 26))\n    }\n}\n\nextension CalendarCell: CalendarPresenterOutput {\n    \n    func enable (_ enabled: Bool) {\n        for but in calendarsButtons {\n            but.isEnabled = enabled\n        }\n    }\n    \n    func setStatusImage (_ imageName: NSImage.Name) {\n        statusImageView.image = NSImage(named: imageName)\n    }\n    \n    func setStatusText (_ text: String) {\n        statusTextField.stringValue = text\n    }\n    \n    func setDescriptionText (_ text: String) {\n        descriptionTextField.stringValue = text\n    }\n    \n    func setCalendarStatus (authorized: Bool, enabled: Bool) {\n        statusImageView.isHidden = authorized\n        butAuthorize.isHidden = authorized\n        butEnable.isHidden = !authorized\n        butEnable.state = enabled ? NSControl.StateValue.on : NSControl.StateValue.off\n    }\n\n    func setCalendars (_ calendars: [String], selected: [String]) {\n\n        for but in calendarsButtons {\n            but.removeFromSuperview()\n        }\n        calendarsButtons = []\n        \n        for title in calendars {\n            let but = NSButton()\n            but.setButtonType(.switch)\n            but.title = title\n            but.sizeToFit()\n            but.state = selected.contains(title) ? .on : .off\n            but.target = self\n            but.action = #selector(didClickCalendarButton)\n            scrollView.addSubview(but)\n            self.calendarsButtons.append(but)\n        }\n        self.needsLayout = true\n    }\n\n    @objc func didClickCalendarButton (_ sender: NSButton) {\n        if sender.state == .on {\n            presenter.enableCalendar(sender.title)\n        } else {\n            presenter.disableCalendar(sender.title)\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Input/Calendar/CalendarCell.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14460.31\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView identifier=\"CalendarCell\" id=\"c22-O7-iKe\" customClass=\"CalendarCell\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"480\" height=\"195\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <box autoresizesSubviews=\"NO\" borderType=\"line\" title=\"Calendar.app\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"RQm-ST-fW3\">\n                    <rect key=\"frame\" x=\"-3\" y=\"-4\" width=\"486\" height=\"199\"/>\n                    <view key=\"contentView\" id=\"bAm-pg-lwW\">\n                        <rect key=\"frame\" x=\"3\" y=\"3\" width=\"480\" height=\"181\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <imageView horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"soa-Mf-B56\">\n                                <rect key=\"frame\" x=\"8\" y=\"143\" width=\"18\" height=\"18\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"18\" id=\"UD3-CQ-0Cq\"/>\n                                    <constraint firstAttribute=\"width\" constant=\"18\" id=\"WP7-bD-H6R\"/>\n                                </constraints>\n                                <imageCell key=\"cell\" refusesFirstResponder=\"YES\" alignment=\"left\" imageScaling=\"proportionallyDown\" image=\"NSStatusNone\" id=\"g96-Mm-inb\"/>\n                            </imageView>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"UaJ-WV-hc1\">\n                                <rect key=\"frame\" x=\"30\" y=\"144\" width=\"176\" height=\"17\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Calendar.app not authorized\" id=\"ASn-hr-APm\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"y1X-Wf-3ng\">\n                                <rect key=\"frame\" x=\"401\" y=\"142\" width=\"69\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"Authorize\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"HFX-xw-W3U\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleAuthorizeButton:\" target=\"c22-O7-iKe\" id=\"BSd-KR-FGc\"/>\n                                </connections>\n                            </button>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"7Et-wb-aOF\">\n                                <rect key=\"frame\" x=\"31\" y=\"111\" width=\"441\" height=\"14\"/>\n                                <textFieldCell key=\"cell\" sendsActionOnEndEditing=\"YES\" title=\"Events from the selected calendars will appear in Jirassic as meetings\" id=\"icW-RF-Xg3\">\n                                    <font key=\"font\" metaFont=\"smallSystem\"/>\n                                    <color key=\"textColor\" name=\"disabledControlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"U0o-hB-0FO\">\n                                <rect key=\"frame\" x=\"10\" y=\"143\" width=\"22\" height=\"18\"/>\n                                <buttonCell key=\"cell\" type=\"check\" bezelStyle=\"regularSquare\" imagePosition=\"left\" state=\"on\" inset=\"2\" id=\"a8i-lq-vV3\">\n                                    <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleEnableButton:\" target=\"c22-O7-iKe\" id=\"wzF-kw-Tcs\"/>\n                                </connections>\n                            </button>\n                            <scrollView borderType=\"none\" horizontalLineScroll=\"10\" horizontalPageScroll=\"10\" verticalLineScroll=\"10\" verticalPageScroll=\"10\" usesPredominantAxisScrolling=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"c9X-tX-mPm\">\n                                <rect key=\"frame\" x=\"30\" y=\"0.0\" width=\"450\" height=\"94\"/>\n                                <clipView key=\"contentView\" drawsBackground=\"NO\" copiesOnScroll=\"NO\" id=\"Fap-3U-t1t\">\n                                    <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"450\" height=\"94\"/>\n                                    <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                    <subviews>\n                                        <view fixedFrame=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"1o2-Py-xoW\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"435\" height=\"79\"/>\n                                            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                        </view>\n                                    </subviews>\n                                    <color key=\"backgroundColor\" white=\"0.0\" alpha=\"0.0\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                </clipView>\n                                <scroller key=\"horizontalScroller\" wantsLayer=\"YES\" verticalHuggingPriority=\"750\" horizontal=\"YES\" id=\"THh-n7-dWZ\">\n                                    <rect key=\"frame\" x=\"0.0\" y=\"78\" width=\"450\" height=\"16\"/>\n                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                </scroller>\n                                <scroller key=\"verticalScroller\" wantsLayer=\"YES\" verticalHuggingPriority=\"750\" doubleValue=\"1\" horizontal=\"NO\" id=\"UBi-zR-YG5\">\n                                    <rect key=\"frame\" x=\"434\" y=\"0.0\" width=\"16\" height=\"94\"/>\n                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                </scroller>\n                            </scrollView>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"7Et-wb-aOF\" firstAttribute=\"leading\" secondItem=\"bAm-pg-lwW\" secondAttribute=\"leading\" constant=\"33\" id=\"9Fc-i0-3re\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"7Et-wb-aOF\" secondAttribute=\"trailing\" constant=\"10\" id=\"ANi-YY-aQS\"/>\n                            <constraint firstItem=\"c9X-tX-mPm\" firstAttribute=\"leading\" secondItem=\"bAm-pg-lwW\" secondAttribute=\"leading\" constant=\"30\" id=\"DTs-rh-FPP\"/>\n                            <constraint firstItem=\"UaJ-WV-hc1\" firstAttribute=\"top\" secondItem=\"soa-Mf-B56\" secondAttribute=\"top\" id=\"FbD-qf-Pro\"/>\n                            <constraint firstItem=\"soa-Mf-B56\" firstAttribute=\"top\" secondItem=\"bAm-pg-lwW\" secondAttribute=\"top\" constant=\"20\" id=\"I1j-nR-ahD\"/>\n                            <constraint firstItem=\"c9X-tX-mPm\" firstAttribute=\"top\" secondItem=\"7Et-wb-aOF\" secondAttribute=\"bottom\" constant=\"17\" id=\"JQS-62-BV9\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"c9X-tX-mPm\" secondAttribute=\"trailing\" id=\"NTb-Tm-yw3\"/>\n                            <constraint firstItem=\"U0o-hB-0FO\" firstAttribute=\"centerY\" secondItem=\"y1X-Wf-3ng\" secondAttribute=\"centerY\" id=\"S5x-AY-5qS\"/>\n                            <constraint firstItem=\"U0o-hB-0FO\" firstAttribute=\"leading\" secondItem=\"bAm-pg-lwW\" secondAttribute=\"leading\" constant=\"12\" id=\"Tnp-wc-yFA\"/>\n                            <constraint firstItem=\"soa-Mf-B56\" firstAttribute=\"leading\" secondItem=\"bAm-pg-lwW\" secondAttribute=\"leading\" constant=\"8\" id=\"c5n-pB-uts\"/>\n                            <constraint firstItem=\"y1X-Wf-3ng\" firstAttribute=\"top\" secondItem=\"soa-Mf-B56\" secondAttribute=\"top\" id=\"cMm-zD-JqY\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"c9X-tX-mPm\" secondAttribute=\"bottom\" id=\"cXO-fJ-ChF\"/>\n                            <constraint firstItem=\"UaJ-WV-hc1\" firstAttribute=\"leading\" secondItem=\"soa-Mf-B56\" secondAttribute=\"trailing\" constant=\"6\" id=\"cxN-iS-Ne9\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"y1X-Wf-3ng\" secondAttribute=\"trailing\" constant=\"10\" id=\"dRf-Za-uMg\"/>\n                            <constraint firstItem=\"7Et-wb-aOF\" firstAttribute=\"top\" secondItem=\"y1X-Wf-3ng\" secondAttribute=\"bottom\" constant=\"18\" id=\"wmC-yn-XDa\"/>\n                        </constraints>\n                    </view>\n                </box>\n            </subviews>\n            <constraints>\n                <constraint firstAttribute=\"trailing\" secondItem=\"RQm-ST-fW3\" secondAttribute=\"trailing\" id=\"BYR-JA-3Lb\"/>\n                <constraint firstItem=\"RQm-ST-fW3\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" id=\"JBL-AC-Gsa\"/>\n                <constraint firstItem=\"RQm-ST-fW3\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" id=\"LjE-yW-nNP\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"RQm-ST-fW3\" secondAttribute=\"bottom\" id=\"PzK-Ow-0JE\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"butAuthorize\" destination=\"y1X-Wf-3ng\" id=\"5gE-bJ-ABa\"/>\n                <outlet property=\"butEnable\" destination=\"U0o-hB-0FO\" id=\"iNX-FA-XZY\"/>\n                <outlet property=\"descriptionTextField\" destination=\"7Et-wb-aOF\" id=\"FQd-qN-OOK\"/>\n                <outlet property=\"scrollView\" destination=\"c9X-tX-mPm\" id=\"Bbe-Ag-RPI\"/>\n                <outlet property=\"statusImageView\" destination=\"soa-Mf-B56\" id=\"RNd-RY-fIT\"/>\n                <outlet property=\"statusTextField\" destination=\"UaJ-WV-hc1\" id=\"81X-oh-Xbi\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"139\" y=\"190.5\"/>\n        </customView>\n    </objects>\n    <resources>\n        <image name=\"NSStatusNone\" width=\"16\" height=\"16\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Input/Calendar/CalendarPresenter.swift",
    "content": "//\n//  CalendarPresenter.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 05/07/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport Cocoa\nimport RCPreferences\n\nprotocol CalendarPresenterInput: class {\n    \n    func enable (_ enabled: Bool)\n    func enableCalendar (_ calendarTitle: String)\n    func disableCalendar (_ calendarTitle: String)\n    func refresh ()\n    func authorize()\n}\n\nprotocol CalendarPresenterOutput: class {\n    \n    func enable (_ enabled: Bool)\n    func setStatusImage (_ imageName: NSImage.Name)\n    func setStatusText (_ text: String)\n    func setDescriptionText (_ text: String)\n    func setCalendarStatus (authorized: Bool, enabled: Bool)\n    func setCalendars (_ calendars: [String], selected: [String])\n}\n\nclass CalendarPresenter {\n    \n    weak var userInterface: CalendarPresenterOutput?\n    private let calendarModule = ModuleCalendar()\n    private let pref = RCPreferences<LocalPreferences>()\n}\n\nextension CalendarPresenter: CalendarPresenterInput {\n\n    func enable (_ enabled: Bool) {\n        pref.set(enabled, forKey: .enableCalendar)\n        userInterface!.enable(enabled)\n    }\n\n    func enableCalendar (_ calendarTitle: String) {\n        var calendars = calendarModule.selectedCalendars\n        calendars.append(calendarTitle)\n        calendarModule.selectedCalendars = calendars\n    }\n\n    func disableCalendar (_ calendarTitle: String) {\n        let calendars = calendarModule.selectedCalendars.filter() { $0 != calendarTitle }\n        calendarModule.selectedCalendars = calendars\n    }\n\n    func authorize() {\n        calendarModule.authorize { (authorized) in\n            DispatchQueue.main.async {\n                self.refresh()\n            }\n        }\n    }\n    \n    func refresh() {\n        \n        if calendarModule.isAuthorizationDetermined {\n            userInterface!.setStatusImage(calendarModule.isAuthorized ? NSImage.statusAvailableName : NSImage.statusPartiallyAvailableName)\n            userInterface!.setStatusText(calendarModule.isAuthorized ? \"Calendar.app is accessible and ready to use\" : \"Calendar.app is not authorized\")\n            userInterface!.setDescriptionText(calendarModule.isAuthorized ? \"Events from the selected calendars will appear in Jirassic as tasks\" : \"Authorize from: System Preferences / Security&Privacy / Privacy / Calendars\")\n            userInterface!.setCalendarStatus (authorized: calendarModule.isAuthorized, enabled: pref.bool(.enableCalendar))\n        } else {\n            userInterface!.setStatusImage(NSImage.statusUnavailableName)\n            userInterface!.setStatusText(\"Calendar.app was not authorized yet\")\n            userInterface!.setCalendarStatus (authorized: calendarModule.isAuthorized, enabled: pref.bool(.enableCalendar))\n        }\n        userInterface!.setCalendars(calendarModule.allCalendarsTitles(), selected: calendarModule.selectedCalendars)\n        userInterface!.enable(calendarModule.isAuthorized && pref.bool(.enableCalendar))\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Input/Git/GitCell.swift",
    "content": "//\n//  GitCell.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 01/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nclass GitCell: NSTableRowView, Saveable {\n\n    static let height = CGFloat(195)\n    \n    @IBOutlet private var statusImageView: NSImageView!\n    @IBOutlet private var butEnable: NSButton!\n    @IBOutlet private var statusTextField: NSTextField!\n    @IBOutlet private var descriptionTextField: NSTextField!\n    @IBOutlet private var emailsTextField: NSTextField!\n    @IBOutlet private var pathsTextField: NSTextField!\n    @IBOutlet private var butInstall: NSButton!\n    @IBOutlet private var butPurchase: NSButton!\n    @IBOutlet private var butPick: NSButton!\n\n    var presenter: GitPresenterInput = GitPresenter()\n    var onPurchasePressed: (() -> Void)?\n    private var emailClickGestureRecognizer: NSClickGestureRecognizer?\n    private var gitUsersPopover: NSPopover?\n\n    override func awakeFromNib() {\n        super.awakeFromNib()\n        (presenter as! GitPresenter).userInterface = self\n        butEnable.isHidden = true\n        butPurchase.isHidden = true\n        emailsTextField.delegate = self\n        pathsTextField.delegate = self\n        \n        let emailClickGestureRecognizer = NSClickGestureRecognizer(target: self, action: #selector(GitCell.emailTextFieldClicked))\n        emailsTextField.addGestureRecognizer(emailClickGestureRecognizer)\n        self.emailClickGestureRecognizer = emailClickGestureRecognizer\n    }\n    \n    deinit {\n        if  let gesture = emailClickGestureRecognizer {\n            emailsTextField.removeGestureRecognizer(gesture)\n        }\n    }\n    \n    func save() {\n        presenter.save(emails: emailsTextField.stringValue, paths: pathsTextField.stringValue)\n    }\n    \n    @IBAction func handleInstallButton (_ sender: NSButton) {\n        #if APPSTORE\n            NSWorkspace.shared.open( URL(string: \"http://www.jirassic.com/#extensions\")!)\n        #else\n            NSWorkspace.shared.open( URL(string: \"https://github.com/ralcr/Jit\")!)\n        #endif\n    }\n    \n    @IBAction func handlePurchaseButton (_ sender: NSButton) {\n        onPurchasePressed?()\n    }\n    \n    @IBAction func handleEnableButton (_ sender: NSButton) {\n        presenter.enableGit(sender.state == .on)\n    }\n    \n    @IBAction func handlePickButton (_ sender: NSButton) {\n        presenter.pickPath()\n    }\n    \n    @objc func emailTextFieldClicked() {\n        guard gitUsersPopover == nil else {\n            return\n        }\n        let popover = NSPopover()\n        let view = GitUsersViewController.instantiateFromStoryboard(\"Components\")\n        view.onDone = {\n            self.gitUsersPopover?.performClose(nil)\n            self.gitUsersPopover = nil\n            self.presenter.isShellScriptInstalled = true\n        }\n        popover.contentViewController = view\n        let rect = CGRect(origin: CGPoint(x: emailsTextField.frame.origin.x, y: GitCell.height-45), size: emailsTextField.frame.size)\n        popover.show(relativeTo: rect, of: self, preferredEdge: NSRectEdge.minY)\n        gitUsersPopover = popover\n    }\n}\n\nextension GitCell: NSTextFieldDelegate {\n    \n    func controlTextDidEndEditing(_ obj: Notification) {\n        save()\n    }\n}\n\nextension GitCell: GitPresenterOutput {\n    \n    func setStatusImage (_ imageName: NSImage.Name) {\n        statusImageView.image = NSImage(named: imageName)\n    }\n    func setStatusText (_ text: String) {\n        statusTextField.stringValue = text\n    }\n    func setDescriptionText (_ text: String) {\n        descriptionTextField.stringValue = text\n    }\n    func setButInstall (enabled: Bool) {\n        butInstall.isHidden = !enabled\n    }\n    func setButPurchase (enabled: Bool) {\n        butPurchase.isHidden = !enabled\n    }\n    func setButEnable (on: Bool?, enabled: Bool?) {\n        if let isOn = on {\n            butEnable.state = isOn ? .on : .off\n        }\n        butEnable.isHidden = enabled == false\n    }\n    func setPaths (_ paths: String?, enabled: Bool?) {\n        if let paths = paths {\n            pathsTextField.stringValue = paths\n        }\n        if let enabled = enabled {\n            pathsTextField.isEnabled = enabled\n            butPick.isEnabled = enabled\n        }\n    }\n    func setEmails (_ emails: String?, enabled: Bool?) {\n        if let emails = emails {\n            emailsTextField.stringValue = emails\n        }\n        if let enabled = enabled {\n            emailsTextField.isEnabled = enabled\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Input/Git/GitCell.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14460.31\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView identifier=\"GitCell\" id=\"c22-O7-iKe\" customClass=\"GitCell\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"480\" height=\"195\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <box autoresizesSubviews=\"NO\" borderType=\"line\" title=\"Git plugin\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"RQm-ST-fW3\">\n                    <rect key=\"frame\" x=\"-3\" y=\"-4\" width=\"486\" height=\"199\"/>\n                    <view key=\"contentView\" id=\"bAm-pg-lwW\">\n                        <rect key=\"frame\" x=\"3\" y=\"3\" width=\"480\" height=\"181\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <imageView horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"soa-Mf-B56\">\n                                <rect key=\"frame\" x=\"8\" y=\"143\" width=\"18\" height=\"18\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"18\" id=\"UD3-CQ-0Cq\"/>\n                                    <constraint firstAttribute=\"width\" constant=\"18\" id=\"WP7-bD-H6R\"/>\n                                </constraints>\n                                <imageCell key=\"cell\" refusesFirstResponder=\"YES\" alignment=\"left\" imageScaling=\"proportionallyDown\" image=\"NSStatusNone\" id=\"g96-Mm-inb\"/>\n                            </imageView>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"UaJ-WV-hc1\">\n                                <rect key=\"frame\" x=\"30\" y=\"144\" width=\"111\" height=\"17\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Checking git cmd\" id=\"ASn-hr-APm\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"y1X-Wf-3ng\">\n                                <rect key=\"frame\" x=\"389\" y=\"142\" width=\"81\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"Instructions\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"HFX-xw-W3U\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleInstallButton:\" target=\"c22-O7-iKe\" id=\"WPT-aA-DoM\"/>\n                                </connections>\n                            </button>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"ndj-0G-pnP\">\n                                <rect key=\"frame\" x=\"432\" y=\"61\" width=\"38\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"Pick\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"yOb-N1-jfv\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handlePickButton:\" target=\"c22-O7-iKe\" id=\"gYH-lc-GaZ\"/>\n                                </connections>\n                            </button>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"cWM-Qg-ewd\">\n                                <rect key=\"frame\" x=\"11\" y=\"26\" width=\"59\" height=\"17\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Git users\" id=\"kAp-st-pbb\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Teq-Pe-PXu\">\n                                <rect key=\"frame\" x=\"105\" y=\"23\" width=\"365\" height=\"22\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" borderStyle=\"bezel\" placeholderString=\"eg. me@email.com,me2@email.com\" bezelStyle=\"round\" id=\"WAw-xv-jpg\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"textColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" red=\"0.95654549870000005\" green=\"0.87322156549999996\" blue=\"0.28354544710000001\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"displayP3\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"7Et-wb-aOF\">\n                                <rect key=\"frame\" x=\"31\" y=\"97\" width=\"441\" height=\"28\"/>\n                                <textFieldCell key=\"cell\" sendsActionOnEndEditing=\"YES\" id=\"icW-RF-Xg3\">\n                                    <font key=\"font\" metaFont=\"smallSystem\"/>\n                                    <string key=\"title\">Commits made with Git are loaded in Jirassic on demand, meaning that they don't get saved to local database or synced over iCloud. If you wish to save them use Jit</string>\n                                    <color key=\"textColor\" name=\"disabledControlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"PbW-vi-SiM\">\n                                <rect key=\"frame\" x=\"11\" y=\"63\" width=\"75\" height=\"17\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Git projects\" id=\"mji-eX-EsZ\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"pe2-mX-fgI\">\n                                <rect key=\"frame\" x=\"105\" y=\"60\" width=\"319\" height=\"22\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" borderStyle=\"bezel\" placeholderString=\"eg. ~/Documents/Project1,~/Documents/Project2\" bezelStyle=\"round\" id=\"DYZ-2W-Nvk\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"textColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" red=\"0.95654549870000005\" green=\"0.87322156549999996\" blue=\"0.28354544710000001\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"displayP3\"/>\n                                </textFieldCell>\n                            </textField>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"U0o-hB-0FO\">\n                                <rect key=\"frame\" x=\"10\" y=\"143\" width=\"22\" height=\"18\"/>\n                                <buttonCell key=\"cell\" type=\"check\" bezelStyle=\"regularSquare\" imagePosition=\"left\" state=\"on\" inset=\"2\" id=\"a8i-lq-vV3\">\n                                    <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleEnableButton:\" target=\"c22-O7-iKe\" id=\"wci-nY-phu\"/>\n                                </connections>\n                            </button>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"4bE-gv-9uR\">\n                                <rect key=\"frame\" x=\"403\" y=\"142\" width=\"67\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"Purchase\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"pkq-VQ-bKH\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handlePurchaseButton:\" target=\"c22-O7-iKe\" id=\"Erb-Du-E6I\"/>\n                                </connections>\n                            </button>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"7Et-wb-aOF\" firstAttribute=\"leading\" secondItem=\"bAm-pg-lwW\" secondAttribute=\"leading\" constant=\"33\" id=\"9Fc-i0-3re\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"7Et-wb-aOF\" secondAttribute=\"trailing\" constant=\"10\" id=\"ANi-YY-aQS\"/>\n                            <constraint firstItem=\"UaJ-WV-hc1\" firstAttribute=\"top\" secondItem=\"soa-Mf-B56\" secondAttribute=\"top\" id=\"FbD-qf-Pro\"/>\n                            <constraint firstItem=\"soa-Mf-B56\" firstAttribute=\"top\" secondItem=\"bAm-pg-lwW\" secondAttribute=\"top\" constant=\"20\" id=\"I1j-nR-ahD\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"ndj-0G-pnP\" secondAttribute=\"trailing\" constant=\"10\" id=\"Jj0-Zd-wvr\"/>\n                            <constraint firstItem=\"Teq-Pe-PXu\" firstAttribute=\"leading\" secondItem=\"bAm-pg-lwW\" secondAttribute=\"leading\" constant=\"105\" id=\"MzN-47-ObN\"/>\n                            <constraint firstItem=\"ndj-0G-pnP\" firstAttribute=\"centerY\" secondItem=\"pe2-mX-fgI\" secondAttribute=\"centerY\" id=\"OBS-s1-lZA\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"Teq-Pe-PXu\" secondAttribute=\"trailing\" constant=\"10\" id=\"QKJ-yE-dBF\"/>\n                            <constraint firstItem=\"pe2-mX-fgI\" firstAttribute=\"top\" secondItem=\"7Et-wb-aOF\" secondAttribute=\"bottom\" constant=\"15\" id=\"RYB-lg-nkT\"/>\n                            <constraint firstItem=\"U0o-hB-0FO\" firstAttribute=\"centerY\" secondItem=\"y1X-Wf-3ng\" secondAttribute=\"centerY\" id=\"S5x-AY-5qS\"/>\n                            <constraint firstItem=\"U0o-hB-0FO\" firstAttribute=\"leading\" secondItem=\"bAm-pg-lwW\" secondAttribute=\"leading\" constant=\"12\" id=\"UXE-Z0-hnh\"/>\n                            <constraint firstItem=\"PbW-vi-SiM\" firstAttribute=\"leading\" secondItem=\"bAm-pg-lwW\" secondAttribute=\"leading\" constant=\"13\" id=\"Xqf-UW-0Yb\"/>\n                            <constraint firstItem=\"cWM-Qg-ewd\" firstAttribute=\"leading\" secondItem=\"bAm-pg-lwW\" secondAttribute=\"leading\" constant=\"13\" id=\"ZOq-Hd-4XN\"/>\n                            <constraint firstItem=\"soa-Mf-B56\" firstAttribute=\"leading\" secondItem=\"bAm-pg-lwW\" secondAttribute=\"leading\" constant=\"8\" id=\"c5n-pB-uts\"/>\n                            <constraint firstItem=\"y1X-Wf-3ng\" firstAttribute=\"top\" secondItem=\"soa-Mf-B56\" secondAttribute=\"top\" id=\"cMm-zD-JqY\"/>\n                            <constraint firstItem=\"pe2-mX-fgI\" firstAttribute=\"leading\" secondItem=\"Teq-Pe-PXu\" secondAttribute=\"leading\" id=\"cUM-b9-bvW\"/>\n                            <constraint firstItem=\"UaJ-WV-hc1\" firstAttribute=\"leading\" secondItem=\"soa-Mf-B56\" secondAttribute=\"trailing\" constant=\"6\" id=\"cxN-iS-Ne9\"/>\n                            <constraint firstItem=\"4bE-gv-9uR\" firstAttribute=\"trailing\" secondItem=\"y1X-Wf-3ng\" secondAttribute=\"trailing\" id=\"dA0-2s-PpL\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"y1X-Wf-3ng\" secondAttribute=\"trailing\" constant=\"10\" id=\"dRf-Za-uMg\"/>\n                            <constraint firstItem=\"cWM-Qg-ewd\" firstAttribute=\"centerY\" secondItem=\"Teq-Pe-PXu\" secondAttribute=\"centerY\" id=\"hPf-oh-FLx\"/>\n                            <constraint firstItem=\"4bE-gv-9uR\" firstAttribute=\"centerY\" secondItem=\"y1X-Wf-3ng\" secondAttribute=\"centerY\" id=\"iNC-NR-qmb\"/>\n                            <constraint firstItem=\"PbW-vi-SiM\" firstAttribute=\"centerY\" secondItem=\"pe2-mX-fgI\" secondAttribute=\"centerY\" id=\"jCo-aS-WaG\"/>\n                            <constraint firstItem=\"Teq-Pe-PXu\" firstAttribute=\"top\" secondItem=\"pe2-mX-fgI\" secondAttribute=\"bottom\" constant=\"15\" id=\"pP7-XB-w5z\"/>\n                            <constraint firstItem=\"ndj-0G-pnP\" firstAttribute=\"leading\" secondItem=\"pe2-mX-fgI\" secondAttribute=\"trailing\" constant=\"8\" id=\"ug3-c4-5fq\"/>\n                            <constraint firstItem=\"7Et-wb-aOF\" firstAttribute=\"top\" secondItem=\"y1X-Wf-3ng\" secondAttribute=\"bottom\" constant=\"18\" id=\"wmC-yn-XDa\"/>\n                        </constraints>\n                    </view>\n                </box>\n            </subviews>\n            <constraints>\n                <constraint firstAttribute=\"trailing\" secondItem=\"RQm-ST-fW3\" secondAttribute=\"trailing\" id=\"BYR-JA-3Lb\"/>\n                <constraint firstItem=\"RQm-ST-fW3\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" id=\"JBL-AC-Gsa\"/>\n                <constraint firstItem=\"RQm-ST-fW3\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" id=\"LjE-yW-nNP\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"RQm-ST-fW3\" secondAttribute=\"bottom\" id=\"PzK-Ow-0JE\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"butEnable\" destination=\"U0o-hB-0FO\" id=\"ffr-bV-tCg\"/>\n                <outlet property=\"butInstall\" destination=\"y1X-Wf-3ng\" id=\"65a-Gm-QVx\"/>\n                <outlet property=\"butPick\" destination=\"ndj-0G-pnP\" id=\"GFu-eK-WbP\"/>\n                <outlet property=\"butPurchase\" destination=\"4bE-gv-9uR\" id=\"Dhw-n1-Krs\"/>\n                <outlet property=\"descriptionTextField\" destination=\"7Et-wb-aOF\" id=\"gUa-u0-loh\"/>\n                <outlet property=\"emailsTextField\" destination=\"Teq-Pe-PXu\" id=\"KBh-qB-qXs\"/>\n                <outlet property=\"pathsTextField\" destination=\"pe2-mX-fgI\" id=\"Dkm-JH-rZc\"/>\n                <outlet property=\"statusImageView\" destination=\"soa-Mf-B56\" id=\"RNd-RY-fIT\"/>\n                <outlet property=\"statusTextField\" destination=\"UaJ-WV-hc1\" id=\"3Sk-ha-tws\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"139\" y=\"190.5\"/>\n        </customView>\n    </objects>\n    <resources>\n        <image name=\"NSStatusNone\" width=\"16\" height=\"16\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Input/Git/GitPresenter.swift",
    "content": "//\n//  GitPresenter.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 01/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport Cocoa\nimport RCPreferences\n\nprotocol GitPresenterInput: class {\n    \n    var isShellScriptInstalled: Bool? {get set}\n    \n    func enableGit (_ enabled: Bool)\n    func refresh (withCommand command: String)\n    func pickPath()\n    func save (emails: String, paths: String)\n}\n\nprotocol GitPresenterOutput: class {\n    \n    func setStatusImage (_ imageName: NSImage.Name)\n    func setStatusText (_ text: String)\n    func setDescriptionText (_ text: String)\n    func setButInstall (enabled: Bool)\n    func setButPurchase (enabled: Bool)\n    func setButEnable (on: Bool?, enabled: Bool?)\n    func setPaths (_ paths: String?, enabled: Bool?)\n    func setEmails (_ emails: String?, enabled: Bool?)\n}\n\nenum GitCellState {\n    // First thing to do is purchase it\n    case needsPurchase\n    // After purchasing you need to install the apple scripts\n    case needsShellScript\n    case needsGitScript\n    // When purchased and reachable via shell you have the option to enable or disable\n    case disabled\n    case enabled\n}\n\nclass GitPresenter {\n    \n    weak var userInterface: GitPresenterOutput?\n    private let gitModule = ModuleGitLogs()\n    private let localPreferences = RCPreferences<LocalPreferences>()\n    private let store = Store.shared\n    \n    var isShellScriptInstalled: Bool? {\n        didSet {\n            refresh()\n        }\n    }\n    \n    init() {\n        \n    }\n    \n    private func refresh() {\n        \n        userInterface?.setPaths(localPreferences.string(.settingsGitPaths),\n                               enabled: localPreferences.bool(.enableGit))\n        \n        userInterface?.setEmails(localPreferences.string(.settingsGitAuthors),\n                                enabled: localPreferences.bool(.enableGit))\n        \n        guard store.isGitPurchased else {\n            refresh(state: .needsPurchase)\n            return\n        }\n        gitModule.checkIfGitInstalled(completion: { [weak self] commandInstalled in\n            \n            guard let wself = self else {\n                return\n            }\n            guard wself.isShellScriptInstalled == true else {\n                wself.refresh(state: .needsShellScript)\n                return\n            }\n            guard commandInstalled else {\n                wself.refresh(state: .needsGitScript)\n                return\n            }\n            \n            wself.refresh(state: wself.localPreferences.bool(.enableGit) ? .enabled : .disabled)\n        })\n    }\n    \n    private func refresh (state: GitCellState) {\n        guard let userInterface = self.userInterface else {\n            return\n        }\n        userInterface.setDescriptionText(\"You will see git commits right in the reports. They are saved to database and synced with iCloud only after closing the day. Note: Git commits are not always 100% reliable\")\n        switch state {\n        case .needsPurchase:\n            userInterface.setStatusImage(NSImage.statusUnavailableName)\n            userInterface.setStatusText(\"Purchase Git support\")\n            userInterface.setButInstall(enabled: false)\n            userInterface.setButPurchase(enabled: true)\n            userInterface.setButEnable(on: false, enabled: false)\n        case .needsShellScript:\n            userInterface.setStatusImage(NSImage.statusUnavailableName)\n            userInterface.setStatusText(\"Not possible to use Git, please install shell scripts first!\")\n            userInterface.setButInstall(enabled: true)\n            userInterface.setButPurchase(enabled: false)\n        case .needsGitScript:\n            userInterface.setStatusImage(NSImage.statusPartiallyAvailableName)\n            userInterface.setStatusText(\"Git plugin is not installed, please install.\")\n            userInterface.setButInstall(enabled: true)\n            userInterface.setButPurchase(enabled: false)\n        case .disabled:\n            userInterface.setStatusText(\"Git plugin is installed and ready to use, please enable.\")\n            userInterface.setButEnable(on: false, enabled: true)\n            userInterface.setButInstall(enabled: false)\n            userInterface.setButPurchase(enabled: false)\n        case .enabled:\n            userInterface.setStatusText(\"Git plugin is installed and ready to use.\")\n            userInterface.setButEnable(on: true, enabled: true)\n            userInterface.setButInstall(enabled: false)\n            userInterface.setButPurchase(enabled: false)\n        }\n    }\n}\n\nextension GitPresenter: GitPresenterInput {\n    \n    func enableGit (_ enabled: Bool) {\n        localPreferences.set(enabled, forKey: .enableGit)\n        userInterface?.setPaths(nil, enabled: enabled)\n        userInterface?.setEmails(nil, enabled: enabled)\n        userInterface?.setButEnable(on: enabled, enabled: nil)\n    }\n    \n    func refresh (withCommand command: String) {\n        // Set the command to userDefaults and it will be read by the hokup module from there\n//        localPreferences.set(command, forKey: .settingsHookupCmdName)\n        refresh()\n    }\n    \n    func pickPath() {\n        \n        let panel = NSOpenPanel()\n        panel.canChooseFiles = false\n        panel.canChooseDirectories = true\n        panel.allowsMultipleSelection = false\n        panel.message = \"Select the root of the git project you want to track\"\n        panel.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.maximumWindow)))\n        panel.begin { [weak self] (result) -> Void in\n            \n            guard let self, let userInterface = self.userInterface else {\n                return\n            }\n            if result == NSApplication.ModalResponse.OK {\n                if let url = panel.urls.first {\n                    var path = url.absoluteString\n                    path = path.replacingOccurrences(of: \"file://\", with: \"\")\n                    path.removeLast()\n                    // TODO: Validate if the picked project is a git project\n                    \n                    let existingPaths = self.localPreferences.string(.settingsGitPaths)\n                    let updatedPaths = existingPaths == \"\" ? path : (existingPaths + \",\" + path)\n                    self.savePaths(updatedPaths)\n                    userInterface.setPaths(updatedPaths, enabled: self.localPreferences.bool(.enableGit))\n                }\n            }\n        }\n    }\n    \n    func save (emails: String, paths: String) {\n        saveEmails(emails)\n        savePaths(paths)\n    }\n    \n    private func saveEmails (_ emails: String) {\n        localPreferences.set(emails, forKey: .settingsGitAuthors)\n    }\n    private func savePaths (_ paths: String) {\n        localPreferences.set(paths, forKey: .settingsGitPaths)\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Input/InputsScrollView.swift",
    "content": "//\n//  InputsScrollView.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 01/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nclass InputsScrollView: NSScrollView {\n    \n    @IBOutlet private var tableView: NSTableView!\n    var dataSource: InputsTableViewDataSource?// If not declared, the reference is released\n    var onPurchasePressed: (() -> Void)?\n    \n    override func awakeFromNib() {\n        super.awakeFromNib()\n        \n        tableView.selectionHighlightStyle = .none\n        tableView.backgroundColor = .clear\n        tableView.intercellSpacing = NSSize(width: 0, height: 30)\n        \n        dataSource = InputsTableViewDataSource(tableView: tableView)\n        dataSource?.onPurchasePressed = { [weak self] in\n            self?.onPurchasePressed?()\n        }\n        tableView.dataSource = dataSource\n        tableView.delegate = dataSource\n        tableView.reloadData()\n    }\n\n    func showSettings (_ settings: SettingsBrowser) {\n        dataSource!.showSettingsBrowser(settings)\n    }\n\n    func settings() -> SettingsBrowser {\n        return dataSource!.settingsBrowser()\n    }\n    \n    func save() {\n        dataSource?.shellCell?.save()\n        dataSource?.jitCell?.save()\n        dataSource?.gitCell?.save()\n        dataSource?.browserCell?.save()\n        dataSource?.calendarCell?.save()\n    }\n    \n    func setShellStatus (compatibility: Compatibility) {\n        dataSource?.shellCell?.setShellStatus (compatibility: compatibility)\n    }\n    \n    func setJirassicStatus (compatibility: Compatibility) {\n        dataSource?.jirassicCell?.setJirassicStatus (compatibility: compatibility)\n    }\n    \n    func setJitStatus (compatibility: Compatibility) {\n        dataSource?.jitCell?.setJitStatus (compatibility: compatibility)\n    }\n    \n    func setGitStatus (available: Bool) {\n        dataSource?.gitCell?.presenter.isShellScriptInstalled = available\n    }\n    \n    func setBrowserStatus (compatibility: Compatibility) {\n        dataSource?.browserCell?.setBrowserStatus (compatibility: compatibility)\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Input/InputsScrollView.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"14109\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14109\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <scrollView focusRingType=\"none\" borderType=\"none\" autohidesScrollers=\"YES\" horizontalLineScroll=\"19\" horizontalPageScroll=\"10\" verticalLineScroll=\"19\" verticalPageScroll=\"10\" usesPredominantAxisScrolling=\"NO\" id=\"0Uk-AY-MTh\" customClass=\"InputsScrollView\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"461\" height=\"339\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <clipView key=\"contentView\" drawsBackground=\"NO\" copiesOnScroll=\"NO\" id=\"fdC-g1-XOM\">\n                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"461\" height=\"339\"/>\n                <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                <subviews>\n                    <tableView focusRingType=\"none\" verticalHuggingPriority=\"750\" allowsExpansionToolTips=\"YES\" columnAutoresizingStyle=\"lastColumnOnly\" columnSelection=\"YES\" multipleSelection=\"NO\" autosaveColumns=\"NO\" rowSizeStyle=\"automatic\" viewBased=\"YES\" id=\"kRT-LQ-d3N\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"461\" height=\"339\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                        <size key=\"intercellSpacing\" width=\"3\" height=\"2\"/>\n                        <color key=\"backgroundColor\" name=\"controlBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"gridColor\" name=\"gridColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <tableColumns>\n                            <tableColumn identifier=\"\" width=\"458\" minWidth=\"40\" maxWidth=\"1000\" id=\"xbJ-qZ-Tc4\">\n                                <tableHeaderCell key=\"headerCell\" lineBreakMode=\"truncatingTail\" borderStyle=\"border\">\n                                    <font key=\"font\" metaFont=\"smallSystem\"/>\n                                    <color key=\"textColor\" name=\"headerTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"headerColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </tableHeaderCell>\n                                <textFieldCell key=\"dataCell\" lineBreakMode=\"truncatingTail\" selectable=\"YES\" editable=\"YES\" title=\"Text Cell\" id=\"oDq-nO-tr4\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                                <tableColumnResizingMask key=\"resizingMask\" resizeWithTable=\"YES\" userResizable=\"YES\"/>\n                                <prototypeCellViews>\n                                    <tableCellView id=\"Fc8-TP-G7g\">\n                                        <rect key=\"frame\" x=\"1\" y=\"1\" width=\"458\" height=\"17\"/>\n                                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                        <subviews>\n                                            <textField verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" fixedFrame=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"mNw-lU-umy\">\n                                                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"458\" height=\"17\"/>\n                                                <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" flexibleMinY=\"YES\"/>\n                                                <textFieldCell key=\"cell\" lineBreakMode=\"truncatingTail\" sendsActionOnEndEditing=\"YES\" title=\"Table View Cell\" id=\"gVH-oo-WhH\">\n                                                    <font key=\"font\" metaFont=\"system\"/>\n                                                    <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                </textFieldCell>\n                                            </textField>\n                                        </subviews>\n                                        <connections>\n                                            <outlet property=\"textField\" destination=\"mNw-lU-umy\" id=\"bzc-YL-i8n\"/>\n                                        </connections>\n                                    </tableCellView>\n                                </prototypeCellViews>\n                            </tableColumn>\n                        </tableColumns>\n                    </tableView>\n                </subviews>\n            </clipView>\n            <scroller key=\"horizontalScroller\" hidden=\"YES\" verticalHuggingPriority=\"750\" horizontal=\"YES\" id=\"nQf-Vj-lJo\">\n                <rect key=\"frame\" x=\"1\" y=\"119\" width=\"223\" height=\"15\"/>\n                <autoresizingMask key=\"autoresizingMask\"/>\n            </scroller>\n            <scroller key=\"verticalScroller\" hidden=\"YES\" verticalHuggingPriority=\"750\" horizontal=\"NO\" id=\"Zeb-P9-vOs\">\n                <rect key=\"frame\" x=\"224\" y=\"17\" width=\"15\" height=\"102\"/>\n                <autoresizingMask key=\"autoresizingMask\"/>\n            </scroller>\n            <connections>\n                <outlet property=\"tableView\" destination=\"kRT-LQ-d3N\" id=\"Rtm-1d-WfY\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"109\" y=\"157\"/>\n        </scrollView>\n    </objects>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Input/InputsTableViewDataSource.swift",
    "content": "//\n//  InputsTableViewDataSource.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 01/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nenum InputType {\n    case shell\n    case jirassic\n    case git\n    case jit\n    case browser\n    case calendar\n    static var all: [InputType] = [.shell, .jirassic, .git, .jit, .browser, .calendar]\n}\n\nclass InputsTableViewDataSource: NSObject {\n    \n    private let tableView: NSTableView\n    private let cells: [InputType] = InputType.all\n    var shellCell: ShellCell?\n    var jirassicCell: JirassicCell?\n    var jitCell: JitCell?\n    var gitCell: GitCell?\n    var browserCell: BrowserCell?\n    var calendarCell: CalendarCell?\n    var onPurchasePressed: (() -> Void)?\n\n    init (tableView: NSTableView) {\n        self.tableView = tableView\n        super.init()\n\n        ShellCell.register(in: tableView)\n        JirassicCell.register(in: tableView)\n        JitCell.register(in: tableView)\n        GitCell.register(in: tableView)\n        BrowserCell.register(in: tableView)\n        CalendarCell.register(in: tableView)\n        \n        shellCell = ShellCell.instantiate(in: self.tableView)\n        jirassicCell = JirassicCell.instantiate(in: self.tableView)\n        jitCell = JitCell.instantiate(in: self.tableView)\n        gitCell = GitCell.instantiate(in: self.tableView)\n        browserCell = BrowserCell.instantiate(in: self.tableView)\n        calendarCell = CalendarCell.instantiate(in: self.tableView)\n\n        gitCell?.onPurchasePressed = { [weak self] in\n            self?.onPurchasePressed?()\n        }\n    }\n\n    func showSettingsBrowser (_ settings: SettingsBrowser) {\n        browserCell!.showSettings(settings)\n    }\n    \n    func settingsBrowser() -> SettingsBrowser {\n        return browserCell!.settings()\n    }\n}\n\nextension InputsTableViewDataSource: NSTableViewDataSource {\n    \n    func numberOfRows (in aTableView: NSTableView) -> Int {\n        return cells.count\n    }\n    \n    func tableView (_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {\n        \n        let inputType = cells[row]\n        switch inputType {\n        case .shell:\n            return ShellCell.height\n        case .jirassic:\n            return JirassicCell.height\n        case .git:\n            return GitCell.height\n        case .jit:\n            return JitCell.height\n        case .browser:\n            return BrowserCell.height\n        case .calendar:\n            return CalendarCell.height\n        }\n    }\n}\n\nextension InputsTableViewDataSource: NSTableViewDelegate {\n    \n    func tableView (_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {\n        \n        switch cells[row] {\n        case .shell:\n            return shellCell!\n        case .jirassic:\n            return jirassicCell!\n        case .git:\n            return gitCell!\n        case .jit:\n            return jitCell!\n        case .browser:\n            return browserCell!\n        case .calendar:\n            return calendarCell!\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Input/JirassicCmd/JirassicCell.swift",
    "content": "//\n//  JirassicCell.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 17/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nclass JirassicCell: NSTableRowView {\n    \n    static let height = CGFloat(60)\n    \n    @IBOutlet private var statusImageView: NSImageView!\n    @IBOutlet private var textField: NSTextField!\n    @IBOutlet private var butInstall: NSButton!\n    \n    func setJirassicStatus (compatibility: Compatibility) {\n        \n        if compatibility.available {\n            statusImageView.image = compatibility.compatible\n                ? NSImage(named: NSImage.statusAvailableName)\n                : NSImage(named: \"WarningButton\")\n            textField.stringValue = compatibility.compatible\n                ? \"Jirassic \\(compatibility.currentVersion) installed, type 'jirassic' in Terminal for more info\"\n                : \"Version \\(compatibility.currentVersion) installed, min required is \\(compatibility.minVersion), please update\"\n        } else {\n            statusImageView.image = NSImage(named: NSImage.statusUnavailableName)\n            textField.stringValue = \"Not installed, please follow instructions!\"\n        }\n        butInstall.isHidden = compatibility.available && compatibility.compatible\n    }\n    \n    func save() {\n        \n    }\n    \n    @IBAction func handleInstallButton (_ sender: NSButton) {\n        #if APPSTORE\n            NSWorkspace.shared.open( URL(string: \"http://www.jirassic.com/#extensions\")!)\n        #else\n            //            presenter?.installJirassic()\n            NSWorkspace.shared.open( URL(string: \"http://www.jirassic.com/#extensions\")!)\n        #endif\n    }\n    \n}\n\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Input/JirassicCmd/JirassicCell.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"14313.18\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14313.18\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView id=\"c22-O7-iKe\" customClass=\"JirassicCell\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"480\" height=\"80\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <box autoresizesSubviews=\"NO\" borderType=\"line\" title=\"Jirassic CLI\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"IK4-a7-zIn\">\n                    <rect key=\"frame\" x=\"-3\" y=\"-4\" width=\"486\" height=\"84\"/>\n                    <view key=\"contentView\" id=\"mvN-gG-3yr\">\n                        <rect key=\"frame\" x=\"1\" y=\"1\" width=\"484\" height=\"68\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <imageView horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"H8T-Jx-U7l\">\n                                <rect key=\"frame\" x=\"8\" y=\"27\" width=\"18\" height=\"18\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"18\" id=\"7XW-4D-pJK\"/>\n                                    <constraint firstAttribute=\"height\" constant=\"18\" id=\"m39-ch-mer\"/>\n                                </constraints>\n                                <imageCell key=\"cell\" refusesFirstResponder=\"YES\" alignment=\"left\" imageScaling=\"proportionallyDown\" image=\"NSStatusNone\" id=\"frd-Mt-kCo\"/>\n                            </imageView>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"HoL-An-9LP\">\n                                <rect key=\"frame\" x=\"30\" y=\"29\" width=\"138\" height=\"17\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Checking shell scripts\" id=\"2za-y1-xof\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Ni8-Be-50n\">\n                                <rect key=\"frame\" x=\"393\" y=\"26\" width=\"81\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"Instructions\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"YiR-4q-fq7\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleInstallButton:\" target=\"c22-O7-iKe\" id=\"pgk-eP-54u\"/>\n                                </connections>\n                            </button>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"H8T-Jx-U7l\" firstAttribute=\"leading\" secondItem=\"mvN-gG-3yr\" secondAttribute=\"leading\" constant=\"8\" id=\"Ay5-nz-osP\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"Ni8-Be-50n\" secondAttribute=\"trailing\" constant=\"10\" id=\"RQ8-uU-Hdw\"/>\n                            <constraint firstItem=\"HoL-An-9LP\" firstAttribute=\"leading\" secondItem=\"H8T-Jx-U7l\" secondAttribute=\"trailing\" constant=\"6\" id=\"rU5-pc-0cC\"/>\n                            <constraint firstItem=\"H8T-Jx-U7l\" firstAttribute=\"centerY\" secondItem=\"mvN-gG-3yr\" secondAttribute=\"centerY\" constant=\"-2\" id=\"t54-tg-6LN\"/>\n                            <constraint firstItem=\"HoL-An-9LP\" firstAttribute=\"centerY\" secondItem=\"mvN-gG-3yr\" secondAttribute=\"centerY\" constant=\"-3\" id=\"tcK-Eq-fsA\"/>\n                            <constraint firstItem=\"Ni8-Be-50n\" firstAttribute=\"centerY\" secondItem=\"mvN-gG-3yr\" secondAttribute=\"centerY\" constant=\"-2\" id=\"yTF-qf-Pqk\"/>\n                        </constraints>\n                    </view>\n                </box>\n            </subviews>\n            <constraints>\n                <constraint firstItem=\"IK4-a7-zIn\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" id=\"F5m-rO-Qa8\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"IK4-a7-zIn\" secondAttribute=\"bottom\" id=\"IcA-j3-0Od\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"IK4-a7-zIn\" secondAttribute=\"trailing\" id=\"OWK-v9-nrh\"/>\n                <constraint firstItem=\"IK4-a7-zIn\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" id=\"vto-TC-aXn\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"butInstall\" destination=\"Ni8-Be-50n\" id=\"ZmP-gy-DSh\"/>\n                <outlet property=\"statusImageView\" destination=\"H8T-Jx-U7l\" id=\"wSR-tP-dmY\"/>\n                <outlet property=\"textField\" destination=\"HoL-An-9LP\" id=\"w2A-ZU-wsx\"/>\n            </connections>\n        </customView>\n    </objects>\n    <resources>\n        <image name=\"NSStatusNone\" width=\"16\" height=\"16\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Input/Jit/JitCell.swift",
    "content": "//\n//  JitCell.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 01/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\nimport RCPreferences\n\nclass JitCell: NSTableRowView {\n\n    static let height = CGFloat(135)\n    \n    @IBOutlet private var statusImageView: NSImageView!\n    @IBOutlet private var statusImageViewGapToButEnableConstraint: NSLayoutConstraint!\n    @IBOutlet private var textField: NSTextField!\n    @IBOutlet private var butInstall: NSButton!\n    @IBOutlet private var butEnable: NSButton!\n\n    private let prefs = RCPreferences<LocalPreferences>()\n\n    override func awakeFromNib() {\n        super.awakeFromNib()\n        butEnable.isHidden = true\n        statusImageView.isHidden = false\n    }\n\n    func save() {\n\n    }\n    \n    func setJitStatus (compatibility: Compatibility) {\n        \n        if compatibility.available {\n            statusImageView.image = compatibility.compatible\n                ? NSImage(named: NSImage.statusAvailableName)\n                : NSImage(named: \"WarningButton\")\n            statusImageViewGapToButEnableConstraint.constant = compatibility.compatible ? -14 : 5\n            \n            textField.stringValue = compatibility.compatible\n                ? \"Jit \\(compatibility.currentVersion) installed, type 'jit' in Terminal for more info\"\n                : \"Version \\(compatibility.currentVersion) installed, min required is \\(compatibility.minVersion), please update\"\n            \n            butEnable.state = prefs.bool(.enableJit) ? .on : .off\n        } else {\n            statusImageView.image = NSImage(named: NSImage.statusUnavailableName)\n            textField.stringValue = \"Cannot determine Jit compatibility, install shell support first!\"\n        }\n        butInstall.isHidden = compatibility.available && compatibility.compatible\n        butEnable.isHidden = !compatibility.available\n        statusImageView.isHidden = compatibility.available && compatibility.compatible\n    }\n\n    @IBAction func handleInstallButton (_ sender: NSButton) {\n        #if APPSTORE\n            NSWorkspace.shared.open( URL(string: \"http://www.jirassic.com/#extensions\")!)\n        #else\n            //            presenter?.installJit()\n            NSWorkspace.shared.open( URL(string: \"https://github.com/ralcr/Jit\")!)\n        #endif\n    }\n    \n    @IBAction func handleEnableButton (_ sender: NSButton) {\n        prefs.set(sender.state == .on, forKey: .enableJit)\n    }\n}\n\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Input/Jit/JitCell.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"14313.18\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14313.18\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView identifier=\"JitCell\" id=\"c22-O7-iKe\" customClass=\"JitCell\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"480\" height=\"135\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <box autoresizesSubviews=\"NO\" borderType=\"line\" title=\"Jit CLI\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"LH9-Gr-LTu\">\n                    <rect key=\"frame\" x=\"-3\" y=\"-4\" width=\"486\" height=\"139\"/>\n                    <view key=\"contentView\" id=\"Ns2-hK-EP5\">\n                        <rect key=\"frame\" x=\"1\" y=\"1\" width=\"484\" height=\"123\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <imageView horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"J2T-Jl-X5Z\">\n                                <rect key=\"frame\" x=\"8\" y=\"85\" width=\"18\" height=\"18\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"18\" id=\"17z-6c-lDC\"/>\n                                    <constraint firstAttribute=\"width\" constant=\"18\" id=\"ZHa-Mr-qjD\"/>\n                                </constraints>\n                                <imageCell key=\"cell\" refusesFirstResponder=\"YES\" alignment=\"left\" imageScaling=\"proportionallyDown\" image=\"WarningButton\" id=\"fIl-5O-cqT\"/>\n                            </imageView>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"5pv-Sa-Pob\">\n                                <rect key=\"frame\" x=\"10\" y=\"85\" width=\"22\" height=\"18\"/>\n                                <buttonCell key=\"cell\" type=\"check\" bezelStyle=\"regularSquare\" imagePosition=\"left\" state=\"on\" inset=\"2\" id=\"Zgx-ob-TCr\">\n                                    <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleEnableButton:\" target=\"c22-O7-iKe\" id=\"qMu-c7-3zZ\"/>\n                                </connections>\n                            </button>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"6xF-lx-omh\">\n                                <rect key=\"frame\" x=\"30\" y=\"86\" width=\"99\" height=\"17\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Checking jit CLI\" id=\"3lc-gE-RWN\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"ZYg-1V-a4C\">\n                                <rect key=\"frame\" x=\"393\" y=\"86\" width=\"81\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"Instructions\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"LvH-GE-wFG\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleInstallButton:\" target=\"c22-O7-iKe\" id=\"YYU-9g-Xh2\"/>\n                                </connections>\n                            </button>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"DyW-dA-ORD\">\n                                <rect key=\"frame\" x=\"30\" y=\"20\" width=\"446\" height=\"46\"/>\n                                <textFieldCell key=\"cell\" sendsActionOnEndEditing=\"YES\" id=\"5gQ-GC-Rg3\">\n                                    <font key=\"font\" metaFont=\"smallSystem\"/>\n                                    <string key=\"title\">Jit is a CLI wrapper over Git which facilitates working with Jira tasks and branches. If enabled, the commits made with Jit will be saved to Jirassic immediately, being more accurate and synced over iCloud.</string>\n                                    <color key=\"textColor\" name=\"disabledControlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"5pv-Sa-Pob\" firstAttribute=\"centerY\" secondItem=\"6xF-lx-omh\" secondAttribute=\"centerY\" id=\"68O-PK-2Rd\"/>\n                            <constraint firstItem=\"J2T-Jl-X5Z\" firstAttribute=\"leading\" secondItem=\"Ns2-hK-EP5\" secondAttribute=\"leading\" constant=\"8\" id=\"KmN-JR-lqD\"/>\n                            <constraint firstItem=\"DyW-dA-ORD\" firstAttribute=\"top\" secondItem=\"6xF-lx-omh\" secondAttribute=\"bottom\" constant=\"20\" id=\"O2D-5i-pbY\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"ZYg-1V-a4C\" secondAttribute=\"trailing\" constant=\"10\" id=\"QyI-WI-PQW\"/>\n                            <constraint firstItem=\"J2T-Jl-X5Z\" firstAttribute=\"top\" secondItem=\"Ns2-hK-EP5\" secondAttribute=\"top\" constant=\"20\" id=\"WLK-Xu-X04\"/>\n                            <constraint firstItem=\"5pv-Sa-Pob\" firstAttribute=\"leading\" secondItem=\"J2T-Jl-X5Z\" secondAttribute=\"trailing\" constant=\"-14\" id=\"hBO-5s-ZWt\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"DyW-dA-ORD\" secondAttribute=\"bottom\" constant=\"20\" id=\"j8u-vD-SE4\"/>\n                            <constraint firstItem=\"DyW-dA-ORD\" firstAttribute=\"leading\" secondItem=\"Ns2-hK-EP5\" secondAttribute=\"leading\" constant=\"32\" id=\"kMn-aK-24L\"/>\n                            <constraint firstItem=\"5pv-Sa-Pob\" firstAttribute=\"top\" secondItem=\"Ns2-hK-EP5\" secondAttribute=\"top\" constant=\"22\" id=\"mAF-uK-ZEO\"/>\n                            <constraint firstItem=\"6xF-lx-omh\" firstAttribute=\"leading\" secondItem=\"5pv-Sa-Pob\" secondAttribute=\"trailing\" constant=\"2\" id=\"n9u-mq-hzK\"/>\n                            <constraint firstItem=\"ZYg-1V-a4C\" firstAttribute=\"centerY\" secondItem=\"6xF-lx-omh\" secondAttribute=\"centerY\" constant=\"-1\" id=\"uLz-8m-FUr\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"DyW-dA-ORD\" secondAttribute=\"trailing\" constant=\"10\" id=\"wsO-f2-y4E\"/>\n                        </constraints>\n                    </view>\n                </box>\n            </subviews>\n            <constraints>\n                <constraint firstAttribute=\"trailing\" secondItem=\"LH9-Gr-LTu\" secondAttribute=\"trailing\" id=\"3HA-8B-Dca\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"LH9-Gr-LTu\" secondAttribute=\"bottom\" id=\"Cy3-gG-ccn\"/>\n                <constraint firstItem=\"LH9-Gr-LTu\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" id=\"UTI-3S-2RP\"/>\n                <constraint firstItem=\"LH9-Gr-LTu\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" id=\"VzY-Un-Lg4\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"butEnable\" destination=\"5pv-Sa-Pob\" id=\"0Ft-4p-NBx\"/>\n                <outlet property=\"butInstall\" destination=\"ZYg-1V-a4C\" id=\"Whq-ZH-cbb\"/>\n                <outlet property=\"statusImageView\" destination=\"J2T-Jl-X5Z\" id=\"dsS-tK-EW3\"/>\n                <outlet property=\"statusImageViewGapToButEnableConstraint\" destination=\"hBO-5s-ZWt\" id=\"X5I-UM-TFw\"/>\n                <outlet property=\"textField\" destination=\"6xF-lx-omh\" id=\"XcO-Rt-Ksk\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"139\" y=\"211.5\"/>\n        </customView>\n    </objects>\n    <resources>\n        <image name=\"WarningButton\" width=\"30\" height=\"30\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Input/Shell/ShellCell.swift",
    "content": "//\n//  ShellCell.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 01/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nclass ShellCell: NSTableRowView {\n    \n    static let height = CGFloat(60)\n    \n    @IBOutlet private var statusImageView: NSImageView!\n    @IBOutlet private var textField: NSTextField!\n    @IBOutlet private var butInstall: NSButton!\n    \n    override func awakeFromNib() {\n        super.awakeFromNib()\n        self.toolTip = \"Shell scripts are needed for communicating with the plugins: reading git logs, reading browser url, finding compatibility.\"\n    }\n    func setShellStatus (compatibility: Compatibility) {\n        \n        if compatibility.available {\n            statusImageView.image = NSImage(named: compatibility.compatible\n                ? NSImage.statusAvailableName\n                : NSImage.statusPartiallyAvailableName)\n            textField.stringValue = compatibility.compatible\n                ? \"Version \\(compatibility.currentVersion) installed, Jirassic is now able to communicate with the shell.\"\n                : \"Outdated, please update!\"\n        } else {\n            statusImageView.image = NSImage(named: NSImage.statusUnavailableName)\n            textField.stringValue = \"Not installed yet\"\n        }\n        butInstall.isHidden = compatibility.available && compatibility.compatible\n    }\n    \n    func save() {\n        // Nothing to save\n    }\n    \n    @IBAction func handleInstallButton (_ sender: NSButton) {\n        #if APPSTORE\n            NSWorkspace.shared.open( URL(string: \"http://www.jirassic.com/#extensions\")!)\n        #else\n            //            presenter?.installJirassic()\n            NSWorkspace.shared.open( URL(string: \"http://www.jirassic.com/#extensions\")!)\n        #endif\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Input/Shell/ShellCell.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"14313.18\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14313.18\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView identifier=\"ShellCell\" id=\"c22-O7-iKe\" customClass=\"ShellCell\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"480\" height=\"120\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <box autoresizesSubviews=\"NO\" borderType=\"line\" title=\"Shell scripts\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Lym-kY-nCa\">\n                    <rect key=\"frame\" x=\"-3\" y=\"-4\" width=\"486\" height=\"124\"/>\n                    <view key=\"contentView\" id=\"p7S-Nq-3V4\">\n                        <rect key=\"frame\" x=\"1\" y=\"1\" width=\"484\" height=\"108\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <imageView horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Ozs-A1-GHW\">\n                                <rect key=\"frame\" x=\"8\" y=\"47\" width=\"18\" height=\"18\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"18\" id=\"PK5-rd-sJz\"/>\n                                    <constraint firstAttribute=\"height\" constant=\"18\" id=\"som-Wg-1T4\"/>\n                                </constraints>\n                                <imageCell key=\"cell\" refusesFirstResponder=\"YES\" alignment=\"left\" imageScaling=\"proportionallyDown\" image=\"NSStatusNone\" id=\"39r-Z5-JYc\"/>\n                            </imageView>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"fgI-x9-bZH\">\n                                <rect key=\"frame\" x=\"30\" y=\"49\" width=\"138\" height=\"17\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Checking shell scripts\" id=\"4Vx-W3-yc2\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"9NN-ai-rt7\">\n                                <rect key=\"frame\" x=\"393\" y=\"46\" width=\"81\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"Instructions\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"zi4-Ow-hwe\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleInstallButton:\" target=\"c22-O7-iKe\" id=\"Py5-Gq-MOk\"/>\n                                </connections>\n                            </button>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"fgI-x9-bZH\" firstAttribute=\"centerY\" secondItem=\"p7S-Nq-3V4\" secondAttribute=\"centerY\" constant=\"-3\" id=\"Hou-ar-Nef\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"9NN-ai-rt7\" secondAttribute=\"trailing\" constant=\"10\" id=\"QxR-eN-31K\"/>\n                            <constraint firstItem=\"Ozs-A1-GHW\" firstAttribute=\"centerY\" secondItem=\"p7S-Nq-3V4\" secondAttribute=\"centerY\" constant=\"-2\" id=\"UPz-Rj-woc\"/>\n                            <constraint firstItem=\"fgI-x9-bZH\" firstAttribute=\"leading\" secondItem=\"Ozs-A1-GHW\" secondAttribute=\"trailing\" constant=\"6\" id=\"Zri-00-iE7\"/>\n                            <constraint firstItem=\"9NN-ai-rt7\" firstAttribute=\"centerY\" secondItem=\"p7S-Nq-3V4\" secondAttribute=\"centerY\" constant=\"-2\" id=\"bSc-BQ-slp\"/>\n                            <constraint firstItem=\"Ozs-A1-GHW\" firstAttribute=\"leading\" secondItem=\"p7S-Nq-3V4\" secondAttribute=\"leading\" constant=\"8\" id=\"gVi-p1-yhQ\"/>\n                        </constraints>\n                    </view>\n                </box>\n            </subviews>\n            <constraints>\n                <constraint firstItem=\"Lym-kY-nCa\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" id=\"Gcw-kY-geg\"/>\n                <constraint firstItem=\"Lym-kY-nCa\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" id=\"JHu-fR-gcI\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"Lym-kY-nCa\" secondAttribute=\"trailing\" id=\"oii-Gh-c1o\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"Lym-kY-nCa\" secondAttribute=\"bottom\" id=\"yG9-v9-fsW\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"butInstall\" destination=\"9NN-ai-rt7\" id=\"BfR-qh-ZdY\"/>\n                <outlet property=\"statusImageView\" destination=\"Ozs-A1-GHW\" id=\"pSu-Tm-Bfc\"/>\n                <outlet property=\"textField\" destination=\"fgI-x9-bZH\" id=\"pBd-aQ-GDx\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"140\" y=\"92\"/>\n        </customView>\n    </objects>\n    <resources>\n        <image name=\"NSStatusNone\" width=\"16\" height=\"16\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Output/CocoaHookup/CocoaHookupCell.swift",
    "content": "//\n//  CocoaHookupCell.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 09/04/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nclass CocoaHookupCell: NSTableRowView, Saveable {\n    \n    static let height = CGFloat(95)\n    \n    @IBOutlet fileprivate var statusImageView: NSImageView!\n    @IBOutlet fileprivate var statusTextField: NSTextField!\n    @IBOutlet fileprivate var butEnable: NSButton!\n    @IBOutlet fileprivate var hookupNameTextField: NSTextField!\n    @IBOutlet fileprivate var butPick: NSButton!\n    \n    var presenter: CocoaHookupPresenterInput = CocoaHookupPresenter()\n    \n    override func awakeFromNib() {\n        super.awakeFromNib()\n        hookupNameTextField.delegate = self\n        (presenter as! CocoaHookupPresenter).userInterface = self\n    }\n    \n    func save() {\n        // Already saved\n    }\n    \n    @IBAction func handleEnableButton (_ sender: NSButton) {\n        presenter.enableCocoaHookup(sender.state == .on)\n    }\n    \n    @IBAction func handlePickButton (_ sender: NSButton) {\n        presenter.pickApp()\n    }\n}\n\nextension CocoaHookupCell: CocoaHookupPresenterOutput {\n    \n    func setStatusImage (_ imageName: NSImage.Name) {\n        statusImageView.image = NSImage(named: imageName)\n    }\n    func setStatusText (_ text: String) {\n        statusTextField.stringValue = text\n    }\n    func setButEnable (on: Bool?, enabled: Bool?) {\n        if let isOn = on {\n            butEnable.title = isOn ? \"Enabled\" : \"Disabled\"\n            butEnable.state = isOn ? .on : .off\n        }\n        if let enabled = enabled {\n            butEnable.isEnabled = enabled\n        }\n    }\n    func setButPick (enabled: Bool) {\n        butPick.isEnabled = enabled\n    }\n    func setApp (appName: String?, enabled: Bool?) {\n        if let appName = appName {\n            hookupNameTextField.stringValue = appName\n        }\n        if let enabled = enabled {\n            hookupNameTextField.isEnabled = enabled\n        }\n    }\n}\n\nextension CocoaHookupCell: NSTextFieldDelegate {\n    \n    func controlTextDidEndEditing (_ obj: Notification) {\n        presenter.refresh(withApp: hookupNameTextField.stringValue)\n    }\n}\n\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Output/CocoaHookup/CocoaHookupCell.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"13771\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"13771\"/>\n        <capability name=\"box content view\" minToolsVersion=\"7.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView identifier=\"CocoaHookupCell\" id=\"YTY-Kw-amg\" customClass=\"CocoaHookupCell\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"480\" height=\"95\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <box autoresizesSubviews=\"NO\" borderType=\"line\" title=\"Mac app hookup\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"xNH-Yj-HPf\">\n                    <rect key=\"frame\" x=\"-3\" y=\"-4\" width=\"486\" height=\"99\"/>\n                    <view key=\"contentView\" id=\"SmN-FM-OwR\">\n                        <rect key=\"frame\" x=\"1\" y=\"1\" width=\"484\" height=\"83\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"QTc-yG-dc9\">\n                                <rect key=\"frame\" x=\"11\" y=\"24\" width=\"66\" height=\"17\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"App name\" id=\"TuV-EQ-2xI\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"v58-82-ta2\">\n                                <rect key=\"frame\" x=\"85\" y=\"21\" width=\"330\" height=\"22\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" borderStyle=\"bezel\" placeholderString=\"eg. MyApp.app\" bezelStyle=\"round\" id=\"JCw-fB-pJn\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"textColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" red=\"0.95654549870000005\" green=\"0.87322156549999996\" blue=\"0.28354544710000001\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"displayP3\"/>\n                                </textFieldCell>\n                            </textField>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"v58-82-ta2\" firstAttribute=\"centerY\" secondItem=\"QTc-yG-dc9\" secondAttribute=\"centerY\" id=\"0s6-dB-0F1\"/>\n                            <constraint firstItem=\"v58-82-ta2\" firstAttribute=\"top\" secondItem=\"SmN-FM-OwR\" secondAttribute=\"top\" constant=\"40\" id=\"Mrf-pq-EBg\"/>\n                            <constraint firstItem=\"QTc-yG-dc9\" firstAttribute=\"leading\" secondItem=\"SmN-FM-OwR\" secondAttribute=\"leading\" constant=\"13\" id=\"Xv2-wD-zyh\"/>\n                            <constraint firstItem=\"v58-82-ta2\" firstAttribute=\"leading\" secondItem=\"QTc-yG-dc9\" secondAttribute=\"trailing\" constant=\"10\" id=\"zZJ-zE-3mT\"/>\n                        </constraints>\n                    </view>\n                </box>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"JmU-05-Npj\">\n                    <rect key=\"frame\" x=\"422\" y=\"19\" width=\"38\" height=\"19\"/>\n                    <buttonCell key=\"cell\" type=\"roundRect\" title=\"Pick\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"C0K-FN-cjf\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"cellTitle\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handlePickButton:\" target=\"YTY-Kw-amg\" id=\"epF-pC-JBe\"/>\n                    </connections>\n                </button>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"dfe-CT-saf\">\n                    <rect key=\"frame\" x=\"400\" y=\"51\" width=\"60\" height=\"19\"/>\n                    <buttonCell key=\"cell\" type=\"roundRect\" title=\"Enabled\" alternateTitle=\"Disabled\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"lnA-op-zQd\">\n                        <behavior key=\"behavior\" lightByBackground=\"YES\" lightByGray=\"YES\" changeBackground=\"YES\" changeGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"cellTitle\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleEnableButton:\" target=\"YTY-Kw-amg\" id=\"Lgr-ms-Ibd\"/>\n                    </connections>\n                </button>\n                <imageView horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"GxR-Fq-RaO\">\n                    <rect key=\"frame\" x=\"10\" y=\"52\" width=\"18\" height=\"18\"/>\n                    <constraints>\n                        <constraint firstAttribute=\"height\" constant=\"18\" id=\"4W0-dU-UbB\"/>\n                        <constraint firstAttribute=\"width\" constant=\"18\" id=\"aqR-4P-WS0\"/>\n                    </constraints>\n                    <imageCell key=\"cell\" refusesFirstResponder=\"YES\" alignment=\"left\" imageScaling=\"proportionallyDown\" image=\"NSStatusNone\" id=\"SFj-G6-cgh\"/>\n                </imageView>\n                <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"OgZ-Bi-Ohj\">\n                    <rect key=\"frame\" x=\"32\" y=\"53\" width=\"137\" height=\"17\"/>\n                    <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Checking hookup app\" id=\"80X-MS-tDZ\">\n                        <font key=\"font\" metaFont=\"system\"/>\n                        <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                    </textFieldCell>\n                </textField>\n            </subviews>\n            <constraints>\n                <constraint firstItem=\"xNH-Yj-HPf\" firstAttribute=\"leading\" secondItem=\"YTY-Kw-amg\" secondAttribute=\"leading\" id=\"27F-E4-Xic\"/>\n                <constraint firstItem=\"GxR-Fq-RaO\" firstAttribute=\"top\" secondItem=\"YTY-Kw-amg\" secondAttribute=\"top\" constant=\"25\" id=\"2uz-Yn-64U\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"JmU-05-Npj\" secondAttribute=\"trailing\" constant=\"20\" id=\"3Zr-9P-jHV\"/>\n                <constraint firstItem=\"JmU-05-Npj\" firstAttribute=\"leading\" secondItem=\"v58-82-ta2\" secondAttribute=\"trailing\" constant=\"9\" id=\"4Q3-Ay-eIq\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"dfe-CT-saf\" secondAttribute=\"trailing\" constant=\"20\" id=\"5fN-2s-I0F\"/>\n                <constraint firstItem=\"OgZ-Bi-Ohj\" firstAttribute=\"leading\" secondItem=\"GxR-Fq-RaO\" secondAttribute=\"trailing\" constant=\"6\" id=\"Mhb-69-LzN\"/>\n                <constraint firstItem=\"GxR-Fq-RaO\" firstAttribute=\"leading\" secondItem=\"YTY-Kw-amg\" secondAttribute=\"leading\" constant=\"10\" id=\"Otd-HJ-i0a\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"xNH-Yj-HPf\" secondAttribute=\"bottom\" id=\"dEp-wb-vHl\"/>\n                <constraint firstItem=\"OgZ-Bi-Ohj\" firstAttribute=\"top\" secondItem=\"GxR-Fq-RaO\" secondAttribute=\"top\" id=\"oKQ-9o-t9Y\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"xNH-Yj-HPf\" secondAttribute=\"trailing\" id=\"qLR-Ir-hrG\"/>\n                <constraint firstItem=\"JmU-05-Npj\" firstAttribute=\"centerY\" secondItem=\"v58-82-ta2\" secondAttribute=\"centerY\" id=\"r3I-gv-4lA\"/>\n                <constraint firstItem=\"xNH-Yj-HPf\" firstAttribute=\"top\" secondItem=\"YTY-Kw-amg\" secondAttribute=\"top\" id=\"sjq-7u-DIS\"/>\n                <constraint firstItem=\"dfe-CT-saf\" firstAttribute=\"top\" secondItem=\"YTY-Kw-amg\" secondAttribute=\"top\" constant=\"25\" id=\"w0Y-w9-nAu\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"butEnable\" destination=\"dfe-CT-saf\" id=\"pCE-JV-qxH\"/>\n                <outlet property=\"butPick\" destination=\"JmU-05-Npj\" id=\"efT-Rd-zS4\"/>\n                <outlet property=\"hookupNameTextField\" destination=\"v58-82-ta2\" id=\"Eo8-Oa-tNa\"/>\n                <outlet property=\"statusImageView\" destination=\"GxR-Fq-RaO\" id=\"GTh-OK-pwz\"/>\n                <outlet property=\"statusTextField\" destination=\"OgZ-Bi-Ohj\" id=\"pgW-Cc-B2k\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"139\" y=\"171.5\"/>\n        </customView>\n    </objects>\n    <resources>\n        <image name=\"NSStatusNone\" width=\"16\" height=\"16\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Output/CocoaHookup/CocoaHookupPresenter.swift",
    "content": "//\n//  CocoaHookupPresenter.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 09/04/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport Cocoa\nimport RCPreferences\n\nprotocol CocoaHookupPresenterInput: class {\n    \n    var isShellScriptInstalled: Bool? {get set}\n    func enableCocoaHookup (_ enabled: Bool)\n    func refresh (withApp appName: String)\n    func pickApp()\n}\n\nprotocol CocoaHookupPresenterOutput: class {\n    \n    func setStatusImage (_ imageName: NSImage.Name)\n    func setStatusText (_ text: String)\n    func setButEnable (on: Bool?, enabled: Bool?)\n    func setButPick (enabled: Bool)\n    func setApp (appName: String?, enabled: Bool?)\n}\n\nclass CocoaHookupPresenter {\n    \n    weak var userInterface: CocoaHookupPresenterOutput?\n    let hookupModule = ModuleHookup()\n    fileprivate let localPreferences = RCPreferences<LocalPreferences>()\n    \n    var isShellScriptInstalled: Bool? {\n        didSet {\n            self.refresh()\n        }\n    }\n    \n    init() {\n        \n    }\n    \n    func refresh() {\n        \n        hookupModule.isAppReachable(completion: { [weak self] appInstalled in\n            \n            guard let wself = self, let userInterface = wself.userInterface else {\n                return\n            }\n            if wself.isShellScriptInstalled == true {\n                userInterface.setStatusImage(appInstalled ? NSImage.statusAvailableName : NSImage.statusPartiallyAvailableName)\n                userInterface.setStatusText(appInstalled ? \"Start/Stop AppleScripts will be sent to the selected Cocoa app\" : \"App not reachable\")\n            } else {\n                userInterface.setStatusImage(NSImage.statusUnavailableName)\n                userInterface.setStatusText(\"Not possible to use hookups, please install shell support first!\")\n            }\n            userInterface.setApp(appName: wself.localPreferences.string(.settingsHookupAppName),\n                                 enabled: wself.localPreferences.bool(.enableCocoaHookup))\n            \n            userInterface.setButEnable(on: wself.localPreferences.bool(.enableCocoaHookup),\n                                       enabled: appInstalled)\n            \n            userInterface.setButPick(enabled: wself.localPreferences.bool(.enableCocoaHookup))\n        })\n    }\n}\n\nextension CocoaHookupPresenter: CocoaHookupPresenterInput {\n    \n    func enableCocoaHookup (_ enabled: Bool) {\n        localPreferences.set(enabled, forKey: .enableCocoaHookup)\n        userInterface!.setApp(appName: nil, enabled: enabled)\n        userInterface!.setButEnable(on: enabled, enabled: nil)\n        userInterface!.setButPick(enabled: enabled)\n    }\n    \n    func refresh (withApp appName: String) {\n        // Set the command to userDefaults and it will be read by the hookup module from there\n        localPreferences.set(appName, forKey: .settingsHookupAppName)\n        refresh()\n    }\n    \n    \n    func pickApp() {\n        \n        let panel = NSOpenPanel()\n        panel.canChooseFiles = true\n        panel.canChooseDirectories = false\n        panel.allowsMultipleSelection = false\n        panel.showsHiddenFiles = false\n        panel.allowedFileTypes = [\"app\"]\n        panel.message = \"Please select the custom .app with support for Jirassic AppleScript\"\n        panel.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.maximumWindow)))\n        panel.begin { [weak self] (result) -> Void in\n            \n            guard let self else {\n                return\n            }\n            if result == NSApplication.ModalResponse.OK {\n                if let url = panel.urls.first {\n                    let appName = url.absoluteString\n                        .components(separatedBy: \"/\")\n                        .last?\n                        .replacingOccurrences(of: \".app\", with: \"\")\n                        .replacingOccurrences(of: \"%20\", with: \" \")\n                    self.refresh (withApp: appName ?? \"\")\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Output/Hookup/HookupCell.swift",
    "content": "//\n//  HookupCell.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 31/01/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nclass HookupCell: NSTableRowView, Saveable {\n    \n    static let height = CGFloat(160)\n    \n    @IBOutlet fileprivate var statusImageView: NSImageView!\n    @IBOutlet fileprivate var statusTextField: NSTextField!\n    @IBOutlet fileprivate var butEnable: NSButton!\n    @IBOutlet fileprivate var hookupNameTextField: NSTextField!\n    @IBOutlet fileprivate var butEnableCredentials: NSButton!\n    @IBOutlet fileprivate var butPick: NSButton!\n    \n    var presenter: HookupPresenterInput = HookupPresenter()\n    \n    override func awakeFromNib() {\n        super.awakeFromNib()\n        hookupNameTextField.delegate = self\n        (presenter as! HookupPresenter).userInterface = self\n    }\n    \n    func save() {\n        // Already saved\n    }\n    \n    @IBAction func handleEnableButton (_ sender: NSButton) {\n        presenter.enableHookup(sender.state == .on)\n    }\n    \n    @IBAction func handleEnableCredentialsButton (_ sender: NSButton) {\n        presenter.enableCredentials(sender.state == .on)\n    }\n    \n    @IBAction func handlePickButton (_ sender: NSButton) {\n        presenter.pickCLI()\n    }\n}\n\nextension HookupCell: HookupPresenterOutput {\n    \n    func setStatusImage (_ imageName: NSImage.Name) {\n        statusImageView.image = NSImage(named: imageName)\n    }\n    func setStatusText (_ text: String) {\n        statusTextField.stringValue = text\n    }\n    func setButEnable (on: Bool?, enabled: Bool?) {\n        if let isOn = on {\n            butEnable.title = isOn ? \"Enabled\" : \"Disabled\"\n            butEnable.state = isOn ? .on : .off\n        }\n        if let enabled = enabled {\n            butEnable.isEnabled = enabled\n        }\n    }\n    func setButEnableCredentials (on: Bool?, enabled: Bool?) {\n        if let isOn = on {\n            butEnableCredentials.state = isOn ? .on : .off\n        }\n        if let enabled = enabled {\n            butEnableCredentials.isEnabled = enabled\n        }\n    }\n    func setButPick (enabled: Bool) {\n        butPick.isEnabled = enabled\n    }\n    func setCommand (path: String?, enabled: Bool?) {\n        if let path = path {\n            hookupNameTextField.stringValue = path\n        }\n        if let enabled = enabled {\n            hookupNameTextField.isEnabled = enabled\n        }\n    }\n}\n\nextension HookupCell: NSTextFieldDelegate {\n    \n    func controlTextDidEndEditing (_ obj: Notification) {\n        presenter.refresh(withCommand: hookupNameTextField.stringValue)\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Output/Hookup/HookupCell.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"13771\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"13771\"/>\n        <capability name=\"box content view\" minToolsVersion=\"7.0\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView identifier=\"HookupCell\" id=\"c22-O7-iKe\" customClass=\"HookupCell\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"480\" height=\"160\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <box autoresizesSubviews=\"NO\" borderType=\"line\" title=\"CLI hookup\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Fpy-Mt-WYx\">\n                    <rect key=\"frame\" x=\"-3\" y=\"-4\" width=\"486\" height=\"164\"/>\n                    <view key=\"contentView\" id=\"ZSq-u6-jDQ\">\n                        <rect key=\"frame\" x=\"1\" y=\"1\" width=\"484\" height=\"148\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" fixedFrame=\"YES\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"b27-6N-xUR\">\n                                <rect key=\"frame\" x=\"11\" y=\"80\" width=\"406\" height=\"17\"/>\n                                <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"To find the full path to your custom cmd type in terminal &quot;which cmd-name&quot;\" id=\"lL2-dX-L8R\">\n                                    <font key=\"font\" metaFont=\"smallSystem\"/>\n                                    <color key=\"textColor\" name=\"disabledControlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"8fZ-Cp-eRf\">\n                                <rect key=\"frame\" x=\"11\" y=\"53\" width=\"57\" height=\"17\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Full path\" id=\"mU5-gT-oxO\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Iya-eE-Nay\">\n                                <rect key=\"frame\" x=\"76\" y=\"50\" width=\"339\" height=\"22\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" borderStyle=\"bezel\" placeholderString=\"eg. /usr/local/bin/cmdName\" bezelStyle=\"round\" id=\"aEb-dy-B5y\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"textColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" red=\"0.95654549870000005\" green=\"0.87322156549999996\" blue=\"0.28354544710000001\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"displayP3\"/>\n                                </textFieldCell>\n                            </textField>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"Iya-eE-Nay\" firstAttribute=\"top\" secondItem=\"ZSq-u6-jDQ\" secondAttribute=\"top\" constant=\"76\" id=\"19n-Ft-7VE\"/>\n                            <constraint firstItem=\"Iya-eE-Nay\" firstAttribute=\"leading\" secondItem=\"8fZ-Cp-eRf\" secondAttribute=\"trailing\" constant=\"10\" id=\"BYD-6H-UII\"/>\n                            <constraint firstItem=\"8fZ-Cp-eRf\" firstAttribute=\"leading\" secondItem=\"ZSq-u6-jDQ\" secondAttribute=\"leading\" constant=\"13\" id=\"ULL-ne-ObK\"/>\n                            <constraint firstItem=\"Iya-eE-Nay\" firstAttribute=\"centerY\" secondItem=\"8fZ-Cp-eRf\" secondAttribute=\"centerY\" id=\"v0B-fo-NXP\"/>\n                        </constraints>\n                    </view>\n                </box>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"dcr-sd-lMl\">\n                    <rect key=\"frame\" x=\"422\" y=\"48\" width=\"38\" height=\"19\"/>\n                    <buttonCell key=\"cell\" type=\"roundRect\" title=\"Pick\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"77k-UQ-WrO\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"cellTitle\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handlePickButton:\" target=\"c22-O7-iKe\" id=\"TIA-DH-w8i\"/>\n                    </connections>\n                </button>\n                <button translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"1n4-yT-yeV\">\n                    <rect key=\"frame\" x=\"8\" y=\"19\" width=\"194\" height=\"18\"/>\n                    <buttonCell key=\"cell\" type=\"check\" title=\"Include credentials from Jira\" bezelStyle=\"regularSquare\" imagePosition=\"left\" state=\"on\" inset=\"2\" id=\"wCg-nU-14d\">\n                        <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                        <font key=\"font\" metaFont=\"system\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleEnableCredentialsButton:\" target=\"c22-O7-iKe\" id=\"OgZ-8x-bua\"/>\n                    </connections>\n                </button>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"VoS-Wa-fQ9\">\n                    <rect key=\"frame\" x=\"400\" y=\"116\" width=\"60\" height=\"19\"/>\n                    <buttonCell key=\"cell\" type=\"roundRect\" title=\"Enabled\" alternateTitle=\"Disabled\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"cHn-29-2sZ\">\n                        <behavior key=\"behavior\" lightByBackground=\"YES\" lightByGray=\"YES\" changeBackground=\"YES\" changeGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"cellTitle\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleEnableButton:\" target=\"c22-O7-iKe\" id=\"zM4-E4-JSc\"/>\n                    </connections>\n                </button>\n                <imageView horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Vab-FZ-KUf\">\n                    <rect key=\"frame\" x=\"10\" y=\"117\" width=\"18\" height=\"18\"/>\n                    <constraints>\n                        <constraint firstAttribute=\"height\" constant=\"18\" id=\"BJj-aW-htN\"/>\n                        <constraint firstAttribute=\"width\" constant=\"18\" id=\"y1y-gJ-GEO\"/>\n                    </constraints>\n                    <imageCell key=\"cell\" refusesFirstResponder=\"YES\" alignment=\"left\" imageScaling=\"proportionallyDown\" image=\"NSStatusNone\" id=\"3Rh-Ib-RZF\"/>\n                </imageView>\n                <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"LTM-Hh-or6\">\n                    <rect key=\"frame\" x=\"32\" y=\"118\" width=\"140\" height=\"17\"/>\n                    <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Checking hookup cmd\" id=\"RRt-S7-Jdp\">\n                        <font key=\"font\" metaFont=\"system\"/>\n                        <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                    </textFieldCell>\n                </textField>\n            </subviews>\n            <constraints>\n                <constraint firstItem=\"1n4-yT-yeV\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"10\" id=\"7FC-0O-z6m\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"1n4-yT-yeV\" secondAttribute=\"bottom\" constant=\"21\" id=\"Fnt-B4-6oF\"/>\n                <constraint firstItem=\"LTM-Hh-or6\" firstAttribute=\"top\" secondItem=\"Vab-FZ-KUf\" secondAttribute=\"top\" id=\"LBz-Y1-yIu\"/>\n                <constraint firstItem=\"dcr-sd-lMl\" firstAttribute=\"leading\" secondItem=\"Iya-eE-Nay\" secondAttribute=\"trailing\" constant=\"9\" id=\"Pcu-86-WlR\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"dcr-sd-lMl\" secondAttribute=\"trailing\" constant=\"20\" id=\"Rsf-rL-ggY\"/>\n                <constraint firstItem=\"VoS-Wa-fQ9\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" constant=\"25\" id=\"W6f-VP-lxq\"/>\n                <constraint firstItem=\"Vab-FZ-KUf\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" constant=\"25\" id=\"Wo4-bi-vVB\"/>\n                <constraint firstItem=\"dcr-sd-lMl\" firstAttribute=\"centerY\" secondItem=\"Iya-eE-Nay\" secondAttribute=\"centerY\" id=\"jRc-5y-5DC\"/>\n                <constraint firstItem=\"Vab-FZ-KUf\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"10\" id=\"jb5-rb-scr\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"Fpy-Mt-WYx\" secondAttribute=\"trailing\" id=\"nh3-SO-LZj\"/>\n                <constraint firstItem=\"Fpy-Mt-WYx\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" id=\"oom-bt-TOY\"/>\n                <constraint firstItem=\"Fpy-Mt-WYx\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" id=\"pkk-tz-Ldp\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"Fpy-Mt-WYx\" secondAttribute=\"bottom\" id=\"sez-Ws-3bx\"/>\n                <constraint firstItem=\"LTM-Hh-or6\" firstAttribute=\"leading\" secondItem=\"Vab-FZ-KUf\" secondAttribute=\"trailing\" constant=\"6\" id=\"vkf-Q8-gRV\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"VoS-Wa-fQ9\" secondAttribute=\"trailing\" constant=\"20\" id=\"x7V-Wp-rdS\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"butEnable\" destination=\"VoS-Wa-fQ9\" id=\"MJj-d1-4f1\"/>\n                <outlet property=\"butEnableCredentials\" destination=\"1n4-yT-yeV\" id=\"pQg-tM-OGH\"/>\n                <outlet property=\"butPick\" destination=\"dcr-sd-lMl\" id=\"73a-9D-9oW\"/>\n                <outlet property=\"hookupNameTextField\" destination=\"Iya-eE-Nay\" id=\"o3i-AN-ae3\"/>\n                <outlet property=\"statusImageView\" destination=\"Vab-FZ-KUf\" id=\"hhL-on-F9D\"/>\n                <outlet property=\"statusTextField\" destination=\"LTM-Hh-or6\" id=\"uPs-rA-D8v\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"139\" y=\"204\"/>\n        </customView>\n    </objects>\n    <resources>\n        <image name=\"NSStatusNone\" width=\"16\" height=\"16\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Output/Hookup/HookupPresenter.swift",
    "content": "//\n//  HookupPresenter.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 01/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport Cocoa\nimport RCPreferences\n\nprotocol HookupPresenterInput: class {\n    \n    var isShellScriptInstalled: Bool? {get set}\n    func enableHookup (_ enabled: Bool)\n    func enableCredentials (_ enabled: Bool)\n    func refresh (withCommand command: String)\n    func pickCLI()\n}\n\nprotocol HookupPresenterOutput: class {\n    \n    func setStatusImage (_ imageName: NSImage.Name)\n    func setStatusText (_ text: String)\n    func setButEnable (on: Bool?, enabled: Bool?)\n    func setButEnableCredentials (on: Bool?, enabled: Bool?)\n    func setButPick (enabled: Bool)\n    func setCommand (path: String?, enabled: Bool?)\n}\n\nclass HookupPresenter {\n    \n    weak var userInterface: HookupPresenterOutput?\n    let hookupModule = ModuleHookup()\n    fileprivate let localPreferences = RCPreferences<LocalPreferences>()\n    \n    var isShellScriptInstalled: Bool? {\n        didSet {\n            self.refresh()\n        }\n    }\n    \n    init() {\n        \n    }\n    \n    func refresh() {\n        \n        hookupModule.isCmdReachable(completion: { [weak self] commandInstalled in\n            \n            guard let wself = self, let userInterface = wself.userInterface else {\n                return\n            }\n            if wself.isShellScriptInstalled == true {\n                userInterface.setStatusImage(commandInstalled ? NSImage.statusAvailableName : NSImage.statusPartiallyAvailableName)\n                userInterface.setStatusText(commandInstalled ? \"Start/End day actions will be sent to this custom cmd\" : \"Custom cmd is not reachable\")\n            } else {\n                userInterface.setStatusImage(NSImage.statusUnavailableName)\n                userInterface.setStatusText(\"Not possible to use custom cmd, please install shell support first!\")\n            }\n            userInterface.setCommand(path: wself.localPreferences.string(.settingsHookupCmdName),\n                                     enabled: wself.localPreferences.bool(.enableHookup))\n            \n            userInterface.setButEnable(on: wself.localPreferences.bool(.enableHookup),\n                                       enabled: commandInstalled)\n            \n            userInterface.setButEnableCredentials(on: wself.localPreferences.bool(.enableHookupCredentials),\n                                                  enabled: commandInstalled)\n            \n            userInterface.setButPick(enabled: wself.localPreferences.bool(.enableHookup))\n        })\n    }\n}\n\nextension HookupPresenter: HookupPresenterInput {\n    \n    func enableHookup (_ enabled: Bool) {\n        localPreferences.set(enabled, forKey: .enableHookup)\n        userInterface!.setCommand(path: nil, enabled: enabled)\n        userInterface!.setButEnable(on: enabled, enabled: nil)\n        userInterface!.setButPick(enabled: enabled)\n    }\n    \n    func enableCredentials (_ enabled: Bool) {\n        localPreferences.set(enabled, forKey: .enableHookupCredentials)\n    }\n    \n    func refresh (withCommand command: String) {\n        // Set the command to userDefaults and it will be read by the hookup module from there\n        localPreferences.set(command, forKey: .settingsHookupCmdName)\n        refresh()\n    }\n    \n    \n    func pickCLI() {\n        \n        let panel = NSOpenPanel()\n        panel.canChooseFiles = true\n        panel.canChooseDirectories = false\n        panel.allowsMultipleSelection = false\n        panel.showsHiddenFiles = true\n        panel.allowedFileTypes = [\"\"]\n        panel.message = \"Please select a CLI app\"\n        panel.level = NSWindow.Level(rawValue: Int(CGWindowLevelForKey(.maximumWindow)))\n        panel.begin { [weak self] (result) -> Void in\n            \n            guard let wself = self else {\n                return\n            }\n            if result == NSApplication.ModalResponse.OK {\n                if let url = panel.urls.first {\n                    var path = url.absoluteString\n                    path = path.replacingOccurrences(of: \"file://\", with: \"\")\n                    \n                    wself.refresh (withCommand: path)\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Output/JiraTempo/JiraTempoCell.swift",
    "content": "//\n//  JiraTempoCell.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 31/01/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\nimport RCPreferences\n\nclass JiraTempoCell: NSTableRowView {\n    \n    static let height = CGFloat(250)\n    \n    @IBOutlet private var butPurchase: NSButton!\n    @IBOutlet private var baseUrlTextField: NSTextField!\n    @IBOutlet private var userTextField: NSTextField!\n    @IBOutlet private var passwordTextField: NSTextField!\n    @IBOutlet private var errorTextField: NSTextField!\n    @IBOutlet private var projectNamePopup: NSPopUpButton!\n    @IBOutlet private var projectIssueNamePopup: NSPopUpButton!\n    @IBOutlet private var progressIndicator: NSProgressIndicator!\n    \n    private let localPreferences = RCPreferences<LocalPreferences>()\n    var presenter: JiraTempoPresenterInput = JiraTempoPresenter()\n    var onPurchasePressed: (() -> Void)?\n\n    override func awakeFromNib() {\n        super.awakeFromNib()\n        \n        baseUrlTextField.delegate = self\n        userTextField.delegate = self\n        passwordTextField.delegate = self\n        \n        baseUrlTextField.stringValue = localPreferences.string(.settingsJiraUrl)\n        userTextField.stringValue = localPreferences.string(.settingsJiraUser)\n        passwordTextField.stringValue = Keychain.getPassword()\n        \n        projectNamePopup.target = self\n        projectNamePopup.action = #selector(JiraTempoCell.projectNamePopupSelected(_:))\n        \n        projectIssueNamePopup.target = self\n        projectIssueNamePopup.action = #selector(JiraTempoCell.projectIssueNamePopupSelected(_:))\n        \n        (presenter as! JiraTempoPresenter).userInterface = self\n        presenter.setupUserInterface()\n        presenter.checkCredentials()\n    }\n    \n    func save() {\n        presenter.save(url: baseUrlTextField.stringValue,\n                       user: userTextField.stringValue,\n                       password: passwordTextField.stringValue)\n    }\n    \n    @IBAction func handlePurchaseButton (_ sender: NSButton) {\n        onPurchasePressed?()\n    }\n    \n    @IBAction func projectNamePopupSelected (_ sender: NSPopUpButton) {\n        if let title = sender.selectedItem?.title {\n            localPreferences.set(title, forKey: .settingsJiraProjectKey)\n            presenter.loadProjectIssues(for: title)\n        }\n    }\n    \n    @IBAction func projectIssueNamePopupSelected (_ sender: NSPopUpButton) {\n        localPreferences.set(sender.selectedItem?.title ?? \"\", forKey: .settingsJiraProjectIssueKey)\n    }\n}\n\nextension JiraTempoCell: JiraTempoPresenterOutput {\n    \n    func setPurchased (_ purchased: Bool) {\n        butPurchase.isHidden = purchased\n        baseUrlTextField.isEnabled = purchased\n        userTextField.isEnabled = purchased\n        passwordTextField.isEnabled = purchased\n        projectNamePopup.isEnabled = purchased\n        projectIssueNamePopup.isEnabled = purchased\n    }\n    \n    func enableProgressIndicator (_ enabled: Bool) {\n        enabled\n            ? progressIndicator.startAnimation(nil)\n            : progressIndicator.stopAnimation(nil)\n    }\n    \n    func showProjects (_ projects: [String], selectedProject: String) {\n        projectNamePopup.removeAllItems()\n        projectNamePopup.addItems(withTitles: projects)\n        projectNamePopup.selectItem(withTitle: selectedProject)\n    }\n    \n    func showProjectIssues (_ issues: [String], selectedIssue: String) {\n        projectIssueNamePopup.removeAllItems()\n        projectIssueNamePopup.addItems(withTitles: issues)\n        projectIssueNamePopup.selectItem(withTitle: selectedIssue)\n    }\n    \n    func showErrorMessage (_ message: String) {\n        errorTextField.stringValue = message\n    }\n}\n\nextension JiraTempoCell: NSTextFieldDelegate {\n    \n    func controlTextDidEndEditing(_ obj: Notification) {\n        \n        guard baseUrlTextField.stringValue != \"\",\n            userTextField.stringValue != \"\",\n            passwordTextField.stringValue != \"\" else {\n            // Fields are empty\n            save()\n            return\n        }\n        guard baseUrlTextField.stringValue != localPreferences.string(.settingsJiraUrl) ||\n            userTextField.stringValue != localPreferences.string(.settingsJiraUser) ||\n            passwordTextField.stringValue != Keychain.getPassword() else {\n            // No change to the fields\n            return\n        }\n        save()\n        presenter.checkCredentials()\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Output/JiraTempo/JiraTempoCell.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14460.31\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView identifier=\"JiraTempoCell\" id=\"c22-O7-iKe\" customClass=\"JiraTempoCell\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"511\" height=\"250\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <box autoresizesSubviews=\"NO\" borderType=\"line\" title=\"Jira Tempo\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"bxZ-h3-hcI\">\n                    <rect key=\"frame\" x=\"-3\" y=\"-4\" width=\"517\" height=\"254\"/>\n                    <view key=\"contentView\" id=\"gTj-S0-GSV\">\n                        <rect key=\"frame\" x=\"3\" y=\"3\" width=\"511\" height=\"236\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" fixedFrame=\"YES\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"LJj-ST-mgw\">\n                                <rect key=\"frame\" x=\"11\" y=\"127\" width=\"73\" height=\"17\"/>\n                                <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Credentials\" id=\"f18-jK-DWj\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" fixedFrame=\"YES\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"168-V1-bw4\">\n                                <rect key=\"frame\" x=\"11\" y=\"156\" width=\"78\" height=\"17\"/>\n                                <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Jira base url\" id=\"J0h-N5-RBr\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"sac-XU-YOc\">\n                                <rect key=\"frame\" x=\"110\" y=\"124\" width=\"180\" height=\"22\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"180\" id=\"gch-lX-jiT\"/>\n                                </constraints>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" borderStyle=\"bezel\" placeholderString=\"User\" bezelStyle=\"round\" id=\"pEb-he-QBb\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"CyJ-B9-4w3\">\n                                <rect key=\"frame\" x=\"110\" y=\"154\" width=\"381\" height=\"22\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" borderStyle=\"bezel\" placeholderString=\"Base url\" bezelStyle=\"round\" id=\"wMy-gy-TCi\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"textColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" red=\"0.95654549870000005\" green=\"0.87322156549999996\" blue=\"0.28354544710000001\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"displayP3\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"DK6-8B-zU7\">\n                                <rect key=\"frame\" x=\"11\" y=\"21\" width=\"84\" height=\"17\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Project name\" id=\"xDr-i8-d3D\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"32U-E8-26L\">\n                                <rect key=\"frame\" x=\"267\" y=\"21\" width=\"73\" height=\"17\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Issue name\" id=\"2XS-9S-G2g\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" fixedFrame=\"YES\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Nox-XD-xeR\">\n                                <rect key=\"frame\" x=\"11\" y=\"199\" width=\"405\" height=\"17\"/>\n                                <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Save daily worklogs to Jira Tempo when you close the day.\" id=\"BeJ-Kq-eHi\">\n                                    <font key=\"font\" metaFont=\"smallSystem\"/>\n                                    <color key=\"textColor\" name=\"disabledControlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" fixedFrame=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"u6l-NZ-sMH\">\n                                <rect key=\"frame\" x=\"11\" y=\"62\" width=\"485\" height=\"37\"/>\n                                <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                <textFieldCell key=\"cell\" sendsActionOnEndEditing=\"YES\" title=\"Error\" id=\"6TL-Ue-k0c\">\n                                    <font key=\"font\" metaFont=\"smallSystem\"/>\n                                    <color key=\"textColor\" red=\"0.82619418379999998\" green=\"0.18153228830000001\" blue=\"0.1534976841\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"displayP3\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <box verticalHuggingPriority=\"750\" boxType=\"separator\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"CuW-rz-EzX\">\n                                <rect key=\"frame\" x=\"12\" y=\"51\" width=\"487\" height=\"5\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"1\" id=\"FgQ-JP-tJl\"/>\n                                </constraints>\n                            </box>\n                            <popUpButton verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"sAK-lu-hJn\">\n                                <rect key=\"frame\" x=\"106\" y=\"16\" width=\"145\" height=\"25\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"140\" id=\"glm-d7-gHE\"/>\n                                </constraints>\n                                <popUpButtonCell key=\"cell\" type=\"push\" title=\"Item 1\" bezelStyle=\"rounded\" alignment=\"left\" lineBreakMode=\"truncatingTail\" state=\"on\" borderStyle=\"borderAndBezel\" imageScaling=\"proportionallyDown\" inset=\"2\" selectedItem=\"3iE-pL-kt9\" id=\"YAM-5t-F1C\">\n                                    <behavior key=\"behavior\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"menu\"/>\n                                    <menu key=\"menu\" id=\"AFV-zQ-GBa\">\n                                        <items>\n                                            <menuItem title=\"Item 1\" state=\"on\" id=\"3iE-pL-kt9\"/>\n                                            <menuItem title=\"Item 2\" id=\"NJi-B1-Ft6\"/>\n                                            <menuItem title=\"Item 3\" id=\"a7w-jg-C5T\"/>\n                                        </items>\n                                    </menu>\n                                </popUpButtonCell>\n                                <connections>\n                                    <action selector=\"projectNamePopupSelected:\" target=\"c22-O7-iKe\" id=\"1Mu-uG-l8H\"/>\n                                </connections>\n                            </popUpButton>\n                            <popUpButton verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"lWn-53-lCO\">\n                                <rect key=\"frame\" x=\"349\" y=\"16\" width=\"145\" height=\"25\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"140\" id=\"2Lw-sn-lt0\"/>\n                                    <constraint firstAttribute=\"height\" constant=\"21\" id=\"vfu-LW-94d\"/>\n                                </constraints>\n                                <popUpButtonCell key=\"cell\" type=\"push\" title=\"Item 1\" bezelStyle=\"rounded\" alignment=\"left\" lineBreakMode=\"truncatingTail\" state=\"on\" borderStyle=\"borderAndBezel\" imageScaling=\"proportionallyDown\" inset=\"2\" selectedItem=\"nac-xQ-QzF\" id=\"HQY-RV-FzS\">\n                                    <behavior key=\"behavior\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"menu\"/>\n                                    <menu key=\"menu\" id=\"s0m-4J-Chx\">\n                                        <items>\n                                            <menuItem title=\"Item 1\" state=\"on\" id=\"nac-xQ-QzF\"/>\n                                            <menuItem title=\"Item 2\" id=\"1ft-yy-NFV\"/>\n                                            <menuItem title=\"Item 3\" id=\"RCu-IO-fvT\"/>\n                                        </items>\n                                    </menu>\n                                </popUpButtonCell>\n                                <connections>\n                                    <action selector=\"projectIssueNamePopupSelected:\" target=\"c22-O7-iKe\" id=\"LuN-sS-acP\"/>\n                                </connections>\n                            </popUpButton>\n                            <progressIndicator wantsLayer=\"YES\" horizontalHuggingPriority=\"750\" verticalHuggingPriority=\"750\" fixedFrame=\"YES\" maxValue=\"100\" displayedWhenStopped=\"NO\" bezeled=\"NO\" indeterminate=\"YES\" controlSize=\"small\" style=\"spinning\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"xNx-oi-lgq\">\n                                <rect key=\"frame\" x=\"13\" y=\"83\" width=\"16\" height=\"16\"/>\n                                <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                            </progressIndicator>\n                            <secureTextField verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"rsL-Fg-y5y\">\n                                <rect key=\"frame\" x=\"303\" y=\"124\" width=\"188\" height=\"22\"/>\n                                <secureTextFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" borderStyle=\"bezel\" usesSingleLineMode=\"YES\" bezelStyle=\"round\" id=\"K3o-5p-cpk\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <allowedInputSourceLocales>\n                                        <string>NSAllRomanInputSourcesLocaleIdentifier</string>\n                                    </allowedInputSourceLocales>\n                                </secureTextFieldCell>\n                            </secureTextField>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"apg-zS-b6p\">\n                                <rect key=\"frame\" x=\"423\" y=\"197\" width=\"67\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"Purchase\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"Snc-aP-0bE\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handlePurchaseButton:\" target=\"c22-O7-iKe\" id=\"Mds-Vr-Z3V\"/>\n                                </connections>\n                            </button>\n                        </subviews>\n                        <constraints>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"CuW-rz-EzX\" secondAttribute=\"trailing\" constant=\"12\" id=\"15m-bS-tAR\"/>\n                            <constraint firstItem=\"sac-XU-YOc\" firstAttribute=\"leading\" secondItem=\"gTj-S0-GSV\" secondAttribute=\"leading\" constant=\"110\" id=\"4br-0t-eIK\"/>\n                            <constraint firstItem=\"sAK-lu-hJn\" firstAttribute=\"centerY\" secondItem=\"DK6-8B-zU7\" secondAttribute=\"centerY\" id=\"4lg-Tf-dLH\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"apg-zS-b6p\" secondAttribute=\"trailing\" constant=\"21\" id=\"6rg-tA-pfb\"/>\n                            <constraint firstItem=\"sac-XU-YOc\" firstAttribute=\"top\" secondItem=\"CyJ-B9-4w3\" secondAttribute=\"bottom\" constant=\"8\" id=\"7xE-GW-gSS\"/>\n                            <constraint firstItem=\"CuW-rz-EzX\" firstAttribute=\"leading\" secondItem=\"gTj-S0-GSV\" secondAttribute=\"leading\" constant=\"12\" id=\"Gq0-Qp-5F2\"/>\n                            <constraint firstItem=\"rsL-Fg-y5y\" firstAttribute=\"leading\" secondItem=\"sac-XU-YOc\" secondAttribute=\"trailing\" constant=\"13\" id=\"HiH-RJ-exW\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"lWn-53-lCO\" secondAttribute=\"trailing\" constant=\"20\" id=\"Jho-md-2Ke\"/>\n                            <constraint firstItem=\"apg-zS-b6p\" firstAttribute=\"top\" secondItem=\"gTj-S0-GSV\" secondAttribute=\"top\" constant=\"20\" id=\"PZN-w6-yxZ\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"rsL-Fg-y5y\" secondAttribute=\"trailing\" constant=\"20\" id=\"Z7P-Es-F9W\"/>\n                            <constraint firstItem=\"CyJ-B9-4w3\" firstAttribute=\"leading\" secondItem=\"gTj-S0-GSV\" secondAttribute=\"leading\" constant=\"110\" id=\"aHi-Dl-LqN\"/>\n                            <constraint firstItem=\"32U-E8-26L\" firstAttribute=\"centerY\" secondItem=\"lWn-53-lCO\" secondAttribute=\"centerY\" id=\"fab-In-Jps\"/>\n                            <constraint firstItem=\"lWn-53-lCO\" firstAttribute=\"leading\" secondItem=\"32U-E8-26L\" secondAttribute=\"trailing\" constant=\"13\" id=\"fpa-Z6-cIc\"/>\n                            <constraint firstItem=\"sAK-lu-hJn\" firstAttribute=\"leading\" secondItem=\"DK6-8B-zU7\" secondAttribute=\"trailing\" constant=\"15\" id=\"iDs-qR-JuG\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"CyJ-B9-4w3\" secondAttribute=\"trailing\" constant=\"20\" id=\"nkc-2p-q0g\"/>\n                            <constraint firstItem=\"rsL-Fg-y5y\" firstAttribute=\"top\" secondItem=\"CyJ-B9-4w3\" secondAttribute=\"bottom\" constant=\"8\" id=\"ofg-KM-fs5\"/>\n                            <constraint firstItem=\"DK6-8B-zU7\" firstAttribute=\"top\" secondItem=\"CuW-rz-EzX\" secondAttribute=\"bottom\" constant=\"15\" id=\"puv-rT-nn2\"/>\n                            <constraint firstItem=\"CyJ-B9-4w3\" firstAttribute=\"top\" secondItem=\"gTj-S0-GSV\" secondAttribute=\"top\" constant=\"60\" id=\"q3H-Ya-5zF\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"CuW-rz-EzX\" secondAttribute=\"bottom\" constant=\"53\" id=\"sqs-KE-wdd\"/>\n                            <constraint firstItem=\"32U-E8-26L\" firstAttribute=\"centerY\" secondItem=\"sAK-lu-hJn\" secondAttribute=\"centerY\" id=\"t0G-LM-GZI\"/>\n                            <constraint firstItem=\"DK6-8B-zU7\" firstAttribute=\"leading\" secondItem=\"gTj-S0-GSV\" secondAttribute=\"leading\" constant=\"13\" id=\"tO6-TE-LTX\"/>\n                        </constraints>\n                    </view>\n                </box>\n            </subviews>\n            <constraints>\n                <constraint firstItem=\"bxZ-h3-hcI\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" id=\"Q6A-vP-O6e\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"bxZ-h3-hcI\" secondAttribute=\"bottom\" id=\"dVD-2O-u0T\"/>\n                <constraint firstItem=\"bxZ-h3-hcI\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" id=\"fHp-En-BMi\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"bxZ-h3-hcI\" secondAttribute=\"trailing\" id=\"uzm-g9-qKb\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"baseUrlTextField\" destination=\"CyJ-B9-4w3\" id=\"JSp-IA-c8g\"/>\n                <outlet property=\"butPurchase\" destination=\"apg-zS-b6p\" id=\"ezC-Ea-cwl\"/>\n                <outlet property=\"errorTextField\" destination=\"u6l-NZ-sMH\" id=\"5bI-aO-BMD\"/>\n                <outlet property=\"passwordTextField\" destination=\"rsL-Fg-y5y\" id=\"Udo-c2-eFM\"/>\n                <outlet property=\"progressIndicator\" destination=\"xNx-oi-lgq\" id=\"gMc-22-FKl\"/>\n                <outlet property=\"projectIssueNamePopup\" destination=\"lWn-53-lCO\" id=\"WFo-Qo-mOQ\"/>\n                <outlet property=\"projectNamePopup\" destination=\"sAK-lu-hJn\" id=\"eea-aj-pZQ\"/>\n                <outlet property=\"userTextField\" destination=\"sac-XU-YOc\" id=\"lxN-nw-ZeF\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"154.5\" y=\"122\"/>\n        </customView>\n    </objects>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Output/JiraTempo/JiraTempoPresenter.swift",
    "content": "//\n//  JiraTempoPresenter.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 01/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport RCPreferences\nimport RCLog\n\nprotocol JiraTempoPresenterInput: class {\n    \n    func setupUserInterface()\n    func checkCredentials()\n    func loadProjects()\n    func loadProjectIssues (for projectKey: String)\n    func save (url: String, user: String, password: String)\n}\n\nprotocol JiraTempoPresenterOutput: class {\n    \n    func setPurchased (_ purchased: Bool)\n    func enableProgressIndicator (_ enabled: Bool)\n    func showProjects (_ projects: [String], selectedProject: String)\n    func showProjectIssues (_ issues: [String], selectedIssue: String)\n    func showErrorMessage (_ message: String)\n}\n\nclass JiraTempoPresenter {\n    \n    weak var userInterface: JiraTempoPresenterOutput?\n    private var moduleJira = ModuleJiraTempo()\n    private let store = Store.shared\n    private let pref = RCPreferences<LocalPreferences>()\n}\n\nextension JiraTempoPresenter: JiraTempoPresenterInput {\n    \n    func checkCredentials() {\n        loadProjects()\n    }\n    \n    func setupUserInterface() {\n        \n        userInterface!.setPurchased(store.isJiraTempoPurchased)\n        userInterface!.showErrorMessage(\"\")\n        \n        let selectedProjectName = pref.string(.settingsJiraProjectKey)\n        let projects = selectedProjectName != \"\" ? [selectedProjectName] : []\n        userInterface!.showProjects(projects, selectedProject: selectedProjectName)\n        \n        let selectedProjectIssueName = pref.string(.settingsJiraProjectIssueKey)\n        let issues = selectedProjectIssueName != \"\" ? [selectedProjectIssueName] : []\n        userInterface!.showProjectIssues(issues, selectedIssue: selectedProjectIssueName)\n    }\n    \n    func loadProjects() {\n        \n        // Start loading only if credentials are all setup, otherwise crashes will happen\n        guard store.isJiraTempoPurchased && moduleJira.isConfigured else {\n            return\n        }\n        userInterface!.enableProgressIndicator(true)\n        userInterface!.showErrorMessage(\"\")\n        \n        moduleJira.fetchProjects(success: { [weak self] (projects) in\n            \n            DispatchQueue.main.async {\n                \n                guard let wself = self, let userInterface = wself.userInterface else {\n                    return\n                }\n                userInterface.enableProgressIndicator(false)\n                \n                let titles = projects.map { $0.key }\n                let selectedProjectKey = wself.pref.string(.settingsJiraProjectKey)\n                \n                userInterface.showProjects(titles, selectedProject: selectedProjectKey)\n                if projects.count > 0 && selectedProjectKey != \"\" {\n                    wself.loadProjectIssues(for: selectedProjectKey)\n                }\n            }\n            \n        }, failure: { [weak self] (error) in\n            \n            DispatchQueue.main.async {\n                self?.handleError(error)\n            }\n            \n        })\n    }\n    \n    func loadProjectIssues (for projectKey: String) {\n        \n        userInterface!.enableProgressIndicator(true)\n        userInterface!.showErrorMessage(\"\")\n        \n        moduleJira.fetchProjectIssues (projectKey: projectKey, success: { [weak self] (issues) in\n            \n            DispatchQueue.main.async {\n                \n                guard let wself = self, let userInterface = wself.userInterface else {\n                    return\n                }\n                userInterface.enableProgressIndicator(false)\n                let titles = issues.map { $0.key }\n                userInterface.showProjectIssues(titles, selectedIssue: wself.pref.string(.settingsJiraProjectIssueKey))\n            }\n            \n        }, failure: { [weak self] (error) in\n            \n            DispatchQueue.main.async {\n                self?.handleError(error)\n            }\n            \n        })\n    }\n    \n    private func handleError(_ error: Error) {\n        RCLog(error)\n        var errorMessage = error.localizedDescription\n        switch error._code {\n        case -1001: errorMessage = \"Server not reachable. Is your Jira limited to internal network?\"\n        case 1: errorMessage = \"Unknown, please verify login via browser. Possible causes are wrong domain or you're using an expired password which is causing Jira to ask for captcha.\"\n        default: errorMessage = error.localizedDescription\n        }\n        userInterface!.enableProgressIndicator(false)\n        userInterface!.showErrorMessage(\"Error: \\(errorMessage)\")\n    }\n    \n    func save (url: String, user: String, password: String) {\n        \n        pref.set(url, forKey: .settingsJiraUrl)\n        pref.set(user, forKey: .settingsJiraUser)\n        // Save password only if different than the existing one\n        if password != Keychain.getPassword() {\n            Keychain.setPassword(password)\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Output/OutputTableViewDataSource.swift",
    "content": "//\n//  OutputTableViewDataSource.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 01/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nenum OutputType {\n    case jiraTempo\n    case cliHookup\n    case cocoaHookup\n}\n\nclass OutputTableViewDataSource: NSObject {\n    \n    private let tableView: NSTableView\n    private let cells: [OutputType] = [.jiraTempo]\n    var jiraCell: JiraTempoCell?\n    var cliHookupCell: HookupCell?\n    var cocoaHookupCell: CocoaHookupCell?\n    var onPurchasePressed: (() -> Void)?\n\n    init (tableView: NSTableView) {\n        self.tableView = tableView\n        super.init()\n        \n        JiraTempoCell.register(in: tableView)\n//        HookupCell.register(in: tableView)\n//        CocoaHookupCell.register(in: tableView)\n        \n        jiraCell = JiraTempoCell.instantiate(in: self.tableView)\n//        cliHookupCell = HookupCell.instantiate(in: self.tableView)\n//        cocoaHookupCell = CocoaHookupCell.instantiate(in: self.tableView)\n        \n        jiraCell?.onPurchasePressed = { [weak self] in\n            self?.onPurchasePressed?()\n        }\n    }\n}\n\nextension OutputTableViewDataSource: NSTableViewDataSource {\n    \n    func numberOfRows (in aTableView: NSTableView) -> Int {\n        return cells.count\n    }\n    \n    func tableView (_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {\n        \n        let outputType = cells[row]\n        switch outputType {\n        case .jiraTempo:\n            return JiraTempoCell.height\n        case .cliHookup:\n            return HookupCell.height\n        case .cocoaHookup:\n            return CocoaHookupCell.height\n        }\n    }\n}\n\nextension OutputTableViewDataSource: NSTableViewDelegate {\n    \n    func tableView (_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {\n        \n        var cell: NSView! = nil\n        let outputType = cells[row]\n        switch outputType {\n        case .jiraTempo:\n            cell = jiraCell!\n        case .cliHookup:\n            cell = cliHookupCell!\n        case .cocoaHookup:\n            cell = cocoaHookupCell!\n        }\n        \n        return cell\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Output/OutputsScrollView.swift",
    "content": "//\n//  OutputsTableView.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 01/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nclass OutputsScrollView: NSScrollView {\n    \n    @IBOutlet fileprivate var tableView: NSTableView!\n    var dataSource: OutputTableViewDataSource?// If not declared, the reference is released\n    var onPurchasePressed: (() -> Void)?\n\n    override func awakeFromNib() {\n        super.awakeFromNib()\n        \n        tableView.selectionHighlightStyle = .none\n        tableView.backgroundColor = .clear\n        tableView.intercellSpacing = NSSize(width: 0, height: 30)\n        \n        dataSource = OutputTableViewDataSource(tableView: tableView)\n        dataSource?.onPurchasePressed = { [weak self] in\n            self?.onPurchasePressed?()\n        }\n        tableView.dataSource = dataSource\n        tableView.delegate = dataSource\n        \n        tableView.reloadData()\n    }\n    \n    func save() {\n        dataSource?.jiraCell?.save()\n        dataSource?.cliHookupCell?.save()\n        dataSource?.cocoaHookupCell?.save()\n    }\n    \n    func setHookupStatus (available: Bool) {\n        dataSource?.cliHookupCell?.presenter.isShellScriptInstalled = available\n        dataSource?.cocoaHookupCell?.presenter.isShellScriptInstalled = available\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Output/OutputsScrollView.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"14109\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14109\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <scrollView focusRingType=\"none\" borderType=\"none\" autohidesScrollers=\"YES\" horizontalLineScroll=\"19\" horizontalPageScroll=\"10\" verticalLineScroll=\"19\" verticalPageScroll=\"10\" usesPredominantAxisScrolling=\"NO\" id=\"T3R-v6-BN3\" customClass=\"OutputsScrollView\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"461\" height=\"339\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <clipView key=\"contentView\" drawsBackground=\"NO\" copiesOnScroll=\"NO\" id=\"SSU-Ai-Lfv\">\n                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"461\" height=\"339\"/>\n                <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                <subviews>\n                    <tableView focusRingType=\"none\" verticalHuggingPriority=\"750\" allowsExpansionToolTips=\"YES\" columnAutoresizingStyle=\"lastColumnOnly\" columnSelection=\"YES\" multipleSelection=\"NO\" autosaveColumns=\"NO\" rowSizeStyle=\"automatic\" viewBased=\"YES\" id=\"wCY-gA-BzG\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"461\" height=\"339\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                        <size key=\"intercellSpacing\" width=\"3\" height=\"2\"/>\n                        <color key=\"backgroundColor\" name=\"controlBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"gridColor\" name=\"gridColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <tableColumns>\n                            <tableColumn identifier=\"\" width=\"458\" minWidth=\"40\" maxWidth=\"1000\" id=\"ZNI-wB-eyo\">\n                                <tableHeaderCell key=\"headerCell\" lineBreakMode=\"truncatingTail\" borderStyle=\"border\">\n                                    <font key=\"font\" metaFont=\"smallSystem\"/>\n                                    <color key=\"textColor\" name=\"headerTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"headerColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </tableHeaderCell>\n                                <textFieldCell key=\"dataCell\" lineBreakMode=\"truncatingTail\" selectable=\"YES\" editable=\"YES\" title=\"Text Cell\" id=\"HXD-u1-xqm\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                                <tableColumnResizingMask key=\"resizingMask\" resizeWithTable=\"YES\" userResizable=\"YES\"/>\n                                <prototypeCellViews>\n                                    <tableCellView id=\"FrP-Hf-HK2\">\n                                        <rect key=\"frame\" x=\"1\" y=\"1\" width=\"458\" height=\"17\"/>\n                                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                        <subviews>\n                                            <textField verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" fixedFrame=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"hoq-65-wxy\">\n                                                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"458\" height=\"17\"/>\n                                                <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" flexibleMinY=\"YES\"/>\n                                                <textFieldCell key=\"cell\" lineBreakMode=\"truncatingTail\" sendsActionOnEndEditing=\"YES\" title=\"Table View Cell\" id=\"rj1-hw-pgg\">\n                                                    <font key=\"font\" metaFont=\"system\"/>\n                                                    <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                </textFieldCell>\n                                            </textField>\n                                        </subviews>\n                                        <connections>\n                                            <outlet property=\"textField\" destination=\"hoq-65-wxy\" id=\"qHr-qM-juh\"/>\n                                        </connections>\n                                    </tableCellView>\n                                </prototypeCellViews>\n                            </tableColumn>\n                        </tableColumns>\n                    </tableView>\n                </subviews>\n            </clipView>\n            <scroller key=\"horizontalScroller\" hidden=\"YES\" verticalHuggingPriority=\"750\" horizontal=\"YES\" id=\"Yag-g1-lWp\">\n                <rect key=\"frame\" x=\"1\" y=\"119\" width=\"223\" height=\"15\"/>\n                <autoresizingMask key=\"autoresizingMask\"/>\n            </scroller>\n            <scroller key=\"verticalScroller\" hidden=\"YES\" verticalHuggingPriority=\"750\" horizontal=\"NO\" id=\"fXN-fB-IL0\">\n                <rect key=\"frame\" x=\"224\" y=\"17\" width=\"15\" height=\"102\"/>\n                <autoresizingMask key=\"autoresizingMask\"/>\n            </scroller>\n            <connections>\n                <outlet property=\"tableView\" destination=\"wCY-gA-BzG\" id=\"Gxf-v1-6Pm\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"109\" y=\"157\"/>\n        </scrollView>\n    </objects>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Saveable.swift",
    "content": "//\n//  Saveable.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 17/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nprotocol Saveable {\n    func save()\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Settings.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"14313.18\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14313.18\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Settings View Controller-->\n        <scene sceneID=\"0zN-Dv-kP5\">\n            <objects>\n                <viewController storyboardIdentifier=\"SettingsViewController\" id=\"J1c-ZL-C5e\" customClass=\"SettingsViewController\" customModule=\"Jirassic\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" id=\"JAR-dh-Pss\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"494\" height=\"494\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                        <subviews>\n                            <button fixedFrame=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"aR4-jV-fsE\">\n                                <rect key=\"frame\" x=\"23\" y=\"22\" width=\"138\" height=\"18\"/>\n                                <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                <buttonCell key=\"cell\" type=\"check\" title=\"Launch at startup\" bezelStyle=\"regularSquare\" imagePosition=\"left\" inset=\"2\" id=\"hx6-4U-fCn\">\n                                    <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleLaunchAtStartupButton:\" target=\"J1c-ZL-C5e\" id=\"hmY-Rl-ndZ\"/>\n                                </connections>\n                            </button>\n                            <button fixedFrame=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"k8O-jk-cLw\">\n                                <rect key=\"frame\" x=\"23\" y=\"53\" width=\"201\" height=\"18\"/>\n                                <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                <buttonCell key=\"cell\" type=\"check\" title=\"Sync with iCloud and iOS app\" bezelStyle=\"regularSquare\" imagePosition=\"left\" state=\"on\" inset=\"2\" id=\"4DA-1R-L49\">\n                                    <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleBackupButton:\" target=\"J1c-ZL-C5e\" id=\"GbM-fW-zKy\"/>\n                                </connections>\n                            </button>\n                            <box translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"PxN-df-6xl\">\n                                <rect key=\"frame\" x=\"7\" y=\"87\" width=\"480\" height=\"362\"/>\n                                <view key=\"contentView\" id=\"8TK-hA-zVh\">\n                                    <rect key=\"frame\" x=\"2\" y=\"2\" width=\"476\" height=\"345\"/>\n                                    <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                </view>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"358\" id=\"5cL-wi-gzh\"/>\n                                </constraints>\n                            </box>\n                            <button translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"nlR-CY-a5k\">\n                                <rect key=\"frame\" x=\"458\" y=\"450\" width=\"24\" height=\"24\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"24\" id=\"4g4-ML-oQZ\"/>\n                                    <constraint firstAttribute=\"height\" constant=\"24\" id=\"E7I-QJ-lJh\"/>\n                                </constraints>\n                                <buttonCell key=\"cell\" type=\"square\" bezelStyle=\"shadowlessSquare\" image=\"NSHomeTemplate\" imagePosition=\"only\" alignment=\"center\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"9MX-x5-EW3\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleSaveButton:\" target=\"J1c-ZL-C5e\" id=\"eUr-xg-ou7\"/>\n                                </connections>\n                            </button>\n                            <segmentedControl verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"SGn-yv-6JW\">\n                                <rect key=\"frame\" x=\"145\" y=\"451\" width=\"205\" height=\"23\"/>\n                                <segmentedCell key=\"cell\" borderStyle=\"border\" alignment=\"left\" style=\"texturedSquare\" trackingMode=\"selectOne\" id=\"pn1-lj-JjN\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <segments>\n                                        <segment label=\"Tracking\"/>\n                                        <segment label=\"Input\" selected=\"YES\" tag=\"1\"/>\n                                        <segment label=\"Output\"/>\n                                    </segments>\n                                </segmentedCell>\n                                <connections>\n                                    <action selector=\"handleSegmentedControl:\" target=\"J1c-ZL-C5e\" id=\"wev-kc-A58\"/>\n                                </connections>\n                            </segmentedControl>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"sOP-ZD-50a\">\n                                <rect key=\"frame\" x=\"12\" y=\"453\" width=\"38\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"Quit\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"fze-b8-HZ5\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleQuitAppButton:\" target=\"J1c-ZL-C5e\" id=\"cS6-mT-WmX\"/>\n                                </connections>\n                            </button>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"JI6-hq-mSe\">\n                                <rect key=\"frame\" x=\"60\" y=\"453\" width=\"20\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"^\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"ghA-S2-xyZ\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleMinimizeAppButton:\" target=\"J1c-ZL-C5e\" id=\"hZX-uF-dti\"/>\n                                </connections>\n                            </button>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"sOP-ZD-50a\" firstAttribute=\"top\" secondItem=\"JAR-dh-Pss\" secondAttribute=\"top\" constant=\"22\" id=\"242-IV-jcI\"/>\n                            <constraint firstItem=\"JI6-hq-mSe\" firstAttribute=\"centerY\" secondItem=\"sOP-ZD-50a\" secondAttribute=\"centerY\" id=\"8dv-Jg-hNO\"/>\n                            <constraint firstItem=\"PxN-df-6xl\" firstAttribute=\"leading\" secondItem=\"JAR-dh-Pss\" secondAttribute=\"leading\" constant=\"10\" id=\"F1s-2p-LIi\"/>\n                            <constraint firstItem=\"sOP-ZD-50a\" firstAttribute=\"leading\" secondItem=\"JAR-dh-Pss\" secondAttribute=\"leading\" constant=\"12\" id=\"MC1-7c-utL\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"PxN-df-6xl\" secondAttribute=\"bottom\" constant=\"91\" id=\"Mhh-04-lzW\"/>\n                            <constraint firstItem=\"SGn-yv-6JW\" firstAttribute=\"centerX\" secondItem=\"JAR-dh-Pss\" secondAttribute=\"centerX\" id=\"ZoM-gS-y3R\"/>\n                            <constraint firstItem=\"JI6-hq-mSe\" firstAttribute=\"leading\" secondItem=\"sOP-ZD-50a\" secondAttribute=\"trailing\" constant=\"10\" id=\"aLV-Bk-ZQg\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"nlR-CY-a5k\" secondAttribute=\"trailing\" constant=\"12\" id=\"bBK-E5-Tw5\"/>\n                            <constraint firstItem=\"PxN-df-6xl\" firstAttribute=\"top\" secondItem=\"JAR-dh-Pss\" secondAttribute=\"top\" constant=\"45\" id=\"c7W-dQ-9er\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"PxN-df-6xl\" secondAttribute=\"trailing\" constant=\"10\" id=\"cPD-hz-qMV\"/>\n                            <constraint firstItem=\"SGn-yv-6JW\" firstAttribute=\"top\" secondItem=\"JAR-dh-Pss\" secondAttribute=\"top\" constant=\"20\" id=\"jSr-nR-Hgq\"/>\n                            <constraint firstItem=\"nlR-CY-a5k\" firstAttribute=\"top\" secondItem=\"JAR-dh-Pss\" secondAttribute=\"top\" constant=\"20\" id=\"tMc-D8-yEa\"/>\n                        </constraints>\n                    </view>\n                    <connections>\n                        <outlet property=\"butBackup\" destination=\"k8O-jk-cLw\" id=\"Pir-WT-wKE\"/>\n                        <outlet property=\"butEnableLaunchAtStartup\" destination=\"aR4-jV-fsE\" id=\"EdN-iT-CFP\"/>\n                        <outlet property=\"container\" destination=\"PxN-df-6xl\" id=\"hXi-Lj-HJT\"/>\n                        <outlet property=\"segmentedControl\" destination=\"SGn-yv-6JW\" id=\"TNf-TG-MYz\"/>\n                    </connections>\n                </viewController>\n                <customObject id=\"C7k-Vd-XtM\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"99\" y=\"770\"/>\n        </scene>\n    </scenes>\n    <resources>\n        <image name=\"NSHomeTemplate\" width=\"14\" height=\"14\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/SettingsInteractor.swift",
    "content": "//\n//  SettingsInteractor.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 06/09/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\nimport ServiceManagement\nimport RCPreferences\nimport RCLog\n\nprotocol SettingsInteractorInput: class {\n    \n    func getAppSettings() -> Settings\n    func saveAppSettings (_ settings: Settings)\n    func enabledLaunchAtStartup (_ enabled: Bool)\n}\n\nprotocol SettingsInteractorOutput: class {\n    \n}\n\nclass SettingsInteractor {\n    \n    weak var presenter: SettingsInteractorOutput?\n    fileprivate let localPreferences = RCPreferences<LocalPreferences>()\n    \n    init() {\n        \n    }\n}\n\nextension SettingsInteractor: SettingsInteractorInput {\n    \n    func getAppSettings() -> Settings {\n        return localRepository!.settings()\n    }\n    \n    func saveAppSettings (_ settings: Settings) {\n        RCLog(\"Saving \\(settings)\")\n        localRepository!.saveSettings(settings)\n    }\n    \n    func enabledLaunchAtStartup (_ enabled: Bool) {\n        \n        let launchAtStartup = SMLoginItemSetEnabled(launcherIdentifier as CFString, enabled)\n        localPreferences.set(launchAtStartup ? enabled : false, forKey: .launchAtStartup)\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/SettingsPresenter.swift",
    "content": "//\n//  SettingsPresenter.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 02/05/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\nimport RCPreferences\n\nprotocol SettingsPresenterInput: class {\n    \n    func checkExtensions()\n    func showSettings()\n    func selectTab (_ tab: SettingsTab)\n    func saveAppSettings (_ settings: Settings)\n    func enableBackup (_ enabled: Bool)\n    func enableLaunchAtStartup (_ enabled: Bool)\n    func installJirassic()\n    func installJit()\n}\n\nprotocol SettingsPresenterOutput: class {\n    \n    func setShellStatus (compatibility: Compatibility)\n    func setJirassicStatus (compatibility: Compatibility)\n    func setJitStatus (compatibility: Compatibility)\n    func setGitStatus (available: Bool)\n    func setBrowserStatus (compatibility: Compatibility)\n    func setHookupStatus (available: Bool)\n    func showAppSettings (_ settings: Settings)\n    func enableBackup (_ enabled: Bool, title: String)\n    func enableLaunchAtStartup (_ enabled: Bool)\n    func selectTab (_ tab: SettingsTab)\n}\n\nclass SettingsPresenter {\n    \n    private var extensions = ExtensionsInteractor()\n    #if !APPSTORE\n    private var extensionsInstaller = ExtensionsInstallerInteractor()\n    #endif\n    weak var userInterface: SettingsPresenterOutput?\n    var interactor: SettingsInteractorInput?\n    private let pref = RCPreferences<LocalPreferences>()\n}\n\nextension SettingsPresenter: SettingsPresenterInput {\n    \n    func checkExtensions() {\n        \n        extensions.getVersions { [weak self] (versions) in\n            \n            guard let userInterface = self?.userInterface else {\n                return\n            }\n            let compatibility = Versioning(versions: versions)\n\n            // Setup shell script\n            userInterface.setShellStatus(compatibility: compatibility.shellScript)\n\n            // Setup jirassic cmd\n            userInterface.setJirassicStatus(compatibility: compatibility.jirassic)\n\n            // Setup jit cmd\n            userInterface.setJitStatus(compatibility: compatibility.jit)\n\n            // Setup browser script\n            userInterface.setBrowserStatus(compatibility: compatibility.browser)\n            \n            // Git requires extra call\n            userInterface.setGitStatus(available: versions.shellScript != \"\")\n            \n            // Hookup requires extra call\n            userInterface.setHookupStatus(available: versions.shellScript != \"\")\n        }\n    }\n    \n    func showSettings() {\n        let settings = interactor!.getAppSettings()\n        userInterface!.showAppSettings(settings)\n        userInterface!.enableLaunchAtStartup( pref.bool(.launchAtStartup) )\n        enableBackup(settings.enableBackup)\n        let lastActiveSettingsTab = SettingsTab(rawValue: pref.int(.settingsActiveTab))!\n        selectTab(lastActiveSettingsTab)\n    }\n    \n    func selectTab (_ tab: SettingsTab) {\n        pref.set(tab.rawValue, forKey: .settingsActiveTab)\n        userInterface!.selectTab(tab)\n    }\n    \n    func saveAppSettings (_ settings: Settings) {\n        interactor!.saveAppSettings(settings)\n    }\n    \n    func enableBackup (_ enabled: Bool) {\n        #if APPSTORE\n        if enabled {\n            // Init the global instance of remoteRepository in AppDelegate\n            remoteRepository = CloudKitRepository()\n            remoteRepository?.getUser({ (user) in\n                if user == nil {\n                    self.userInterface?.enableBackup(false, title: \"Syncing with iCloud not possible, you are not logged into iCloud\")\n                    remoteRepository = nil\n                } else {\n                    self.userInterface?.enableBackup(true, title: \"Sync with iCloud and iOS app\")\n                }\n            })\n        } else {\n            remoteRepository = nil\n            self.userInterface?.enableBackup(enabled, title: \"Sync with iCloud and iOS app\")\n        }\n        #endif\n    }\n    \n    func enableLaunchAtStartup (_ enabled: Bool) {\n        interactor!.enabledLaunchAtStartup(enabled)\n    }\n    \n    func installJirassic() {\n        #if !APPSTORE\n        extensionsInstaller.installJirassic { (success) in\n//            self.userInterface!.setJirassicStatus(compatibility: <#T##Compatibility#>)\n        }\n        #endif\n    }\n    \n    func installJit() {\n        #if !APPSTORE\n        extensionsInstaller.installJit { (success) in\n//            self.userInterface!.setJitStatus(compatibility: <#T##Compatibility#>)\n        }\n        #endif\n    }\n}\n\nextension SettingsPresenter: SettingsInteractorOutput {\n    \n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/SettingsViewController.swift",
    "content": "//\n//  SettingsViewController.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 06/05/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\nimport RCPreferences\nimport RCLog\n\nenum SettingsTab: Int {\n    case tracking = 0\n    case input = 1\n    case output = 2\n    case store = 3\n}\n\nclass SettingsViewController: NSViewController {\n    \n    @IBOutlet private var segmentedControl: NSSegmentedControl!\n    @IBOutlet private var container: NSBox!\n    @IBOutlet private var butBackup: NSButton!\n    @IBOutlet private var butEnableLaunchAtStartup: NSButton!\n    // Tracking tab\n    private var trackingView: TrackingView?\n    // Input tab\n    private var inputsScrollView: InputsScrollView?\n    // Output tab\n    private var outputsScrollView: OutputsScrollView?\n    // Store tab\n    private var storeView: StoreView?\n    \n    weak var appWireframe: AppWireframe?\n    var presenter: SettingsPresenterInput?\n    private let localPreferences = RCPreferences<LocalPreferences>()\n\t\n    override func viewDidAppear() {\n        super.viewDidAppear()\n        createLayer()\n        \n        trackingView = TrackingView.instantiateFromXib()\n        inputsScrollView = InputsScrollView.instantiateFromXib()\n        outputsScrollView = OutputsScrollView.instantiateFromXib()\n//        storeView = StoreView.instantiateFromXib()\n        \n        presenter!.checkExtensions()\n        presenter!.showSettings()\n\n        inputsScrollView?.onPurchasePressed = { [weak self] in\n            self?.presenter?.selectTab(.store)\n        }\n        outputsScrollView?.onPurchasePressed = { [weak self] in\n            self?.presenter?.selectTab(.store)\n        }\n        \n        #if !APPSTORE\n            butBackup.isEnabled = false\n            butBackup.state = NSControl.StateValue.off\n            butEnableLaunchAtStartup.isEnabled = false\n            butEnableLaunchAtStartup.state = NSControl.StateValue.off\n        #endif\n    }\n    \n    override func viewWillDisappear() {\n        super.viewWillDisappear()\n        \n        let settings = Settings(\n            enableBackup: butBackup.state == NSControl.StateValue.on,\n            settingsTracking: trackingView!.settings(),\n            settingsBrowser: inputsScrollView!.settings()\n        )\n        presenter!.saveAppSettings(settings)\n        \n        trackingView?.save()\n        inputsScrollView?.save()\n        outputsScrollView?.save()\n    }\n    \n    deinit {\n        RCLog(\"deinit\")\n    }\n    \n    func removeSelectedTabView() {\n        trackingView!.removeFromSuperview()\n        inputsScrollView!.removeFromSuperview()\n        outputsScrollView!.removeFromSuperview()\n//        storeView!.removeFromSuperview()\n    }\n}\n\nextension SettingsViewController {\n\t\n    @IBAction func handleSaveButton (_ sender: NSButton) {\n        appWireframe!.flipToTasksController()\n    }\n    \n    @IBAction func handleBackupButton (_ sender: NSButton) {\n        presenter!.enableBackup(sender.state == NSControl.StateValue.on)\n    }\n    \n    @IBAction func handleLaunchAtStartupButton (_ sender: NSButton) {\n        presenter!.enableLaunchAtStartup(sender.state == NSControl.StateValue.on)\n    }\n    \n    @IBAction func handleSegmentedControl (_ sender: NSSegmentedControl) {\n        let tab = SettingsTab(rawValue: sender.selectedSegment)!\n        presenter!.selectTab(tab)\n    }\n    \n    @IBAction func handleQuitAppButton (_ sender: NSButton) {\n        NSApplication.shared.terminate(nil)\n    }\n    \n    @IBAction func handleMinimizeAppButton (_ sender: NSButton) {\n        AppDelegate.sharedApp().menu.triggerClose()\n    }\n}\n\nextension SettingsViewController: Animatable {\n    \n    func createLayer() {\n        view.layer = CALayer()\n        view.wantsLayer = true\n    }\n}\n\nextension SettingsViewController: SettingsPresenterOutput {\n    \n    func setShellStatus (compatibility: Compatibility) {\n        inputsScrollView?.setShellStatus (compatibility: compatibility)\n    }\n    \n    func setJirassicStatus (compatibility: Compatibility) {\n        inputsScrollView?.setJirassicStatus (compatibility: compatibility)\n    }\n    \n    func setJitStatus (compatibility: Compatibility) {\n        inputsScrollView?.setJitStatus (compatibility: compatibility)\n    }\n    \n    func setGitStatus (available: Bool) {\n        inputsScrollView?.setGitStatus (available: available)\n    }\n    \n    func setBrowserStatus (compatibility: Compatibility) {\n        inputsScrollView?.setBrowserStatus (compatibility: compatibility)\n    }\n    \n    func setHookupStatus (available: Bool) {\n        outputsScrollView?.setHookupStatus (available: available)\n    }\n    \n    func showAppSettings (_ settings: Settings) {\n        \n        trackingView?.showSettings(settings.settingsTracking)\n        inputsScrollView?.showSettings(settings.settingsBrowser)\n        \n        butBackup.state = settings.enableBackup ? NSControl.StateValue.on : NSControl.StateValue.off\n    }\n    \n    func enableLaunchAtStartup (_ enabled: Bool) {\n        butEnableLaunchAtStartup.state = enabled ? NSControl.StateValue.on : NSControl.StateValue.off\n    }\n    \n    func enableBackup (_ enabled: Bool, title: String) {\n        butBackup.state = enabled ? NSControl.StateValue.on : NSControl.StateValue.off\n        butBackup.title = title\n    }\n    \n    func selectTab (_ tab: SettingsTab) {\n        removeSelectedTabView()\n        segmentedControl!.selectedSegment = tab.rawValue\n        switch tab {\n        case .tracking:\n            container.addSubview(trackingView!)\n            trackingView!.constrainToSuperview()\n        case .input:\n            container.addSubview(inputsScrollView!)\n            inputsScrollView!.constrainToSuperview()\n        case .output:\n            container.addSubview(outputsScrollView!)\n            outputsScrollView!.constrainToSuperview()\n        case .store:\n            break\n//            container.addSubview(storeView!)\n//            storeView!.constrainToSuperview()\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Store/StoreView.swift",
    "content": "//\n//  StoreView.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 18/10/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\nimport RCPreferences\nimport RCLog\n\nclass StoreView: NSView {\n\n    @IBOutlet private var butBuy: NSButton!\n    @IBOutlet private var butCancel: NSButton!\n    @IBOutlet private var butRestore: NSButton!\n    @IBOutlet private var progressIndicatorAll: NSProgressIndicator!\n    @IBOutlet private var progressIndicatorRestore: NSProgressIndicator!\n    @IBOutlet private var priceTextField: NSTextField!\n    @IBOutlet private var descriptionAllTextField: NSTextField!\n    \n    private let localPreferences = RCPreferences<LocalPreferences>()\n    private let store = Store.shared\n    \n    override func awakeFromNib() {\n        super.awakeFromNib()\n        progressIndicatorAll.isHidden = true\n        progressIndicatorRestore.isHidden = true\n        refresh()\n    }\n    \n    @IBAction func handleBuyButton (_ sender: NSButton) {\n        butBuy.isHidden = true\n        progressIndicatorAll.isHidden = false\n        progressIndicatorAll.startAnimation(sender)\n        store.purchase(product: .full) { [weak self] (success) in\n            DispatchQueue.main.async {\n                if success {\n                    self?.progressIndicatorAll.isHidden = true\n                    self?.progressIndicatorAll.stopAnimation(nil)\n                    self?.refresh()\n                }\n            }\n        }\n    }\n    \n    @IBAction func handleCancelButton (_ sender: NSButton) {\n        if let url = URL(string: \"https://apps.apple.com/account/subscriptions\"),\n            NSWorkspace.shared.open(url) {\n            RCLog(\"default browser was successfully opened\")\n        }\n    }\n    \n    @IBAction func handleRestoreButton (_ sender: NSButton) {\n        butRestore.isHidden = true\n        progressIndicatorRestore.isHidden = false\n        progressIndicatorRestore.startAnimation(sender)\n        store.restore() { [weak self] (success) in\n            DispatchQueue.main.async {\n                if success {\n                    self?.butRestore.isHidden = false\n                    self?.progressIndicatorRestore.isHidden = true\n                    self?.progressIndicatorRestore.stopAnimation(nil)\n                }\n            }\n        }\n    }\n    \n    private func refresh() {\n        butBuy.isHidden = store.isGitPurchased && store.isJiraTempoPurchased\n        butCancel.isHidden = !butBuy.isHidden\n        butRestore.isHidden = store.isGitPurchased && store.isJiraTempoPurchased\n        descriptionAllTextField.stringValue = \"Try for 30 days for free, after that you will be charged every 6 months. The subscription can be disabled from your App Store account.\\n\\nWhat's included in the subscription:\\n• Git plugin will let you see commits made with Git in the daily reports\\n• Jira Tempo plugin will let you save daily reports directly to Jira Tempo\"\n        \n        store.getProduct(.full) { [weak self] skProduct in\n            if let product = skProduct {\n                DispatchQueue.main.async {\n                    self?.priceTextField.stringValue = product.localizedPrice() ?? \"\"\n                }\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Store/StoreView.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"14313.18\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14313.18\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView id=\"c22-O7-iKe\" customClass=\"StoreView\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"480\" height=\"363\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <textField verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"awB-nn-Xtk\">\n                    <rect key=\"frame\" x=\"18\" y=\"228\" width=\"444\" height=\"17\"/>\n                    <textFieldCell key=\"cell\" selectable=\"YES\" title=\"-\" id=\"vOe-IV-Vru\">\n                        <font key=\"font\" metaFont=\"system\"/>\n                        <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                    </textFieldCell>\n                </textField>\n                <textField verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Jqo-6U-U3f\">\n                    <rect key=\"frame\" x=\"18\" y=\"253\" width=\"444\" height=\"17\"/>\n                    <textFieldCell key=\"cell\" selectable=\"YES\" title=\"$\" id=\"g9v-a5-AUU\">\n                        <font key=\"font\" metaFont=\"systemBold\"/>\n                        <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                    </textFieldCell>\n                </textField>\n                <progressIndicator wantsLayer=\"YES\" horizontalHuggingPriority=\"750\" verticalHuggingPriority=\"750\" maxValue=\"100\" displayedWhenStopped=\"NO\" bezeled=\"NO\" indeterminate=\"YES\" controlSize=\"small\" style=\"spinning\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"YFV-j0-u7b\">\n                    <rect key=\"frame\" x=\"444\" y=\"286\" width=\"16\" height=\"16\"/>\n                </progressIndicator>\n                <progressIndicator wantsLayer=\"YES\" horizontalHuggingPriority=\"750\" verticalHuggingPriority=\"750\" maxValue=\"100\" displayedWhenStopped=\"NO\" bezeled=\"NO\" indeterminate=\"YES\" controlSize=\"small\" style=\"spinning\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"35M-5i-yFZ\">\n                    <rect key=\"frame\" x=\"16\" y=\"23\" width=\"16\" height=\"16\"/>\n                </progressIndicator>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"3rx-h7-sf6\">\n                    <rect key=\"frame\" x=\"385\" y=\"281\" width=\"75\" height=\"25\"/>\n                    <buttonCell key=\"cell\" type=\"roundTextured\" title=\"Subscribe\" bezelStyle=\"texturedRounded\" alignment=\"center\" lineBreakMode=\"truncatingTail\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"bLj-tL-fnL\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"system\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleBuyButton:\" target=\"c22-O7-iKe\" id=\"wIR-TK-LfT\"/>\n                    </connections>\n                </button>\n                <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"3e5-0l-KIc\">\n                    <rect key=\"frame\" x=\"16\" y=\"277\" width=\"208\" height=\"36\"/>\n                    <constraints>\n                        <constraint firstAttribute=\"height\" constant=\"36\" id=\"X5B-NU-LzV\"/>\n                    </constraints>\n                    <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"left\" title=\"Git + Jira Tempo\" id=\"KBF-9b-zvf\">\n                        <font key=\"font\" metaFont=\"system\" size=\"30\"/>\n                        <color key=\"textColor\" red=\"0.7843137255\" green=\"0.1176470588\" blue=\"0.47058823529999999\" alpha=\"1\" colorSpace=\"calibratedRGB\"/>\n                        <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                    </textFieldCell>\n                </textField>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"g1H-aj-wut\">\n                    <rect key=\"frame\" x=\"16\" y=\"18\" width=\"61\" height=\"25\"/>\n                    <buttonCell key=\"cell\" type=\"roundTextured\" title=\"Restore\" bezelStyle=\"texturedRounded\" alignment=\"center\" lineBreakMode=\"truncatingTail\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"hCk-rS-nzl\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"system\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleRestoreButton:\" target=\"c22-O7-iKe\" id=\"1z4-69-mUJ\"/>\n                    </connections>\n                </button>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"UrJ-hk-HHW\">\n                    <rect key=\"frame\" x=\"326\" y=\"281\" width=\"134\" height=\"25\"/>\n                    <buttonCell key=\"cell\" type=\"roundTextured\" title=\"Cancel subscription\" bezelStyle=\"texturedRounded\" alignment=\"center\" lineBreakMode=\"truncatingTail\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"mIG-da-1p6\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"system\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleCancelButton:\" target=\"c22-O7-iKe\" id=\"1ma-6j-N36\"/>\n                    </connections>\n                </button>\n            </subviews>\n            <constraints>\n                <constraint firstItem=\"awB-nn-Xtk\" firstAttribute=\"top\" secondItem=\"Jqo-6U-U3f\" secondAttribute=\"bottom\" constant=\"8\" id=\"4Su-OY-4Ju\"/>\n                <constraint firstItem=\"35M-5i-yFZ\" firstAttribute=\"leading\" secondItem=\"g1H-aj-wut\" secondAttribute=\"leading\" id=\"598-hg-0Tw\"/>\n                <constraint firstItem=\"3rx-h7-sf6\" firstAttribute=\"top\" secondItem=\"3e5-0l-KIc\" secondAttribute=\"top\" constant=\"8\" id=\"HyK-e2-BwN\"/>\n                <constraint firstItem=\"YFV-j0-u7b\" firstAttribute=\"centerY\" secondItem=\"3rx-h7-sf6\" secondAttribute=\"centerY\" id=\"IVF-Xi-HeG\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"awB-nn-Xtk\" secondAttribute=\"trailing\" constant=\"20\" id=\"IaB-QL-u3u\"/>\n                <constraint firstItem=\"UrJ-hk-HHW\" firstAttribute=\"centerY\" secondItem=\"3rx-h7-sf6\" secondAttribute=\"centerY\" id=\"PRw-Ss-xR1\"/>\n                <constraint firstItem=\"Jqo-6U-U3f\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"20\" id=\"Rjx-o1-Uzo\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"3rx-h7-sf6\" secondAttribute=\"trailing\" constant=\"20\" id=\"SHw-h9-Jji\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"Jqo-6U-U3f\" secondAttribute=\"trailing\" constant=\"20\" id=\"Thy-I8-Xht\"/>\n                <constraint firstItem=\"YFV-j0-u7b\" firstAttribute=\"trailing\" secondItem=\"3rx-h7-sf6\" secondAttribute=\"trailing\" id=\"U9F-Iu-ZtK\"/>\n                <constraint firstItem=\"35M-5i-yFZ\" firstAttribute=\"centerY\" secondItem=\"g1H-aj-wut\" secondAttribute=\"centerY\" id=\"frT-ML-Rcn\"/>\n                <constraint firstItem=\"3e5-0l-KIc\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"18\" id=\"fxU-iz-pYb\"/>\n                <constraint firstItem=\"Jqo-6U-U3f\" firstAttribute=\"top\" secondItem=\"3e5-0l-KIc\" secondAttribute=\"bottom\" constant=\"7\" id=\"hW6-9P-g5D\"/>\n                <constraint firstItem=\"UrJ-hk-HHW\" firstAttribute=\"trailing\" secondItem=\"3rx-h7-sf6\" secondAttribute=\"trailing\" id=\"jsF-1a-yCv\"/>\n                <constraint firstItem=\"awB-nn-Xtk\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"20\" id=\"nOF-ZF-XSj\"/>\n                <constraint firstItem=\"3e5-0l-KIc\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" constant=\"50\" id=\"nwi-V3-khj\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"g1H-aj-wut\" secondAttribute=\"bottom\" constant=\"20\" id=\"orz-D7-vp9\"/>\n                <constraint firstItem=\"g1H-aj-wut\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"16\" id=\"vXb-0e-Ou4\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"butBuy\" destination=\"3rx-h7-sf6\" id=\"1b2-el-sT5\"/>\n                <outlet property=\"butCancel\" destination=\"UrJ-hk-HHW\" id=\"4f5-3B-5g0\"/>\n                <outlet property=\"butRestore\" destination=\"g1H-aj-wut\" id=\"MaI-bL-3w3\"/>\n                <outlet property=\"descriptionAllTextField\" destination=\"awB-nn-Xtk\" id=\"cXW-wB-aL4\"/>\n                <outlet property=\"priceTextField\" destination=\"Jqo-6U-U3f\" id=\"nVO-YT-23z\"/>\n                <outlet property=\"progressIndicatorAll\" destination=\"YFV-j0-u7b\" id=\"G5E-Im-RD0\"/>\n                <outlet property=\"progressIndicatorRestore\" destination=\"35M-5i-yFZ\" id=\"fuf-k3-SWk\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"139\" y=\"199.5\"/>\n        </customView>\n    </objects>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Tracking/TrackingView.swift",
    "content": "//\n//  TrackingView.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 02/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nclass TrackingView: NSView {\n    \n    @IBOutlet fileprivate var butAutotrack: NSButton!\n    @IBOutlet fileprivate var autotrackingModeSegmentedControl: NSSegmentedControl!\n    @IBOutlet fileprivate var butTrackStartOfDay: NSButton!\n    @IBOutlet fileprivate var butTrackLunch: NSButton!\n    @IBOutlet fileprivate var butTrackScrum: NSButton!\n//    @IBOutlet fileprivate var butTrackMeetings: NSButton!\n    @IBOutlet fileprivate var startOfDayTimePicker: NSDatePicker!\n    @IBOutlet fileprivate var endOfDayTimePicker: NSDatePicker!\n    @IBOutlet fileprivate var lunchTimePicker: NSDatePicker!\n    @IBOutlet fileprivate var scrumTimePicker: NSDatePicker!\n    @IBOutlet fileprivate var minSleepDurationLabel: NSTextField!\n    @IBOutlet fileprivate var minSleepDurationSlider: NSSlider!\n    \n    \n    @IBAction func handleAutoTrackButton (_ sender: NSButton) {\n        autotrackingModeSegmentedControl.isEnabled = sender.state == NSControl.StateValue.on\n    }\n    \n    @IBAction func handleMinSleepDuration (_ sender: NSSlider) {\n        minSleepDurationLabel.stringValue = \"Ignore sleeps shorter than \\(sender.integerValue) minutes\"\n    }\n    \n    func showSettings (_ settings: SettingsTracking) {\n        \n        butAutotrack.state = settings.autotrack ? NSControl.StateValue.on : NSControl.StateValue.off\n        autotrackingModeSegmentedControl.selectedSegment = settings.autotrackingMode.rawValue\n        minSleepDurationSlider.integerValue = settings.minSleepDuration\n        handleMinSleepDuration(minSleepDurationSlider)\n        butTrackStartOfDay.state = settings.trackStartOfDay ? NSControl.StateValue.on : NSControl.StateValue.off\n        butTrackLunch.state = settings.trackLunch ? NSControl.StateValue.on : NSControl.StateValue.off\n        butTrackScrum.state = settings.trackScrum ? NSControl.StateValue.on : NSControl.StateValue.off\n        \n        startOfDayTimePicker.dateValue = settings.startOfDayTime\n        endOfDayTimePicker.dateValue = settings.endOfDayTime\n        lunchTimePicker.dateValue = settings.lunchTime\n        scrumTimePicker.dateValue = settings.scrumTime\n    }\n    \n    func settings() -> SettingsTracking {\n        \n        return SettingsTracking(\n            \n            autotrack: butAutotrack.state == NSControl.StateValue.on,\n            autotrackingMode: TrackingMode(rawValue: autotrackingModeSegmentedControl.selectedSegment)!,\n            trackLunch: butTrackLunch.state == NSControl.StateValue.on,\n            trackScrum: butTrackScrum.state == NSControl.StateValue.on,\n            trackMeetings: true,//butTrackMeetings.state == NSControl.StateValue.on,\n            trackStartOfDay: butTrackStartOfDay.state == NSControl.StateValue.on,\n            startOfDayTime: startOfDayTimePicker.dateValue,\n            endOfDayTime: endOfDayTimePicker.dateValue,\n            lunchTime: lunchTimePicker.dateValue,\n            scrumTime: scrumTimePicker.dateValue,\n            minSleepDuration: minSleepDurationSlider.integerValue\n        )\n    }\n    \n    func save() {\n        \n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Settings/Tracking/TrackingView.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"14313.18\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14313.18\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView id=\"c22-O7-iKe\" customClass=\"TrackingView\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"545\" height=\"358\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <button translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"wac-II-n6f\">\n                    <rect key=\"frame\" x=\"14\" y=\"118\" width=\"166\" height=\"18\"/>\n                    <buttonCell key=\"cell\" type=\"check\" title=\"Lunch begins around\" bezelStyle=\"regularSquare\" imagePosition=\"left\" state=\"on\" inset=\"2\" id=\"Vph-zn-2b8\">\n                        <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                        <font key=\"font\" metaFont=\"system\"/>\n                    </buttonCell>\n                </button>\n                <button toolTip=\"Working hours not including the lunch break\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"HF2-Ra-st6\">\n                    <rect key=\"frame\" x=\"14\" y=\"175\" width=\"128\" height=\"18\"/>\n                    <buttonCell key=\"cell\" type=\"check\" title=\"Working between\" bezelStyle=\"regularSquare\" imagePosition=\"left\" state=\"on\" inset=\"2\" id=\"8L9-IG-yRe\">\n                        <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                        <font key=\"font\" metaFont=\"system\"/>\n                    </buttonCell>\n                </button>\n                <button translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"NDv-L1-vNy\">\n                    <rect key=\"frame\" x=\"14\" y=\"61\" width=\"166\" height=\"18\"/>\n                    <buttonCell key=\"cell\" type=\"check\" title=\"Scrum begins around\" bezelStyle=\"regularSquare\" imagePosition=\"left\" state=\"on\" inset=\"2\" id=\"y7O-oz-hLe\">\n                        <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                        <font key=\"font\" metaFont=\"system\"/>\n                    </buttonCell>\n                </button>\n                <button translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"UNt-JQ-D2v\">\n                    <rect key=\"frame\" x=\"14\" y=\"292\" width=\"239\" height=\"18\"/>\n                    <buttonCell key=\"cell\" type=\"check\" title=\"Log tasks when computer wakes up\" bezelStyle=\"regularSquare\" imagePosition=\"left\" state=\"on\" inset=\"2\" id=\"yJ1-ae-fOV\">\n                        <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                        <font key=\"font\" metaFont=\"system\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleAutoTrackButton:\" target=\"c22-O7-iKe\" id=\"lwP-fT-7qv\"/>\n                    </connections>\n                </button>\n                <segmentedControl verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"jIg-Xc-Qbw\">\n                    <rect key=\"frame\" x=\"259\" y=\"288\" width=\"159\" height=\"24\"/>\n                    <segmentedCell key=\"cell\" borderStyle=\"border\" alignment=\"left\" style=\"rounded\" trackingMode=\"selectOne\" id=\"Rdk-FP-9v8\">\n                        <font key=\"font\" metaFont=\"system\"/>\n                        <segments>\n                            <segment label=\"Automatically\"/>\n                            <segment label=\"Ask\" selected=\"YES\" tag=\"1\"/>\n                        </segments>\n                    </segmentedCell>\n                </segmentedControl>\n                <box boxType=\"custom\" cornerRadius=\"4\" title=\"Box\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Kuw-aQ-8xH\">\n                    <rect key=\"frame\" x=\"179\" y=\"52\" width=\"193\" height=\"37\"/>\n                    <view key=\"contentView\" id=\"c0z-Nc-3cP\">\n                        <rect key=\"frame\" x=\"1\" y=\"1\" width=\"191\" height=\"35\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <datePicker verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"ENR-qr-Ivl\">\n                                <rect key=\"frame\" x=\"14\" y=\"6\" width=\"61\" height=\"27\"/>\n                                <datePickerCell key=\"cell\" borderStyle=\"bezel\" alignment=\"left\" id=\"qEZ-OF-aWH\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <date key=\"date\" timeIntervalSinceReferenceDate=\"-595956600\">\n                                        <!--1982-02-12 08:30:00 +0000-->\n                                    </date>\n                                    <color key=\"backgroundColor\" name=\"controlBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <datePickerElements key=\"datePickerElements\" hour=\"YES\" minute=\"YES\"/>\n                                </datePickerCell>\n                            </datePicker>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Uji-XU-7I1\">\n                                <rect key=\"frame\" x=\"88\" y=\"9\" width=\"94\" height=\"17\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"(± 20 minutes)\" id=\"aU4-nH-NpL\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"ENR-qr-Ivl\" firstAttribute=\"leading\" secondItem=\"c0z-Nc-3cP\" secondAttribute=\"leading\" constant=\"14\" id=\"Aoa-as-SdN\"/>\n                            <constraint firstItem=\"Uji-XU-7I1\" firstAttribute=\"leading\" secondItem=\"ENR-qr-Ivl\" secondAttribute=\"trailing\" constant=\"18\" id=\"Gcb-qq-zb2\"/>\n                            <constraint firstItem=\"ENR-qr-Ivl\" firstAttribute=\"centerY\" secondItem=\"c0z-Nc-3cP\" secondAttribute=\"centerY\" id=\"OrM-WY-xWG\"/>\n                            <constraint firstItem=\"ENR-qr-Ivl\" firstAttribute=\"baseline\" secondItem=\"Uji-XU-7I1\" secondAttribute=\"baseline\" id=\"a6f-50-sLY\"/>\n                        </constraints>\n                    </view>\n                    <constraints>\n                        <constraint firstAttribute=\"height\" constant=\"37\" id=\"rV2-QM-kgT\"/>\n                    </constraints>\n                </box>\n                <box boxType=\"custom\" cornerRadius=\"4\" title=\"Box\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"bmw-w2-81i\">\n                    <rect key=\"frame\" x=\"179\" y=\"108\" width=\"193\" height=\"37\"/>\n                    <view key=\"contentView\" id=\"A7G-pB-dME\">\n                        <rect key=\"frame\" x=\"1\" y=\"1\" width=\"191\" height=\"35\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"3uf-Yb-135\">\n                                <rect key=\"frame\" x=\"88\" y=\"9\" width=\"63\" height=\"17\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"(± 1 hour)\" id=\"IrJ-Od-Q25\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <datePicker verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"YS9-cC-uWR\">\n                                <rect key=\"frame\" x=\"14\" y=\"6\" width=\"61\" height=\"27\"/>\n                                <datePickerCell key=\"cell\" borderStyle=\"bezel\" alignment=\"left\" id=\"On0-Eg-fEC\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <date key=\"date\" timeIntervalSinceReferenceDate=\"-595947600\">\n                                        <!--1982-02-12 11:00:00 +0000-->\n                                    </date>\n                                    <color key=\"backgroundColor\" name=\"controlBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <datePickerElements key=\"datePickerElements\" hour=\"YES\" minute=\"YES\"/>\n                                </datePickerCell>\n                            </datePicker>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"YS9-cC-uWR\" firstAttribute=\"centerY\" secondItem=\"A7G-pB-dME\" secondAttribute=\"centerY\" id=\"38f-F2-RnM\"/>\n                            <constraint firstItem=\"YS9-cC-uWR\" firstAttribute=\"leading\" secondItem=\"A7G-pB-dME\" secondAttribute=\"leading\" constant=\"14\" id=\"LVf-PV-k0G\"/>\n                            <constraint firstItem=\"YS9-cC-uWR\" firstAttribute=\"baseline\" secondItem=\"3uf-Yb-135\" secondAttribute=\"baseline\" id=\"VQ1-p5-Bk5\"/>\n                            <constraint firstItem=\"3uf-Yb-135\" firstAttribute=\"leading\" secondItem=\"YS9-cC-uWR\" secondAttribute=\"trailing\" constant=\"18\" id=\"qYr-00-9fJ\"/>\n                        </constraints>\n                    </view>\n                </box>\n                <box boxType=\"custom\" cornerRadius=\"4\" title=\"Box\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"l1p-kb-Dga\">\n                    <rect key=\"frame\" x=\"179\" y=\"165\" width=\"193\" height=\"37\"/>\n                    <view key=\"contentView\" id=\"nCg-8V-yCx\">\n                        <rect key=\"frame\" x=\"1\" y=\"1\" width=\"191\" height=\"35\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                        <subviews>\n                            <datePicker verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"QaT-p5-5Ex\">\n                                <rect key=\"frame\" x=\"14\" y=\"6\" width=\"61\" height=\"27\"/>\n                                <datePickerCell key=\"cell\" borderStyle=\"bezel\" alignment=\"left\" id=\"b6Q-Fq-aq5\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <date key=\"date\" timeIntervalSinceReferenceDate=\"-595962000\">\n                                        <!--1982-02-12 07:00:00 +0000-->\n                                    </date>\n                                    <color key=\"backgroundColor\" name=\"controlBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <datePickerElements key=\"datePickerElements\" hour=\"YES\" minute=\"YES\"/>\n                                </datePickerCell>\n                            </datePicker>\n                            <datePicker verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"vSu-qe-UXJ\">\n                                <rect key=\"frame\" x=\"122\" y=\"6\" width=\"61\" height=\"27\"/>\n                                <datePickerCell key=\"cell\" borderStyle=\"bezel\" alignment=\"left\" id=\"fDx-LT-HFQ\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <date key=\"date\" timeIntervalSinceReferenceDate=\"-595933200\">\n                                        <!--1982-02-12 15:00:00 +0000-->\n                                    </date>\n                                    <color key=\"backgroundColor\" name=\"controlBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <datePickerElements key=\"datePickerElements\" hour=\"YES\" minute=\"YES\"/>\n                                </datePickerCell>\n                            </datePicker>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"AEe-Qd-aAQ\">\n                                <rect key=\"frame\" x=\"82\" y=\"9\" width=\"27\" height=\"17\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"and\" id=\"2Jy-M8-ZAL\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"QaT-p5-5Ex\" firstAttribute=\"baseline\" secondItem=\"AEe-Qd-aAQ\" secondAttribute=\"baseline\" id=\"24f-qI-tjo\"/>\n                            <constraint firstItem=\"QaT-p5-5Ex\" firstAttribute=\"centerY\" secondItem=\"nCg-8V-yCx\" secondAttribute=\"centerY\" id=\"KZd-6D-ZJ9\"/>\n                            <constraint firstItem=\"AEe-Qd-aAQ\" firstAttribute=\"baseline\" secondItem=\"vSu-qe-UXJ\" secondAttribute=\"baseline\" id=\"L3K-KM-i65\"/>\n                            <constraint firstItem=\"AEe-Qd-aAQ\" firstAttribute=\"leading\" secondItem=\"QaT-p5-5Ex\" secondAttribute=\"trailing\" constant=\"12\" id=\"VUx-kf-2pA\"/>\n                            <constraint firstItem=\"AEe-Qd-aAQ\" firstAttribute=\"centerX\" secondItem=\"nCg-8V-yCx\" secondAttribute=\"centerX\" id=\"ZIf-c5-M2W\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"vSu-qe-UXJ\" secondAttribute=\"trailing\" constant=\"11\" id=\"eJm-xB-hKW\"/>\n                            <constraint firstItem=\"QaT-p5-5Ex\" firstAttribute=\"leading\" secondItem=\"nCg-8V-yCx\" secondAttribute=\"leading\" constant=\"14\" id=\"qEo-UR-geQ\"/>\n                            <constraint firstItem=\"vSu-qe-UXJ\" firstAttribute=\"leading\" secondItem=\"AEe-Qd-aAQ\" secondAttribute=\"trailing\" constant=\"15\" id=\"s8N-u5-geA\"/>\n                        </constraints>\n                    </view>\n                </box>\n                <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"QZa-7i-ghA\">\n                    <rect key=\"frame\" x=\"14\" y=\"235\" width=\"233\" height=\"17\"/>\n                    <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Ignore sleeps shorter than 10 minutes\" id=\"CUp-FW-k1J\">\n                        <font key=\"font\" metaFont=\"system\"/>\n                        <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                    </textFieldCell>\n                </textField>\n                <slider verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"tN8-4C-2i5\">\n                    <rect key=\"frame\" x=\"259\" y=\"234\" width=\"159\" height=\"24\"/>\n                    <sliderCell key=\"cell\" continuous=\"YES\" state=\"on\" alignment=\"left\" minValue=\"5\" maxValue=\"30\" doubleValue=\"13\" tickMarkPosition=\"above\" numberOfTickMarks=\"10\" sliderType=\"linear\" id=\"DzM-oD-W38\"/>\n                    <connections>\n                        <action selector=\"handleMinSleepDuration:\" target=\"c22-O7-iKe\" id=\"Aah-HW-b2s\"/>\n                    </connections>\n                </slider>\n                <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"eXx-ul-UhD\">\n                    <rect key=\"frame\" x=\"391\" y=\"176\" width=\"109\" height=\"17\"/>\n                    <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"(excluding lunch)\" id=\"hTJ-hO-7NI\">\n                        <font key=\"font\" metaFont=\"system\"/>\n                        <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                    </textFieldCell>\n                </textField>\n            </subviews>\n            <constraints>\n                <constraint firstItem=\"HF2-Ra-st6\" firstAttribute=\"top\" secondItem=\"QZa-7i-ghA\" secondAttribute=\"bottom\" constant=\"44\" id=\"3h3-cM-vK1\"/>\n                <constraint firstItem=\"bmw-w2-81i\" firstAttribute=\"leading\" secondItem=\"wac-II-n6f\" secondAttribute=\"trailing\" constant=\"1\" id=\"64y-z3-lMi\"/>\n                <constraint firstItem=\"wac-II-n6f\" firstAttribute=\"trailing\" secondItem=\"NDv-L1-vNy\" secondAttribute=\"trailing\" id=\"6MY-UD-1UQ\"/>\n                <constraint firstItem=\"tN8-4C-2i5\" firstAttribute=\"top\" secondItem=\"jIg-Xc-Qbw\" secondAttribute=\"bottom\" constant=\"32\" id=\"7iv-hS-RXM\"/>\n                <constraint firstItem=\"wac-II-n6f\" firstAttribute=\"leading\" secondItem=\"NDv-L1-vNy\" secondAttribute=\"leading\" id=\"949-3f-nQe\"/>\n                <constraint firstItem=\"UNt-JQ-D2v\" firstAttribute=\"leading\" secondItem=\"HF2-Ra-st6\" secondAttribute=\"leading\" id=\"CeP-Mw-5pK\"/>\n                <constraint firstItem=\"bmw-w2-81i\" firstAttribute=\"top\" secondItem=\"l1p-kb-Dga\" secondAttribute=\"bottom\" constant=\"20\" symbolic=\"YES\" id=\"DIj-JH-agH\"/>\n                <constraint firstItem=\"Kuw-aQ-8xH\" firstAttribute=\"top\" secondItem=\"bmw-w2-81i\" secondAttribute=\"bottom\" constant=\"19\" id=\"DXo-92-mQR\"/>\n                <constraint firstItem=\"UNt-JQ-D2v\" firstAttribute=\"baseline\" secondItem=\"jIg-Xc-Qbw\" secondAttribute=\"baseline\" constant=\"2\" id=\"EFV-lo-lfT\"/>\n                <constraint firstItem=\"l1p-kb-Dga\" firstAttribute=\"leading\" secondItem=\"bmw-w2-81i\" secondAttribute=\"leading\" id=\"G5S-eH-wOY\"/>\n                <constraint firstItem=\"jIg-Xc-Qbw\" firstAttribute=\"trailing\" secondItem=\"tN8-4C-2i5\" secondAttribute=\"trailing\" id=\"Hc5-vM-W9d\"/>\n                <constraint firstItem=\"HF2-Ra-st6\" firstAttribute=\"leading\" secondItem=\"wac-II-n6f\" secondAttribute=\"leading\" id=\"Iaa-tA-6M9\"/>\n                <constraint firstItem=\"l1p-kb-Dga\" firstAttribute=\"top\" secondItem=\"tN8-4C-2i5\" secondAttribute=\"bottom\" constant=\"34\" id=\"JZq-hW-zPS\"/>\n                <constraint firstItem=\"wac-II-n6f\" firstAttribute=\"centerY\" secondItem=\"bmw-w2-81i\" secondAttribute=\"centerY\" id=\"KQq-ce-nai\"/>\n                <constraint firstItem=\"eXx-ul-UhD\" firstAttribute=\"leading\" secondItem=\"nCg-8V-yCx\" secondAttribute=\"trailing\" constant=\"22\" id=\"KwA-B9-c9x\"/>\n                <constraint firstItem=\"bmw-w2-81i\" firstAttribute=\"leading\" secondItem=\"Kuw-aQ-8xH\" secondAttribute=\"leading\" id=\"LZI-kt-oF4\"/>\n                <constraint firstItem=\"UNt-JQ-D2v\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"16\" id=\"P7o-Ll-BlU\"/>\n                <constraint firstItem=\"jIg-Xc-Qbw\" firstAttribute=\"leading\" secondItem=\"UNt-JQ-D2v\" secondAttribute=\"trailing\" constant=\"10\" id=\"TME-m2-gvK\"/>\n                <constraint firstItem=\"QZa-7i-ghA\" firstAttribute=\"leading\" secondItem=\"UNt-JQ-D2v\" secondAttribute=\"leading\" id=\"UDy-7Q-kC4\"/>\n                <constraint firstItem=\"eXx-ul-UhD\" firstAttribute=\"centerY\" secondItem=\"HF2-Ra-st6\" secondAttribute=\"centerY\" id=\"Ymi-jo-Zty\"/>\n                <constraint firstItem=\"NDv-L1-vNy\" firstAttribute=\"top\" secondItem=\"wac-II-n6f\" secondAttribute=\"bottom\" constant=\"43\" id=\"agf-HU-QHf\"/>\n                <constraint firstItem=\"HF2-Ra-st6\" firstAttribute=\"centerY\" secondItem=\"l1p-kb-Dga\" secondAttribute=\"centerY\" id=\"cSt-Sk-yxT\"/>\n                <constraint firstItem=\"jIg-Xc-Qbw\" firstAttribute=\"leading\" secondItem=\"tN8-4C-2i5\" secondAttribute=\"leading\" id=\"ltu-3u-bO9\"/>\n                <constraint firstItem=\"l1p-kb-Dga\" firstAttribute=\"leading\" secondItem=\"HF2-Ra-st6\" secondAttribute=\"trailing\" constant=\"39\" id=\"mDu-NY-hyC\"/>\n                <constraint firstItem=\"l1p-kb-Dga\" firstAttribute=\"top\" secondItem=\"QZa-7i-ghA\" secondAttribute=\"bottom\" constant=\"33\" id=\"mjc-nT-FeA\"/>\n                <constraint firstItem=\"wac-II-n6f\" firstAttribute=\"top\" secondItem=\"HF2-Ra-st6\" secondAttribute=\"bottom\" constant=\"43\" id=\"o4o-Ul-oEg\"/>\n                <constraint firstItem=\"l1p-kb-Dga\" firstAttribute=\"trailing\" secondItem=\"bmw-w2-81i\" secondAttribute=\"trailing\" id=\"oz2-Rn-c4W\"/>\n                <constraint firstItem=\"QZa-7i-ghA\" firstAttribute=\"top\" secondItem=\"UNt-JQ-D2v\" secondAttribute=\"bottom\" constant=\"42\" id=\"qql-8J-jZ6\"/>\n                <constraint firstItem=\"UNt-JQ-D2v\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" constant=\"50\" id=\"t0B-hr-fXc\"/>\n                <constraint firstItem=\"bmw-w2-81i\" firstAttribute=\"trailing\" secondItem=\"Kuw-aQ-8xH\" secondAttribute=\"trailing\" id=\"tcG-0A-Puc\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"autotrackingModeSegmentedControl\" destination=\"jIg-Xc-Qbw\" id=\"XFb-hO-Hrc\"/>\n                <outlet property=\"butAutotrack\" destination=\"UNt-JQ-D2v\" id=\"SOc-9O-0Bo\"/>\n                <outlet property=\"butTrackLunch\" destination=\"wac-II-n6f\" id=\"mU3-q5-XZv\"/>\n                <outlet property=\"butTrackScrum\" destination=\"NDv-L1-vNy\" id=\"sTL-Bb-4fl\"/>\n                <outlet property=\"butTrackStartOfDay\" destination=\"HF2-Ra-st6\" id=\"k10-V7-Wla\"/>\n                <outlet property=\"endOfDayTimePicker\" destination=\"vSu-qe-UXJ\" id=\"iN3-db-Rai\"/>\n                <outlet property=\"lunchTimePicker\" destination=\"YS9-cC-uWR\" id=\"bTK-2L-cen\"/>\n                <outlet property=\"minSleepDurationLabel\" destination=\"QZa-7i-ghA\" id=\"Gv0-QH-hBv\"/>\n                <outlet property=\"minSleepDurationSlider\" destination=\"tN8-4C-2i5\" id=\"Zhb-Cm-Wwg\"/>\n                <outlet property=\"scrumTimePicker\" destination=\"ENR-qr-Ivl\" id=\"trG-mG-X99\"/>\n                <outlet property=\"startOfDayTimePicker\" destination=\"QaT-p5-5Ex\" id=\"jcB-Q0-3rS\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"171.5\" y=\"212\"/>\n        </customView>\n    </objects>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/TaskSuggestion/TaskSuggestionPresenter.swift",
    "content": "//\n//  TaskSuggestionPresenter.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 30/11/2016.\n//  Copyright © 2016 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nprotocol TaskSuggestionPresenterInput: class {\n    func setup (startSleepDate: Date?, endSleepDate: Date?)\n    func selectSegment (atIndex index: Int)\n    func save (selectedSegment: Int, notes: String, startSleepDate: Date?, endSleepDate: Date?)\n}\n\nprotocol TaskSuggestionPresenterOutput: class {\n    func selectSegment (atIndex index: Int)\n    func setTime (_ notes: String)\n    func setNotes (_ notes: String)\n    func hideTaskTypes()\n}\n\nclass TaskSuggestionPresenter {\n    \n    weak var userInterface: TaskSuggestionPresenterOutput?\n    private var isStartOfDay = false\n    private let startWorkText = \"Good morning, ready to start working?\"\n    private let moduleCalendar = ModuleCalendar()\n    \n    private func taskType (forIndex index: Int) -> TaskType {\n        \n        switch index {\n        case 0: return .scrum\n        case 1: return .meeting\n        case 2: return .lunch\n        case 3: return .waste\n        case 4: return .learning\n        default: return .issue\n        }\n    }\n    \n    private func selectedSegment (forTaskType taskType: TaskType) -> Int {\n        \n        switch taskType {\n            case .scrum: return 0\n            case .meeting: return 1\n            case .lunch: return 2\n            case .waste: return 3\n            case .learning: return 4\n            default: return -1\n        }\n    }\n}\n\nextension TaskSuggestionPresenter: TaskSuggestionPresenterInput {\n    \n    func setup (startSleepDate: Date?, endSleepDate: Date?) {\n        \n        var time = \"\"\n        if let startDate = startSleepDate {\n            time += \"Away between \\(startDate.HHmm()) - \"\n        }\n        time += endSleepDate!.HHmm()\n        userInterface!.setTime(time)\n        \n        if let startDate = startSleepDate {\n            let settings: Settings = SettingsInteractor().getAppSettings()\n            let interactor = ComputerWakeUpInteractor(repository: localRepository, remoteRepository: remoteRepository, settings: settings)\n            if let type = interactor.estimationForDate(startDate, currentDate: endSleepDate ?? Date()) {\n                if type == .startDay {\n                    isStartOfDay = true\n                    userInterface!.setNotes(startWorkText)\n                    userInterface!.hideTaskTypes()\n                } else {\n                    let index = selectedSegment(forTaskType: type)\n                    selectSegment(atIndex: index)\n                    // If selected segment is meeting, try to see if the meeting is a calendar event and populate with that data\n                    if type == .meeting {\n                        moduleCalendar.events(dateStart: startDate, dateEnd: startDate.endOfDay()) { (tasks) in\n                            for task in tasks {\n                                if task.startDate!.isAlmostSameHourAs(startDate) &&\n                                    task.endDate.isAlmostSameHourAs(endSleepDate!, devianceSeconds: 30.0.minToSec) {\n                                    \n                                    self.userInterface!.setNotes(task.notes ?? \"\")\n                                    break\n                                }\n                            }\n                        }\n                    }\n                }\n            }\n        } else {\n            isStartOfDay = true\n            userInterface!.setNotes(startWorkText)\n            userInterface!.hideTaskTypes()\n        }\n    }\n    \n    func selectSegment (atIndex index: Int) {\n        \n        let type = taskType(forIndex: index)\n        userInterface!.setNotes(type.defaultNotes)\n        userInterface!.selectSegment(atIndex: index)\n    }\n    \n    func save (selectedSegment: Int, notes: String, startSleepDate: Date?, endSleepDate: Date?) {\n        \n        var task: Task\n        \n        if isStartOfDay {\n            task = Task(endDate: endSleepDate!, type: .startDay)\n        } else {\n            let type = taskType(forIndex: selectedSegment)\n            task = Task(endDate: endSleepDate!, type: type)\n            task.notes = notes\n            task.startDate = startSleepDate\n        }\n        \n        let saveInteractor = TaskInteractor(repository: localRepository, remoteRepository: remoteRepository)\n        saveInteractor.saveTask(task, allowSyncing: true, completion: { savedTask in\n            \n        })\n        if task.taskType == .startDay {\n            ModuleHookup().insert(task: task)\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/TaskSuggestion/TaskSuggestionTests.swift",
    "content": "//\n//  TaskSuggestionTests.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 10/12/2016.\n//  Copyright © 2016 Imagin soft. All rights reserved.\n//\n\nimport XCTest\n@testable import Jirassic_no_cloud\n\nfileprivate class TaskSuggestionPresenterMock: TaskSuggestionPresenterOutput {\n    var selectSegment_called = false\n    var setTime_called = false\n    var setNotes_called = false\n    var hideTaskTypes_called = false\n    func selectSegment (atIndex index: Int) { selectSegment_called = true }\n    func setTime (_ notes: String) { setTime_called = true }\n    func setNotes (_ notes: String) { setNotes_called = true }\n    func hideTaskTypes() { hideTaskTypes_called = true }\n}\n\nclass TaskSuggestionTests: XCTestCase {\n\n    override func setUp() {\n        super.setUp()\n        localRepository = InMemoryCoreDataRepository()\n    }\n    \n    override func tearDown() {\n        super.tearDown()\n    }\n\n    func testMethod_setup() {\n        \n        let presenter = TaskSuggestionPresenter()\n        let controller = TaskSuggestionPresenterMock()\n        presenter.userInterface = controller\n        \n        presenter.setup (startSleepDate: Date(), endSleepDate: Date())\n        XCTAssert(controller.setTime_called)\n        XCTAssert(controller.setNotes_called)\n        XCTAssert(controller.hideTaskTypes_called)\n        XCTAssertFalse(controller.selectSegment_called)\n    }\n    \n    func testMethod_setTime() {\n        \n        let presenter = TaskSuggestionPresenter()\n        let controller = TaskSuggestionPresenterMock()\n        presenter.userInterface = controller\n        \n        presenter.selectSegment (atIndex: 0)\n        XCTAssertFalse(controller.setTime_called)\n        XCTAssertFalse(controller.hideTaskTypes_called)\n        XCTAssert(controller.setNotes_called)\n        XCTAssert(controller.selectSegment_called)\n    }\n    \n    func testMethod_save() {\n        \n        let presenter = TaskSuggestionPresenter()\n        let controller = TaskSuggestionPresenterMock()\n        presenter.userInterface = controller\n        \n        presenter.save (selectedSegment: 0, notes: \"\", startSleepDate: Date(), endSleepDate: Date())\n//        XCTAssert(controller.setNotes_called)\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/TaskSuggestion/TaskSuggestionViewController.swift",
    "content": "//\n//  TaskSuggestionViewController.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 30/11/2016.\n//  Copyright © 2016 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nclass TaskSuggestionViewController: NSViewController {\n    \n    @IBOutlet private weak var segmentedControl: NSSegmentedControl?\n    @IBOutlet private weak var titleTextField: NSTextField!\n    @IBOutlet private weak var notesTextField: NSTextField!\n    \n    var presenter: TaskSuggestionPresenterInput?\n    var startSleepDate: Date?\n    var endSleepDate: Date?\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        presenter!.setup(startSleepDate: startSleepDate, endSleepDate: endSleepDate)\n    }\n    \n    @IBAction func handleSegmentedControl (_ sender: NSSegmentedControl) {\n        presenter!.selectSegment(atIndex: sender.selectedSegment)\n    }\n    \n    @IBAction func handleIgnoreButton (_ sender: NSButton) {\n        AppDelegate.sharedApp().removeActivePopup()\n    }\n    \n    @IBAction func handleSaveButton (_ sender: NSButton) {\n        presenter!.save(selectedSegment: segmentedControl != nil ? segmentedControl!.selectedSegment : -1,\n                        notes: notesTextField.stringValue,\n                        startSleepDate: startSleepDate,\n                        endSleepDate: endSleepDate)\n        AppDelegate.sharedApp().removeActivePopup()\n    }\n}\n\nextension TaskSuggestionViewController: TaskSuggestionPresenterOutput {\n    \n    func selectSegment (atIndex index: Int) {\n        segmentedControl!.selectedSegment = index\n    }\n    \n    func setTime (_ notes: String) {\n        titleTextField.stringValue = notes\n    }\n    \n    func setNotes (_ notes: String) {\n        notesTextField.stringValue = notes\n    }\n    \n    func hideTaskTypes() {\n        segmentedControl!.removeFromSuperview()\n        segmentedControl = nil\n//        notesTextField.removeAutoresizing()\n//        _ = notesTextField.constraintToBottom(self.view, distance: CGFloat(0))\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/AllTasks/CellProtocol.swift",
    "content": "//\n//  CellProtocol.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 10/05/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\n\nprotocol CellProtocol {\n\n\tvar statusImage: NSImageView? {get}\n\tvar data: TaskCreationData {get set}\n\tvar duration: String {get set}\n    var isDark: Bool {get set}\n    var isEditable: Bool {get set}\n    var isRemovable: Bool {get set}\n    var isIgnored: Bool {get set}\n    var color: NSColor {get set}\n    var timeToolTip: String? {get set}\n\t\n\tvar didEndEditingCell: ((_ cell: CellProtocol) -> ())? {get set}\n\tvar didClickRemoveCell: ((_ cell: CellProtocol) -> ())? {get set}\n\tvar didClickAddCell: ((_ cell: CellProtocol) -> ())? {get set}\n\tvar didCopyContentCell: ((_ cell: CellProtocol) -> ())? {get set}\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/AllTasks/HeaderView/TasksHeaderView.swift",
    "content": "//\n//  FooterCell.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 30/01/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\nimport RCPreferences\n\nclass TasksHeaderView: NSTableHeaderView {\n\n    @IBOutlet private var backgroundView: NSVisualEffectView!\n    @IBOutlet private var butAdd: NSButton!\n    @IBOutlet private var butCloseDay: NSButton!\n    @IBOutlet private var butWorklogs: NSButton!\n    @IBOutlet private var butJiraSetup: NSButton!\n\n    private unowned let appWireframe = AppDelegate.sharedApp().appWireframe\n    private var store = Store.shared\n    private var moduleJira = ModuleJiraTempo()\n    private let pref = RCPreferences<LocalPreferences>()\n    var didClickAddTask: (() -> Void)?\n    var didClickCloseDay: (() -> Void)?\n    var didClickSaveWorklogs: (() -> Void)?\n    var isDayEnded: Bool = false {\n        didSet {\n            let isJiraAvailable = store.isJiraTempoPurchased && moduleJira.isConfigured && moduleJira.isProjectConfigured\n            self.butAdd.isHidden = isDayEnded\n            self.butCloseDay.isHidden = isDayEnded\n            self.butWorklogs.isHidden = !isDayEnded\n            self.butWorklogs.isEnabled = isJiraAvailable\n            self.butJiraSetup.isHidden = isDayEnded ? isJiraAvailable : true\n        }\n    }\n    \n    override func awakeFromNib() {\n        super.awakeFromNib()\n        if #available(OSX 10.14, *) {\n            // In OS14 there is  already a default blurry background\n            backgroundView.isHidden = true\n        }\n    }\n    \n    override func headerRect(ofColumn column: Int) -> NSRect {\n        // This will prevent for a label to appear  in the middle of the header\n        return NSRect.zero\n    }\n    \n    // Overriding this in OS14 removes default blurry background and the custom one adds ugly edges to buttons\n//    override func draw (_ dirtyRect: NSRect) {\n//    }\n\n    @IBAction func handleAddButton (_ sender: NSButton) {\n        didClickAddTask?()\n    }\n    \n    @IBAction func handleCloseDayButton (_ sender: NSButton) {\n        didClickCloseDay?()\n    }\n    \n    @IBAction func handleWorklogsButton (_ sender: NSButton) {\n        didClickSaveWorklogs?()\n    }\n    \n    @IBAction func handleJiraSetupButton (_ sender: NSButton) {\n        pref.set(SettingsTab.output.rawValue, forKey: .settingsActiveTab)\n        appWireframe.flipToSettingsController()\n    }\n\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/AllTasks/HeaderView/TasksHeaderView.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14460.31\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView identifier=\"TasksHeaderView\" id=\"c22-O7-iKe\" customClass=\"TasksHeaderView\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"454\" height=\"60\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <visualEffectView wantsLayer=\"YES\" blendingMode=\"withinWindow\" material=\"headerView\" state=\"active\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"G3y-Gc-Fo0\">\n                    <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"454\" height=\"60\"/>\n                </visualEffectView>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Ca7-bt-zzl\">\n                    <rect key=\"frame\" x=\"16\" y=\"19\" width=\"180\" height=\"22\"/>\n                    <constraints>\n                        <constraint firstAttribute=\"width\" constant=\"180\" id=\"LcH-xv-Khy\"/>\n                        <constraint firstAttribute=\"height\" constant=\"21\" id=\"ZSP-mf-RSN\"/>\n                    </constraints>\n                    <buttonCell key=\"cell\" type=\"inline\" title=\"View &amp; save worklogs to Jira\" bezelStyle=\"inline\" alignment=\"center\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"jyn-Uj-MYd\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"smallSystemBold\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleWorklogsButton:\" target=\"c22-O7-iKe\" id=\"H4Y-Kf-aFK\"/>\n                    </connections>\n                </button>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"hGd-uQ-oVI\">\n                    <rect key=\"frame\" x=\"16\" y=\"19\" width=\"84\" height=\"22\"/>\n                    <constraints>\n                        <constraint firstAttribute=\"width\" constant=\"84\" id=\"aIF-Ua-EvT\"/>\n                        <constraint firstAttribute=\"height\" constant=\"21\" id=\"cUp-G5-Pf2\"/>\n                    </constraints>\n                    <buttonCell key=\"cell\" type=\"inline\" title=\"Add task\" bezelStyle=\"inline\" alignment=\"center\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"MQg-Q4-ejA\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"smallSystemBold\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleAddButton:\" target=\"c22-O7-iKe\" id=\"xPX-St-Za4\"/>\n                    </connections>\n                </button>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"uAc-jr-se2\">\n                    <rect key=\"frame\" x=\"350\" y=\"19\" width=\"84\" height=\"22\"/>\n                    <constraints>\n                        <constraint firstAttribute=\"height\" constant=\"21\" id=\"1EQ-yN-ZBK\"/>\n                        <constraint firstAttribute=\"width\" constant=\"84\" id=\"gDa-WP-xPg\"/>\n                    </constraints>\n                    <buttonCell key=\"cell\" type=\"inline\" title=\"Close day\" bezelStyle=\"inline\" alignment=\"center\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"TQ5-EY-xdp\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"smallSystemBold\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleCloseDayButton:\" target=\"c22-O7-iKe\" id=\"ntd-ay-WNX\"/>\n                    </connections>\n                </button>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Mpy-Nv-lYn\">\n                    <rect key=\"frame\" x=\"204\" y=\"20\" width=\"50\" height=\"19\"/>\n                    <buttonCell key=\"cell\" type=\"roundRect\" title=\"Setup\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"mLC-pf-tpN\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"system\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleJiraSetupButton:\" target=\"c22-O7-iKe\" id=\"9f2-ae-Npn\"/>\n                    </connections>\n                </button>\n            </subviews>\n            <constraints>\n                <constraint firstItem=\"hGd-uQ-oVI\" firstAttribute=\"centerY\" secondItem=\"c22-O7-iKe\" secondAttribute=\"centerY\" id=\"04F-ms-XJx\"/>\n                <constraint firstItem=\"hGd-uQ-oVI\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"16\" id=\"5KR-F5-HAg\"/>\n                <constraint firstItem=\"G3y-Gc-Fo0\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" id=\"6rH-J1-1Qe\"/>\n                <constraint firstItem=\"uAc-jr-se2\" firstAttribute=\"centerY\" secondItem=\"c22-O7-iKe\" secondAttribute=\"centerY\" id=\"A67-H0-a3l\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"G3y-Gc-Fo0\" secondAttribute=\"trailing\" id=\"Ena-xg-kyW\"/>\n                <constraint firstItem=\"Mpy-Nv-lYn\" firstAttribute=\"leading\" secondItem=\"Ca7-bt-zzl\" secondAttribute=\"trailing\" constant=\"8\" id=\"OhW-Qc-w9Q\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"G3y-Gc-Fo0\" secondAttribute=\"bottom\" id=\"bBM-JF-X6s\"/>\n                <constraint firstItem=\"Mpy-Nv-lYn\" firstAttribute=\"centerY\" secondItem=\"c22-O7-iKe\" secondAttribute=\"centerY\" id=\"cDs-UT-aDY\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"uAc-jr-se2\" secondAttribute=\"trailing\" constant=\"20\" id=\"fla-hf-sWR\"/>\n                <constraint firstItem=\"G3y-Gc-Fo0\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" id=\"iTa-k4-tZH\"/>\n                <constraint firstItem=\"Ca7-bt-zzl\" firstAttribute=\"leading\" secondItem=\"hGd-uQ-oVI\" secondAttribute=\"leading\" id=\"t2C-Lh-hmH\"/>\n                <constraint firstItem=\"Ca7-bt-zzl\" firstAttribute=\"centerY\" secondItem=\"c22-O7-iKe\" secondAttribute=\"centerY\" id=\"tBT-qw-lNA\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"backgroundView\" destination=\"G3y-Gc-Fo0\" id=\"ShE-Fb-LMI\"/>\n                <outlet property=\"butAdd\" destination=\"hGd-uQ-oVI\" id=\"3iX-M6-W2m\"/>\n                <outlet property=\"butCloseDay\" destination=\"uAc-jr-se2\" id=\"KdB-3P-8a6\"/>\n                <outlet property=\"butJiraSetup\" destination=\"Mpy-Nv-lYn\" id=\"a0T-TH-aWu\"/>\n                <outlet property=\"butWorklogs\" destination=\"Ca7-bt-zzl\" id=\"OPQ-12-3Lv\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"126\" y=\"63\"/>\n        </customView>\n    </objects>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/AllTasks/NonTaskCell/NonTaskCell.swift",
    "content": "//\n//  NonTaskCell.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 07/05/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\n\nclass NonTaskCell: NSTableRowView, CellProtocol {\n\n    @IBOutlet var statusImage: NSImageView?\n    @IBOutlet private var statusImageWidthContraint: NSLayoutConstraint!\n    @IBOutlet private var dateStartTextField: TimeBox!\n    @IBOutlet private var dateStartTextFieldLeadingContraint: NSLayoutConstraint!\n\t@IBOutlet private var dateEndTextField: TimeBox!\n\t@IBOutlet private var notesTextField: NSTextField!\n\t@IBOutlet private var notesTextFieldTrailingContraint: NSLayoutConstraint!\n\t@IBOutlet private var butRemove: NSButton!\n\t@IBOutlet private var butAdd: NSButton!\n    \n    private var isEditing = false\n    private var wasEdited = false\n    private var trackingArea: NSTrackingArea?\n    private var activeTimeboxPopover: NSPopover?\n\t\n\tvar didEndEditingCell: ((_ cell: CellProtocol) -> ())?\n\tvar didClickRemoveCell: ((_ cell: CellProtocol) -> ())?\n\tvar didClickAddCell: ((_ cell: CellProtocol) -> ())?\n\tvar didCopyContentCell: ((_ cell: CellProtocol) -> ())?\n    \n    private var _data: TaskCreationData?\n\tvar data: TaskCreationData {\n\t\tget {\n            if let dateStart = _data?.dateStart {\n                let newHM = Date.parseHHmm(self.dateStartTextField.stringValue)\n                let date = dateStart.dateByUpdating(hour: newHM.hour, minute: newHM.min)\n                _data?.dateStart = date\n            }\n            let newHM = Date.parseHHmm(self.dateEndTextField.stringValue)\n            let dateEnd = _data!.dateEnd.dateByUpdating(hour: newHM.hour, minute: newHM.min)\n            _data?.dateEnd = dateEnd\n            \n            if self.notesTextField.stringValue != \"\" {\n                _data?.notes = self.notesTextField.stringValue\n            }\n            \n            return _data!\n\t\t}\n        set {\n            _data = newValue\n            if let dateStart = newValue.dateStart {\n                self.dateStartTextField.stringValue = dateStart.HHmm()\n                self.dateStartTextField.isHidden = false\n                self.dateStartTextFieldLeadingContraint.constant = 14\n            } else {\n                self.dateStartTextField.isHidden = true\n                self.dateStartTextFieldLeadingContraint.constant = 14 - 36 - 4\n            }\n            self.dateEndTextField.stringValue = newValue.dateEnd.HHmm()\n\t\t\tself.notesTextField.stringValue = newValue.notes ?? \"\"\n\t\t}\n\t}\n\tvar duration: String {\n\t\tget {\n\t\t\treturn \"\"\n\t\t}\n        set {\n            fatalError(\"Not available\")\n        }\n    }\n    var isDark: Bool = false {\n        didSet {\n            dateStartTextField.isDark = isDark\n            dateEndTextField.isDark = isDark\n        }\n    }\n    var isEditable: Bool = true {\n        didSet {\n            notesTextField.isEditable = isEditable\n        }\n    }\n    var isRemovable: Bool = true\n    var isIgnored: Bool = false {\n        didSet {\n            self.notesTextField!.alphaValue = isIgnored ? 0.5 : 1.0\n        }\n    }\n    var color: NSColor = NSColor.black {\n        didSet {\n            self.notesTextField!.textColor = color\n        }\n    }\n    var timeToolTip: String? {\n        didSet {\n            dateStartTextField.toolTip = timeToolTip\n            dateEndTextField.toolTip = timeToolTip\n        }\n    }\n\t\n\toverride func awakeFromNib() {\n        super.awakeFromNib()\n        \n\t\tbutRemove.isHidden = true\n\t\tbutAdd.isHidden = true\n        butRemove.wantsLayer = true\n        dateStartTextField.onClick = {\n            self.createTimeboxPopover(timebox: self.dateStartTextField)\n        }\n        dateEndTextField.onClick = {\n            self.createTimeboxPopover(timebox: self.dateEndTextField)\n        }\n        if AppDelegate.sharedApp().theme.isDark {\n            notesTextField!.textColor = NSColor.white\n        }\n\t}\n\t\n\toverride func drawBackground (in dirtyRect: NSRect) {\n        \n\t\tNSColor(calibratedWhite: 1.0, alpha: 0.0).setFill()\n\t\tlet selectionPath = NSBezierPath(roundedRect: dirtyRect, xRadius: 0, yRadius: 0)\n\t\tselectionPath.fill()\n\t}\n    \n    private func createTimeboxPopover (timebox: TimeBox) {\n        guard activeTimeboxPopover == nil, isEditable else {\n            return\n        }\n        let popover = NSPopover()\n        let view = TimeBoxViewController.instantiateFromStoryboard(\"Components\")\n        view.didSave = {\n            let hasChanges = timebox.stringValue != view.stringValue\n            timebox.stringValue = view.stringValue\n            popover.performClose(nil)\n            if hasChanges {\n                self.didEndEditingCell?(self)\n            }\n        }\n        view.didCancel = {\n            popover.performClose(nil)\n            self.activeTimeboxPopover = nil\n        }\n        popover.contentViewController = view\n        popover.show(relativeTo: timebox.frame, of: self, preferredEdge: NSRectEdge.maxY)\n        view.stringValue = timebox.stringValue\n        \n        activeTimeboxPopover = popover\n    }\n}\n\nextension NonTaskCell {\n\t\n\t@IBAction func handleRemoveButton (_ sender: NSButton) {\n\t\tdidClickRemoveCell?(self)\n\t}\n\t\n\t@IBAction func handleAddButton (_ sender: NSButton) {\n\t\tdidClickAddCell?(self)\n\t}\n}\n\nextension NonTaskCell {\n    \n\toverride func mouseEntered (with theEvent: NSEvent) {\n        super.mouseEntered(with: theEvent)\n        \n\t\tself.butRemove.isHidden = false\n        self.butAdd.isHidden = false\n\t\tself.notesTextFieldTrailingContraint.constant = 80\n\t\tself.setNeedsDisplay(self.frame)\n\t}\n\t\n//    override func mouseMoved(with event: NSEvent) {\n//        \n//        let locationInWindow = event.locationInWindow\n//        let locationInView = self.convert(locationInWindow, from: nil)\n//        RCLog(locationInView)\n//        if dateStartTextField.frame.contains(locationInView) {\n//            dateStartTextField.font = NSFont.systemFont(ofSize: 14)\n//        }\n//    }\n    \n\toverride func mouseExited (with theEvent: NSEvent) {\n        super.mouseExited(with: theEvent)\n        \n\t\tself.butRemove.isHidden = true\n        self.butAdd.isHidden = true\n\t\tself.notesTextFieldTrailingContraint.constant = 10\n\t\tself.setNeedsDisplay(self.frame)\n\t}\n\t\n\tfunc ensureTrackingArea() {\n        \n\t\tif trackingArea == nil {\n\t\t\ttrackingArea = NSTrackingArea(rect: NSZeroRect,\n\t\t\t\toptions: [\n                    NSTrackingArea.Options.inVisibleRect,\n                    NSTrackingArea.Options.activeAlways,\n                    NSTrackingArea.Options.mouseEnteredAndExited\n                ],\n\t\t\t\towner: self,\n\t\t\t\tuserInfo: nil)\n\t\t}\n\t}\n\t\n\toverride func updateTrackingAreas() {\n\t\tsuper.updateTrackingAreas()\n        \n\t\tself.ensureTrackingArea()\n\t\tif !self.trackingAreas.contains(self.trackingArea!) {\n\t\t\tself.addTrackingArea(self.trackingArea!)\n\t\t}\n\t}\n}\n\nextension NonTaskCell: NSTextFieldDelegate {\n    \n    public func control(_ control: NSControl, textShouldBeginEditing fieldEditor: NSText) -> Bool {\n        isEditing = true\n        return true\n    }\n    \n    public func control(_ control: NSControl, textShouldEndEditing fieldEditor: NSText) -> Bool {\n        if wasEdited {\n            wasEdited = false\n            didEndEditingCell?(self)\n        }\n        return true\n    }\n    \n    public func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {\n        // Detect Enter key\n        if wasEdited && commandSelector == #selector(NSResponder.insertNewline(_:)) {\n            didEndEditingCell?(self)\n            wasEdited = false\n        }\n        return false\n    }\n    \n    func controlTextDidChange (_ obj: Notification) {\n        wasEdited = true\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/AllTasks/NonTaskCell/NonTaskCell.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14460.31\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView identifier=\"NonTaskCell\" id=\"c22-O7-iKe\" customClass=\"NonTaskCell\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"341\" height=\"34\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <textField focusRingType=\"none\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"mSe-2c-CEz\">\n                    <rect key=\"frame\" x=\"92\" y=\"11\" width=\"241\" height=\"13\"/>\n                    <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" focusRingType=\"none\" alignment=\"left\" title=\"Scrum\" id=\"V6V-UH-zIc\">\n                        <font key=\"font\" metaFont=\"systemBold\" size=\"10\"/>\n                        <color key=\"textColor\" name=\"systemGrayColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" white=\"1\" alpha=\"0.0\" colorSpace=\"deviceWhite\"/>\n                    </textFieldCell>\n                    <connections>\n                        <outlet property=\"delegate\" destination=\"c22-O7-iKe\" id=\"nXg-Io-bJL\"/>\n                    </connections>\n                </textField>\n                <box boxType=\"custom\" cornerRadius=\"7\" title=\"Box\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"tqo-U8-RGc\" customClass=\"TimeBox\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n                    <rect key=\"frame\" x=\"14\" y=\"10\" width=\"36\" height=\"14\"/>\n                    <view key=\"contentView\" id=\"L9X-k7-ZjZ\">\n                        <rect key=\"frame\" x=\"1\" y=\"1\" width=\"34\" height=\"12\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                    </view>\n                    <constraints>\n                        <constraint firstAttribute=\"height\" constant=\"14\" id=\"1dM-lX-jYV\"/>\n                        <constraint firstAttribute=\"width\" constant=\"36\" id=\"Tar-cs-kbw\"/>\n                    </constraints>\n                </box>\n                <box boxType=\"custom\" cornerRadius=\"7\" title=\"Box\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"MAr-Mi-Hug\" customClass=\"TimeBox\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n                    <rect key=\"frame\" x=\"54\" y=\"10\" width=\"36\" height=\"14\"/>\n                    <view key=\"contentView\" id=\"0O8-z5-GYa\">\n                        <rect key=\"frame\" x=\"1\" y=\"1\" width=\"34\" height=\"12\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                    </view>\n                    <constraints>\n                        <constraint firstAttribute=\"width\" constant=\"36\" id=\"JBJ-mO-VHe\"/>\n                        <constraint firstAttribute=\"height\" constant=\"14\" id=\"tgs-FZ-bha\"/>\n                    </constraints>\n                </box>\n                <button translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"JnH-wo-pJy\">\n                    <rect key=\"frame\" x=\"309\" y=\"10\" width=\"16\" height=\"16\"/>\n                    <constraints>\n                        <constraint firstAttribute=\"height\" constant=\"16\" id=\"7MI-XH-Yv3\"/>\n                        <constraint firstAttribute=\"width\" constant=\"16\" id=\"HJH-Sf-528\"/>\n                    </constraints>\n                    <buttonCell key=\"cell\" type=\"square\" bezelStyle=\"shadowlessSquare\" image=\"NSRemoveTemplate\" imagePosition=\"only\" alignment=\"center\" state=\"on\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"iIg-Ta-PA6\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"system\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleRemoveButton:\" target=\"c22-O7-iKe\" id=\"TpF-le-3We\"/>\n                    </connections>\n                </button>\n                <button translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"z4T-g2-tdS\">\n                    <rect key=\"frame\" x=\"284\" y=\"10\" width=\"16\" height=\"16\"/>\n                    <constraints>\n                        <constraint firstAttribute=\"width\" constant=\"16\" id=\"nqW-yh-9HU\"/>\n                        <constraint firstAttribute=\"height\" constant=\"16\" id=\"u2a-dx-CSH\"/>\n                    </constraints>\n                    <buttonCell key=\"cell\" type=\"square\" bezelStyle=\"shadowlessSquare\" image=\"NSAddTemplate\" imagePosition=\"only\" alignment=\"center\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"PPd-DR-pXH\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"system\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleAddButton:\" target=\"c22-O7-iKe\" id=\"eaV-Iu-0RD\"/>\n                    </connections>\n                </button>\n                <imageView horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"1gO-Mn-ATS\">\n                    <rect key=\"frame\" x=\"0.0\" y=\"9\" width=\"16\" height=\"16\"/>\n                    <constraints>\n                        <constraint firstAttribute=\"width\" constant=\"16\" id=\"7yW-fH-jqf\"/>\n                        <constraint firstAttribute=\"height\" constant=\"16\" id=\"w6q-0t-ius\"/>\n                    </constraints>\n                    <imageCell key=\"cell\" refusesFirstResponder=\"YES\" alignment=\"left\" imageScaling=\"proportionallyDown\" image=\"NSStatusAvailable\" id=\"xFv-O5-zbJ\"/>\n                </imageView>\n            </subviews>\n            <constraints>\n                <constraint firstItem=\"1gO-Mn-ATS\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" id=\"2WT-I3-hg1\"/>\n                <constraint firstItem=\"MAr-Mi-Hug\" firstAttribute=\"centerY\" secondItem=\"c22-O7-iKe\" secondAttribute=\"centerY\" id=\"6Sh-mu-aqc\"/>\n                <constraint firstItem=\"1gO-Mn-ATS\" firstAttribute=\"centerY\" secondItem=\"c22-O7-iKe\" secondAttribute=\"centerY\" id=\"AQ4-xS-01a\"/>\n                <constraint firstAttribute=\"centerY\" secondItem=\"JnH-wo-pJy\" secondAttribute=\"centerY\" constant=\"1\" id=\"BfB-re-cQN\"/>\n                <constraint firstItem=\"mSe-2c-CEz\" firstAttribute=\"leading\" secondItem=\"MAr-Mi-Hug\" secondAttribute=\"trailing\" constant=\"4\" id=\"Esg-fT-F47\"/>\n                <constraint firstItem=\"JnH-wo-pJy\" firstAttribute=\"leading\" secondItem=\"z4T-g2-tdS\" secondAttribute=\"trailing\" constant=\"9\" id=\"NNh-nr-9GO\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"JnH-wo-pJy\" secondAttribute=\"trailing\" constant=\"16\" id=\"NYK-xv-SAy\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"mSe-2c-CEz\" secondAttribute=\"trailing\" constant=\"10\" id=\"OxX-q5-0hQ\"/>\n                <constraint firstItem=\"MAr-Mi-Hug\" firstAttribute=\"leading\" secondItem=\"tqo-U8-RGc\" secondAttribute=\"trailing\" constant=\"4\" id=\"PLI-Pf-PaE\"/>\n                <constraint firstItem=\"mSe-2c-CEz\" firstAttribute=\"centerY\" secondItem=\"c22-O7-iKe\" secondAttribute=\"centerY\" id=\"Qz6-sT-SxZ\"/>\n                <constraint firstItem=\"tqo-U8-RGc\" firstAttribute=\"centerY\" secondItem=\"c22-O7-iKe\" secondAttribute=\"centerY\" id=\"b1p-AL-fPW\"/>\n                <constraint firstItem=\"tqo-U8-RGc\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"14\" id=\"nm2-hB-hAj\"/>\n                <constraint firstAttribute=\"centerY\" secondItem=\"z4T-g2-tdS\" secondAttribute=\"centerY\" constant=\"0.5\" id=\"pLz-EK-2EF\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"butAdd\" destination=\"z4T-g2-tdS\" id=\"Abq-cd-a9h\"/>\n                <outlet property=\"butRemove\" destination=\"JnH-wo-pJy\" id=\"DVY-pe-Va1\"/>\n                <outlet property=\"dateEndTextField\" destination=\"MAr-Mi-Hug\" id=\"vwx-gw-aaE\"/>\n                <outlet property=\"dateStartTextField\" destination=\"tqo-U8-RGc\" id=\"97u-xp-y1h\"/>\n                <outlet property=\"dateStartTextFieldLeadingContraint\" destination=\"nm2-hB-hAj\" id=\"KQC-NV-HgF\"/>\n                <outlet property=\"notesTextField\" destination=\"mSe-2c-CEz\" id=\"jmn-xA-2rK\"/>\n                <outlet property=\"notesTextFieldTrailingContraint\" destination=\"OxX-q5-0hQ\" id=\"Rc7-3M-NaS\"/>\n                <outlet property=\"statusImage\" destination=\"1gO-Mn-ATS\" id=\"3VV-os-nJr\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"256.5\" y=\"173\"/>\n        </customView>\n    </objects>\n    <resources>\n        <image name=\"NSAddTemplate\" width=\"11\" height=\"11\"/>\n        <image name=\"NSRemoveTemplate\" width=\"11\" height=\"11\"/>\n        <image name=\"NSStatusAvailable\" width=\"16\" height=\"16\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/AllTasks/TaskCell/TaskCell.swift",
    "content": "//\n//  TaskCell.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 28/03/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\n\nclass TaskCell: NSTableRowView, CellProtocol {\n    \n    @IBOutlet var contentView: NSView!\n    \n\t@IBOutlet var statusImage: NSImageView?\n\t@IBOutlet private var dateEndTextField: TimeBox!\n\t@IBOutlet private var issueNrTextField: NSTextField!\n    @IBOutlet private var notesTextField: NSTextField!\n    @IBOutlet private var notesTextFieldRightConstrain: NSLayoutConstraint!\n    \n    @IBOutlet private var butAdd: NSButton!\n\t@IBOutlet private var butRemove: NSButton!\n    @IBOutlet private var butRemoveWidthConstraint: NSLayoutConstraint!\n    \n    @IBOutlet private var line1: NSBox!\n    @IBOutlet private var line2: NSBox!\n\t\n\tprivate var isEditing = false\n\tprivate var wasEdited = false\n\tprivate var mouseInside = false\n\tprivate var trackingArea: NSTrackingArea?\n    private var activeTimeboxPopover: NSPopover?\n\t\n\tvar didEndEditingCell: ((_ cell: CellProtocol) -> ())?\n\tvar didClickRemoveCell: ((_ cell: CellProtocol) -> ())?\n\tvar didClickAddCell: ((_ cell: CellProtocol) -> ())?\n\tvar didCopyContentCell: ((_ cell: CellProtocol) -> ())?\n\t\n\t// Sets data to the cell\n    var _dateEnd = Date()\n\tvar _dateEndHHmm = \"\"\n\tvar data: TaskCreationData {\n\t\tget {\n            let hm = Date.parseHHmm(self.dateEndTextField!.stringValue)\n            let date = _dateEnd.dateByUpdating(hour: hm.hour, minute: hm.min)\n\t\t\treturn (\n                dateStart: nil,\n                dateEnd: date,\n                taskNumber: self.issueNrTextField.stringValue,\n                notes: self.notesTextField.stringValue,\n                taskType: .issue\n            )\n\t\t}\n\t\tset {\n            _dateEnd = newValue.dateEnd\n            _dateEndHHmm = _dateEnd.HHmm()\n            dateEndTextField.stringValue = _dateEndHHmm\n\t\t\tissueNrTextField.stringValue = newValue.taskNumber ?? \"\"\n\t\t\tnotesTextField.stringValue = newValue.notes ?? \"\"\n\t\t}\n\t}\n    var duration: String {\n        get {\n            return \"\"\n        }\n        set {\n            fatalError(\"Not available\")\n        }\n    }\n    var isDark: Bool = false {\n        didSet {\n            dateEndTextField.isDark = isDark\n        }\n    }\n    var isEditable: Bool = true {\n        didSet {\n            issueNrTextField.isEditable = isEditable\n            notesTextField.isEditable = isEditable\n        }\n    }\n    var isRemovable: Bool = true {\n        didSet {\n            butRemove.isEnabled = isRemovable\n        }\n    }\n    var isIgnored: Bool = false\n    var color: NSColor = NSColor.black {\n        didSet {\n            self.notesTextField!.textColor = color\n        }\n    }\n    var timeToolTip: String? {\n        didSet {\n            self.toolTip = nil\n            dateEndTextField.toolTip = timeToolTip\n        }\n    }\n    \n\toverride func awakeFromNib() {\n        super.awakeFromNib()\n\t\tshowMouseOverControls(false)\n        notesTextFieldRightConstrain.constant = 0\n        dateEndTextField.onClick = { [weak self] in\n            if let wself = self {\n                wself.createTimeboxPopover(timebox: wself.dateEndTextField)\n            }\n        }\n\t}\n    \n    private func createTimeboxPopover (timebox: TimeBox) {\n        guard activeTimeboxPopover == nil else {\n            return\n        }\n        let popover = NSPopover()\n        let view = TimeBoxViewController.instantiateFromStoryboard(\"Components\")\n        view.didSave = {\n            let hasChanges = timebox.stringValue != view.stringValue\n            timebox.stringValue = view.stringValue\n            popover.performClose(nil)\n            if hasChanges {\n                self.didEndEditingCell?(self)\n            }\n        }\n        view.didCancel = {\n            popover.performClose(nil)\n            self.activeTimeboxPopover = nil\n        }\n        popover.contentViewController = view\n        popover.show(relativeTo: timebox.frame, of: self, preferredEdge: NSRectEdge.maxY)\n        view.stringValue = timebox.stringValue\n        \n        activeTimeboxPopover = popover\n    }\n}\n\nextension TaskCell {\n\t\n\t@IBAction func handleRemoveButton (_ sender: NSButton) {\n\t\tdidClickRemoveCell?(self)\n\t}\n\t\n\t@IBAction func handleAddButton (_ sender: NSButton) {\n\t\tdidClickAddCell?(self)\n\t}\n}\n\nextension TaskCell {\n\n\toverride func drawBackground (in dirtyRect: NSRect) {\n\t\t\n        let width = dirtyRect.size.width - kCellLeftPadding * 2\n        let height = dirtyRect.size.height - kGapBetweenCells - 2\n        \n        if isEditing {\n            let selectionRect = NSRect(x: kCellLeftPadding, y: 2, width: width, height: height)\n            NSColor.red.setStroke()\n            let selectionPath = NSBezierPath(roundedRect: selectionRect, xRadius: 6, yRadius: 6)\n            selectionPath.stroke()\n        }\n\t\telse if self.mouseInside {\n            notesTextFieldRightConstrain!.constant = isRemovable ? 90 : 40\n            butRemoveWidthConstraint.constant = isRemovable ? 40 : 0\n\t\t\tlet selectionRect = NSRect(x: kCellLeftPadding, y: 2, width: width, height: height)\n\t\t\t//NSColor(calibratedWhite: 1.0, alpha: 0.0).setFill()\n            AppDelegate.sharedApp().theme.highlightLineColor.setStroke()\n//\t\t\tNSColor(calibratedRed: 0.3, green: 0.1, blue: 0.1, alpha: 1.0).setStroke()\n\t\t\tlet selectionPath = NSBezierPath(roundedRect: selectionRect, xRadius: 6, yRadius: 6)\n//\t\t\tselectionPath.fill()\n\t\t\tselectionPath.stroke()\n\t\t}\n        else {\n            notesTextFieldRightConstrain!.constant = 0\n\t\t\tlet selectionRect = NSRect(x: kCellLeftPadding, y: 2, width: width, height: height)\n//            NSColor(calibratedWhite: 1.0, alpha: 1.0).setFill()\n            AppDelegate.sharedApp().theme.lineColor.setStroke()\n\t\t\tlet selectionPath = NSBezierPath(roundedRect: selectionRect, xRadius: 6, yRadius: 6)\n//            selectionPath.fill()\n            selectionPath.stroke()\n\t\t}\n\t}\n\t\n\toverride func mouseEntered (with theEvent: NSEvent) {\n        super.mouseEntered(with: theEvent)\n\t\tself.mouseInside = true\n\t\tself.showMouseOverControls(self.mouseInside)\n\t\tself.setNeedsDisplay(self.frame)\n\t}\n\t\n    override func mouseExited (with theEvent: NSEvent) {\n        super.mouseExited(with: theEvent)\n\t\tself.mouseInside = false\n\t\tself.showMouseOverControls(self.mouseInside)\n\t\tself.setNeedsDisplay(self.frame)\n\t}\n\t\n\tfunc showMouseOverControls (_ show: Bool) {\n\t\tbutRemove.isHidden = !show\n\t\tbutAdd.isHidden = !show\n        line1.isHidden = !show\n        line2.isHidden = !show\n\t}\n\t\n\tfunc ensureTrackingArea() {\n\t\tif trackingArea == nil {\n\t\t\ttrackingArea = NSTrackingArea(\n\t\t\t\trect: NSZeroRect,\n\t\t\t\toptions: [NSTrackingArea.Options.inVisibleRect,\n                          NSTrackingArea.Options.activeAlways,\n                          NSTrackingArea.Options.mouseEnteredAndExited],\n\t\t\t\towner: self,\n\t\t\t\tuserInfo: nil\n\t\t\t)\n\t\t}\n\t}\n\t\n\toverride func updateTrackingAreas() {\n\t\tsuper.updateTrackingAreas()\n\t\tself.ensureTrackingArea()\n\t\tif !self.trackingAreas.contains(self.trackingArea!) {\n\t\t\tself.addTrackingArea(self.trackingArea!)\n\t\t}\n\t}\n}\n\nextension TaskCell: NSTextFieldDelegate {\n    \n    public func control(_ control: NSControl, textShouldBeginEditing fieldEditor: NSText) -> Bool {\n        isEditing = true\n        self.setNeedsDisplay(self.frame)\n        return true\n    }\n    \n    public func control(_ control: NSControl, textShouldEndEditing fieldEditor: NSText) -> Bool {\n        if wasEdited {\n            wasEdited = false\n            isEditing = false\n            didEndEditingCell?(self)\n            self.setNeedsDisplay(self.frame)\n        }\n        return true\n    }\n    \n    public func control(_ control: NSControl, textView: NSTextView, doCommandBy commandSelector: Selector) -> Bool {\n        // Detect Enter key\n        if wasEdited && commandSelector == #selector(NSResponder.insertNewline(_:)) {\n            wasEdited = false\n            isEditing = false\n            didEndEditingCell?(self)\n            self.setNeedsDisplay(self.frame)\n        }\n        return false\n    }\n    \n    func controlTextDidChange (_ obj: Notification) {\n        wasEdited = true\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/AllTasks/TaskCell/TaskCell.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"14313.18\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14313.18\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView identifier=\"TaskCell\" id=\"c22-O7-iKe\" customClass=\"TaskCell\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"345\" height=\"90\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <customView translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"nlM-Fp-eXf\">\n                    <rect key=\"frame\" x=\"10\" y=\"16\" width=\"325\" height=\"74\"/>\n                    <subviews>\n                        <imageView horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"251\" fixedFrame=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"iAi-8T-Cme\">\n                            <rect key=\"frame\" x=\"4\" y=\"52\" width=\"16\" height=\"16\"/>\n                            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                            <imageCell key=\"cell\" refusesFirstResponder=\"YES\" alignment=\"left\" imageScaling=\"proportionallyDown\" image=\"NSStatusAvailable\" id=\"8nF-e0-hw4\"/>\n                        </imageView>\n                        <textField focusRingType=\"none\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" preferredMaxLayoutWidth=\"195\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"bpM-64-Faf\">\n                            <rect key=\"frame\" x=\"28\" y=\"49\" width=\"199\" height=\"20\"/>\n                            <constraints>\n                                <constraint firstAttribute=\"height\" constant=\"20\" id=\"Bd8-bF-FUz\"/>\n                            </constraints>\n                            <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" focusRingType=\"none\" alignment=\"left\" title=\"AA-0000\" placeholderString=\"----------\" id=\"dlI-ub-5hj\">\n                                <font key=\"font\" metaFont=\"systemBold\"/>\n                                <color key=\"textColor\" name=\"textColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                <color key=\"backgroundColor\" red=\"0.95654549870000005\" green=\"0.87322156549999996\" blue=\"0.28354544710000001\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"displayP3\"/>\n                            </textFieldCell>\n                            <connections>\n                                <outlet property=\"delegate\" destination=\"c22-O7-iKe\" id=\"vb7-vl-ZlY\"/>\n                            </connections>\n                        </textField>\n                        <textField focusRingType=\"none\" verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" allowsCharacterPickerTouchBarItem=\"YES\" preferredMaxLayoutWidth=\"195\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"tMm-ch-iIr\">\n                            <rect key=\"frame\" x=\"28\" y=\"2\" width=\"199\" height=\"47\"/>\n                            <textFieldCell key=\"cell\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" focusRingType=\"none\" title=\"Notes\" placeholderString=\"What did you do in this task?\" id=\"PIu-Xg-tz0\">\n                                <font key=\"font\" metaFont=\"system\"/>\n                                <color key=\"textColor\" name=\"textColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                <color key=\"backgroundColor\" name=\"systemPinkColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                            </textFieldCell>\n                            <connections>\n                                <outlet property=\"delegate\" destination=\"c22-O7-iKe\" id=\"wBj-nC-xMX\"/>\n                            </connections>\n                        </textField>\n                        <box horizontalHuggingPriority=\"750\" boxType=\"separator\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"mpD-Z5-CaT\">\n                            <rect key=\"frame\" x=\"243\" y=\"5\" width=\"5\" height=\"64\"/>\n                            <constraints>\n                                <constraint firstAttribute=\"width\" constant=\"1\" id=\"Gr8-eT-92p\"/>\n                            </constraints>\n                        </box>\n                        <button translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"egw-SB-d18\">\n                            <rect key=\"frame\" x=\"244\" y=\"0.0\" width=\"40\" height=\"74\"/>\n                            <constraints>\n                                <constraint firstAttribute=\"width\" constant=\"40\" id=\"sT2-bK-Lgt\"/>\n                            </constraints>\n                            <buttonCell key=\"cell\" type=\"square\" bezelStyle=\"shadowlessSquare\" image=\"NSAddTemplate\" imagePosition=\"only\" alignment=\"center\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"QSn-Zg-qm9\">\n                                <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                <font key=\"font\" metaFont=\"system\"/>\n                            </buttonCell>\n                            <connections>\n                                <action selector=\"handleAddButton:\" target=\"c22-O7-iKe\" id=\"D81-SN-tJv\"/>\n                            </connections>\n                        </button>\n                        <box horizontalHuggingPriority=\"750\" boxType=\"separator\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"EWV-4g-F8D\">\n                            <rect key=\"frame\" x=\"284\" y=\"5\" width=\"5\" height=\"64\"/>\n                            <constraints>\n                                <constraint firstAttribute=\"width\" constant=\"1\" id=\"u6K-AF-tb4\"/>\n                            </constraints>\n                        </box>\n                        <button translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"xar-Oo-330\">\n                            <rect key=\"frame\" x=\"285\" y=\"0.0\" width=\"40\" height=\"74\"/>\n                            <constraints>\n                                <constraint firstAttribute=\"width\" constant=\"40\" id=\"sLm-Pa-cG9\"/>\n                            </constraints>\n                            <buttonCell key=\"cell\" type=\"square\" bezelStyle=\"shadowlessSquare\" image=\"NSRemoveTemplate\" imagePosition=\"only\" alignment=\"center\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"FC9-P2-mEo\">\n                                <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                <font key=\"font\" metaFont=\"system\"/>\n                            </buttonCell>\n                            <connections>\n                                <action selector=\"handleRemoveButton:\" target=\"c22-O7-iKe\" id=\"oWe-AX-kJB\"/>\n                            </connections>\n                        </button>\n                    </subviews>\n                    <constraints>\n                        <constraint firstAttribute=\"bottom\" secondItem=\"xar-Oo-330\" secondAttribute=\"bottom\" id=\"1qr-l8-df2\"/>\n                        <constraint firstItem=\"tMm-ch-iIr\" firstAttribute=\"trailing\" secondItem=\"bpM-64-Faf\" secondAttribute=\"trailing\" id=\"8Ce-Qx-9Nt\"/>\n                        <constraint firstAttribute=\"bottom\" secondItem=\"EWV-4g-F8D\" secondAttribute=\"bottom\" constant=\"5\" id=\"9z3-VD-G9h\"/>\n                        <constraint firstItem=\"egw-SB-d18\" firstAttribute=\"top\" secondItem=\"nlM-Fp-eXf\" secondAttribute=\"top\" id=\"A8C-VE-1z0\"/>\n                        <constraint firstItem=\"egw-SB-d18\" firstAttribute=\"leading\" secondItem=\"mpD-Z5-CaT\" secondAttribute=\"trailing\" constant=\"-2\" id=\"EHw-5b-Lpz\"/>\n                        <constraint firstAttribute=\"trailing\" secondItem=\"tMm-ch-iIr\" secondAttribute=\"trailing\" constant=\"100\" id=\"GXk-TS-g3i\"/>\n                        <constraint firstItem=\"tMm-ch-iIr\" firstAttribute=\"top\" secondItem=\"bpM-64-Faf\" secondAttribute=\"bottom\" id=\"MER-UY-x06\"/>\n                        <constraint firstAttribute=\"bottom\" secondItem=\"mpD-Z5-CaT\" secondAttribute=\"bottom\" constant=\"5\" id=\"SdS-02-fCE\"/>\n                        <constraint firstItem=\"tMm-ch-iIr\" firstAttribute=\"leading\" secondItem=\"nlM-Fp-eXf\" secondAttribute=\"leading\" constant=\"30\" id=\"UnF-KY-oDx\"/>\n                        <constraint firstItem=\"xar-Oo-330\" firstAttribute=\"leading\" secondItem=\"egw-SB-d18\" secondAttribute=\"trailing\" constant=\"1\" id=\"VTp-j8-otJ\"/>\n                        <constraint firstItem=\"xar-Oo-330\" firstAttribute=\"top\" secondItem=\"nlM-Fp-eXf\" secondAttribute=\"top\" id=\"Zxl-PT-glX\"/>\n                        <constraint firstItem=\"bpM-64-Faf\" firstAttribute=\"top\" secondItem=\"nlM-Fp-eXf\" secondAttribute=\"top\" constant=\"5\" id=\"i80-2L-3fg\"/>\n                        <constraint firstAttribute=\"height\" constant=\"74\" id=\"jsx-bp-3Np\"/>\n                        <constraint firstAttribute=\"bottom\" secondItem=\"egw-SB-d18\" secondAttribute=\"bottom\" id=\"kC9-mp-4hd\"/>\n                        <constraint firstItem=\"tMm-ch-iIr\" firstAttribute=\"leading\" secondItem=\"bpM-64-Faf\" secondAttribute=\"leading\" id=\"kGG-Qr-vpT\"/>\n                        <constraint firstItem=\"mpD-Z5-CaT\" firstAttribute=\"top\" secondItem=\"nlM-Fp-eXf\" secondAttribute=\"top\" constant=\"5\" id=\"oMi-aE-8SP\"/>\n                        <constraint firstItem=\"EWV-4g-F8D\" firstAttribute=\"top\" secondItem=\"nlM-Fp-eXf\" secondAttribute=\"top\" constant=\"5\" id=\"qAM-Si-IO3\"/>\n                        <constraint firstItem=\"xar-Oo-330\" firstAttribute=\"leading\" secondItem=\"EWV-4g-F8D\" secondAttribute=\"trailing\" constant=\"-2\" id=\"uCo-7K-wSr\"/>\n                        <constraint firstAttribute=\"trailing\" secondItem=\"xar-Oo-330\" secondAttribute=\"trailing\" id=\"urD-PQ-AsU\"/>\n                        <constraint firstAttribute=\"bottom\" secondItem=\"tMm-ch-iIr\" secondAttribute=\"bottom\" constant=\"2\" id=\"yz7-nz-o73\"/>\n                    </constraints>\n                </customView>\n                <box boxType=\"custom\" cornerRadius=\"7\" title=\"Box\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"UTX-pz-ZnX\" customClass=\"TimeBox\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n                    <rect key=\"frame\" x=\"14\" y=\"0.0\" width=\"36\" height=\"14\"/>\n                    <view key=\"contentView\" id=\"EVi-OW-h99\">\n                        <rect key=\"frame\" x=\"1\" y=\"1\" width=\"34\" height=\"12\"/>\n                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                    </view>\n                    <constraints>\n                        <constraint firstAttribute=\"width\" constant=\"36\" id=\"Pn7-Qy-ohv\"/>\n                        <constraint firstAttribute=\"height\" constant=\"14\" id=\"hqY-fV-JSI\"/>\n                    </constraints>\n                </box>\n            </subviews>\n            <constraints>\n                <constraint firstItem=\"nlM-Fp-eXf\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"10\" id=\"5pK-hC-WL3\"/>\n                <constraint firstItem=\"tMm-ch-iIr\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"40\" id=\"A3i-PF-oFz\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"UTX-pz-ZnX\" secondAttribute=\"bottom\" id=\"ByP-aF-wgx\"/>\n                <constraint firstItem=\"UTX-pz-ZnX\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"14\" id=\"GHp-Kf-eDz\"/>\n                <constraint firstItem=\"nlM-Fp-eXf\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" id=\"ly0-hP-Uy0\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"nlM-Fp-eXf\" secondAttribute=\"trailing\" constant=\"10\" id=\"yya-mA-7J5\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"butAdd\" destination=\"egw-SB-d18\" id=\"lTV-j8-xOY\"/>\n                <outlet property=\"butRemove\" destination=\"xar-Oo-330\" id=\"Af2-ho-QDb\"/>\n                <outlet property=\"butRemoveWidthConstraint\" destination=\"sLm-Pa-cG9\" id=\"tL8-cV-zpG\"/>\n                <outlet property=\"contentView\" destination=\"nlM-Fp-eXf\" id=\"Mbb-tX-J7N\"/>\n                <outlet property=\"dateEndTextField\" destination=\"UTX-pz-ZnX\" id=\"aub-uX-L1y\"/>\n                <outlet property=\"issueNrTextField\" destination=\"bpM-64-Faf\" id=\"9xX-zW-tPC\"/>\n                <outlet property=\"line1\" destination=\"mpD-Z5-CaT\" id=\"C5p-dQ-v8c\"/>\n                <outlet property=\"line2\" destination=\"EWV-4g-F8D\" id=\"EVg-sQ-hHA\"/>\n                <outlet property=\"notesTextField\" destination=\"tMm-ch-iIr\" id=\"ryB-wU-IJs\"/>\n                <outlet property=\"notesTextFieldRightConstrain\" destination=\"GXk-TS-g3i\" id=\"MiD-17-vyw\"/>\n                <outlet property=\"statusImage\" destination=\"iAi-8T-Cme\" id=\"kez-tX-mzz\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"224.5\" y=\"289\"/>\n        </customView>\n    </objects>\n    <resources>\n        <image name=\"NSAddTemplate\" width=\"11\" height=\"11\"/>\n        <image name=\"NSRemoveTemplate\" width=\"11\" height=\"11\"/>\n        <image name=\"NSStatusAvailable\" width=\"16\" height=\"16\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/AllTasks/TaskCell/TaskCellPresenter.swift",
    "content": "//\n//  TaskCellPresenter.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 27/11/15.\n//  Copyright © 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\n\nclass TaskCellPresenter: NSObject {\n\n\tvar cell: CellProtocol!\n\t\n\tconvenience init (cell: CellProtocol) {\n\t\tself.init()\n\t\tself.cell = cell\n\t}\n\t\n\tfunc present (previousTask: Task?, currentTask theTask: Task) {\n\t\t\n        cell.statusImage?.image = nil\n        \n        switch theTask.taskType {\n        case .issue:\n            cell.statusImage?.image = NSImage(named: NSImage.statusAvailableName)\n            \n        case .gitCommit:\n            cell.statusImage?.image = NSImage(named: \"GitIcon\")\n            \n        case .coderev:\n            cell.color = NSColor.systemGray\n            \n        case .startDay, .endDay:\n            cell.color = NSColor.systemBlue\n            \n        case .calendar:\n            cell.color = NSColor.systemGray\n            cell.statusImage?.image = NSImage(named: \"CalendarIcon\")\n            \n        default:\n            cell.color = NSColor.systemGray\n        }\n\n        var notes = theTask.notes ?? \"\"\n        if notes == \"\" {\n            notes = theTask.taskType.defaultNotes\n        }\n        // The codereview notes is a list of tasks that were reviewed\n        if theTask.taskType == .coderev && theTask.notes != nil && theTask.notes != \"\" {\n            notes = \"\\(theTask.taskType.defaultNotes): \\(notes)\"\n        }\n\t\tcell.data = (\n            dateStart: theTask.startDate,\n            dateEnd: theTask.endDate,\n\t\t\ttaskNumber: theTask.taskNumber,\n            notes: notes,\n\t\t\ttaskType: theTask.taskType\n\t\t)\n        cell.isDark = AppDelegate.sharedApp().theme.isDark\n        cell.isEditable = theTask.objectId != nil\n        cell.isRemovable = theTask.objectId != nil\n        cell.isIgnored = theTask.taskType == .lunch || theTask.taskType == .waste\n        cell.timeToolTip = theTask.objectId != nil ? \"Click to edit\" : \"Item can be edited after the day is closed\"\n\t}\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/AllTasks/TaskCell/TaskCellTests.swift",
    "content": "//\n//  TaskCellTests.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 17/09/15.\n//  Copyright © 2015 Cristian Baluta. All rights reserved.\n//\n\nimport XCTest\n@testable import Jirassic_no_cloud\n\nclass TaskCellTests: XCTestCase {\n\t\n//    func testSettingData() {\n//\t\t\n//\t\tlet _cell = cell()\n//\t\tRCLog(_cell)\n//\t\t_cell.data = (dateStart: \"dateStart\", dateEnd: \"dateEnd\", issue: \"IOS-01\", notes: \"notes\")\n//\t\t\n//\t\tXCTAssert(_cell.data.dateStart == \"dateStart\", \"\")\n//\t\tXCTAssert(_cell.data.dateEnd == \"dateEnd\", \"\")\n//\t\tXCTAssert(_cell.data.issue == \"IOS-01\", \"\")\n//\t\tXCTAssert(_cell.data.notes == \"notes\", \"\")\n//    }\n//\t\n//\tfunc cell() -> TaskCell {\n//\t\tvar views: NSArray?\n//\t\tNSBundle.mainBundle().loadNibNamed(\"TaskCell\", owner: self, topLevelObjects: &views)\n//\t\tRCLog(views)\n//\t\tRCLog(views?.objectAtIndex(0))\n//\t\tRCLog(views?.objectAtIndex(1))\n//\t\tif let c = views?.objectAtIndex(0) as? TaskCell {\n//\t\t\treturn c\n//\t\t} else if let c = views?.objectAtIndex(1) as? TaskCell {\n//\t\t\treturn c\n//\t\t}\n//\t\treturn TaskCell()\n//\t}\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/AllTasks/TasksDataSource.swift",
    "content": "//\n//  TasksDataSource.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 17/02/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nlet kNonTaskCellHeight = CGFloat(40.0)\nlet kTaskCellHeight = CGFloat(90.0)\nlet kGapBetweenCells = CGFloat(16.0)\nlet kCellLeftPadding = CGFloat(10.0)\n\nclass TasksDataSource: NSObject, TasksAndReportsDataSource {\n    \n    var tableView: NSTableView! {\n        didSet {\n            TaskCell.register(in: tableView)\n            NonTaskCell.register(in: tableView)\n        }\n    }\n    var tasks: [Task]\n    var didClickAddRow: ((_ row: Int) -> Void)?\n    var didClickRemoveRow: ((_ row: Int) -> Void)?\n    var isDayEnded: Bool {\n        return self.tasks.contains(where: { $0.taskType == .endDay })\n    }\n    \n    init (tasks: [Task]) {\n        self.tasks = tasks\n    }\n    \n    private func cellForTaskType (_ taskType: TaskType) -> CellProtocol {\n        \n        switch taskType {\n        case TaskType.issue, TaskType.gitCommit:\n            return TaskCell.instantiate(in: self.tableView)\n        default:\n            return NonTaskCell.instantiate(in: self.tableView)\n        }\n    }\n    \n    func addTask (_ task: Task, at row: Int) {\n        tasks.insert(task, at: row)\n    }\n    \n    func removeTask (at row: Int) {\n        tasks.remove(at: row)\n    }\n}\n\nextension TasksDataSource: NSTableViewDataSource {\n    \n    func numberOfRows (in aTableView: NSTableView) -> Int {\n        return tasks.count\n    }\n    \n    func tableView (_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {\n        \n        let theData = tasks[row]\n        switch theData.taskType {\n        case TaskType.issue, TaskType.gitCommit:\n            return kTaskCellHeight\n        default:\n            return kNonTaskCellHeight\n        }\n    }\n}\n\nextension TasksDataSource: NSTableViewDelegate {\n    \n    func tableView (_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {\n\n        var theData = tasks[row]\n        let thePreviousData: Task? = row == 0 ? nil : tasks[row-1]\n        \n        var cell: CellProtocol = self.cellForTaskType(theData.taskType)\n        TaskCellPresenter(cell: cell).present(previousTask: thePreviousData, currentTask: theData)\n        \n        cell.didEndEditingCell = { [weak self] (cell: CellProtocol) in\n            let updatedData = cell.data\n            theData.taskNumber = updatedData.taskNumber\n            theData.notes = updatedData.notes\n            theData.startDate = updatedData.dateStart\n            theData.endDate = updatedData.dateEnd\n            // Save to local variable\n            self?.tasks[row] = theData\n            // Save to db and server\n            let saveInteractor = TaskInteractor(repository: localRepository, remoteRepository: remoteRepository)\n            saveInteractor.saveTask(theData, allowSyncing: true, completion: { savedTask in\n                tableView.reloadData(forRowIndexes: [row], columnIndexes: [0])\n            })\n        }\n        cell.didClickRemoveCell = { [weak self] (cell: CellProtocol) in\n            // Ugly hack to find the row number from which the action came\n            tableView.enumerateAvailableRowViews({ (rowView, rowIndex) -> Void in\n                if rowView.subviews.first! == cell as! NSTableRowView {\n                    self?.didClickRemoveRow!(rowIndex)\n                    return\n                }\n            })\n        }\n        cell.didClickAddCell = { [weak self] (cell: CellProtocol) in\n            // Ugly hack to find the row number from which the action came\n            tableView.enumerateAvailableRowViews( { rowView, rowIndex in\n                if rowView.subviews.first! == cell as! NSTableRowView {\n                    self?.didClickAddRow!(rowIndex)\n                    return\n                }\n            })\n        }\n        \n        return cell as? NSView\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/DataSource.swift",
    "content": "//\n//  DataSource.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 18/02/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nprotocol TasksAndReportsDataSource {\n    var tableView: NSTableView! {get set}\n    var didClickAddRow: ((_ row: Int) -> Void)? {get set}\n    var didClickRemoveRow: ((_ row: Int) -> Void)? {get set}\n    func addTask (_ task: Task, at row: Int)\n    func removeTask (at row: Int)\n}\n\ntypealias DataSource = NSTableViewDataSource & NSTableViewDelegate & TasksAndReportsDataSource\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/MonthReports/MonthReportsHeaderView.swift",
    "content": "//\n//  MonthReportsHeaderView.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 25/10/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nclass MonthReportsHeaderView: ReportsHeaderView {\n    \n    @IBOutlet private var butCopyAll: NSButton!\n    @IBOutlet private var butCopyAsHtml: NSButton!\n    @IBOutlet private var totalDaysTextField: NSTextField!\n    \n    var numberOfDays: Int {\n        get {\n            return 0\n        }\n        set {\n            totalDaysTextField.stringValue = \"Number of days: \\(newValue)\"\n        }\n    }\n    \n    override func awakeFromNib() {\n        super.awakeFromNib()\n        \n        butCopyAsHtml.state = pref.bool(.copyWorklogsAsHtml) ? .on : .off\n        butCopyAsHtml.toolTip = \"This can be set in 'Settings/Tracking/Working between'\"\n    }\n}\n\nextension MonthReportsHeaderView {\n\n    @IBAction func handleHtmlButton (_ sender: NSButton) {\n        pref.set(sender.state == .on, forKey: .copyWorklogsAsHtml)\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/MonthReports/MonthReportsHeaderView.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"23077.2\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"23077.2\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView identifier=\"MonthReportsHeaderView\" id=\"c22-O7-iKe\" customClass=\"MonthReportsHeaderView\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"454\" height=\"100\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <visualEffectView wantsLayer=\"YES\" blendingMode=\"withinWindow\" material=\"headerView\" state=\"active\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"DSw-pl-rG3\">\n                    <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"454\" height=\"100\"/>\n                </visualEffectView>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Ca7-bt-zzl\">\n                    <rect key=\"frame\" x=\"14\" y=\"63\" width=\"161\" height=\"18\"/>\n                    <buttonCell key=\"cell\" type=\"check\" title=\"Show time in percents\" bezelStyle=\"regularSquare\" imagePosition=\"left\" inset=\"2\" id=\"jyn-Uj-MYd\">\n                        <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                        <font key=\"font\" metaFont=\"system\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handlePercentsButton:\" target=\"c22-O7-iKe\" id=\"OSs-vC-5Xq\"/>\n                    </connections>\n                </button>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Mpy-Nv-lYn\">\n                    <rect key=\"frame\" x=\"193\" y=\"63\" width=\"141\" height=\"18\"/>\n                    <buttonCell key=\"cell\" type=\"check\" title=\"Round to 8.0 hours\" bezelStyle=\"regularSquare\" imagePosition=\"left\" state=\"on\" inset=\"2\" id=\"mLC-pf-tpN\">\n                        <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                        <font key=\"font\" metaFont=\"system\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleRoundButton:\" target=\"c22-O7-iKe\" id=\"eS9-wA-rEj\"/>\n                    </connections>\n                </button>\n                <textField focusRingType=\"none\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Nzw-0j-cKu\">\n                    <rect key=\"frame\" x=\"416\" y=\"64\" width=\"24\" height=\"16\"/>\n                    <textFieldCell key=\"cell\" lineBreakMode=\"clipping\" title=\"8.0\" id=\"M0j-5S-fes\">\n                        <font key=\"font\" metaFont=\"system\"/>\n                        <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                    </textFieldCell>\n                </textField>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"SgF-Of-wi3\">\n                    <rect key=\"frame\" x=\"16\" y=\"20\" width=\"60\" height=\"21\"/>\n                    <buttonCell key=\"cell\" type=\"inline\" title=\"Copy\" bezelStyle=\"inline\" alignment=\"center\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"nti-3s-Vrr\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"smallSystemBold\"/>\n                    </buttonCell>\n                    <constraints>\n                        <constraint firstAttribute=\"width\" constant=\"60\" id=\"1B4-TI-tm3\"/>\n                        <constraint firstAttribute=\"height\" constant=\"21\" id=\"Vsv-Kx-8Bi\"/>\n                    </constraints>\n                    <connections>\n                        <action selector=\"handleCopyAllButton:\" target=\"c22-O7-iKe\" id=\"u2Q-Mg-vCi\"/>\n                    </connections>\n                </button>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"6FX-aq-vD0\">\n                    <rect key=\"frame\" x=\"94\" y=\"22\" width=\"106\" height=\"18\"/>\n                    <buttonCell key=\"cell\" type=\"check\" title=\"Copy as html\" bezelStyle=\"regularSquare\" imagePosition=\"left\" state=\"on\" inset=\"2\" id=\"ynS-P6-xgU\">\n                        <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                        <font key=\"font\" metaFont=\"system\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleHtmlButton:\" target=\"c22-O7-iKe\" id=\"uQ2-nG-0wm\"/>\n                    </connections>\n                </button>\n                <textField focusRingType=\"none\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"9ci-eL-n8B\">\n                    <rect key=\"frame\" x=\"316\" y=\"23\" width=\"124\" height=\"16\"/>\n                    <textFieldCell key=\"cell\" lineBreakMode=\"clipping\" title=\"Number of days: 20\" id=\"CbO-KS-84g\">\n                        <font key=\"font\" metaFont=\"system\"/>\n                        <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                    </textFieldCell>\n                </textField>\n            </subviews>\n            <constraints>\n                <constraint firstAttribute=\"trailing\" secondItem=\"9ci-eL-n8B\" secondAttribute=\"trailing\" constant=\"16\" id=\"3oh-y8-xBM\"/>\n                <constraint firstItem=\"Ca7-bt-zzl\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"16\" id=\"5tt-yf-WIb\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"SgF-Of-wi3\" secondAttribute=\"bottom\" constant=\"20\" id=\"9Xp-tl-rEe\"/>\n                <constraint firstItem=\"Nzw-0j-cKu\" firstAttribute=\"centerY\" secondItem=\"Mpy-Nv-lYn\" secondAttribute=\"centerY\" id=\"FtJ-Lv-HyU\"/>\n                <constraint firstItem=\"DSw-pl-rG3\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" id=\"Kik-nC-aaV\"/>\n                <constraint firstItem=\"Mpy-Nv-lYn\" firstAttribute=\"leading\" secondItem=\"Ca7-bt-zzl\" secondAttribute=\"trailing\" constant=\"20\" id=\"OhW-Qc-w9Q\"/>\n                <constraint firstItem=\"9ci-eL-n8B\" firstAttribute=\"centerY\" secondItem=\"6FX-aq-vD0\" secondAttribute=\"centerY\" id=\"P2d-yB-TMQ\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"DSw-pl-rG3\" secondAttribute=\"trailing\" id=\"PHa-Vq-Cvs\"/>\n                <constraint firstItem=\"DSw-pl-rG3\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" id=\"Q6M-Hf-VWK\"/>\n                <constraint firstItem=\"Ca7-bt-zzl\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" constant=\"20\" id=\"QuN-EN-IbL\"/>\n                <constraint firstItem=\"SgF-Of-wi3\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"16\" id=\"Z6Q-7v-8ht\"/>\n                <constraint firstItem=\"Mpy-Nv-lYn\" firstAttribute=\"centerY\" secondItem=\"Ca7-bt-zzl\" secondAttribute=\"centerY\" id=\"b8V-Vd-t8l\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"DSw-pl-rG3\" secondAttribute=\"bottom\" id=\"b8d-Ij-qJe\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"Nzw-0j-cKu\" secondAttribute=\"trailing\" constant=\"16\" id=\"hJe-bR-kX1\"/>\n                <constraint firstItem=\"6FX-aq-vD0\" firstAttribute=\"leading\" secondItem=\"SgF-Of-wi3\" secondAttribute=\"trailing\" constant=\"20\" id=\"rXy-Xd-Qwe\"/>\n                <constraint firstItem=\"6FX-aq-vD0\" firstAttribute=\"centerY\" secondItem=\"SgF-Of-wi3\" secondAttribute=\"centerY\" id=\"vEj-VP-q2N\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"backgroundView\" destination=\"DSw-pl-rG3\" id=\"SyJ-WD-w16\"/>\n                <outlet property=\"butCopyAll\" destination=\"SgF-Of-wi3\" id=\"T5U-jL-eYQ\"/>\n                <outlet property=\"butCopyAsHtml\" destination=\"6FX-aq-vD0\" id=\"o6r-Og-E9r\"/>\n                <outlet property=\"butPercents\" destination=\"Ca7-bt-zzl\" id=\"vM5-71-Srn\"/>\n                <outlet property=\"butRound\" destination=\"Mpy-Nv-lYn\" id=\"rdX-W9-fEm\"/>\n                <outlet property=\"totalDaysTextField\" destination=\"9ci-eL-n8B\" id=\"OvO-e0-5s1\"/>\n                <outlet property=\"totalTimeTextField\" destination=\"Nzw-0j-cKu\" id=\"50m-UJ-5NS\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"126\" y=\"63\"/>\n        </customView>\n    </objects>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/Reports/HeaderView/ReportsHeaderView.swift",
    "content": "//\n//  ReportsHeaderView.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 19/02/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\nimport RCPreferences\n\nclass ReportsHeaderView: NSTableHeaderView {\n    \n    @IBOutlet private var backgroundView: NSVisualEffectView!\n    @IBOutlet private var butPercents: NSButton!\n    @IBOutlet private var butRound: NSButton!\n    @IBOutlet private var totalTimeTextField: NSTextField!\n    internal let pref = RCPreferences<LocalPreferences>()\n    \n    var didChangeSettings: (() -> Void)?\n    var didClickCopyAll: ((Bool) -> Void)?\n\n    // In hours\n    var workedTime: String {\n        get {\n            return \"\"\n        }\n        set {\n            totalTimeTextField.stringValue = newValue\n        }\n    }\n    var workdayTime: Double {\n        get {\n            return 0.0\n        }\n        set {\n            butRound.title = \"Round to \\(newValue) hours\"\n        }\n    }\n    \n    override func awakeFromNib() {\n        super.awakeFromNib()\n        \n        butPercents.title = \"Show time in percents\"\n        butPercents.state = pref.bool(.usePercents) ? .on : .off\n        \n        butRound.state = pref.bool(.enableRoundingDay) ? .on : .off\n        butRound.toolTip = \"This can be set in 'Settings/Tracking/Working between'\"\n        \n        if #available(OSX 10.14, *) {\n            // In OS14 there is  already a default blurry background\n            backgroundView.isHidden = true\n        }\n    }\n\n    // Overriding this in OS14 removes default blurry background and the custom one adds ugly edges to buttons\n//    override func draw (_ dirtyRect: NSRect) {\n//    }\n    \n    override func headerRect(ofColumn column: Int) -> NSRect {\n        // This will prevent for a label to appear  in the middle of the header\n        return NSRect.zero\n    }\n}\n\nextension ReportsHeaderView {\n    \n    @IBAction func handleRoundButton (_ sender: NSButton) {\n        pref.set(sender.state == .on, forKey: .enableRoundingDay)\n        didChangeSettings?()\n    }\n    \n    @IBAction func handlePercentsButton (_ sender: NSButton) {\n        pref.set(sender.state == .on, forKey: .usePercents)\n        didChangeSettings?()\n    }\n\n    @IBAction func handleCopyAllButton (_ sender: NSButton) {\n        didClickCopyAll?(pref.bool(.copyWorklogsAsHtml))\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/Reports/HeaderView/ReportsHeaderView.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"23077.2\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"23077.2\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView identifier=\"ReportsHeaderView\" id=\"c22-O7-iKe\" customClass=\"ReportsHeaderView\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"454\" height=\"98\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <visualEffectView wantsLayer=\"YES\" blendingMode=\"withinWindow\" material=\"headerView\" state=\"active\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"gp8-1T-0i3\">\n                    <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"454\" height=\"98\"/>\n                </visualEffectView>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"8zO-4Y-Dfa\">\n                    <rect key=\"frame\" x=\"16\" y=\"21\" width=\"68\" height=\"21\"/>\n                    <buttonCell key=\"cell\" type=\"inline\" title=\"Copy all\" bezelStyle=\"inline\" alignment=\"center\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"Mnf-fv-jbf\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" size=\"11\" name=\".SFNS-Semibold\"/>\n                    </buttonCell>\n                    <constraints>\n                        <constraint firstAttribute=\"width\" constant=\"68\" id=\"DLj-3Q-czs\"/>\n                        <constraint firstAttribute=\"height\" constant=\"21\" id=\"TXh-Ia-0oZ\"/>\n                    </constraints>\n                    <connections>\n                        <action selector=\"handleCopyAllButton:\" target=\"c22-O7-iKe\" id=\"OpS-Pi-nB5\"/>\n                    </connections>\n                </button>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Ca7-bt-zzl\">\n                    <rect key=\"frame\" x=\"14\" y=\"61\" width=\"161\" height=\"18\"/>\n                    <buttonCell key=\"cell\" type=\"check\" title=\"Show time in percents\" bezelStyle=\"regularSquare\" imagePosition=\"left\" inset=\"2\" id=\"jyn-Uj-MYd\">\n                        <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                        <font key=\"font\" metaFont=\"system\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handlePercentsButton:\" target=\"c22-O7-iKe\" id=\"OSs-vC-5Xq\"/>\n                    </connections>\n                </button>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Mpy-Nv-lYn\">\n                    <rect key=\"frame\" x=\"193\" y=\"61\" width=\"141\" height=\"18\"/>\n                    <buttonCell key=\"cell\" type=\"check\" title=\"Round to 8.0 hours\" bezelStyle=\"regularSquare\" imagePosition=\"left\" state=\"on\" inset=\"2\" id=\"mLC-pf-tpN\">\n                        <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                        <font key=\"font\" metaFont=\"system\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleRoundButton:\" target=\"c22-O7-iKe\" id=\"eS9-wA-rEj\"/>\n                    </connections>\n                </button>\n                <textField focusRingType=\"none\" horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Nzw-0j-cKu\">\n                    <rect key=\"frame\" x=\"416\" y=\"62\" width=\"24\" height=\"16\"/>\n                    <textFieldCell key=\"cell\" lineBreakMode=\"clipping\" title=\"8.0\" id=\"M0j-5S-fes\">\n                        <font key=\"font\" metaFont=\"system\"/>\n                        <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                    </textFieldCell>\n                </textField>\n            </subviews>\n            <constraints>\n                <constraint firstItem=\"Ca7-bt-zzl\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"16\" id=\"5tt-yf-WIb\"/>\n                <constraint firstItem=\"Ca7-bt-zzl\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" constant=\"20\" id=\"IG7-c8-Qop\"/>\n                <constraint firstItem=\"8zO-4Y-Dfa\" firstAttribute=\"top\" secondItem=\"Ca7-bt-zzl\" secondAttribute=\"bottom\" constant=\"20\" id=\"JYI-ue-VvH\"/>\n                <constraint firstItem=\"Ca7-bt-zzl\" firstAttribute=\"centerY\" secondItem=\"Mpy-Nv-lYn\" secondAttribute=\"centerY\" id=\"Nmv-BO-Uf5\"/>\n                <constraint firstItem=\"Mpy-Nv-lYn\" firstAttribute=\"leading\" secondItem=\"Ca7-bt-zzl\" secondAttribute=\"trailing\" constant=\"20\" id=\"OhW-Qc-w9Q\"/>\n                <constraint firstItem=\"Mpy-Nv-lYn\" firstAttribute=\"centerY\" secondItem=\"Nzw-0j-cKu\" secondAttribute=\"centerY\" id=\"QCd-92-vlC\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"gp8-1T-0i3\" secondAttribute=\"bottom\" id=\"T3S-GA-mAM\"/>\n                <constraint firstItem=\"gp8-1T-0i3\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" id=\"V9j-Dd-vCe\"/>\n                <constraint firstItem=\"8zO-4Y-Dfa\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"16\" id=\"aHG-WT-cTu\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"gp8-1T-0i3\" secondAttribute=\"trailing\" id=\"f9f-hY-geb\"/>\n                <constraint firstItem=\"gp8-1T-0i3\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" id=\"fRU-Ld-GwP\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"Nzw-0j-cKu\" secondAttribute=\"trailing\" constant=\"16\" id=\"hJe-bR-kX1\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"backgroundView\" destination=\"gp8-1T-0i3\" id=\"BuE-qm-Ij7\"/>\n                <outlet property=\"butPercents\" destination=\"Ca7-bt-zzl\" id=\"vM5-71-Srn\"/>\n                <outlet property=\"butRound\" destination=\"Mpy-Nv-lYn\" id=\"rdX-W9-fEm\"/>\n                <outlet property=\"totalTimeTextField\" destination=\"Nzw-0j-cKu\" id=\"50m-UJ-5NS\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"126\" y=\"113\"/>\n        </customView>\n    </objects>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/Reports/ReportCell/ReportCell.swift",
    "content": "//\n//  ReportCell.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 04/09/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\n\nclass ReportCell: NSTableRowView, CellProtocol {\n\n    var statusImage: NSImageView?\n    @IBOutlet fileprivate var durationTextField: NSTextField?\n    @IBOutlet fileprivate var taskNrTextField: NSTextField?\n    @IBOutlet fileprivate var notesTextField: NSTextField?\n    @IBOutlet fileprivate var butCopy: NSButton?\n    @IBOutlet fileprivate var butCopyWidthConstraint: NSLayoutConstraint?\n    fileprivate var trackingArea: NSTrackingArea?\n    fileprivate var bgColor: NSColor = NSColor.clear\n    \n    var didEndEditingCell: ((_ cell: CellProtocol) -> ())?\n    var didClickRemoveCell: ((_ cell: CellProtocol) -> ())?\n    var didClickAddCell: ((_ cell: CellProtocol) -> ())?\n    var didCopyContentCell: ((_ cell: CellProtocol) -> ())?\n    \n    var data: TaskCreationData {\n        get {\n            return (\n                dateStart: nil,\n                dateEnd: Date(),\n                taskNumber: self.taskNrTextField!.stringValue,\n                notes: self.notesTextField!.stringValue,\n                taskType: .issue\n            )\n        }\n        set {\n            self.taskNrTextField!.stringValue = newValue.taskNumber ?? \"\"\n            self.notesTextField!.stringValue = newValue.notes ?? \"\"\n        }\n    }\n    var duration: String {\n        get {\n            return durationTextField!.stringValue\n        }\n        set {\n            self.durationTextField!.stringValue = newValue\n        }\n    }\n    var heightThatFits: CGFloat {\n        get {\n            let titleTextField = self.taskNrTextField!.sizeThatFits(\n                NSSize(width: self.frame.size.width - 60 - 70, height: 1000)\n            )\n            let notesTextField = self.notesTextField!.sizeThatFits(\n                NSSize(width: self.frame.size.width - self.notesTextField!.frame.origin.x, height: 1000)\n            )\n            \n            return 6 + titleTextField.height + 4 + notesTextField.height + 6\n        }\n    }\n    var isDark: Bool = false\n    var isEditable: Bool = false\n    var isRemovable: Bool = false\n    var isIgnored: Bool = false\n    var color: NSColor = NSColor.black\n    var timeToolTip: String?\n    \n    override func awakeFromNib() {\n        super.awakeFromNib()\n        butCopyWidthConstraint?.constant = 0\n        taskNrTextField?.preferredMaxLayoutWidth = CGFloat(300)\n        ensureTrackingArea()\n    }\n    \n    override func draw (_ dirtyRect: NSRect) {\n        bgColor.set()\n        dirtyRect.fill()\n    }\n    \n    @IBAction func handleCopyButton (_ sender: NSButton) {\n        \n        let string = \"\\(taskNrTextField!.stringValue)\\n\\(notesTextField!.stringValue)\"\n        NSPasteboard.general.clearContents()\n        NSPasteboard.general.writeObjects([string as NSPasteboardWriting])\n    }\n    \n}\n\nextension ReportCell {\n    \n    override func mouseEntered (with theEvent: NSEvent) {\n        butCopyWidthConstraint?.constant = 47\n        bgColor = NSColor.white\n        butCopy!.needsLayout = true\n        self.needsDisplay = true\n        if isDark == true {\n            taskNrTextField?.textColor = NSColor.black\n            notesTextField?.textColor = NSColor.darkGray\n            durationTextField?.textColor = NSColor.darkGray\n        }\n    }\n    \n    override func mouseExited (with theEvent: NSEvent) {\n        butCopyWidthConstraint?.constant = 0\n        bgColor = NSColor.clear\n        butCopy!.needsLayout = true\n        self.needsDisplay = true\n        if isDark == true {\n            taskNrTextField?.textColor = NSColor.white\n            notesTextField?.textColor = NSColor.lightGray\n            durationTextField?.textColor = NSColor.lightGray\n        }\n    }\n    \n    override func updateTrackingAreas() {\n        super.updateTrackingAreas()\n        \n        self.ensureTrackingArea()\n        if !(self.trackingAreas as NSArray).contains(self.trackingArea!) {\n            self.addTrackingArea(self.trackingArea!);\n        }\n    }\n    \n    func ensureTrackingArea() {\n        if trackingArea == nil {\n            trackingArea = NSTrackingArea(\n                rect: self.bounds,\n                options: [NSTrackingArea.Options.inVisibleRect,\n                          NSTrackingArea.Options.activeAlways,\n                          NSTrackingArea.Options.mouseEnteredAndExited],\n                owner: self,\n                userInfo: nil\n            )\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/Reports/ReportCell/ReportCell.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"14313.18\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14313.18\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\"/>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customView identifier=\"ReportCell\" id=\"c22-O7-iKe\" customClass=\"ReportCell\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"345\" height=\"50\"/>\n            <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n            <subviews>\n                <textField focusRingType=\"none\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" preferredMaxLayoutWidth=\"216\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"bpM-64-Faf\">\n                    <rect key=\"frame\" x=\"59\" y=\"27\" width=\"216\" height=\"17\"/>\n                    <textFieldCell key=\"cell\" selectable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" focusRingType=\"none\" alignment=\"left\" title=\"Task number\" drawsBackground=\"YES\" id=\"dlI-ub-5hj\">\n                        <font key=\"font\" metaFont=\"systemBold\"/>\n                        <color key=\"textColor\" name=\"textColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" white=\"1\" alpha=\"0.0\" colorSpace=\"deviceWhite\"/>\n                    </textFieldCell>\n                </textField>\n                <textField focusRingType=\"none\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"HS2-iB-3Ta\">\n                    <rect key=\"frame\" x=\"281\" y=\"27\" width=\"51\" height=\"17\"/>\n                    <constraints>\n                        <constraint firstAttribute=\"width\" constant=\"47\" id=\"2nv-uf-Elb\"/>\n                        <constraint firstAttribute=\"height\" constant=\"17\" id=\"6CB-mp-rwI\"/>\n                    </constraints>\n                    <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" allowsUndo=\"NO\" sendsActionOnEndEditing=\"YES\" state=\"on\" focusRingType=\"none\" alignment=\"right\" placeholderString=\"00:00\" id=\"kk5-M4-fbR\">\n                        <font key=\"font\" metaFont=\"system\"/>\n                        <color key=\"textColor\" name=\"systemGrayColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" white=\"1\" alpha=\"0.0\" colorSpace=\"deviceWhite\"/>\n                    </textFieldCell>\n                </textField>\n                <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"caC-fV-ZwQ\">\n                    <rect key=\"frame\" x=\"12\" y=\"20\" width=\"47\" height=\"25\"/>\n                    <constraints>\n                        <constraint firstAttribute=\"height\" constant=\"22\" id=\"WSL-NK-Yp0\"/>\n                        <constraint firstAttribute=\"width\" constant=\"47\" id=\"Yrs-c8-ijJ\"/>\n                    </constraints>\n                    <buttonCell key=\"cell\" type=\"roundTextured\" title=\"Copy\" bezelStyle=\"texturedRounded\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"fyr-x7-lVJ\">\n                        <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                        <font key=\"font\" metaFont=\"system\"/>\n                    </buttonCell>\n                    <connections>\n                        <action selector=\"handleCopyButton:\" target=\"c22-O7-iKe\" id=\"YdM-J6-5Wg\"/>\n                    </connections>\n                </button>\n                <textField focusRingType=\"none\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" preferredMaxLayoutWidth=\"333\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"5uZ-oc-wrR\">\n                    <rect key=\"frame\" x=\"12\" y=\"6\" width=\"333\" height=\"17\"/>\n                    <textFieldCell key=\"cell\" selectable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" focusRingType=\"none\" alignment=\"left\" title=\"Task notes\" drawsBackground=\"YES\" id=\"29U-pf-bPN\">\n                        <font key=\"font\" metaFont=\"system\"/>\n                        <color key=\"textColor\" name=\"systemGrayColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"0.0\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                    </textFieldCell>\n                </textField>\n            </subviews>\n            <constraints>\n                <constraint firstItem=\"bpM-64-Faf\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" constant=\"6\" id=\"4LC-Du-N7a\"/>\n                <constraint firstItem=\"5uZ-oc-wrR\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"12\" id=\"5mO-XJ-c6e\"/>\n                <constraint firstItem=\"HS2-iB-3Ta\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" constant=\"6\" id=\"CdD-BY-vkN\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"HS2-iB-3Ta\" secondAttribute=\"trailing\" constant=\"15\" id=\"Cge-0e-uSq\"/>\n                <constraint firstItem=\"bpM-64-Faf\" firstAttribute=\"leading\" secondItem=\"caC-fV-ZwQ\" secondAttribute=\"trailing\" id=\"DHh-0e-UNE\"/>\n                <constraint firstItem=\"HS2-iB-3Ta\" firstAttribute=\"leading\" secondItem=\"bpM-64-Faf\" secondAttribute=\"trailing\" constant=\"8\" id=\"GsV-4p-3AN\"/>\n                <constraint firstAttribute=\"trailing\" secondItem=\"5uZ-oc-wrR\" secondAttribute=\"trailing\" id=\"Kyq-c4-fAD\"/>\n                <constraint firstItem=\"caC-fV-ZwQ\" firstAttribute=\"leading\" secondItem=\"c22-O7-iKe\" secondAttribute=\"leading\" constant=\"12\" id=\"cZS-0S-iX6\"/>\n                <constraint firstItem=\"caC-fV-ZwQ\" firstAttribute=\"top\" secondItem=\"c22-O7-iKe\" secondAttribute=\"top\" constant=\"6\" id=\"fxo-Oc-e8a\"/>\n                <constraint firstAttribute=\"bottom\" secondItem=\"5uZ-oc-wrR\" secondAttribute=\"bottom\" constant=\"6\" id=\"nKY-rU-Out\"/>\n                <constraint firstItem=\"5uZ-oc-wrR\" firstAttribute=\"top\" secondItem=\"bpM-64-Faf\" secondAttribute=\"bottom\" constant=\"4\" id=\"zsg-3g-1Ut\"/>\n            </constraints>\n            <connections>\n                <outlet property=\"butCopy\" destination=\"caC-fV-ZwQ\" id=\"E5h-P0-WBt\"/>\n                <outlet property=\"butCopyWidthConstraint\" destination=\"Yrs-c8-ijJ\" id=\"MUX-IT-h57\"/>\n                <outlet property=\"durationTextField\" destination=\"HS2-iB-3Ta\" id=\"NnR-E7-aVg\"/>\n                <outlet property=\"notesTextField\" destination=\"5uZ-oc-wrR\" id=\"vTY-dZ-ItF\"/>\n                <outlet property=\"taskNrTextField\" destination=\"bpM-64-Faf\" id=\"eZv-mn-kHX\"/>\n            </connections>\n            <point key=\"canvasLocation\" x=\"224.5\" y=\"274\"/>\n        </customView>\n    </objects>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/Reports/ReportCell/ReportCellPresenter.swift",
    "content": "//\n//  ReportCellPresenter.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 06/11/2016.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\nimport RCPreferences\n\nclass ReportCellPresenter: NSObject {\n    \n    var cell: CellProtocol!\n    private let pref = RCPreferences<LocalPreferences>()\n    \n    convenience init (cell: CellProtocol) {\n        self.init()\n        self.cell = cell\n    }\n    \n    func present (theReport: Report) {\n\n        let notes: [String] = theReport.notes.compactMap { note in\n            guard note.count > 0 else {\n                return nil\n            }\n            return \"• \\(note)\"\n        }\n        let notesJoined = notes.joined(separator: \"\\n\")\n        var taskNumber = theReport.taskNumber == \"coderev\" ? \"Code reviews\" : theReport.taskNumber\n        taskNumber = taskNumber == \"learning\" ? \"Learning\" : taskNumber\n        taskNumber = taskNumber == \"meeting\" ? \"Meetings\" : taskNumber\n        var title = theReport.title\n            .replacingOccurrences(of: \"_\", with: \" \")\n            .trimmingCharacters(in: .whitespacesAndNewlines)\n        if theReport.taskNumber == \"learning\" || theReport.taskNumber == \"meeting\" {\n            title = \"\"\n        }\n        cell.data = (\n            dateStart: nil,\n            dateEnd: Date(),\n            taskNumber: taskNumber + \"  \" + title,\n            notes: notesJoined,\n            taskType: .issue\n        )\n        cell.duration = pref.bool(.usePercents)\n            ? \"\\(theReport.duration.secToPercent)\"\n            : theReport.duration.secToHoursAndMin// Date(timeIntervalSince1970: theReport.duration).HHmmGMT()\n        cell.statusImage?.image = NSImage(named: NSImage.statusAvailableName)\n        cell.isDark = AppDelegate.sharedApp().theme.isDark\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/Reports/ReportsDataSource.swift",
    "content": "//\n//  ReportsDataSource.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 17/02/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nclass ReportsDataSource: NSObject, TasksAndReportsDataSource {\n    \n    var tableView: NSTableView! {\n        didSet {\n            if #available(OSX 10.13, *) {\n                tableView.usesAutomaticRowHeights = true\n            }\n            ReportCell.register(in: tableView)\n        }\n    }\n    var didClickAddRow: ((_ row: Int) -> Void)?\n    var didClickRemoveRow: ((_ row: Int) -> Void)?\n    private var tempCell: ReportCell?\n    let numberOfDays: Int\n    var reports: [Report]\n    \n    init (reports: [Report], numberOfDays: Int) {\n        self.reports = reports\n        self.numberOfDays = numberOfDays\n    }\n    \n    func addTask (_ task: Task, at row: Int) {\n        \n    }\n    \n    func removeTask (at row: Int) {\n        \n    }\n}\n\nextension ReportsDataSource: NSTableViewDataSource {\n    \n    func numberOfRows (in aTableView: NSTableView) -> Int {\n        return reports.count\n    }\n    \n    func tableView (_ tableView: NSTableView, heightOfRow row: Int) -> CGFloat {\n        \n        if #available(OSX 10.13, *) {\n            // This version of osx supports cell autoresizing\n            return CGFloat(50)\n        }\n        let theData = reports[row]\n        // Calculate height to fit content\n        if tempCell == nil {\n            tempCell = ReportCell.instantiate(in: tableView)\n            tempCell?.frame = NSRect(x: 0, y: 0, width: tableView.frame.size.width, height: 50)\n        }\n        ReportCellPresenter(cell: tempCell!).present(theReport: theData)\n        \n        return tempCell!.heightThatFits\n    }\n}\n\nextension ReportsDataSource: NSTableViewDelegate {\n    \n    func tableView (_ tableView: NSTableView, viewFor tableColumn: NSTableColumn?, row: Int) -> NSView? {\n        \n        let theData = reports[row]\n        let cell: CellProtocol = ReportCell.instantiate(in: self.tableView)\n        ReportCellPresenter(cell: cell).present(theReport: theData)\n        \n        return cell as? NSView\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/Tasks.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" initialViewController=\"wHU-IX-gfU\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14460.31\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Tasks View Controller-->\n        <scene sceneID=\"dDM-mM-AcD\">\n            <objects>\n                <viewController storyboardIdentifier=\"TasksViewController\" id=\"wHU-IX-gfU\" customClass=\"TasksViewController\" customModule=\"Jirassic\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <customView key=\"view\" id=\"FwC-dy-0bY\" customClass=\"TasksView\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"491\" height=\"442\"/>\n                        <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                        <subviews>\n                            <button translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"sOM-pv-IVs\">\n                                <rect key=\"frame\" x=\"457\" y=\"400\" width=\"22\" height=\"22\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"22\" id=\"Eei-gN-2Pv\"/>\n                                    <constraint firstAttribute=\"width\" constant=\"22\" id=\"uXc-Dc-STF\"/>\n                                </constraints>\n                                <buttonCell key=\"cell\" type=\"square\" bezelStyle=\"shadowlessSquare\" image=\"NSActionTemplate\" imagePosition=\"only\" alignment=\"center\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"bzr-8c-L6L\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                </buttonCell>\n                                <accessibility description=\"Settings\" identifier=\"Settings\"/>\n                                <connections>\n                                    <action selector=\"handleSettingsButton:\" target=\"wHU-IX-gfU\" id=\"WAP-fv-TY8\"/>\n                                </connections>\n                            </button>\n                            <box verticalHuggingPriority=\"750\" boxType=\"separator\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"SJz-Xr-YhG\">\n                                <rect key=\"frame\" x=\"12\" y=\"379\" width=\"467\" height=\"5\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"1\" id=\"13l-2d-raK\"/>\n                                </constraints>\n                            </box>\n                            <splitView arrangesAllSubviews=\"NO\" dividerStyle=\"thin\" vertical=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"pVs-CS-Pcx\">\n                                <rect key=\"frame\" x=\"12\" y=\"0.0\" width=\"479\" height=\"380\"/>\n                                <subviews>\n                                    <customView id=\"bMb-qH-ZuV\">\n                                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"110\" height=\"380\"/>\n                                        <autoresizingMask key=\"autoresizingMask\"/>\n                                        <subviews>\n                                            <scrollView borderType=\"none\" autohidesScrollers=\"YES\" horizontalLineScroll=\"20\" horizontalPageScroll=\"10\" verticalLineScroll=\"20\" verticalPageScroll=\"10\" usesPredominantAxisScrolling=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"TP3-Rr-lmx\" customClass=\"CalendarScrollView\" customModule=\"Jirassic\" customModuleProvider=\"target\">\n                                                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"110\" height=\"380\"/>\n                                                <clipView key=\"contentView\" focusRingType=\"none\" drawsBackground=\"NO\" copiesOnScroll=\"NO\" id=\"c1O-Xx-nvd\">\n                                                    <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"110\" height=\"380\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                                    <subviews>\n                                                        <outlineView verticalHuggingPriority=\"750\" allowsExpansionToolTips=\"YES\" columnAutoresizingStyle=\"lastColumnOnly\" selectionHighlightStyle=\"sourceList\" multipleSelection=\"NO\" autosaveColumns=\"NO\" rowHeight=\"18\" rowSizeStyle=\"automatic\" viewBased=\"YES\" indentationPerLevel=\"16\" outlineTableColumn=\"Xnl-4a-lUw\" id=\"fay-QN-mrU\">\n                                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"110\" height=\"380\"/>\n                                                            <autoresizingMask key=\"autoresizingMask\"/>\n                                                            <size key=\"intercellSpacing\" width=\"3\" height=\"2\"/>\n                                                            <color key=\"backgroundColor\" name=\"_sourceListBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                            <color key=\"gridColor\" name=\"gridColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                            <tableColumns>\n                                                                <tableColumn width=\"107\" minWidth=\"16\" maxWidth=\"1000\" id=\"Xnl-4a-lUw\">\n                                                                    <tableHeaderCell key=\"headerCell\" lineBreakMode=\"truncatingTail\" borderStyle=\"border\">\n                                                                        <font key=\"font\" metaFont=\"smallSystem\"/>\n                                                                        <color key=\"textColor\" name=\"headerTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                        <color key=\"backgroundColor\" name=\"headerColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                    </tableHeaderCell>\n                                                                    <textFieldCell key=\"dataCell\" lineBreakMode=\"truncatingTail\" selectable=\"YES\" editable=\"YES\" title=\"Text Cell\" id=\"fs9-jc-Uln\">\n                                                                        <font key=\"font\" metaFont=\"system\"/>\n                                                                        <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                        <color key=\"backgroundColor\" name=\"controlBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                    </textFieldCell>\n                                                                    <tableColumnResizingMask key=\"resizingMask\" resizeWithTable=\"YES\" userResizable=\"YES\"/>\n                                                                    <prototypeCellViews>\n                                                                        <tableCellView identifier=\"HeaderCell\" focusRingType=\"none\" id=\"E2C-re-qlX\">\n                                                                            <rect key=\"frame\" x=\"1\" y=\"1\" width=\"107\" height=\"18\"/>\n                                                                            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                                                            <subviews>\n                                                                                <textField verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"fRl-Vg-jtL\">\n                                                                                    <rect key=\"frame\" x=\"-2\" y=\"0.0\" width=\"111\" height=\"18\"/>\n                                                                                    <textFieldCell key=\"cell\" lineBreakMode=\"truncatingTail\" sendsActionOnEndEditing=\"YES\" title=\"HEADER CELL\" id=\"iuD-UQ-2qs\">\n                                                                                        <font key=\"font\" metaFont=\"systemBold\" size=\"14\"/>\n                                                                                        <color key=\"textColor\" white=\"0.0\" alpha=\"1\" colorSpace=\"calibratedWhite\"/>\n                                                                                        <color key=\"backgroundColor\" white=\"0.0\" alpha=\"0.0\" colorSpace=\"custom\" customColorSpace=\"genericGamma22GrayColorSpace\"/>\n                                                                                    </textFieldCell>\n                                                                                </textField>\n                                                                            </subviews>\n                                                                            <constraints>\n                                                                                <constraint firstAttribute=\"bottom\" secondItem=\"fRl-Vg-jtL\" secondAttribute=\"bottom\" id=\"Cbj-ql-67m\"/>\n                                                                                <constraint firstAttribute=\"trailing\" secondItem=\"fRl-Vg-jtL\" secondAttribute=\"trailing\" id=\"gj8-IP-hzr\"/>\n                                                                                <constraint firstItem=\"fRl-Vg-jtL\" firstAttribute=\"leading\" secondItem=\"E2C-re-qlX\" secondAttribute=\"leading\" id=\"q1t-Fp-fke\"/>\n                                                                                <constraint firstItem=\"fRl-Vg-jtL\" firstAttribute=\"top\" secondItem=\"E2C-re-qlX\" secondAttribute=\"top\" id=\"uHl-VP-AuR\"/>\n                                                                            </constraints>\n                                                                            <connections>\n                                                                                <outlet property=\"textField\" destination=\"fRl-Vg-jtL\" id=\"ekx-cO-K5B\"/>\n                                                                            </connections>\n                                                                        </tableCellView>\n                                                                        <tableCellView identifier=\"DataCell\" id=\"5Ph-vx-WC0\">\n                                                                            <rect key=\"frame\" x=\"1\" y=\"21\" width=\"107\" height=\"17\"/>\n                                                                            <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                                                            <subviews>\n                                                                                <textField verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"yfV-9b-MRv\">\n                                                                                    <rect key=\"frame\" x=\"-2\" y=\"0.0\" width=\"111\" height=\"17\"/>\n                                                                                    <textFieldCell key=\"cell\" lineBreakMode=\"truncatingTail\" sendsActionOnEndEditing=\"YES\" title=\"18 - Feb\" id=\"4C3-zA-yMZ\">\n                                                                                        <font key=\"font\" metaFont=\"system\"/>\n                                                                                        <color key=\"textColor\" name=\"disabledControlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                                        <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                                                    </textFieldCell>\n                                                                                </textField>\n                                                                            </subviews>\n                                                                            <constraints>\n                                                                                <constraint firstItem=\"yfV-9b-MRv\" firstAttribute=\"leading\" secondItem=\"5Ph-vx-WC0\" secondAttribute=\"leading\" id=\"JdP-th-YtA\"/>\n                                                                                <constraint firstItem=\"yfV-9b-MRv\" firstAttribute=\"top\" secondItem=\"5Ph-vx-WC0\" secondAttribute=\"top\" id=\"aim-cI-TaD\"/>\n                                                                                <constraint firstAttribute=\"trailing\" secondItem=\"yfV-9b-MRv\" secondAttribute=\"trailing\" id=\"dBU-PM-ddk\"/>\n                                                                                <constraint firstAttribute=\"bottom\" secondItem=\"yfV-9b-MRv\" secondAttribute=\"bottom\" id=\"lrI-cP-jaS\"/>\n                                                                            </constraints>\n                                                                            <connections>\n                                                                                <outlet property=\"textField\" destination=\"yfV-9b-MRv\" id=\"GSZ-fL-APw\"/>\n                                                                            </connections>\n                                                                        </tableCellView>\n                                                                    </prototypeCellViews>\n                                                                </tableColumn>\n                                                            </tableColumns>\n                                                        </outlineView>\n                                                    </subviews>\n                                                    <nil key=\"backgroundColor\"/>\n                                                </clipView>\n                                                <scroller key=\"horizontalScroller\" hidden=\"YES\" wantsLayer=\"YES\" verticalHuggingPriority=\"750\" horizontal=\"YES\" id=\"x5B-dL-F07\">\n                                                    <rect key=\"frame\" x=\"0.0\" y=\"364\" width=\"110\" height=\"16\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                </scroller>\n                                                <scroller key=\"verticalScroller\" hidden=\"YES\" wantsLayer=\"YES\" verticalHuggingPriority=\"750\" horizontal=\"NO\" id=\"0zs-E5-8L9\">\n                                                    <rect key=\"frame\" x=\"224\" y=\"17\" width=\"15\" height=\"102\"/>\n                                                    <autoresizingMask key=\"autoresizingMask\"/>\n                                                </scroller>\n                                                <connections>\n                                                    <outlet property=\"outlineView\" destination=\"fay-QN-mrU\" id=\"w5k-9U-hZE\"/>\n                                                </connections>\n                                            </scrollView>\n                                        </subviews>\n                                        <constraints>\n                                            <constraint firstItem=\"TP3-Rr-lmx\" firstAttribute=\"top\" secondItem=\"bMb-qH-ZuV\" secondAttribute=\"top\" id=\"Ws7-Za-hT5\"/>\n                                            <constraint firstAttribute=\"bottom\" secondItem=\"TP3-Rr-lmx\" secondAttribute=\"bottom\" id=\"aZA-Mh-PDz\"/>\n                                            <constraint firstItem=\"TP3-Rr-lmx\" firstAttribute=\"leading\" secondItem=\"bMb-qH-ZuV\" secondAttribute=\"leading\" id=\"bkA-VZ-KCf\"/>\n                                            <constraint firstAttribute=\"trailing\" secondItem=\"TP3-Rr-lmx\" secondAttribute=\"trailing\" id=\"tJA-af-5i1\"/>\n                                        </constraints>\n                                    </customView>\n                                    <customView id=\"JZx-xW-wh2\">\n                                        <rect key=\"frame\" x=\"111\" y=\"0.0\" width=\"368\" height=\"380\"/>\n                                        <autoresizingMask key=\"autoresizingMask\"/>\n                                        <subviews>\n                                            <progressIndicator wantsLayer=\"YES\" horizontalHuggingPriority=\"750\" verticalHuggingPriority=\"750\" maxValue=\"100\" displayedWhenStopped=\"NO\" bezeled=\"NO\" indeterminate=\"YES\" controlSize=\"small\" style=\"spinning\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"85r-Gq-mow\">\n                                                <rect key=\"frame\" x=\"176\" y=\"182\" width=\"16\" height=\"16\"/>\n                                            </progressIndicator>\n                                        </subviews>\n                                        <constraints>\n                                            <constraint firstItem=\"85r-Gq-mow\" firstAttribute=\"centerX\" secondItem=\"JZx-xW-wh2\" secondAttribute=\"centerX\" id=\"CHC-AY-j8C\"/>\n                                            <constraint firstItem=\"85r-Gq-mow\" firstAttribute=\"centerY\" secondItem=\"JZx-xW-wh2\" secondAttribute=\"centerY\" id=\"uLY-lI-OJ8\"/>\n                                        </constraints>\n                                    </customView>\n                                </subviews>\n                                <holdingPriorities>\n                                    <real value=\"266\"/>\n                                    <real value=\"250\"/>\n                                </holdingPriorities>\n                            </splitView>\n                            <segmentedControl verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"95a-7I-VNJ\">\n                                <rect key=\"frame\" x=\"111.5\" y=\"399\" width=\"269\" height=\"23\"/>\n                                <segmentedCell key=\"cell\" borderStyle=\"border\" alignment=\"left\" style=\"texturedSquare\" trackingMode=\"selectOne\" id=\"fYS-Rm-Q7V\">\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <segments>\n                                        <segment label=\"All tasks\"/>\n                                        <segment label=\"Report\" selected=\"YES\" tag=\"1\"/>\n                                        <segment label=\"Monthly reports\"/>\n                                    </segments>\n                                </segmentedCell>\n                                <connections>\n                                    <action selector=\"handleSegmentedControl:\" target=\"wHU-IX-gfU\" id=\"1hR-gG-H11\"/>\n                                </connections>\n                            </segmentedControl>\n                            <progressIndicator wantsLayer=\"YES\" horizontalHuggingPriority=\"750\" verticalHuggingPriority=\"750\" maxValue=\"100\" displayedWhenStopped=\"NO\" bezeled=\"NO\" indeterminate=\"YES\" controlSize=\"small\" style=\"spinning\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"lYQ-Lm-GnG\">\n                                <rect key=\"frame\" x=\"438\" y=\"403\" width=\"16\" height=\"16\"/>\n                            </progressIndicator>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"GOP-YB-kkJ\">\n                                <rect key=\"frame\" x=\"435\" y=\"400\" width=\"22\" height=\"22\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"22\" id=\"1I9-pc-lxE\"/>\n                                    <constraint firstAttribute=\"height\" constant=\"22\" id=\"eig-6p-JSj\"/>\n                                </constraints>\n                                <buttonCell key=\"cell\" type=\"square\" bezelStyle=\"shadowlessSquare\" image=\"NSRefreshTemplate\" imagePosition=\"overlaps\" alignment=\"center\" state=\"on\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"Hph-hf-85K\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleRefreshButton:\" target=\"wHU-IX-gfU\" id=\"NFp-1V-gaM\"/>\n                                </connections>\n                            </button>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"dKg-L3-iYb\">\n                                <rect key=\"frame\" x=\"12\" y=\"401\" width=\"38\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"Quit\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"Rbt-IB-xge\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleQuitAppButton:\" target=\"wHU-IX-gfU\" id=\"Unl-fe-pMn\"/>\n                                </connections>\n                            </button>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"uwg-ZV-XEf\">\n                                <rect key=\"frame\" x=\"60\" y=\"401\" width=\"20\" height=\"19\"/>\n                                <buttonCell key=\"cell\" type=\"roundRect\" title=\"^\" bezelStyle=\"roundedRect\" alignment=\"center\" state=\"on\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"XAx-PW-mjs\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleMinimizeAppButton:\" target=\"wHU-IX-gfU\" id=\"8JQ-19-WTf\"/>\n                                </connections>\n                            </button>\n                            <button toolTip=\"Some plugins needs updating.\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"AWO-mi-jqE\">\n                                <rect key=\"frame\" x=\"413\" y=\"400\" width=\"22\" height=\"22\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"22\" id=\"6Ea-jH-hJI\"/>\n                                    <constraint firstAttribute=\"width\" constant=\"22\" id=\"XeN-vA-brM\"/>\n                                </constraints>\n                                <buttonCell key=\"cell\" type=\"square\" bezelStyle=\"shadowlessSquare\" image=\"WarningButton\" imagePosition=\"only\" alignment=\"center\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"NaV-bW-dGt\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                </buttonCell>\n                                <accessibility description=\"Settings\" identifier=\"Settings\"/>\n                                <connections>\n                                    <action selector=\"handleWarningButton:\" target=\"wHU-IX-gfU\" id=\"UkX-8J-BTW\"/>\n                                </connections>\n                            </button>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"lYQ-Lm-GnG\" firstAttribute=\"centerY\" secondItem=\"GOP-YB-kkJ\" secondAttribute=\"centerY\" id=\"1Vd-we-oBW\"/>\n                            <constraint firstItem=\"uwg-ZV-XEf\" firstAttribute=\"centerY\" secondItem=\"dKg-L3-iYb\" secondAttribute=\"centerY\" id=\"3m4-yi-xBZ\"/>\n                            <constraint firstItem=\"95a-7I-VNJ\" firstAttribute=\"top\" secondItem=\"FwC-dy-0bY\" secondAttribute=\"top\" constant=\"20\" id=\"BIc-JC-FRc\"/>\n                            <constraint firstItem=\"dKg-L3-iYb\" firstAttribute=\"top\" secondItem=\"FwC-dy-0bY\" secondAttribute=\"top\" constant=\"22\" id=\"EDa-6H-Km8\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"sOM-pv-IVs\" secondAttribute=\"trailing\" constant=\"12\" id=\"EDp-gv-hVw\"/>\n                            <constraint firstItem=\"sOM-pv-IVs\" firstAttribute=\"leading\" secondItem=\"AWO-mi-jqE\" secondAttribute=\"trailing\" constant=\"22\" id=\"HM3-hh-hbz\"/>\n                            <constraint firstItem=\"sOM-pv-IVs\" firstAttribute=\"top\" secondItem=\"FwC-dy-0bY\" secondAttribute=\"top\" constant=\"20\" id=\"IOj-nH-o5u\"/>\n                            <constraint firstItem=\"GOP-YB-kkJ\" firstAttribute=\"centerY\" secondItem=\"AWO-mi-jqE\" secondAttribute=\"centerY\" id=\"MmY-HK-Va4\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"pVs-CS-Pcx\" secondAttribute=\"trailing\" id=\"Txh-8R-Xmj\"/>\n                            <constraint firstItem=\"uwg-ZV-XEf\" firstAttribute=\"leading\" secondItem=\"dKg-L3-iYb\" secondAttribute=\"trailing\" constant=\"10\" id=\"Uqr-uo-mGH\"/>\n                            <constraint firstItem=\"SJz-Xr-YhG\" firstAttribute=\"leading\" secondItem=\"FwC-dy-0bY\" secondAttribute=\"leading\" constant=\"12\" id=\"c6a-uG-6en\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"pVs-CS-Pcx\" secondAttribute=\"bottom\" id=\"jOP-OI-xoU\"/>\n                            <constraint firstItem=\"SJz-Xr-YhG\" firstAttribute=\"top\" secondItem=\"FwC-dy-0bY\" secondAttribute=\"top\" constant=\"60\" id=\"kgn-ml-hof\"/>\n                            <constraint firstItem=\"95a-7I-VNJ\" firstAttribute=\"centerX\" secondItem=\"FwC-dy-0bY\" secondAttribute=\"centerX\" id=\"lHI-TJ-Zn1\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"SJz-Xr-YhG\" secondAttribute=\"trailing\" constant=\"12\" id=\"leq-Tf-xCq\"/>\n                            <constraint firstItem=\"dKg-L3-iYb\" firstAttribute=\"leading\" secondItem=\"FwC-dy-0bY\" secondAttribute=\"leading\" constant=\"12\" id=\"nTc-sS-BE0\"/>\n                            <constraint firstItem=\"pVs-CS-Pcx\" firstAttribute=\"top\" secondItem=\"FwC-dy-0bY\" secondAttribute=\"top\" constant=\"62\" id=\"rPW-Au-hGz\"/>\n                            <constraint firstItem=\"lYQ-Lm-GnG\" firstAttribute=\"centerX\" secondItem=\"GOP-YB-kkJ\" secondAttribute=\"centerX\" id=\"tnZ-eU-hgu\"/>\n                            <constraint firstItem=\"GOP-YB-kkJ\" firstAttribute=\"top\" secondItem=\"sOM-pv-IVs\" secondAttribute=\"top\" id=\"xFb-Fn-yNs\"/>\n                            <constraint firstItem=\"pVs-CS-Pcx\" firstAttribute=\"leading\" secondItem=\"FwC-dy-0bY\" secondAttribute=\"leading\" constant=\"12\" id=\"xh1-lJ-1K2\"/>\n                            <constraint firstItem=\"sOM-pv-IVs\" firstAttribute=\"leading\" secondItem=\"GOP-YB-kkJ\" secondAttribute=\"trailing\" id=\"yab-oA-B2u\"/>\n                        </constraints>\n                    </customView>\n                    <connections>\n                        <outlet property=\"butMinimize\" destination=\"uwg-ZV-XEf\" id=\"n7a-2i-PGD\"/>\n                        <outlet property=\"butQuit\" destination=\"dKg-L3-iYb\" id=\"UTl-h4-8iX\"/>\n                        <outlet property=\"butRefresh\" destination=\"GOP-YB-kkJ\" id=\"okT-iV-BcZ\"/>\n                        <outlet property=\"butSettings\" destination=\"sOM-pv-IVs\" id=\"kgx-pV-DJa\"/>\n                        <outlet property=\"butWarning\" destination=\"AWO-mi-jqE\" id=\"Z87-Is-xRG\"/>\n                        <outlet property=\"butWarningRightConstraint\" destination=\"HM3-hh-hbz\" id=\"b0Q-vR-rBr\"/>\n                        <outlet property=\"calendarScrollView\" destination=\"TP3-Rr-lmx\" id=\"Zzl-gR-bBE\"/>\n                        <outlet property=\"listSegmentedControl\" destination=\"95a-7I-VNJ\" id=\"8E8-Sc-7fh\"/>\n                        <outlet property=\"loadingTasksIndicator\" destination=\"85r-Gq-mow\" id=\"x3D-ic-FGi\"/>\n                        <outlet property=\"splitView\" destination=\"pVs-CS-Pcx\" id=\"cl7-Lo-9AU\"/>\n                        <outlet property=\"syncIndicator\" destination=\"lYQ-Lm-GnG\" id=\"0L3-eP-npg\"/>\n                    </connections>\n                </viewController>\n                <customObject id=\"PVZ-YR-gJH\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"95.5\" y=\"-283\"/>\n        </scene>\n        <!--Task Suggestion View Controller-->\n        <scene sceneID=\"nAc-ky-Zce\">\n            <objects>\n                <viewController storyboardIdentifier=\"TaskSuggestionViewController\" id=\"tRv-ep-RyQ\" customClass=\"TaskSuggestionViewController\" customModule=\"Jirassic\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" id=\"F46-mC-JhQ\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"491\" height=\"104\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                        <subviews>\n                            <button verticalHuggingPriority=\"749\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"55W-A0-75h\">\n                                <rect key=\"frame\" x=\"411\" y=\"0.0\" width=\"80\" height=\"52\"/>\n                                <buttonCell key=\"cell\" type=\"square\" title=\"Save\" bezelStyle=\"shadowlessSquare\" alignment=\"center\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"bTq-7V-gcM\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"systemBold\"/>\n                                </buttonCell>\n                                <color key=\"contentTintColor\" name=\"systemBlueColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                <connections>\n                                    <action selector=\"handleSaveButton:\" target=\"tRv-ep-RyQ\" id=\"VQw-Ze-tQc\"/>\n                                </connections>\n                            </button>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"xms-pO-x4G\">\n                                <rect key=\"frame\" x=\"411\" y=\"52\" width=\"80\" height=\"52\"/>\n                                <buttonCell key=\"cell\" type=\"square\" title=\"Ignore\" bezelStyle=\"shadowlessSquare\" alignment=\"center\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"pDT-IB-e1W\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleIgnoreButton:\" target=\"tRv-ep-RyQ\" id=\"nxo-VW-zvW\"/>\n                                </connections>\n                            </button>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" fixedFrame=\"YES\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"ql7-Oz-1OK\">\n                                <rect key=\"frame\" x=\"18\" y=\"78\" width=\"344\" height=\"17\"/>\n                                <autoresizingMask key=\"autoresizingMask\" flexibleMaxX=\"YES\" flexibleMinY=\"YES\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"12:30 - 13.25\" id=\"XUG-df-poy\">\n                                    <font key=\"font\" metaFont=\"systemBold\"/>\n                                    <color key=\"textColor\" name=\"systemBlueColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField focusRingType=\"none\" verticalHuggingPriority=\"750\" horizontalCompressionResistancePriority=\"250\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"wTJ-JW-h3W\">\n                                <rect key=\"frame\" x=\"18\" y=\"46\" width=\"394\" height=\"24\"/>\n                                <textFieldCell key=\"cell\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" focusRingType=\"none\" placeholderString=\"What did you do while away?\" id=\"vVI-i0-CV1\">\n                                    <font key=\"font\" metaFont=\"system\" size=\"20\"/>\n                                    <color key=\"textColor\" name=\"textColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" white=\"1\" alpha=\"0.0\" colorSpace=\"deviceWhite\"/>\n                                </textFieldCell>\n                            </textField>\n                            <segmentedControl verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"ZGF-O7-hvq\">\n                                <rect key=\"frame\" x=\"19\" y=\"9\" width=\"324\" height=\"20\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"18\" id=\"M3U-lw-qlU\"/>\n                                </constraints>\n                                <segmentedCell key=\"cell\" borderStyle=\"border\" alignment=\"left\" style=\"roundRect\" trackingMode=\"selectOne\" id=\"Pdl-Oi-foe\">\n                                    <font key=\"font\" metaFont=\"cellTitle\"/>\n                                    <segments>\n                                        <segment label=\"Scrum\"/>\n                                        <segment label=\"Meeting\" selected=\"YES\" tag=\"1\"/>\n                                        <segment label=\"Food\"/>\n                                        <segment label=\"Waste\"/>\n                                        <segment label=\"Learning\"/>\n                                    </segments>\n                                </segmentedCell>\n                                <connections>\n                                    <action selector=\"handleSegmentedControl:\" target=\"tRv-ep-RyQ\" id=\"UaC-K0-4ue\"/>\n                                </connections>\n                            </segmentedControl>\n                            <box horizontalHuggingPriority=\"750\" boxType=\"separator\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"CGp-Zh-lOB\">\n                                <rect key=\"frame\" x=\"408\" y=\"0.0\" width=\"5\" height=\"104\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" relation=\"greaterThanOrEqual\" constant=\"70\" id=\"7NW-pb-i5r\"/>\n                                </constraints>\n                            </box>\n                            <box verticalHuggingPriority=\"750\" boxType=\"separator\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"mC8-Jn-pJP\">\n                                <rect key=\"frame\" x=\"412\" y=\"50\" width=\"79\" height=\"5\"/>\n                            </box>\n                        </subviews>\n                        <constraints>\n                            <constraint firstItem=\"CGp-Zh-lOB\" firstAttribute=\"leading\" secondItem=\"wTJ-JW-h3W\" secondAttribute=\"trailing\" id=\"0kJ-i1-uDH\"/>\n                            <constraint firstItem=\"mC8-Jn-pJP\" firstAttribute=\"centerY\" secondItem=\"F46-mC-JhQ\" secondAttribute=\"centerY\" id=\"8Sb-Ia-84N\"/>\n                            <constraint firstItem=\"wTJ-JW-h3W\" firstAttribute=\"top\" secondItem=\"F46-mC-JhQ\" secondAttribute=\"top\" constant=\"34\" id=\"8bz-Sq-k6h\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"CGp-Zh-lOB\" secondAttribute=\"bottom\" id=\"AYe-CY-0Ib\"/>\n                            <constraint firstItem=\"mC8-Jn-pJP\" firstAttribute=\"top\" secondItem=\"xms-pO-x4G\" secondAttribute=\"bottom\" constant=\"-1\" id=\"Ctv-Hh-yns\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"xms-pO-x4G\" secondAttribute=\"trailing\" id=\"EIS-9X-FYz\"/>\n                            <constraint firstItem=\"CGp-Zh-lOB\" firstAttribute=\"top\" secondItem=\"F46-mC-JhQ\" secondAttribute=\"top\" id=\"FAM-wJ-ShU\"/>\n                            <constraint firstItem=\"55W-A0-75h\" firstAttribute=\"leading\" secondItem=\"CGp-Zh-lOB\" secondAttribute=\"trailing\" id=\"Ghk-DV-vpm\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"55W-A0-75h\" secondAttribute=\"trailing\" id=\"Io9-0e-CfM\"/>\n                            <constraint firstItem=\"xms-pO-x4G\" firstAttribute=\"top\" secondItem=\"F46-mC-JhQ\" secondAttribute=\"top\" id=\"IpK-IL-Ihm\"/>\n                            <constraint firstItem=\"ZGF-O7-hvq\" firstAttribute=\"leading\" secondItem=\"F46-mC-JhQ\" secondAttribute=\"leading\" constant=\"20\" id=\"LCZ-0w-abe\"/>\n                            <constraint firstItem=\"wTJ-JW-h3W\" firstAttribute=\"leading\" secondItem=\"F46-mC-JhQ\" secondAttribute=\"leading\" constant=\"20\" id=\"M2b-Rf-pGx\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"55W-A0-75h\" secondAttribute=\"bottom\" id=\"U2c-Yy-ztR\"/>\n                            <constraint firstItem=\"55W-A0-75h\" firstAttribute=\"top\" secondItem=\"mC8-Jn-pJP\" secondAttribute=\"bottom\" id=\"W3G-sC-NLT\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"CGp-Zh-lOB\" secondAttribute=\"trailing\" constant=\"80\" id=\"W7e-9Y-Fkp\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"mC8-Jn-pJP\" secondAttribute=\"trailing\" id=\"Wsj-N1-nxK\"/>\n                            <constraint firstItem=\"mC8-Jn-pJP\" firstAttribute=\"leading\" secondItem=\"CGp-Zh-lOB\" secondAttribute=\"trailing\" constant=\"1\" id=\"dlz-sP-JyV\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"ZGF-O7-hvq\" secondAttribute=\"bottom\" constant=\"10\" id=\"fcP-Dv-1IX\"/>\n                            <constraint firstItem=\"xms-pO-x4G\" firstAttribute=\"leading\" secondItem=\"CGp-Zh-lOB\" secondAttribute=\"trailing\" id=\"gM6-mf-DE5\"/>\n                            <constraint firstItem=\"ZGF-O7-hvq\" firstAttribute=\"top\" secondItem=\"wTJ-JW-h3W\" secondAttribute=\"bottom\" constant=\"18\" id=\"sEi-D8-nHs\"/>\n                        </constraints>\n                    </view>\n                    <connections>\n                        <outlet property=\"notesTextField\" destination=\"wTJ-JW-h3W\" id=\"NwV-nb-rDW\"/>\n                        <outlet property=\"segmentedControl\" destination=\"ZGF-O7-hvq\" id=\"J2A-Xd-Vhz\"/>\n                        <outlet property=\"titleTextField\" destination=\"ql7-Oz-1OK\" id=\"ir4-Di-RaZ\"/>\n                    </connections>\n                </viewController>\n                <customObject id=\"xgm-Ey-9tg\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"96\" y=\"90\"/>\n        </scene>\n    </scenes>\n    <resources>\n        <image name=\"NSActionTemplate\" width=\"14\" height=\"14\"/>\n        <image name=\"NSRefreshTemplate\" width=\"11\" height=\"15\"/>\n        <image name=\"WarningButton\" width=\"30\" height=\"30\"/>\n    </resources>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/TasksInteractor.swift",
    "content": "//\n//  TasksInteractor.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 22/10/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport RCPreferences\nimport RCLog\n\nprotocol TasksInteractorInput: class {\n\n    func reloadCalendar()\n    func reloadTasks (inDay day: Day)\n    func reloadTasks (inMonth day: Day)\n}\n\nprotocol TasksInteractorOutput: class {\n\n    func calendarDidLoad (_ weeks: [Week])\n    func tasksDidLoad (_ tasks: [Task])\n}\n\nclass TasksInteractor {\n\n    weak var presenter: TasksPresenter?\n    \n    private let daysReader: ReadDaysInteractor!\n    private let tasksReader: ReadTasksInteractor!\n    private let moduleGit = ModuleGitLogs()\n    private let moduleCalendar = ModuleCalendar()\n    private let pref = RCPreferences<LocalPreferences>()\n    private var currentTasks = [Task]()\n    private var currentDateStart: Date?\n    \n    init() {\n        daysReader = ReadDaysInteractor(repository: localRepository, remoteRepository: remoteRepository)\n        tasksReader = ReadTasksInteractor(repository: localRepository, remoteRepository: remoteRepository)\n    }\n}\n\nextension TasksInteractor: TasksInteractorInput {\n\n    func reloadCalendar() {\n\n        let startRequestDate = Date()\n        daysReader.query(startingDate: Date(timeIntervalSinceNow: -12.monthsToSec).endOfDay()) { [weak self] weeks in\n            let endRequestDate = Date()\n            RCLog(endRequestDate.timeIntervalSince(startRequestDate))\n            DispatchQueue.main.async {\n                guard let wself = self else {\n                    return\n                }\n                wself.presenter?.calendarDidLoad(weeks)\n            }\n        }\n    }\n\n    func reloadTasks (inDay day: Day) {\n\n        let dateStart = day.dateStart\n        let dateEnd = day.dateEnd ?? dateStart.endOfDay()\n        currentDateStart = dateStart\n        reloadTasks(dateStart: dateStart, dateEnd: dateEnd)\n    }\n\n    func reloadTasks (inMonth day: Day) {\n\n        let dateStart = day.dateStart.startOfMonth()\n        let dateEnd = dateStart.endOfMonth()\n        currentDateStart = dateStart\n        reloadTasks(dateStart: dateStart, dateEnd: dateEnd)\n    }\n\n    private func reloadTasks (dateStart: Date, dateEnd: Date) {\n        \n        self.currentTasks = []\n        self.addLocalTasks(dateStart: dateStart, dateEnd: dateEnd) { [weak self] in\n            guard let self, !self.currentTasks.isEmpty else {\n                self?.presenter?.tasksDidLoad([])\n                return\n            }\n            let isMonthRead = dateEnd.timeIntervalSince(dateStart) > 24.hoursToSec\n            if isMonthRead || self.currentTasks.contains(where: { $0.taskType == .endDay }) {\n                self.presenter?.tasksDidLoad(self.currentTasks)\n                return\n            }\n            self.addGitLogs(dateStart: dateStart, dateEnd: dateEnd) {\n                self.addCalendarEvents(dateStart: dateStart, dateEnd: dateEnd) {\n                    self.presenter?.tasksDidLoad(self.currentTasks)\n                }\n            }\n        }\n    }\n    \n    private func addLocalTasks (dateStart: Date, dateEnd: Date, completion: () -> Void) {\n        currentTasks = tasksReader.tasks(between: dateStart, and: dateEnd)\n        // Sort by date\n        currentTasks.sort(by: {\n            // If tasks have the same date might be the end of the day compared with the last task\n            // In this case endDay should be the latter task\n            guard $0.endDate != $1.endDate else {\n                return $1.taskType == .endDay\n            }\n            return $0.endDate < $1.endDate\n        })\n        completion()\n    }\n\n    private func addGitLogs (dateStart: Date, dateEnd: Date, completion: @escaping () -> Void) {\n\n        guard pref.bool(.enableGit) else {\n            completion()\n            return\n        }\n        moduleGit.fetchLogs(dateStart: dateStart, dateEnd: dateEnd) { [weak self] gitTasks in\n\n            guard let self, self.currentDateStart == dateStart else {\n                RCLog(\"Different day was selected than the one loading\")\n                return\n            }\n            self.currentTasks = MergeTasksInteractor().merge(tasks: self.currentTasks, with: gitTasks)\n            completion()\n        }\n    }\n\n    private func addCalendarEvents (dateStart: Date, dateEnd: Date, completion: @escaping () -> Void) {\n\n        guard pref.bool(.enableCalendar) else {\n            completion()\n            return\n        }\n        moduleCalendar.events(dateStart: dateStart, dateEnd: dateEnd) { [weak self] calendarTasks in\n\n            guard let self, self.currentDateStart == dateStart else {\n                RCLog(\"Different day was selected than the one loading\")\n                return\n            }\n            self.currentTasks = MergeTasksInteractor().merge(tasks: self.currentTasks, with: calendarTasks)\n            completion()\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/TasksPresenter.swift",
    "content": "//\n//  TasksPresenter.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 05/05/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\nimport RCPreferences\n\nprotocol TasksPresenterInput: class {\n    \n    func initUI()\n    func syncData()\n    func reloadData()\n    func reloadTasksOnDay (_ day: Day, listType: ListType)\n    func updateNoTasksState()\n    func messageButtonDidPress()\n    func startDay()\n    func closeDay (shouldSaveToJira: Bool)\n    func insertTaskWithData (_ taskData: TaskCreationData)\n    func insertTask (after row: Int)\n    func removeTask (at row: Int)\n}\n\nprotocol TasksPresenterOutput: class {\n    \n    func showLoadingIndicator (_ show: Bool)\n    func showWarning (_ show: Bool)\n    func showMessage (_ message: MessageViewModel)\n    func showCalendar (_ weeks: [Week])\n    func showTasks (_ tasks: [Task])\n    func showReports (_ reports: [Report], numberOfDays: Int, type: ListType)\n    func removeTasksController()\n    func selectDay (_ day: Day)\n    func presentNewTaskController (date: Date)\n    func presentEndDayController (date: Date, tasks: [Task])\n}\n\nenum ListType: Int {\n    \n    case allTasks = 0\n    case report = 1\n    case monthlyReports = 2\n}\n\nclass TasksPresenter {\n    \n    weak var appWireframe: AppWireframe?\n    weak var ui: TasksPresenterOutput?\n    var interactor: TasksInteractorInput?\n    \n    private var currentTasks = [Task]()\n    private var currentReports = [Report]()\n    private var selectedListType = ListType.allTasks\n    private let pref = RCPreferences<LocalPreferences>()\n    private var extensions = ExtensionsInteractor()\n    private var lastSelectedDay: Day?\n}\n\nextension TasksPresenter: TasksPresenterInput {\n    \n    func initUI() {\n        ui!.showWarning(false)\n        ui!.showLoadingIndicator(false)\n        reloadData()\n        extensions.getVersions { [weak self] (versions) in\n            guard let userInterface = self?.ui else {\n                return\n            }\n            let compatibility = Versioning(versions: versions)\n            if compatibility.shellScript.available {\n                userInterface.showWarning(!compatibility.jirassic.compatible || !compatibility.jit.compatible)\n            } else {\n                userInterface.showWarning(false)\n            }\n        }\n//        updateNoTasksState()\n    }\n    \n    func syncData() {\n        reloadData()\n    }\n    \n    func reloadData() {\n        ui!.removeTasksController()\n        ui!.showLoadingIndicator(true)\n        interactor!.reloadCalendar()\n    }\n\n    func reloadTasksOnDay (_ day: Day, listType: ListType) {\n        ui!.removeTasksController()\n        ui!.showLoadingIndicator(true)\n        lastSelectedDay = day\n        selectedListType = listType\n        switch selectedListType {\n        case .allTasks, .report:\n            interactor!.reloadTasks(inDay: day)\n        case .monthlyReports:\n            interactor!.reloadTasks(inMonth: day)\n        }\n    }\n\n    func updateNoTasksState() {\n        \n        if currentTasks.count == 0 {\n            ui!.showMessage((\n                title: \"Good morning!\",\n                message: \"Ready to start working today?\",\n                buttonTitle: \"Start day\"))\n        }\n        else if currentTasks.count == 1, selectedListType == .report {\n            ui!.showMessage((\n                title: \"No task yet\",\n                message: \"Go to 'All tasks' tab and log some work first!\",\n                buttonTitle: nil))\n        } else {\n            appWireframe!.removePlaceholder()\n        }\n    }\n    \n    func messageButtonDidPress() {\n        \n        if currentTasks.count == 0 {\n            startDay()\n        } else {\n            ui!.presentNewTaskController(date: Date())\n        }\n    }\n    \n    func startDay() {\n        \n        let task = Task(endDate: Date(), type: .startDay)\n        let saveInteractor = TaskInteractor(repository: localRepository, remoteRepository: remoteRepository)\n        saveInteractor.saveTask(task, allowSyncing: true, completion: { [weak self] savedTask in\n            self?.reloadData()\n        })\n        ModuleHookup().insert(task: task)\n    }\n\n    func closeDay (shouldSaveToJira: Bool) {\n        \n        let closeDay = CloseDay()\n        closeDay.close(with: currentTasks)\n        if shouldSaveToJira {\n            // Reload data will be called after save with success\n            ui!.presentEndDayController(date: lastSelectedDay?.dateStart ?? Date(), tasks: currentTasks)\n        } else {\n            reloadData()\n        }\n    }\n\n    func insertTaskWithData (_ taskData: TaskCreationData) {\n        \n        var task = Task()\n        task.notes = taskData.notes\n        task.taskNumber = taskData.taskNumber\n        task.startDate = taskData.dateStart\n        task.endDate = taskData.dateEnd\n        task.taskType = taskData.taskType\n        \n        let saveInteractor = TaskInteractor(repository: localRepository, remoteRepository: remoteRepository)\n        saveInteractor.saveTask(task, allowSyncing: false, completion: { savedTask in\n            \n        })\n    }\n    \n    func insertTask (after row: Int) {\n        \n        guard currentTasks.count > row + 1 else {\n            // Insert task at the end\n            let taskBefore = currentTasks[row]\n            let nextDate = taskBefore.endDate.isSameDayAs(Date()) ? Date() : taskBefore.endDate.addingTimeInterval(3600)\n            ui!.presentNewTaskController(date: nextDate)\n            return\n        }\n        // Insert task between 2 other tasks\n        let taskBefore = currentTasks[row]\n        let taskAfter = currentTasks[row+1]\n        let middleTimestamp = taskAfter.endDate.timeIntervalSince(taskBefore.endDate) / 2\n        let middleDate = taskBefore.endDate.addingTimeInterval(middleTimestamp)\n        ui!.presentNewTaskController(date: middleDate)\n    }\n    \n    func removeTask (at row: Int) {\n        \n        let task = currentTasks[row]\n        currentTasks.remove(at: row)\n        let deleteInteractor = TaskInteractor(repository: localRepository, remoteRepository: remoteRepository)\n        deleteInteractor.deleteTask(task)\n        updateNoTasksState()\n        if currentTasks.count == 0 {\n            let reader = ReadDaysInteractor(repository: localRepository, remoteRepository: nil)\n            reader.queryAll { [weak self] (weeks) in\n                self?.ui?.showCalendar(weeks)\n            }\n        }\n    }\n}\n\nextension TasksPresenter: TasksInteractorOutput {\n\n    func calendarDidLoad (_ weeks: [Week]) {\n\n        guard let ui = self.ui else {\n            return\n        }\n        ui.showLoadingIndicator(false)\n        let day = lastSelectedDay ?? Day(dateStart: Date(), dateEnd: nil)\n        ui.showCalendar(weeks)\n        ui.selectDay(day)\n    }\n\n    func tasksDidLoad (_ tasks: [Task]) {\n\n        guard let ui = self.ui else {\n            return\n        }\n        ui.showLoadingIndicator(false)\n        ui.removeTasksController()\n        currentTasks = tasks\n\n        switch selectedListType {\n        case .allTasks:\n            ui.showTasks(currentTasks)\n            \n        case .report:\n            let settings = SettingsInteractor().getAppSettings()\n            let targetHoursInDay = pref.bool(.enableRoundingDay)\n                ? TimeInteractor(settings: settings).workingDayLength()\n                : nil\n            let reportInteractor = CreateReport()\n            let reports = reportInteractor.reports(fromTasks: currentTasks,\n                                                   targetHoursInDay: targetHoursInDay)\n            currentReports = reports.reversed()\n            ui.showReports(currentReports, numberOfDays: 1, type: selectedListType)\n            \n        case .monthlyReports:\n            let settings = SettingsInteractor().getAppSettings()\n            let targetHoursInDay = pref.bool(.enableRoundingDay)\n                ? TimeInteractor(settings: settings).workingDayLength()\n                : nil\n            let reportInteractor = CreateMonthReport()\n            let reports = reportInteractor.reports(fromTasks: currentTasks,\n                                                   targetHoursInDay: targetHoursInDay,\n                                                   roundHours: true)\n            currentReports = reports.byTasks\n            ui.showReports(currentReports, numberOfDays: reports.byDays.count, type: selectedListType)\n            break\n        }\n        updateNoTasksState()\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/TasksScrollView.swift",
    "content": "//\n//  TasksScrollView.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 28/03/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\nimport RCPreferences\n\nclass TasksScrollView: NSScrollView {\n\t\n    private var tableView: NSTableView!\n    private var dataSource: DataSource!\n    private var listType: ListType!\n    private let pref = RCPreferences<LocalPreferences>()\n    \n    var didClickAddRow: ((_ row: Int, _ rect: CGRect?) -> Void)?\n    var didClickRemoveRow: ((_ row: Int) -> Void)?\n    var didClickCloseDay: ((_ tasks: [Task], _ shouldSaveToJira: Bool) -> Void)?\n    var didClickCopyDailyReport: (() -> Void)?\n    var didClickCopyMonthlyReport: ((_ asHtml: Bool) -> Void)?\n    var didChangeSettings: (() -> Void)?\n\t\n    required init?(coder: NSCoder) {\n        super.init(coder: coder)\n    }\n    \n    override init(frame frameRect: NSRect) {\n        super.init(frame: frameRect)\n        setupTableView()\n    }\n    \n    convenience init (dataSource: DataSource, listType: ListType) {\n        self.init(frame: NSRect.zero)\n        self.setupTableView()\n        self.listType = listType\n        reloadDataSource(dataSource)\n    }\n    \n    func reloadData() {\n        tableView!.reloadData()\n    }\n    \n    func reloadDataSource (_ dataSource: DataSource) {\n        self.dataSource = dataSource\n        self.dataSource.tableView = tableView\n        tableView.dataSource = self.dataSource\n        tableView.delegate = self.dataSource\n        addHeader()\n        \n        self.dataSource.didClickAddRow = { [weak self] row in\n            self?.didClickAddRow!(row, nil)\n        }\n        self.dataSource.didClickRemoveRow = { [weak self] row in\n            self?.didClickRemoveRow!(row)\n        }\n    }\n    \n    private func setupTableView() {\n        \n        self.automaticallyAdjustsContentInsets = false\n        self.contentInsets = NSEdgeInsetsMake(0, 0, 0, 0)\n        self.drawsBackground = false\n        self.hasVerticalScroller = true\n        \n        tableView = NSTableView(frame: self.frame)\n        tableView.selectionHighlightStyle = NSTableView.SelectionHighlightStyle.none\n        tableView.backgroundColor = NSColor.clear\n        tableView.headerView = nil\n        \n        let column = NSTableColumn(identifier: NSUserInterfaceItemIdentifier(rawValue: \"taskColumn\"))\n        column.width = 400\n        tableView.addTableColumn(column)\n        \n        self.documentView = tableView!\n\t}\n    \n    private func addHeader() {\n        \n        if let dataSource = self.dataSource as? TasksDataSource {\n            \n            guard dataSource.tasks.count > 0 else {\n                tableView.headerView = nil\n                return\n            }\n            guard tableView.headerView == nil else {\n                return\n            }\n            let headerView = TasksHeaderView.instantiateFromXib()\n            headerView.didClickCloseDay = { [weak self] in\n                self?.didClickCloseDay!(dataSource.tasks, false)\n            }\n            headerView.didClickAddTask = { [weak self] in\n                if let wself = self {\n                    wself.didClickAddRow!(wself.dataSource.numberOfRows!(in: wself.tableView) - 1,\n                                          CGRect(x: 60, y: headerView.frame.size.height + wself.contentView.documentVisibleRect.origin.y, width: 1, height: 1))\n                }\n            }\n            headerView.didClickSaveWorklogs = { [weak self] in\n                self?.didClickCloseDay!(dataSource.tasks, true)\n            }\n            headerView.isDayEnded = dataSource.isDayEnded\n            \n            tableView.headerView = headerView\n        }\n        else if let dataSource = self.dataSource as? ReportsDataSource {\n            \n            guard dataSource.reports.count > 0 else {\n                tableView.headerView = nil\n                return\n            }\n            guard tableView.headerView == nil else {\n                return\n            }\n            let settings = SettingsInteractor().getAppSettings()\n            let workingDayLength = TimeInteractor(settings: settings).workingDayLength()\n            let totalTime = StatisticsInteractor().duration(of: dataSource.reports)\n            \n            var headerView: ReportsHeaderView!\n            switch listType! {\n            case .report:\n                headerView = ReportsHeaderView.instantiateFromXib()\n                headerView.didClickCopyAll = { asHtml in\n                    self.didClickCopyDailyReport?()\n                }\n            case .monthlyReports:\n                let monthHeaderView = MonthReportsHeaderView.instantiateFromXib()\n                monthHeaderView.numberOfDays = dataSource.numberOfDays\n                monthHeaderView.didClickCopyAll = { asHtml in\n                    self.didClickCopyMonthlyReport?(asHtml)\n                }\n                headerView = monthHeaderView\n            default:\n                break\n            }\n            headerView.workdayTime = workingDayLength.secToPercent\n            headerView.workedTime = pref.bool(.usePercents)\n                ? String(describing: totalTime.secToPercent)\n                : totalTime.secToHoursAndMin\n            headerView.didChangeSettings = { [weak self] in\n                self?.didChangeSettings!()\n            }\n            tableView.headerView = headerView\n        }\n    }\n\t\n\tfunc addTask (_ task: Task, at row: Int) {\n        if let dataSource = tableView.dataSource as? TasksDataSource {\n            dataSource.addTask(task, at: row)\n            addHeader()\n        }\n\t}\n\t\n    func removeTask (at row: Int) {\n        if let dataSource = tableView.dataSource as? TasksDataSource {\n            dataSource.removeTask(at: row)\n            let rowsToRemoveFromTable = IndexSet(integer: row)\n            tableView.removeRows(at: rowsToRemoveFromTable, withAnimation: .effectFade)\n            addHeader()\n        }\n\t}\n    \n    func frameOfCell (atRow row: Int) -> NSRect {\n        return tableView.frameOfCell(atColumn: 0, row: row)\n    }\n    \n    func view() -> NSTableView {\n        return self.tableView\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/TasksView.swift",
    "content": "//\n//  TasksView.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 19/02/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nclass TasksView: NSView {\n    \n    override func mouseUp (with theEvent: NSEvent) {\n        if theEvent.clickCount == 2 {\n            AppDelegate.sharedApp().menu.triggerClose()\n        }\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Tasks/TasksViewController.swift",
    "content": "//\n//  TasksViewController.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 28/03/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Cocoa\nimport RCPreferences\nimport RCLog\n\nclass TasksViewController: NSViewController {\n\t\n\t@IBOutlet private var splitView: NSSplitView!\n\t@IBOutlet private var calendarScrollView: CalendarScrollView!\n\tprivate var tasksScrollView: TasksScrollView?\n    @IBOutlet private var listSegmentedControl: NSSegmentedControl!\n    @IBOutlet private var butRefresh: NSButton!\n    @IBOutlet private var butSettings: NSButton!\n    @IBOutlet private var butWarning: NSButton!\n    @IBOutlet private var butWarningRightConstraint: NSLayoutConstraint!\n    @IBOutlet private var butQuit: NSButton!\n    @IBOutlet private var butMinimize: NSButton!\n    @IBOutlet private var loadingTasksIndicator: NSProgressIndicator!\n    @IBOutlet private var syncIndicator: NSProgressIndicator!\n    \n    weak var appWireframe: AppWireframe?\n    var presenter: TasksPresenterInput?\n    /// Property to keep a reference to the active cell rect\n    private var rectToDisplayPopoverAt: NSRect?\n    private var activePopover: NSPopover?\n\t\n\toverride func awakeFromNib() {\n        super.awakeFromNib()\n\t\tcreateLayer()\n\t}\n\t\n    override func viewDidLoad() {\n        super.viewDidLoad()\n        \n\t\tregisterForNotifications()\n        listSegmentedControl!.selectedSegment = TaskTypeSelection().lastType().rawValue\n        hideControls(false)\n        \n        calendarScrollView!.didSelectDay = { [weak self] (day: Day) in\n            guard let strongSelf = self else {\n                return\n            }\n            let selectedListType = ListType(rawValue: strongSelf.listSegmentedControl!.selectedSegment)!\n            strongSelf.presenter!.reloadTasksOnDay(day, listType: selectedListType)\n        }\n    }\n\t\n\toverride func viewDidAppear() {\n\t\tsuper.viewDidAppear()\n        presenter!.initUI()\n\t}\n\t\n    deinit {\n        RCLog(self)\n\t\tNotificationCenter.default.removeObserver(self)\n\t}\n    \n    private func hideControls (_ hide: Bool) {\n        butSettings.isHidden = hide\n        butRefresh.isHidden = remoteRepository == nil ? true : hide\n        butWarning.isHidden = hide\n        butQuit.isHidden = hide\n        butMinimize.isHidden = hide\n        listSegmentedControl.isHidden = hide\n    }\n}\n\nextension TasksViewController: Animatable {\n    \n    func createLayer() {\n        view.layer = CALayer()\n        view.wantsLayer = true\n        view.layer?.backgroundColor = .white\n    }\n}\n\nextension TasksViewController {\n\t\n\t@IBAction func handleSegmentedControl (_ sender: NSSegmentedControl) {\n        let listType = ListType(rawValue: sender.selectedSegment)!\n        TaskTypeSelection().setType(listType)\n        if let selectedDay = calendarScrollView!.selectedDay {\n            presenter!.reloadTasksOnDay(selectedDay, listType: listType)\n        }\n\t}\n    \n    @IBAction func handleRefreshButton (_ sender: NSButton) {\n        presenter!.syncData()\n    }\n    \n    @IBAction func handleSettingsButton (_ sender: NSButton) {\n        appWireframe!.flipToSettingsController()\n    }\n    \n    @IBAction func handleWarningButton (_ sender: NSButton) {\n        RCPreferences<LocalPreferences>().set(SettingsTab.input.rawValue, forKey: .settingsActiveTab)\n        appWireframe!.flipToSettingsController()\n    }\n    \n    @IBAction func handleQuitAppButton (_ sender: NSButton) {\n        NSApplication.shared.terminate(nil)\n    }\n    \n    @IBAction func handleMinimizeAppButton (_ sender: NSButton) {\n        AppDelegate.sharedApp().menu.triggerClose()\n    }\n}\n\nextension TasksViewController: TasksPresenterOutput {\n    \n    func showLoadingIndicator (_ show: Bool) {\n        \n        butRefresh.isHidden = remoteRepository == nil ? true : show\n        butWarningRightConstraint.constant = butRefresh.isHidden ? 0 : 22\n        if show {\n            loadingTasksIndicator.isHidden = false\n            loadingTasksIndicator.startAnimation(nil)\n        } else {\n            loadingTasksIndicator.stopAnimation(nil)\n            loadingTasksIndicator.isHidden = true\n        }\n    }\n    \n    func showWarning (_ show: Bool) {\n        butWarning.isHidden = !show\n    }\n    \n    func showMessage (_ message: MessageViewModel) {\n        \n        let controller = appWireframe!.presentPlaceholder(message, intoSplitView: splitView!)\n        controller.didPressButton = {\n            self.presenter?.messageButtonDidPress()\n        }\n    }\n    \n    func showCalendar (_ weeks: [Week]) {\n        \n        calendarScrollView.weeks = weeks\n        calendarScrollView.reloadData()\n    }\n    \n    func showTasks (_ tasks: [Task]) {\n        \n        let dataSource = TasksDataSource(tasks: tasks)\n        \n        var frame = splitView!.subviews[SplitViewColumn.tasks.rawValue].frame\n        frame.origin = NSPoint.zero\n        let scrollView = TasksScrollView(dataSource: dataSource, listType: .allTasks)\n        scrollView.frame = frame\n        splitView.subviews[SplitViewColumn.tasks.rawValue].addSubview(scrollView)\n        scrollView.constrainToSuperview()\n        scrollView.didClickAddRow = { [weak self] (row, rect) in\n            RCLogO(\"Add item after row \\(row)\")\n            if row >= 0 {\n                self?.rectToDisplayPopoverAt = rect ?? self?.tasksScrollView?.frameOfCell(atRow: row)\n                self?.presenter!.insertTask(after: row)\n            }\n        }\n        scrollView.didClickRemoveRow = { [weak self] row in\n            RCLogO(\"Remove item at row \\(row)\")\n            if row >= 0 {\n                self?.presenter!.removeTask(at: row)\n                self?.tasksScrollView!.removeTask(at: row)\n            }\n        }\n        scrollView.didClickCloseDay = { [weak self] (tasks, shouldSaveToJira) in\n            self?.presenter!.closeDay(shouldSaveToJira: shouldSaveToJira)\n        }\n        \n        scrollView.reloadData()\n        tasksScrollView = scrollView\n    }\n    \n    func showReports (_ reports: [Report], numberOfDays: Int, type: ListType) {\n        \n        let dataSource = ReportsDataSource(reports: reports, numberOfDays: numberOfDays)\n        \n        var frame = splitView.subviews[SplitViewColumn.tasks.rawValue].frame\n        frame.origin = NSPoint.zero\n        let scrollView = TasksScrollView(dataSource: dataSource, listType: type)\n        scrollView.frame = frame\n        splitView!.subviews[SplitViewColumn.tasks.rawValue].addSubview(scrollView)\n        scrollView.constrainToSuperview()\n        scrollView.reloadData()\n        scrollView.didChangeSettings = { [weak self] in\n            if let strongSelf = self {\n                strongSelf.handleSegmentedControl(strongSelf.listSegmentedControl)\n            }\n        }\n        scrollView.didClickCopyDailyReport = {\n            let interactor = CreateDayReport()\n            let string = interactor.stringReports(dataSource.reports)\n            print(string)\n            NSPasteboard.general.clearContents()\n            NSPasteboard.general.writeObjects([string as NSPasteboardWriting])\n        }\n        scrollView.didClickCopyMonthlyReport = { asHtml in\n            var string = \"\"\n            let interactor = CreateMonthReport()\n            if asHtml {\n//                string = interactor.htmlReports(dataSource.reports)\n                string = interactor.csvReports(dataSource.reports)\n            } else {\n                let joined = interactor.joinReports(dataSource.reports)\n                string = joined.notes + \"\\n\\n\" + joined.totalDuration.secToHoursAndMin\n            }\n            NSPasteboard.general.clearContents()\n            NSPasteboard.general.writeObjects([string as NSPasteboardWriting])\n        }\n        \n        tasksScrollView = scrollView\n    }\n    \n    func removeTasksController() {\n        \n        if tasksScrollView != nil {\n            tasksScrollView?.removeFromSuperview()\n            tasksScrollView = nil\n        }\n    }\n    \n    func selectDay (_ day: Day) {\n        calendarScrollView.selectDay(day)\n    }\n    \n    func presentNewTaskController (date: Date) {\n        \n        let popover = NSPopover()\n        let controller = NewTaskViewController.instantiateFromStoryboard(\"Components\")\n        controller.onSave = { [weak self] (taskData: TaskCreationData) -> Void in\n            if let self {\n                self.presenter!.insertTaskWithData(taskData)\n                self.presenter!.updateNoTasksState()\n                self.presenter!.reloadData()\n                popover.performClose(nil)\n            }\n        }\n        controller.onCancel = { [weak self] in\n            if let self {\n                popover.performClose(nil)\n                self.activePopover = nil\n                self.presenter!.updateNoTasksState()\n            }\n        }\n        popover.contentViewController = controller\n        popover.show(relativeTo: rectToDisplayPopoverAt!, of: self.tasksScrollView!.view(), preferredEdge: NSRectEdge.maxY)\n        // Add data after popover is presented\n        controller.dateStart = nil// TODO Add scrum start date when around scrum date\n        controller.dateEnd = date\n        activePopover = popover\n    }\n\n    func presentEndDayController (date: Date, tasks: [Task]) {\n\n        splitView.isHidden = true\n        appWireframe!.removePlaceholder()\n        hideControls(true)\n\n        let controller = appWireframe!.presentEndDayController(date: date, tasks: tasks)\n        controller.onSave = { [weak self] in\n            if let strongSelf = self {\n                strongSelf.appWireframe!.removeEndDayController()\n                strongSelf.splitView.isHidden = false\n                strongSelf.hideControls(false)\n                strongSelf.presenter!.reloadData()\n            }\n        }\n        controller.onCancel = { [weak self] in\n            if let strongSelf = self {\n                strongSelf.appWireframe!.removeEndDayController()\n                strongSelf.splitView.isHidden = false\n                strongSelf.hideControls(false)\n                strongSelf.presenter!.updateNoTasksState()\n            }\n        }\n    }\n}\n\nextension TasksViewController {\n\t\n\tfunc registerForNotifications() {\n\t\t\n\t\tNotificationCenter.default.addObserver(self,\n\t\t\tselector: #selector(TasksViewController.handleNewTaskAdded(_:)),\n\t\t\tname: NSNotification.Name(rawValue: kNewTaskWasAddedNotification),\n\t\t\tobject: nil)\n\t}\n\t\n\t@objc func handleNewTaskAdded (_ notif: Notification) {\n        presenter!.reloadData()\n\t}\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Worklogs/Worklogs.storyboard",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB\" version=\"3.0\" toolsVersion=\"14460.31\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\">\n    <dependencies>\n        <deployment identifier=\"macosx\"/>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"14460.31\"/>\n        <capability name=\"documents saved in the Xcode 8 format\" minToolsVersion=\"8.0\"/>\n    </dependencies>\n    <scenes>\n        <!--Worklogs View Controller-->\n        <scene sceneID=\"Y9Q-wg-vcI\">\n            <objects>\n                <viewController storyboardIdentifier=\"WorklogsViewController\" id=\"LR9-OL-5Y4\" customClass=\"WorklogsViewController\" customModule=\"Jirassic\" customModuleProvider=\"target\" sceneMemberID=\"viewController\">\n                    <view key=\"view\" id=\"xUO-DE-YPz\">\n                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"500\" height=\"395\"/>\n                        <autoresizingMask key=\"autoresizingMask\"/>\n                        <subviews>\n                            <box verticalHuggingPriority=\"750\" boxType=\"separator\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"G1R-uM-dDo\">\n                                <rect key=\"frame\" x=\"20\" y=\"60\" width=\"460\" height=\"5\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"1\" id=\"JRc-Mb-zOf\"/>\n                                </constraints>\n                            </box>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"8Hy-HX-Oze\">\n                                <rect key=\"frame\" x=\"14\" y=\"13\" width=\"82\" height=\"32\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"70\" id=\"CjD-3M-9rs\"/>\n                                    <constraint firstAttribute=\"height\" constant=\"21\" id=\"y8x-Nz-0aN\"/>\n                                </constraints>\n                                <buttonCell key=\"cell\" type=\"push\" title=\"Cancel\" bezelStyle=\"rounded\" alignment=\"center\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"wAK-6E-hjL\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                    <string key=\"keyEquivalent\" base64-UTF8=\"YES\">\nGw\n</string>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleCancelButton:\" target=\"LR9-OL-5Y4\" id=\"h6s-4B-DJV\"/>\n                                </connections>\n                            </button>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"jhb-VM-Iem\">\n                                <rect key=\"frame\" x=\"96\" y=\"13\" width=\"71\" height=\"32\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"21\" id=\"4Ur-Sz-KYl\"/>\n                                    <constraint firstAttribute=\"width\" constant=\"59\" id=\"LMI-Jb-d3M\"/>\n                                </constraints>\n                                <buttonCell key=\"cell\" type=\"push\" title=\"Save\" bezelStyle=\"rounded\" alignment=\"center\" borderStyle=\"border\" imageScaling=\"proportionallyDown\" inset=\"2\" id=\"ohC-cQ-84i\">\n                                    <behavior key=\"behavior\" pushIn=\"YES\" lightByBackground=\"YES\" lightByGray=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"systemBold\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleSaveButton:\" target=\"LR9-OL-5Y4\" id=\"ieE-2d-hYj\"/>\n                                </connections>\n                            </button>\n                            <button verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"e3H-Wf-oUT\">\n                                <rect key=\"frame\" x=\"160\" y=\"295\" width=\"322\" height=\"18\"/>\n                                <buttonCell key=\"cell\" type=\"check\" title=\"Round to 8hrs\" bezelStyle=\"regularSquare\" imagePosition=\"left\" state=\"on\" inset=\"2\" id=\"CDM-8b-1hm\">\n                                    <behavior key=\"behavior\" changeContents=\"YES\" doesNotDimImage=\"YES\" lightByContents=\"YES\"/>\n                                    <font key=\"font\" metaFont=\"system\"/>\n                                </buttonCell>\n                                <connections>\n                                    <action selector=\"handleRoundButton:\" target=\"LR9-OL-5Y4\" id=\"BXJ-cO-g4y\"/>\n                                </connections>\n                            </button>\n                            <progressIndicator wantsLayer=\"YES\" horizontalHuggingPriority=\"750\" verticalHuggingPriority=\"750\" maxValue=\"100\" displayedWhenStopped=\"NO\" bezeled=\"NO\" indeterminate=\"YES\" controlSize=\"small\" style=\"spinning\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"6MC-ZA-8OA\">\n                                <rect key=\"frame\" x=\"169\" y=\"23\" width=\"16\" height=\"16\"/>\n                            </progressIndicator>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" allowsCharacterPickerTouchBarItem=\"YES\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"dTz-me-jZu\">\n                                <rect key=\"frame\" x=\"18\" y=\"342\" width=\"470\" height=\"36\"/>\n                                <constraints>\n                                    <constraint firstAttribute=\"height\" constant=\"36\" id=\"a8p-zm-dWL\"/>\n                                </constraints>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"left\" title=\"Tue 18Feb 2018\" id=\"fAJ-fR-tUN\">\n                                    <font key=\"font\" metaFont=\"system\" size=\"30\"/>\n                                    <color key=\"textColor\" name=\"systemBlueColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Sch-1W-QW0\">\n                                <rect key=\"frame\" x=\"18\" y=\"259\" width=\"65\" height=\"17\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Worklogs\" id=\"1lA-Hz-gX5\">\n                                    <font key=\"font\" metaFont=\"systemBold\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Ohz-Z1-Kou\">\n                                <rect key=\"frame\" x=\"18\" y=\"296\" width=\"60\" height=\"17\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" title=\"Duration\" id=\"YIv-7L-9dQ\">\n                                    <font key=\"font\" metaFont=\"systemBold\"/>\n                                    <color key=\"textColor\" name=\"labelColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                            <box boxType=\"custom\" cornerRadius=\"4\" title=\"Box\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"wvv-Ec-CGM\">\n                                <rect key=\"frame\" x=\"20\" y=\"83\" width=\"460\" height=\"170\"/>\n                                <view key=\"contentView\" id=\"3nh-dS-MCD\">\n                                    <rect key=\"frame\" x=\"1\" y=\"1\" width=\"458\" height=\"168\"/>\n                                    <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                    <subviews>\n                                        <scrollView borderType=\"none\" horizontalLineScroll=\"10\" horizontalPageScroll=\"10\" verticalLineScroll=\"10\" verticalPageScroll=\"10\" hasHorizontalScroller=\"NO\" usesPredominantAxisScrolling=\"NO\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"Lqu-Zg-xM9\">\n                                            <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"458\" height=\"168\"/>\n                                            <clipView key=\"contentView\" drawsBackground=\"NO\" copiesOnScroll=\"NO\" id=\"Jdu-Ay-7Ab\">\n                                                <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"458\" height=\"168\"/>\n                                                <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                                <subviews>\n                                                    <textView importsGraphics=\"NO\" verticallyResizable=\"YES\" usesFontPanel=\"YES\" findStyle=\"panel\" continuousSpellChecking=\"YES\" allowsUndo=\"YES\" usesRuler=\"YES\" allowsNonContiguousLayout=\"YES\" quoteSubstitution=\"YES\" dashSubstitution=\"YES\" smartInsertDelete=\"YES\" id=\"wK7-5f-7YU\">\n                                                        <rect key=\"frame\" x=\"0.0\" y=\"0.0\" width=\"458\" height=\"168\"/>\n                                                        <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                                        <color key=\"textColor\" name=\"textColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                        <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                        <size key=\"minSize\" width=\"458\" height=\"168\"/>\n                                                        <size key=\"maxSize\" width=\"466\" height=\"10000000\"/>\n                                                        <color key=\"insertionPointColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                    </textView>\n                                                </subviews>\n                                                <color key=\"backgroundColor\" white=\"1\" alpha=\"0.0\" colorSpace=\"deviceWhite\"/>\n                                            </clipView>\n                                            <scroller key=\"horizontalScroller\" hidden=\"YES\" wantsLayer=\"YES\" verticalHuggingPriority=\"750\" doubleValue=\"1\" horizontal=\"YES\" id=\"R84-Za-yfV\">\n                                                <rect key=\"frame\" x=\"-100\" y=\"-100\" width=\"87\" height=\"18\"/>\n                                                <autoresizingMask key=\"autoresizingMask\"/>\n                                            </scroller>\n                                            <scroller key=\"verticalScroller\" wantsLayer=\"YES\" verticalHuggingPriority=\"750\" doubleValue=\"1\" horizontal=\"NO\" id=\"5Yq-da-2Pg\">\n                                                <rect key=\"frame\" x=\"442\" y=\"0.0\" width=\"16\" height=\"168\"/>\n                                                <autoresizingMask key=\"autoresizingMask\"/>\n                                            </scroller>\n                                        </scrollView>\n                                    </subviews>\n                                    <constraints>\n                                        <constraint firstItem=\"Lqu-Zg-xM9\" firstAttribute=\"leading\" secondItem=\"3nh-dS-MCD\" secondAttribute=\"leading\" id=\"IfP-s5-4hd\"/>\n                                        <constraint firstItem=\"Lqu-Zg-xM9\" firstAttribute=\"top\" secondItem=\"3nh-dS-MCD\" secondAttribute=\"top\" id=\"IoC-xz-tyU\"/>\n                                        <constraint firstAttribute=\"trailing\" secondItem=\"Lqu-Zg-xM9\" secondAttribute=\"trailing\" id=\"RUt-op-1oT\"/>\n                                        <constraint firstAttribute=\"bottom\" secondItem=\"Lqu-Zg-xM9\" secondAttribute=\"bottom\" id=\"Uvp-Iv-NLJ\"/>\n                                    </constraints>\n                                </view>\n                            </box>\n                            <box boxType=\"custom\" cornerRadius=\"4\" title=\"Box\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"jsv-ba-jIY\">\n                                <rect key=\"frame\" x=\"92\" y=\"293\" width=\"50\" height=\"22\"/>\n                                <view key=\"contentView\" id=\"qzU-Vu-VRh\">\n                                    <rect key=\"frame\" x=\"1\" y=\"1\" width=\"48\" height=\"20\"/>\n                                    <autoresizingMask key=\"autoresizingMask\" widthSizable=\"YES\" heightSizable=\"YES\"/>\n                                    <subviews>\n                                        <textField focusRingType=\"none\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"V7N-JC-Ex3\">\n                                            <rect key=\"frame\" x=\"3\" y=\"0.0\" width=\"47\" height=\"20\"/>\n                                            <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" selectable=\"YES\" editable=\"YES\" sendsActionOnEndEditing=\"YES\" state=\"on\" focusRingType=\"none\" placeholderString=\"8.0\" id=\"leb-Pd-auw\">\n                                                <font key=\"font\" metaFont=\"system\"/>\n                                                <color key=\"textColor\" name=\"controlTextColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                                <color key=\"backgroundColor\" name=\"textBackgroundColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                            </textFieldCell>\n                                        </textField>\n                                    </subviews>\n                                    <constraints>\n                                        <constraint firstItem=\"V7N-JC-Ex3\" firstAttribute=\"leading\" secondItem=\"qzU-Vu-VRh\" secondAttribute=\"leading\" constant=\"5\" id=\"Fxz-Tb-62r\"/>\n                                        <constraint firstItem=\"V7N-JC-Ex3\" firstAttribute=\"top\" secondItem=\"qzU-Vu-VRh\" secondAttribute=\"top\" id=\"fvp-g9-frQ\"/>\n                                        <constraint firstAttribute=\"bottom\" secondItem=\"V7N-JC-Ex3\" secondAttribute=\"bottom\" id=\"ig0-6B-2cr\"/>\n                                        <constraint firstAttribute=\"trailing\" secondItem=\"V7N-JC-Ex3\" secondAttribute=\"trailing\" id=\"vda-LR-hZD\"/>\n                                    </constraints>\n                                </view>\n                                <constraints>\n                                    <constraint firstAttribute=\"width\" constant=\"50\" id=\"c5m-fh-Sy0\"/>\n                                    <constraint firstAttribute=\"height\" constant=\"22\" id=\"gTG-QG-bUW\"/>\n                                </constraints>\n                            </box>\n                            <textField horizontalHuggingPriority=\"251\" verticalHuggingPriority=\"750\" translatesAutoresizingMaskIntoConstraints=\"NO\" id=\"NII-4l-3AP\">\n                                <rect key=\"frame\" x=\"191\" y=\"24\" width=\"291\" height=\"13\"/>\n                                <textFieldCell key=\"cell\" scrollable=\"YES\" lineBreakMode=\"clipping\" sendsActionOnEndEditing=\"YES\" alignment=\"left\" title=\"Jira tempo error\" id=\"dMu-sV-zHf\">\n                                    <font key=\"font\" metaFont=\"systemBold\" size=\"10\"/>\n                                    <color key=\"textColor\" red=\"0.29921834723827678\" green=\"0.67359528979985772\" blue=\"0.17200419567309094\" alpha=\"1\" colorSpace=\"custom\" customColorSpace=\"sRGB\"/>\n                                    <color key=\"backgroundColor\" name=\"controlColor\" catalog=\"System\" colorSpace=\"catalog\"/>\n                                </textFieldCell>\n                            </textField>\n                        </subviews>\n                        <constraints>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"jhb-VM-Iem\" secondAttribute=\"bottom\" constant=\"20\" id=\"2OV-9w-laU\"/>\n                            <constraint firstItem=\"6MC-ZA-8OA\" firstAttribute=\"leading\" secondItem=\"jhb-VM-Iem\" secondAttribute=\"trailing\" constant=\"8\" id=\"4PM-aR-ybc\"/>\n                            <constraint firstItem=\"jsv-ba-jIY\" firstAttribute=\"top\" secondItem=\"xUO-DE-YPz\" secondAttribute=\"top\" constant=\"80\" id=\"4pZ-aZ-Qa8\"/>\n                            <constraint firstItem=\"dTz-me-jZu\" firstAttribute=\"top\" secondItem=\"xUO-DE-YPz\" secondAttribute=\"top\" constant=\"17\" id=\"HTj-Ic-vbB\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"wvv-Ec-CGM\" secondAttribute=\"trailing\" constant=\"20\" id=\"NQn-tP-2Un\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"NII-4l-3AP\" secondAttribute=\"trailing\" constant=\"20\" id=\"QeJ-fQ-bu4\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"dTz-me-jZu\" secondAttribute=\"trailing\" constant=\"14\" id=\"U2s-Kk-429\"/>\n                            <constraint firstItem=\"G1R-uM-dDo\" firstAttribute=\"leading\" secondItem=\"xUO-DE-YPz\" secondAttribute=\"leading\" constant=\"20\" id=\"Xcd-AZ-Ebs\"/>\n                            <constraint firstItem=\"Ohz-Z1-Kou\" firstAttribute=\"leading\" secondItem=\"Sch-1W-QW0\" secondAttribute=\"leading\" id=\"dvE-V6-Nar\"/>\n                            <constraint firstItem=\"G1R-uM-dDo\" firstAttribute=\"top\" secondItem=\"wvv-Ec-CGM\" secondAttribute=\"bottom\" constant=\"20\" id=\"fgF-wf-CCw\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"e3H-Wf-oUT\" secondAttribute=\"trailing\" constant=\"20\" id=\"gZU-33-Od7\"/>\n                            <constraint firstItem=\"Ohz-Z1-Kou\" firstAttribute=\"centerY\" secondItem=\"jsv-ba-jIY\" secondAttribute=\"centerY\" id=\"kiP-Q1-lJR\"/>\n                            <constraint firstItem=\"e3H-Wf-oUT\" firstAttribute=\"leading\" secondItem=\"jsv-ba-jIY\" secondAttribute=\"trailing\" constant=\"20\" id=\"m3W-LO-5uq\"/>\n                            <constraint firstItem=\"jsv-ba-jIY\" firstAttribute=\"leading\" secondItem=\"Ohz-Z1-Kou\" secondAttribute=\"trailing\" constant=\"16\" id=\"mYN-q8-GNW\"/>\n                            <constraint firstItem=\"NII-4l-3AP\" firstAttribute=\"centerY\" secondItem=\"jhb-VM-Iem\" secondAttribute=\"centerY\" id=\"oFj-TZ-gta\"/>\n                            <constraint firstItem=\"NII-4l-3AP\" firstAttribute=\"leading\" secondItem=\"jhb-VM-Iem\" secondAttribute=\"trailing\" constant=\"32\" id=\"oTb-Sg-124\"/>\n                            <constraint firstItem=\"6MC-ZA-8OA\" firstAttribute=\"centerY\" secondItem=\"jhb-VM-Iem\" secondAttribute=\"centerY\" id=\"oX1-MF-Gns\"/>\n                            <constraint firstItem=\"wvv-Ec-CGM\" firstAttribute=\"top\" secondItem=\"Sch-1W-QW0\" secondAttribute=\"bottom\" constant=\"6\" id=\"oz6-L6-UI5\"/>\n                            <constraint firstItem=\"wvv-Ec-CGM\" firstAttribute=\"leading\" secondItem=\"xUO-DE-YPz\" secondAttribute=\"leading\" constant=\"20\" id=\"rNf-0A-dfR\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"G1R-uM-dDo\" secondAttribute=\"bottom\" constant=\"62\" id=\"rXW-sM-eDL\"/>\n                            <constraint firstItem=\"jhb-VM-Iem\" firstAttribute=\"leading\" secondItem=\"8Hy-HX-Oze\" secondAttribute=\"trailing\" constant=\"12\" id=\"reg-5S-ARk\"/>\n                            <constraint firstItem=\"Sch-1W-QW0\" firstAttribute=\"leading\" secondItem=\"wvv-Ec-CGM\" secondAttribute=\"leading\" id=\"sJ0-n6-Dy3\"/>\n                            <constraint firstAttribute=\"bottom\" secondItem=\"8Hy-HX-Oze\" secondAttribute=\"bottom\" constant=\"20\" id=\"tcA-Mi-7dR\"/>\n                            <constraint firstItem=\"dTz-me-jZu\" firstAttribute=\"leading\" secondItem=\"xUO-DE-YPz\" secondAttribute=\"leading\" constant=\"20\" id=\"v2F-Im-dY2\"/>\n                            <constraint firstAttribute=\"trailing\" secondItem=\"G1R-uM-dDo\" secondAttribute=\"trailing\" constant=\"20\" id=\"v59-je-XFi\"/>\n                            <constraint firstItem=\"e3H-Wf-oUT\" firstAttribute=\"centerY\" secondItem=\"jsv-ba-jIY\" secondAttribute=\"centerY\" id=\"wsf-Yt-VUZ\"/>\n                            <constraint firstItem=\"wvv-Ec-CGM\" firstAttribute=\"top\" secondItem=\"jsv-ba-jIY\" secondAttribute=\"bottom\" constant=\"40\" id=\"zn4-GD-Kpo\"/>\n                            <constraint firstItem=\"8Hy-HX-Oze\" firstAttribute=\"leading\" secondItem=\"xUO-DE-YPz\" secondAttribute=\"leading\" constant=\"20\" id=\"zpB-AT-934\"/>\n                        </constraints>\n                    </view>\n                    <connections>\n                        <outlet property=\"butRound\" destination=\"e3H-Wf-oUT\" id=\"NSb-qd-3q0\"/>\n                        <outlet property=\"butSave\" destination=\"jhb-VM-Iem\" id=\"6Ov-Fp-hgl\"/>\n                        <outlet property=\"dateTextField\" destination=\"dTz-me-jZu\" id=\"3wB-X0-3KT\"/>\n                        <outlet property=\"durationTextField\" destination=\"V7N-JC-Ex3\" id=\"vea-qt-T6t\"/>\n                        <outlet property=\"jiraErrorTextField\" destination=\"NII-4l-3AP\" id=\"lnB-OC-xvv\"/>\n                        <outlet property=\"progressIndicator\" destination=\"6MC-ZA-8OA\" id=\"5Y9-gL-iEP\"/>\n                        <outlet property=\"worklogTextView\" destination=\"wK7-5f-7YU\" id=\"06y-Ez-hrO\"/>\n                    </connections>\n                </viewController>\n                <customObject id=\"Y1B-OI-dLQ\" userLabel=\"First Responder\" customClass=\"NSResponder\" sceneMemberID=\"firstResponder\"/>\n            </objects>\n            <point key=\"canvasLocation\" x=\"658\" y=\"230.5\"/>\n        </scene>\n    </scenes>\n</document>\n"
  },
  {
    "path": "Delivery/macOS/Screens/Worklogs/WorklogsPresenter.swift",
    "content": "//\n//  WorklogsPresenter.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 05/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport RCPreferences\n\nprotocol WorklogsPresenterInput: class {\n    func setup (date: Date, tasks: [Task])\n    func save (worklog: String)\n    func enableRounding (_ enabled: Bool)\n}\n\nprotocol WorklogsPresenterOutput: class {\n    func showRounding (enabled: Bool, title: String)\n    func showDuration (_ duration: Double)\n    func showWorklog (_ worklog: String)\n    func showProgressIndicator (_ show: Bool)\n    func showJiraMessage (_ message: String, isError: Bool)\n    func saveSuccess()\n}\n\nclass WorklogsPresenter {\n    \n    weak var userInterface: WorklogsPresenterOutput?\n    var date: Date?\n    private let pref = RCPreferences<LocalPreferences>()\n    private var moduleJira = ModuleJiraTempo()\n    private let reportsInteractor = CreateReport()\n    private var workdayLength = 0.0\n    private var workedLength = 0.0\n    private var tasks: [Task] = []\n}\n\nextension WorklogsPresenter: WorklogsPresenterInput {\n\n    func setup (date: Date, tasks: [Task]) {\n        self.date = date\n        self.tasks = tasks\n        show(tasks: tasks)\n    }\n    \n    private func show (tasks: [Task]) {\n        \n        // Find the real number of worked hours\n        let reports = reportsInteractor.reports(fromTasks: tasks, targetHoursInDay: nil)\n        let message = reportsInteractor.toString(reports)\n        \n        let settings = SettingsInteractor().getAppSettings()\n        workdayLength = TimeInteractor(settings: settings).workingDayLength()\n        workedLength = StatisticsInteractor().duration(of: reports)\n        let duration = (pref.bool(.enableRoundingDay) ? workdayLength : workedLength).secToPercent\n        \n        userInterface!.showDuration(duration)\n        userInterface!.showWorklog(message)\n        setupRoundingButton(workdayLength: workdayLength.secToPercent,\n                            workedLength: workedLength.secToPercent)\n    }\n    \n    private func setupRoundingButton (workdayLength: TimeInterval, workedLength: TimeInterval) {\n        userInterface!.showRounding(enabled: pref.bool(.enableRoundingDay),\n                                    title: \"Round worklogs duration to \\(String(describing: workdayLength)) hours\")\n    }\n    \n    func save (worklog: String) {\n        userInterface!.showJiraMessage(\"\", isError: false)\n\n        // Save to jira tempo\n        let isRoundingEnabled = pref.bool(.enableRoundingDay)\n        \n        userInterface!.showProgressIndicator(true)\n        let duration = isRoundingEnabled ? workdayLength : workedLength\n        moduleJira.postWorklog(worklog: worklog, duration: duration, date: date!, success: { [weak self] in\n            \n                DispatchQueue.main.async {\n                    if let userInterface = self?.userInterface {\n                        userInterface.showProgressIndicator(false)\n                        userInterface.showJiraMessage(\"Worklogs saved to Jira\", isError: false)\n                        userInterface.saveSuccess()\n                    }\n                }\n            }, failure: { [weak self] error in\n                \n                DispatchQueue.main.async {\n                    if let userInterface = self?.userInterface {\n                        userInterface.showProgressIndicator(false)\n                        userInterface.showJiraMessage(error.localizedDescription, isError: true)\n                    }\n                }\n        })\n    }\n    \n    func enableRounding (_ enabled: Bool) {\n        pref.set(enabled, forKey: .enableRoundingDay)\n        let duration = enabled ? workdayLength : workedLength\n        userInterface!.showDuration(duration.secToPercent)\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/Screens/Worklogs/WorklogsViewController.swift",
    "content": "//\n//  WorklogsViewController.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 05/02/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Cocoa\n\nclass WorklogsViewController: NSViewController {\n    \n    @IBOutlet private var dateTextField: NSTextField!\n    @IBOutlet private var durationTextField: NSTextField!\n    @IBOutlet private var worklogTextView: NSTextView!\n    @IBOutlet private var progressIndicator: NSProgressIndicator!\n    @IBOutlet private var jiraErrorTextField: NSTextField!\n    @IBOutlet private var butRound: NSButton!\n    @IBOutlet private var butSave: NSButton!\n    \n    var onSave: (() -> Void)?\n    var onCancel: (() -> Void)?\n    var presenter: WorklogsPresenterInput?\n    var date: Date?\n    var tasks: [Task]?\n    weak var appWireframe: AppWireframe?\n    \n    override func viewDidLoad() {\n        super.viewDidLoad()\n        \n        dateTextField.stringValue = date!.EEEEMMMdd()\n        jiraErrorTextField.stringValue = \"\"\n        \n        worklogTextView.drawsBackground = false\n        worklogTextView.backgroundColor = NSColor.clear\n        \n        presenter!.setup(date: date!, tasks: tasks!)\n    }\n    \n    @IBAction func handleCancelButton (_ sender: NSButton) {\n        self.onCancel?()\n    }\n    \n    @IBAction func handleSaveButton (_ sender: NSButton) {\n        presenter!.save(worklog: worklogTextView.string)\n    }\n    \n    @IBAction func handleRoundButton (_ sender: NSButton) {\n        presenter!.enableRounding(sender.state == .on)\n    }\n}\n\nextension WorklogsViewController: WorklogsPresenterOutput {\n    \n    func showRounding (enabled: Bool, title: String) {\n        butRound.state = enabled ? .on : .off\n        butRound.title = title\n    }\n    \n    func showDuration (_ duration: Double) {\n        durationTextField.stringValue = String(describing: duration)\n    }\n    \n    func showWorklog (_ worklog: String) {\n        worklogTextView.string = worklog\n    }\n    \n    func showProgressIndicator (_ show: Bool) {\n        show\n            ? progressIndicator.startAnimation(nil)\n            : progressIndicator.stopAnimation(nil)\n    }\n    \n    func showJiraMessage (_ message: String, isError: Bool) {\n        jiraErrorTextField.stringValue = message\n        jiraErrorTextField.textColor = isError ? NSColor.red : NSColor(red: 76/255, green: 172/255, blue: 44/255, alpha: 1.0)\n    }\n    \n    func saveSuccess() {\n        self.onSave?()\n    }\n}\n"
  },
  {
    "path": "Delivery/macOS/jirassic.sdef",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE dictionary SYSTEM \"file://localhost/System/Library/DTDs/sdef.dtd\">\n\n<dictionary title=\"Jirassic Terminology\">\n    \n\t<suite name=\"Jirassic Suite\" code=\"jirs\" description=\"Jirassic commands\">\n        <command name=\"create task\" code=\"crtetask\" description=\"Create a new Task from a given json\">\n            <cocoa class=\"Jirassic.NewTaskCommand\"/>\n            <direct-parameter description=\"The json encoded\">\n                <type type=\"text\"/>\n            </direct-parameter>\n        </command>\n\t</suite>￼\n    \n</dictionary>\n"
  },
  {
    "path": "Delivery/macOS-cmd/main.swift",
    "content": "//\n//  jirassic\n//\n//  Created by Baluta Cristian on 06/01/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nvar shouldKeepRunning = true\nlet theRL = RunLoop.current\nlet appVersion = \"18.12.12\"\n//while shouldKeepRunning && theRL.run(mode: .defaultRunLoopMode, before: .distantFuture) {}\n\nenum ArgType {\n    case taskNr\n    case notes\n}\n\nenum Command: String {\n    case list = \"list\"\n    case reports = \"reports\"\n    case insert = \"insert\"\n    case scrum = \"scrum\"\n    case lunch = \"lunch\"\n    case meeting = \"meeting\"\n    case waste = \"waste\"\n    case learning = \"learning\"\n    case coderev = \"coderev\"\n    case version = \"version\"\n}\n\nfunc printHelp() {\n    print(\"\")\n    print(\"jirassic \\(appVersion) - (c)2018 Imagin soft\")\n    print(\"\")\n    print(\"Usage:\")\n    print(\"     list [yyyy.mm.dd]  If date is missing list tasks from today\")\n    print(\"     reports [yyyy.mm.dd|yyyy.mm] [hours per day]  If date is missing, list reports from today\")\n    print(\"     insert -nr <task number> -notes <notes> -duration <mm>\")\n    print(\"     scrum|lunch|meeting|waste|learning|coderev <duration>  Duration in minutes\")\n    print(\"\")\n}\n\nlet urls = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask)\nlet libraryDirectory = urls.first!\nlet jirassicSandboxedAppSupportDir = libraryDirectory.appendingPathComponent(\"Containers/com.jirassic.macos/Data/Library/Application Support/Jirassic\")\n//print(urls)\n//print(jirassicSandboxedAppSupportDir)\n// /Users/Cristian/Library/Containers/com.ralcr.Jirassic.osx/Data/Library/Application%20Support/Jirassic/\n// /Users/Cristian/Library/Application%20Support/Jirassic/\nlet localRepository: Repository! = SqliteRepository(documentsDirectory: jirassicSandboxedAppSupportDir)\nvar remoteRepository: Repository?\nlet reader = ReadTasksInteractor(repository: localRepository, remoteRepository: remoteRepository)\n\n\n//let settings = localRepository!.settings()\n//print(currentTasks)\n\n\n// Insert the task\nvar arguments = ProcessInfo.processInfo.arguments\n//arguments.append(\"list\")\n//arguments.append(\"2018.11.09\")\n//arguments.append(\"reports\")\n//arguments.append(\"2018.11.09\")\n//arguments.append(\"6\")\n//print(arguments)\n\narguments.remove(at: 0)// First arg is the filepath and needs to be removed\n\nguard arguments.count > 0 else {\n    printHelp()\n    exit(0)\n}\n\nfunc dayStarted() -> Bool {\n    \n    let currentTasks = reader.tasksInDay(Date())\n    guard currentTasks.count > 0 else {\n        print(\"Working day was not started yet, start it with 'jirassic start'\")\n        return false\n    }\n    return true\n}\n\nfunc list (dayOnDate date: Date) {\n    \n    print(\"\")\n    let tasks = reader.tasksInDay(date)\n    if tasks.count > 0 {\n        for task in tasks {\n            let startTime = task.startDate != nil ? (task.startDate!.HHmm() + \" \") : \"\"\n            let notes = task.notes ?? task.taskType.defaultNotes\n            print(\"• \" + startTime + task.endDate.HHmm() + \" \" + notes)\n        }\n    } else {\n        print(\"No tasks!\")\n    }\n    print(\"\")\n}\n\nfunc reports (forDay date: Date, targetHoursInDay: Double?) {\n    \n    print(\"\")\n    let tasks = reader.tasksInDay(date)\n    let reportsInteractor = CreateReport()\n    let duration: Double? = targetHoursInDay != nil ? targetHoursInDay!.hoursToSec : nil\n    let reports = reportsInteractor.reports(fromTasks: tasks, targetHoursInDay: duration)\n    if reports.count > 0 {\n        let message = reportsInteractor.toString(reports)\n        print(message)\n        print(\"\")\n        let workedLength = StatisticsInteractor().duration(of: reports)\n        print(\"Total duration: \\(workedLength.secToHoursAndMin)\")\n    } else {\n        print(\"No tasks!\")\n    }\n    print(\"\")\n}\n\nfunc reports (forMonth date: Date, targetHoursInDay: Double?) {\n\n    print(\"\")\n    print(\"Reports for the month of \\(date.startOfMonth().MMMMdd()) - \\(date.endOfMonth().MMMMdd()) \\(date.YYYY())\")\n    print(\"\")\n    \n    let tasks = reader.tasksInMonth(date)\n    let monthReportsInteractor = CreateMonthReport()\n    let duration: Double? = targetHoursInDay != nil ? targetHoursInDay!.hoursToSec : nil\n    let result = monthReportsInteractor.reports(fromTasks: tasks, targetHoursInDay: duration)\n    if result.byTasks.count > 0 {\n        let joined = monthReportsInteractor.joinReports(result.byTasks)\n        print(joined.notes)\n        print(\"\")\n        print(\"Total duration: \\(joined.totalDuration.secToHoursAndMin)\")\n    } else {\n        print(\"No tasks!\")\n    }\n    print(\"\")\n}\n\nfunc insertIssue (arguments: [String]) {\n    \n    guard dayStarted() else {\n        return\n    }\n    \n    var argType: ArgType?\n    var taskNumber: String?\n    let taskType = TaskType.issue\n    var notes: String?\n    \n    for arg in arguments {\n        if arg.hasPrefix(\"-\") {\n            switch arg {\n                case \"-nr\": argType = .taskNr\n                    break\n                case \"-notes\": argType = .notes\n                    break\n                default:\n                    print(\"Unsupported argument \\(arg). Is it a typo?\")\n                    break\n            }\n        } else if let argType = argType {\n            switch argType {\n            case .taskNr: taskNumber = arg\n                break\n            case .notes:\n                if notes == nil {\n                    notes = arg\n                } else {\n                    notes = \"\\(notes!) \\(arg)\"\n                }\n                break\n            }\n        }\n    }\n    \n    let task = Task(\n        lastModifiedDate: nil,\n        startDate: nil,\n        endDate: Date(),\n        notes: notes,\n        taskNumber: taskNumber,\n        taskTitle: nil,\n        taskType: taskType,\n        objectId: String.generateId()\n    )\n//    print(task)\n    let saveInteractor = TaskInteractor(repository: localRepository, remoteRepository: remoteRepository)\n    saveInteractor.saveTask(task, allowSyncing: false, completion: {_ in \n        \n    })\n    \n    print(\"Task saved\")\n}\n\nfunc insert (taskType: Command, arguments: [String]) {\n    \n    guard dayStarted() else {\n        return\n    }\n    var task: Task?\n    \n    switch taskType {\n        case .scrum: task = Task(endDate: Date(), type: .scrum)\n            break\n        case .lunch: task = Task(endDate: Date(), type: .lunch)\n            break\n        case .meeting: task = Task(endDate: Date(), type: .meeting)\n            break\n        case .waste: task = Task(endDate: Date(), type: .waste)\n            break\n        case .learning: task = Task(endDate: Date(), type: .learning)\n            break\n        case .coderev: task = Task(endDate: Date(), type: .coderev)\n            break\n        default:\n            return\n    }\n    \n    if let duration = arguments.first {\n        if let d = Double(duration) {\n            if d > 0 {\n                let startDate = task?.endDate.addingTimeInterval(d)\n                task?.startDate = startDate\n            }\n        }\n    }\n    \n//    print(task!)\n    let saveInteractor = TaskInteractor(repository: localRepository, remoteRepository: nil)\n    saveInteractor.saveTask(task!, allowSyncing: false, completion: { _ in })\n    \n    print(taskType.rawValue.capitalized + \" saved\")\n}\n\nlet commandStr = arguments.remove(at: 0)\nif let command = Command(rawValue: commandStr) {\n    switch command {\n        case .list:\n            var date = Date()\n            if arguments.count > 0 {\n                let arg = arguments.remove(at: 0)\n                date = Date(YYYYMMddString: arg)\n            }\n            list (dayOnDate: date)\n            break\n        case .reports:\n            var date = Date()\n            var duration: Double? = nil\n            if arguments.count >= 2 {\n                duration = Double(arguments[1])\n            }\n            if arguments.count > 0 {\n                let arg = arguments.remove(at: 0)\n                if arg.components(separatedBy: \".\").count == 2 {\n                    // We have only year and month. Add a day and call the month reports\n                    date = Date(YYYYMMddString: \"\\(arg).01\")\n                    reports (forMonth: date, targetHoursInDay: duration)\n                    break\n                } else if arg.components(separatedBy: \".\").count == 3 {\n                    // We have year, month and day\n                    date = Date(YYYYMMddString: arg)\n                }\n            }\n            reports (forDay: date, targetHoursInDay: duration)\n            break\n        case .insert:\n            insertIssue (arguments: arguments)\n            break\n        case .scrum, .lunch, .meeting, .waste, .learning, .coderev:\n            insert (taskType: command, arguments: arguments)\n            break\n        case .version:\n            print(appVersion)\n    }\n} else {\n    print(\"\\nUnsupported command.\\n\")\n    printHelp()\n}\n\nexit(0)\n"
  },
  {
    "path": "Delivery/macOS-launcher/AppDelegate.h",
    "content": "//\n//  AppDelegate.h\n//\n//  Created by Cristian Baluta on 18/03/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\n#import <Cocoa/Cocoa.h>\n\n@interface AppDelegate : NSObject <NSApplicationDelegate>\n\n\n@end\n\n"
  },
  {
    "path": "Delivery/macOS-launcher/AppDelegate.m",
    "content": "//\n//  AppDelegate.m\n//\n//  Created by Cristian Baluta on 18/03/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\n#import \"AppDelegate.h\"\n\n@implementation AppDelegate\n\n- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {\n    \n    NSString *appIdentifier = @\"com.jirassic.macos\";\n    \n    BOOL alreadyRunning = NO;\n    for (NSRunningApplication *app in [NSWorkspace sharedWorkspace].runningApplications) {\n        if ([app.bundleIdentifier isEqualToString:appIdentifier]) {\n            alreadyRunning = YES;\n            break;\n        }\n    }\n    if (!alreadyRunning) {\n        [[NSDistributedNotificationCenter defaultCenter] addObserver:self \n                                                            selector:@selector(terminate) \n                                                                name:@\"killme\" \n                                                              object:appIdentifier];\n        \n        BOOL launched = [[NSWorkspace sharedWorkspace] launchApplication:@\"Jirassic.app\"];\n        NSLog(@\"Jirassic launched %i\", launched);\n        \n//        NSWorkspace *workspace = [NSWorkspace sharedWorkspace];\n//        NSURL *url = [NSURL fileURLWithPath:[workspace fullPathForApplication:@\"Jirassic.app\"]];\n//        NSLog(@\"Jirassic url %@\", url);\n//        NSError *error = nil;\n////        NSArray *arguments = @[@\"launchedByLauncher\"];\n//        NSDictionary *config = @{NSWorkspaceLaunchConfigurationEnvironment: @{@\"launchedByLauncher\": @YES}};\n//        [workspace launchApplicationAtURL:url\n//                                  options:NSWorkspaceLaunchDefault\n//                            configuration:config\n//                                    error:&error];\n    } else {\n        [self terminate];\n    }\n}\n\n- (void)terminate {\n    [NSApp terminate:nil];\n}\n\n@end\n"
  },
  {
    "path": "Delivery/macOS-launcher/Base.lproj/MainMenu.xib",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<document type=\"com.apple.InterfaceBuilder3.Cocoa.XIB\" version=\"3.0\" toolsVersion=\"11762\" systemVersion=\"16D32\" targetRuntime=\"MacOSX.Cocoa\" propertyAccessControl=\"none\" useAutolayout=\"YES\" customObjectInstantitationMethod=\"direct\">\n    <dependencies>\n        <plugIn identifier=\"com.apple.InterfaceBuilder.CocoaPlugin\" version=\"11762\"/>\n    </dependencies>\n    <objects>\n        <customObject id=\"-2\" userLabel=\"File's Owner\" customClass=\"NSApplication\">\n            <connections>\n                <outlet property=\"delegate\" destination=\"Voe-Tx-rLC\" id=\"GzC-gU-4Uq\"/>\n            </connections>\n        </customObject>\n        <customObject id=\"-1\" userLabel=\"First Responder\" customClass=\"FirstResponder\"/>\n        <customObject id=\"-3\" userLabel=\"Application\" customClass=\"NSObject\"/>\n        <customObject id=\"Voe-Tx-rLC\" customClass=\"AppDelegate\"/>\n        <customObject id=\"YLy-65-1bz\" customClass=\"NSFontManager\"/>\n        <menu title=\"Main Menu\" systemMenu=\"main\" id=\"AYu-sK-qS6\">\n            <items>\n                <menuItem title=\"Jirassic\" id=\"1Xt-HY-uBw\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <menu key=\"submenu\" title=\"Jirassic\" systemMenu=\"apple\" id=\"uQy-DD-JDr\">\n                        <items>\n                            <menuItem title=\"About cmdclauncher\" id=\"5kV-Vb-QxS\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <connections>\n                                    <action selector=\"orderFrontStandardAboutPanel:\" target=\"-1\" id=\"Exp-CZ-Vem\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem isSeparatorItem=\"YES\" id=\"VOq-y0-SEH\"/>\n                            <menuItem title=\"Preferences…\" keyEquivalent=\",\" id=\"BOF-NM-1cW\"/>\n                            <menuItem isSeparatorItem=\"YES\" id=\"wFC-TO-SCJ\"/>\n                            <menuItem title=\"Services\" id=\"NMo-om-nkz\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Services\" systemMenu=\"services\" id=\"hz9-B4-Xy5\"/>\n                            </menuItem>\n                            <menuItem isSeparatorItem=\"YES\" id=\"4je-JR-u6R\"/>\n                            <menuItem title=\"Hide cmdclauncher\" keyEquivalent=\"h\" id=\"Olw-nP-bQN\">\n                                <connections>\n                                    <action selector=\"hide:\" target=\"-1\" id=\"PnN-Uc-m68\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Hide Others\" keyEquivalent=\"h\" id=\"Vdr-fp-XzO\">\n                                <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                <connections>\n                                    <action selector=\"hideOtherApplications:\" target=\"-1\" id=\"VT4-aY-XCT\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Show All\" id=\"Kd2-mp-pUS\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <connections>\n                                    <action selector=\"unhideAllApplications:\" target=\"-1\" id=\"Dhg-Le-xox\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem isSeparatorItem=\"YES\" id=\"kCx-OE-vgT\"/>\n                            <menuItem title=\"Quit cmdclauncher\" keyEquivalent=\"q\" id=\"4sb-4s-VLi\">\n                                <connections>\n                                    <action selector=\"terminate:\" target=\"-1\" id=\"Te7-pn-YzF\"/>\n                                </connections>\n                            </menuItem>\n                        </items>\n                    </menu>\n                </menuItem>\n                <menuItem title=\"File\" id=\"dMs-cI-mzQ\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <menu key=\"submenu\" title=\"File\" id=\"bib-Uj-vzu\">\n                        <items>\n                            <menuItem title=\"New\" keyEquivalent=\"n\" id=\"Was-JA-tGl\">\n                                <connections>\n                                    <action selector=\"newDocument:\" target=\"-1\" id=\"4Si-XN-c54\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Open…\" keyEquivalent=\"o\" id=\"IAo-SY-fd9\">\n                                <connections>\n                                    <action selector=\"openDocument:\" target=\"-1\" id=\"bVn-NM-KNZ\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Open Recent\" id=\"tXI-mr-wws\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Open Recent\" systemMenu=\"recentDocuments\" id=\"oas-Oc-fiZ\">\n                                    <items>\n                                        <menuItem title=\"Clear Menu\" id=\"vNY-rz-j42\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"clearRecentDocuments:\" target=\"-1\" id=\"Daa-9d-B3U\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem isSeparatorItem=\"YES\" id=\"m54-Is-iLE\"/>\n                            <menuItem title=\"Close\" keyEquivalent=\"w\" id=\"DVo-aG-piG\">\n                                <connections>\n                                    <action selector=\"performClose:\" target=\"-1\" id=\"HmO-Ls-i7Q\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Save…\" keyEquivalent=\"s\" id=\"pxx-59-PXV\">\n                                <connections>\n                                    <action selector=\"saveDocument:\" target=\"-1\" id=\"teZ-XB-qJY\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Save As…\" keyEquivalent=\"S\" id=\"Bw7-FT-i3A\">\n                                <connections>\n                                    <action selector=\"saveDocumentAs:\" target=\"-1\" id=\"mDf-zr-I0C\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Revert to Saved\" keyEquivalent=\"r\" id=\"KaW-ft-85H\">\n                                <connections>\n                                    <action selector=\"revertDocumentToSaved:\" target=\"-1\" id=\"iJ3-Pv-kwq\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem isSeparatorItem=\"YES\" id=\"aJh-i4-bef\"/>\n                            <menuItem title=\"Page Setup…\" keyEquivalent=\"P\" id=\"qIS-W8-SiK\">\n                                <modifierMask key=\"keyEquivalentModifierMask\" shift=\"YES\" command=\"YES\"/>\n                                <connections>\n                                    <action selector=\"runPageLayout:\" target=\"-1\" id=\"Din-rz-gC5\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Print…\" keyEquivalent=\"p\" id=\"aTl-1u-JFS\">\n                                <connections>\n                                    <action selector=\"print:\" target=\"-1\" id=\"qaZ-4w-aoO\"/>\n                                </connections>\n                            </menuItem>\n                        </items>\n                    </menu>\n                </menuItem>\n                <menuItem title=\"Edit\" id=\"5QF-Oa-p0T\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <menu key=\"submenu\" title=\"Edit\" id=\"W48-6f-4Dl\">\n                        <items>\n                            <menuItem title=\"Undo\" keyEquivalent=\"z\" id=\"dRJ-4n-Yzg\">\n                                <connections>\n                                    <action selector=\"undo:\" target=\"-1\" id=\"M6e-cu-g7V\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Redo\" keyEquivalent=\"Z\" id=\"6dh-zS-Vam\">\n                                <connections>\n                                    <action selector=\"redo:\" target=\"-1\" id=\"oIA-Rs-6OD\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem isSeparatorItem=\"YES\" id=\"WRV-NI-Exz\"/>\n                            <menuItem title=\"Cut\" keyEquivalent=\"x\" id=\"uRl-iY-unG\">\n                                <connections>\n                                    <action selector=\"cut:\" target=\"-1\" id=\"YJe-68-I9s\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Copy\" keyEquivalent=\"c\" id=\"x3v-GG-iWU\">\n                                <connections>\n                                    <action selector=\"copy:\" target=\"-1\" id=\"G1f-GL-Joy\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Paste\" keyEquivalent=\"v\" id=\"gVA-U4-sdL\">\n                                <connections>\n                                    <action selector=\"paste:\" target=\"-1\" id=\"UvS-8e-Qdg\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Paste and Match Style\" keyEquivalent=\"V\" id=\"WeT-3V-zwk\">\n                                <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                <connections>\n                                    <action selector=\"pasteAsPlainText:\" target=\"-1\" id=\"cEh-KX-wJQ\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Delete\" id=\"pa3-QI-u2k\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <connections>\n                                    <action selector=\"delete:\" target=\"-1\" id=\"0Mk-Ml-PaM\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Select All\" keyEquivalent=\"a\" id=\"Ruw-6m-B2m\">\n                                <connections>\n                                    <action selector=\"selectAll:\" target=\"-1\" id=\"VNm-Mi-diN\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem isSeparatorItem=\"YES\" id=\"uyl-h8-XO2\"/>\n                            <menuItem title=\"Find\" id=\"4EN-yA-p0u\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Find\" id=\"1b7-l0-nxx\">\n                                    <items>\n                                        <menuItem title=\"Find…\" tag=\"1\" keyEquivalent=\"f\" id=\"Xz5-n4-O0W\">\n                                            <connections>\n                                                <action selector=\"performFindPanelAction:\" target=\"-1\" id=\"cD7-Qs-BN4\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Find and Replace…\" tag=\"12\" keyEquivalent=\"f\" id=\"YEy-JH-Tfz\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"performFindPanelAction:\" target=\"-1\" id=\"WD3-Gg-5AJ\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Find Next\" tag=\"2\" keyEquivalent=\"g\" id=\"q09-fT-Sye\">\n                                            <connections>\n                                                <action selector=\"performFindPanelAction:\" target=\"-1\" id=\"NDo-RZ-v9R\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Find Previous\" tag=\"3\" keyEquivalent=\"G\" id=\"OwM-mh-QMV\">\n                                            <connections>\n                                                <action selector=\"performFindPanelAction:\" target=\"-1\" id=\"HOh-sY-3ay\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Use Selection for Find\" tag=\"7\" keyEquivalent=\"e\" id=\"buJ-ug-pKt\">\n                                            <connections>\n                                                <action selector=\"performFindPanelAction:\" target=\"-1\" id=\"U76-nv-p5D\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Jump to Selection\" keyEquivalent=\"j\" id=\"S0p-oC-mLd\">\n                                            <connections>\n                                                <action selector=\"centerSelectionInVisibleArea:\" target=\"-1\" id=\"IOG-6D-g5B\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Spelling and Grammar\" id=\"Dv1-io-Yv7\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Spelling\" id=\"3IN-sU-3Bg\">\n                                    <items>\n                                        <menuItem title=\"Show Spelling and Grammar\" keyEquivalent=\":\" id=\"HFo-cy-zxI\">\n                                            <connections>\n                                                <action selector=\"showGuessPanel:\" target=\"-1\" id=\"vFj-Ks-hy3\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Check Document Now\" keyEquivalent=\";\" id=\"hz2-CU-CR7\">\n                                            <connections>\n                                                <action selector=\"checkSpelling:\" target=\"-1\" id=\"fz7-VC-reM\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"bNw-od-mp5\"/>\n                                        <menuItem title=\"Check Spelling While Typing\" id=\"rbD-Rh-wIN\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"toggleContinuousSpellChecking:\" target=\"-1\" id=\"7w6-Qz-0kB\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Check Grammar With Spelling\" id=\"mK6-2p-4JG\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"toggleGrammarChecking:\" target=\"-1\" id=\"muD-Qn-j4w\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Correct Spelling Automatically\" id=\"78Y-hA-62v\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"toggleAutomaticSpellingCorrection:\" target=\"-1\" id=\"2lM-Qi-WAP\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Substitutions\" id=\"9ic-FL-obx\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Substitutions\" id=\"FeM-D8-WVr\">\n                                    <items>\n                                        <menuItem title=\"Show Substitutions\" id=\"z6F-FW-3nz\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"orderFrontSubstitutionsPanel:\" target=\"-1\" id=\"oku-mr-iSq\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"gPx-C9-uUO\"/>\n                                        <menuItem title=\"Smart Copy/Paste\" id=\"9yt-4B-nSM\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"toggleSmartInsertDelete:\" target=\"-1\" id=\"3IJ-Se-DZD\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Smart Quotes\" id=\"hQb-2v-fYv\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"toggleAutomaticQuoteSubstitution:\" target=\"-1\" id=\"ptq-xd-QOA\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Smart Dashes\" id=\"rgM-f4-ycn\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"toggleAutomaticDashSubstitution:\" target=\"-1\" id=\"oCt-pO-9gS\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Smart Links\" id=\"cwL-P1-jid\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"toggleAutomaticLinkDetection:\" target=\"-1\" id=\"Gip-E3-Fov\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Data Detectors\" id=\"tRr-pd-1PS\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"toggleAutomaticDataDetection:\" target=\"-1\" id=\"R1I-Nq-Kbl\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Text Replacement\" id=\"HFQ-gK-NFA\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"toggleAutomaticTextReplacement:\" target=\"-1\" id=\"DvP-Fe-Py6\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Transformations\" id=\"2oI-Rn-ZJC\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Transformations\" id=\"c8a-y6-VQd\">\n                                    <items>\n                                        <menuItem title=\"Make Upper Case\" id=\"vmV-6d-7jI\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"uppercaseWord:\" target=\"-1\" id=\"sPh-Tk-edu\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Make Lower Case\" id=\"d9M-CD-aMd\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"lowercaseWord:\" target=\"-1\" id=\"iUZ-b5-hil\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Capitalize\" id=\"UEZ-Bs-lqG\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"capitalizeWord:\" target=\"-1\" id=\"26H-TL-nsh\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Speech\" id=\"xrE-MZ-jX0\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Speech\" id=\"3rS-ZA-NoH\">\n                                    <items>\n                                        <menuItem title=\"Start Speaking\" id=\"Ynk-f8-cLZ\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"startSpeaking:\" target=\"-1\" id=\"654-Ng-kyl\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Stop Speaking\" id=\"Oyz-dy-DGm\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"stopSpeaking:\" target=\"-1\" id=\"dX8-6p-jy9\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                        </items>\n                    </menu>\n                </menuItem>\n                <menuItem title=\"Format\" id=\"jxT-CU-nIS\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <menu key=\"submenu\" title=\"Format\" id=\"GEO-Iw-cKr\">\n                        <items>\n                            <menuItem title=\"Font\" id=\"Gi5-1S-RQB\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Font\" systemMenu=\"font\" id=\"aXa-aM-Jaq\">\n                                    <items>\n                                        <menuItem title=\"Show Fonts\" keyEquivalent=\"t\" id=\"Q5e-8K-NDq\">\n                                            <connections>\n                                                <action selector=\"orderFrontFontPanel:\" target=\"YLy-65-1bz\" id=\"WHr-nq-2xA\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Bold\" tag=\"2\" keyEquivalent=\"b\" id=\"GB9-OM-e27\">\n                                            <connections>\n                                                <action selector=\"addFontTrait:\" target=\"YLy-65-1bz\" id=\"hqk-hr-sYV\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Italic\" tag=\"1\" keyEquivalent=\"i\" id=\"Vjx-xi-njq\">\n                                            <connections>\n                                                <action selector=\"addFontTrait:\" target=\"YLy-65-1bz\" id=\"IHV-OB-c03\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Underline\" keyEquivalent=\"u\" id=\"WRG-CD-K1S\">\n                                            <connections>\n                                                <action selector=\"underline:\" target=\"-1\" id=\"FYS-2b-JAY\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"5gT-KC-WSO\"/>\n                                        <menuItem title=\"Bigger\" tag=\"3\" keyEquivalent=\"+\" id=\"Ptp-SP-VEL\">\n                                            <connections>\n                                                <action selector=\"modifyFont:\" target=\"YLy-65-1bz\" id=\"Uc7-di-UnL\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Smaller\" tag=\"4\" keyEquivalent=\"-\" id=\"i1d-Er-qST\">\n                                            <connections>\n                                                <action selector=\"modifyFont:\" target=\"YLy-65-1bz\" id=\"HcX-Lf-eNd\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"kx3-Dk-x3B\"/>\n                                        <menuItem title=\"Kern\" id=\"jBQ-r6-VK2\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Kern\" id=\"tlD-Oa-oAM\">\n                                                <items>\n                                                    <menuItem title=\"Use Default\" id=\"GUa-eO-cwY\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"useStandardKerning:\" target=\"-1\" id=\"6dk-9l-Ckg\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Use None\" id=\"cDB-IK-hbR\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"turnOffKerning:\" target=\"-1\" id=\"U8a-gz-Maa\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Tighten\" id=\"46P-cB-AYj\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"tightenKerning:\" target=\"-1\" id=\"hr7-Nz-8ro\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Loosen\" id=\"ogc-rX-tC1\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"loosenKerning:\" target=\"-1\" id=\"8i4-f9-FKE\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem title=\"Ligatures\" id=\"o6e-r0-MWq\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Ligatures\" id=\"w0m-vy-SC9\">\n                                                <items>\n                                                    <menuItem title=\"Use Default\" id=\"agt-UL-0e3\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"useStandardLigatures:\" target=\"-1\" id=\"7uR-wd-Dx6\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Use None\" id=\"J7y-lM-qPV\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"turnOffLigatures:\" target=\"-1\" id=\"iX2-gA-Ilz\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Use All\" id=\"xQD-1f-W4t\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"useAllLigatures:\" target=\"-1\" id=\"KcB-kA-TuK\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem title=\"Baseline\" id=\"OaQ-X3-Vso\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Baseline\" id=\"ijk-EB-dga\">\n                                                <items>\n                                                    <menuItem title=\"Use Default\" id=\"3Om-Ey-2VK\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"unscript:\" target=\"-1\" id=\"0vZ-95-Ywn\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Superscript\" id=\"Rqc-34-cIF\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"superscript:\" target=\"-1\" id=\"3qV-fo-wpU\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Subscript\" id=\"I0S-gh-46l\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"subscript:\" target=\"-1\" id=\"Q6W-4W-IGz\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Raise\" id=\"2h7-ER-AoG\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"raiseBaseline:\" target=\"-1\" id=\"4sk-31-7Q9\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem title=\"Lower\" id=\"1tx-W0-xDw\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"lowerBaseline:\" target=\"-1\" id=\"OF1-bc-KW4\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"Ndw-q3-faq\"/>\n                                        <menuItem title=\"Show Colors\" keyEquivalent=\"C\" id=\"bgn-CT-cEk\">\n                                            <connections>\n                                                <action selector=\"orderFrontColorPanel:\" target=\"-1\" id=\"mSX-Xz-DV3\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"iMs-zA-UFJ\"/>\n                                        <menuItem title=\"Copy Style\" keyEquivalent=\"c\" id=\"5Vv-lz-BsD\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"copyFont:\" target=\"-1\" id=\"GJO-xA-L4q\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Paste Style\" keyEquivalent=\"v\" id=\"vKC-jM-MkH\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"pasteFont:\" target=\"-1\" id=\"JfD-CL-leO\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                            <menuItem title=\"Text\" id=\"Fal-I4-PZk\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <menu key=\"submenu\" title=\"Text\" id=\"d9c-me-L2H\">\n                                    <items>\n                                        <menuItem title=\"Align Left\" keyEquivalent=\"{\" id=\"ZM1-6Q-yy1\">\n                                            <connections>\n                                                <action selector=\"alignLeft:\" target=\"-1\" id=\"zUv-R1-uAa\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Center\" keyEquivalent=\"|\" id=\"VIY-Ag-zcb\">\n                                            <connections>\n                                                <action selector=\"alignCenter:\" target=\"-1\" id=\"spX-mk-kcS\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Justify\" id=\"J5U-5w-g23\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"alignJustified:\" target=\"-1\" id=\"ljL-7U-jND\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Align Right\" keyEquivalent=\"}\" id=\"wb2-vD-lq4\">\n                                            <connections>\n                                                <action selector=\"alignRight:\" target=\"-1\" id=\"r48-bG-YeY\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"4s2-GY-VfK\"/>\n                                        <menuItem title=\"Writing Direction\" id=\"H1b-Si-o9J\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <menu key=\"submenu\" title=\"Writing Direction\" id=\"8mr-sm-Yjd\">\n                                                <items>\n                                                    <menuItem title=\"Paragraph\" enabled=\"NO\" id=\"ZvO-Gk-QUH\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                    </menuItem>\n                                                    <menuItem id=\"YGs-j5-SAR\">\n                                                        <string key=\"title\">\tDefault</string>\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"makeBaseWritingDirectionNatural:\" target=\"-1\" id=\"qtV-5e-UBP\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem id=\"Lbh-J2-qVU\">\n                                                        <string key=\"title\">\tLeft to Right</string>\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"makeBaseWritingDirectionLeftToRight:\" target=\"-1\" id=\"S0X-9S-QSf\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem id=\"jFq-tB-4Kx\">\n                                                        <string key=\"title\">\tRight to Left</string>\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"makeBaseWritingDirectionRightToLeft:\" target=\"-1\" id=\"5fk-qB-AqJ\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem isSeparatorItem=\"YES\" id=\"swp-gr-a21\"/>\n                                                    <menuItem title=\"Selection\" enabled=\"NO\" id=\"cqv-fj-IhA\">\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                    </menuItem>\n                                                    <menuItem id=\"Nop-cj-93Q\">\n                                                        <string key=\"title\">\tDefault</string>\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"makeTextWritingDirectionNatural:\" target=\"-1\" id=\"lPI-Se-ZHp\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem id=\"BgM-ve-c93\">\n                                                        <string key=\"title\">\tLeft to Right</string>\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"makeTextWritingDirectionLeftToRight:\" target=\"-1\" id=\"caW-Bv-w94\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                    <menuItem id=\"RB4-Sm-HuC\">\n                                                        <string key=\"title\">\tRight to Left</string>\n                                                        <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                                        <connections>\n                                                            <action selector=\"makeTextWritingDirectionRightToLeft:\" target=\"-1\" id=\"EXD-6r-ZUu\"/>\n                                                        </connections>\n                                                    </menuItem>\n                                                </items>\n                                            </menu>\n                                        </menuItem>\n                                        <menuItem isSeparatorItem=\"YES\" id=\"fKy-g9-1gm\"/>\n                                        <menuItem title=\"Show Ruler\" id=\"vLm-3I-IUL\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                            <connections>\n                                                <action selector=\"toggleRuler:\" target=\"-1\" id=\"FOx-HJ-KwY\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Copy Ruler\" keyEquivalent=\"c\" id=\"MkV-Pr-PK5\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" control=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"copyRuler:\" target=\"-1\" id=\"71i-fW-3W2\"/>\n                                            </connections>\n                                        </menuItem>\n                                        <menuItem title=\"Paste Ruler\" keyEquivalent=\"v\" id=\"LVM-kO-fVI\">\n                                            <modifierMask key=\"keyEquivalentModifierMask\" control=\"YES\" command=\"YES\"/>\n                                            <connections>\n                                                <action selector=\"pasteRuler:\" target=\"-1\" id=\"cSh-wd-qM2\"/>\n                                            </connections>\n                                        </menuItem>\n                                    </items>\n                                </menu>\n                            </menuItem>\n                        </items>\n                    </menu>\n                </menuItem>\n                <menuItem title=\"View\" id=\"H8h-7b-M4v\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <menu key=\"submenu\" title=\"View\" id=\"HyV-fh-RgO\">\n                        <items>\n                            <menuItem title=\"Show Toolbar\" keyEquivalent=\"t\" id=\"snW-S8-Cw5\">\n                                <modifierMask key=\"keyEquivalentModifierMask\" option=\"YES\" command=\"YES\"/>\n                                <connections>\n                                    <action selector=\"toggleToolbarShown:\" target=\"-1\" id=\"BXY-wc-z0C\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Customize Toolbar…\" id=\"1UK-8n-QPP\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <connections>\n                                    <action selector=\"runToolbarCustomizationPalette:\" target=\"-1\" id=\"pQI-g3-MTW\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem isSeparatorItem=\"YES\" id=\"hB3-LF-h0Y\"/>\n                            <menuItem title=\"Show Sidebar\" keyEquivalent=\"s\" id=\"kIP-vf-haE\">\n                                <modifierMask key=\"keyEquivalentModifierMask\" control=\"YES\" command=\"YES\"/>\n                                <connections>\n                                    <action selector=\"toggleSourceList:\" target=\"-1\" id=\"iwa-gc-5KM\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Enter Full Screen\" keyEquivalent=\"f\" id=\"4J7-dP-txa\">\n                                <modifierMask key=\"keyEquivalentModifierMask\" control=\"YES\" command=\"YES\"/>\n                                <connections>\n                                    <action selector=\"toggleFullScreen:\" target=\"-1\" id=\"dU3-MA-1Rq\"/>\n                                </connections>\n                            </menuItem>\n                        </items>\n                    </menu>\n                </menuItem>\n                <menuItem title=\"Window\" id=\"aUF-d1-5bR\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <menu key=\"submenu\" title=\"Window\" systemMenu=\"window\" id=\"Td7-aD-5lo\">\n                        <items>\n                            <menuItem title=\"Minimize\" keyEquivalent=\"m\" id=\"OY7-WF-poV\">\n                                <connections>\n                                    <action selector=\"performMiniaturize:\" target=\"-1\" id=\"VwT-WD-YPe\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem title=\"Zoom\" id=\"R4o-n2-Eq4\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <connections>\n                                    <action selector=\"performZoom:\" target=\"-1\" id=\"DIl-cC-cCs\"/>\n                                </connections>\n                            </menuItem>\n                            <menuItem isSeparatorItem=\"YES\" id=\"eu3-7i-yIM\"/>\n                            <menuItem title=\"Bring All to Front\" id=\"LE2-aR-0XJ\">\n                                <modifierMask key=\"keyEquivalentModifierMask\"/>\n                                <connections>\n                                    <action selector=\"arrangeInFront:\" target=\"-1\" id=\"DRN-fu-gQh\"/>\n                                </connections>\n                            </menuItem>\n                        </items>\n                    </menu>\n                </menuItem>\n                <menuItem title=\"Help\" id=\"wpr-3q-Mcd\">\n                    <modifierMask key=\"keyEquivalentModifierMask\"/>\n                    <menu key=\"submenu\" title=\"Help\" systemMenu=\"help\" id=\"F2S-fz-NVQ\">\n                        <items>\n                            <menuItem title=\"cmdclauncher Help\" keyEquivalent=\"?\" id=\"FKE-Sm-Kum\">\n                                <connections>\n                                    <action selector=\"showHelp:\" target=\"-1\" id=\"y7X-2Q-9no\"/>\n                                </connections>\n                            </menuItem>\n                        </items>\n                    </menu>\n                </menuItem>\n            </items>\n        </menu>\n    </objects>\n</document>\n"
  },
  {
    "path": "Delivery/macOS-launcher/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIconFile</key>\n\t<string></string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>APPL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n\t<key>LSApplicationCategoryType</key>\n\t<string>public.app-category.productivity</string>\n\t<key>LSBackgroundOnly</key>\n\t<true/>\n\t<key>LSMinimumSystemVersion</key>\n\t<string>$(MACOSX_DEPLOYMENT_TARGET)</string>\n\t<key>NSHumanReadableCopyright</key>\n\t<string>Copyright © 2016 Imagin soft. All rights reserved.</string>\n\t<key>NSMainNibFile</key>\n\t<string>MainMenu</string>\n\t<key>NSPrincipalClass</key>\n\t<string>NSApplication</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "Delivery/macOS-launcher/JirassicLauncher.entitlements",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>com.apple.security.app-sandbox</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "Delivery/macOS-launcher/main.m",
    "content": "//\n//  main.m\n//\n//  Created by Cristian Baluta on 18/03/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\n#import <Cocoa/Cocoa.h>\n\nint main(int argc, const char * argv[]) {\n    return NSApplicationMain(argc, argv);\n}\n"
  },
  {
    "path": "External/AppleScriptCommands/NewTaskCommand.swift",
    "content": "//\n//  NewTaskCommand.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 08/04/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport RCPreferences\nimport RCLog\n\nclass NewTaskCommand: NSScriptCommand {\n    \n    let pref = RCPreferences<LocalPreferences>()\n    \n    override func execute() -> Any? {\n        \n        guard pref.bool(.enableJit) else {\n            RCLogErrorO(\"Jit is not enabled.\")\n            return nil\n        }\n        guard let json = arguments?[\"\"] as? String else {\n            RCLogErrorO(\"Invalid argument\")\n            return nil\n        }\n        RCLog(json)\n        let validJson = json.replacingOccurrences(of: \"'\", with: \"\\\"\")\n        \n        guard let data = validJson.data(using: String.Encoding.utf8) else {\n            return nil\n        }\n        guard let jdict = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: String], let dict = jdict else {\n            return nil\n        }\n        RCLog(dict)\n        let notes = dict[\"notes\"] ?? \"\"\n        let taskTitle = dict[\"branchName\"] ?? \"\"\n        let taskNumber = dict[\"taskNumber\"] != \"null\" ? dict[\"taskNumber\"]! : taskTitle\n        let taskType = dict[\"taskType\"] != nil\n            ? TaskType(rawValue: Int(dict[\"taskType\"]!)!)!\n            : TaskType.gitCommit\n        let informativeText = \"\\(taskNumber): \\(notes)\"\n        \n        // If the day was not started, start it now\n        let reader = ReadTasksInteractor(repository: localRepository, remoteRepository: remoteRepository)\n        let currentTasks = reader.tasksInDay(Date())\n        if currentTasks.count == 0 {\n            startDay()\n        }\n        \n        // Save task\n        let task = Task(\n            lastModifiedDate: nil,\n            startDate: nil,\n            endDate: Date(),\n            notes: notes,\n            taskNumber: taskNumber,\n            taskTitle: taskTitle,\n            taskType: taskType,\n            objectId: String.generateId()\n        )\n        let saveInteractor = TaskInteractor(repository: localRepository, remoteRepository: remoteRepository)\n        saveInteractor.saveTask(task, allowSyncing: true, completion: { savedTask in\n            \n        })\n        \n        // Notify app\n        UserNotifications().showNotification(\"Git commit added\", informativeText: informativeText)\n        InternalNotifications.notifyAboutNewlyAddedTask(task)\n        \n        return nil\n    }\n    \n    private func startDay() {\n        \n        var startDate = AppDelegate.sharedApp().sleep.lastWakeDate\n        if startDate == nil {\n            let settings: Settings = SettingsInteractor().getAppSettings()\n            startDate = settings.settingsTracking.startOfDayTime.dateByKeepingTime()\n        }\n        let comps = startDate!.components()\n        let startDayMark = Task(endDate: Date(hour: comps.hour, minute: comps.minute), type: TaskType.startDay)\n        \n        let saveInteractor = TaskInteractor(repository: localRepository, remoteRepository: remoteRepository)\n        saveInteractor.saveTask(startDayMark, allowSyncing: true, completion: { savedTask in\n            \n        })\n    }\n}\n"
  },
  {
    "path": "External/CloudKit/CloudKitRepository+Settings.swift",
    "content": "//\n//  CloudKitRepository+Settings.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 02/04/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nextension CloudKitRepository: RepositorySettings {\n    \n    func settings() -> Settings {\n        fatalError(\"Not applicable\")\n    }\n    \n    func saveSettings (_ settings: Settings) {\n        fatalError(\"Not applicable\")\n    }\n}\n"
  },
  {
    "path": "External/CloudKit/CloudKitRepository+Tasks.swift",
    "content": "//\n//  CloudKitRepository+Tasks.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 02/04/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport CloudKit\nimport RCLog\n\nextension CloudKitRepository: RepositoryTasks {\n\n    func queryTask (withId objectId: String) -> Task? {\n        fatalError(\"This method is not applicable to CloudKitRepository\")\n    }\n    \n    func queryTasks (startDate: Date, endDate: Date, predicate: NSPredicate? = nil) -> [Task] {\n        fatalError(\"This method is not applicable to CloudKitRepository\")\n    }\n\n    func queryTasks (startDate: Date, endDate: Date, predicate: NSPredicate? = nil, completion: @escaping ([Task], NSError?) -> Void) {\n        let predicate = NSPredicate(format: \"endDate >= %@ AND endDate <= %@\", startDate as CVarArg, endDate as CVarArg)\n        fetchRecords(ofType: \"Task\", predicate: predicate) { (records) in\n            completion(self.tasksFromRecords(records ?? []), nil)\n        }\n    }\n    \n    func queryUnsyncedTasks() -> [Task] {\n        fatalError(\"This method is not applicable to CloudKitRepository\")\n    }\n    \n    func queryDeletedTasks (_ completion: @escaping ([Task]) -> Void) {\n        fatalError(\"This method is not applicable to CloudKitRepository\")\n    }\n    \n    func queryUpdates (_ completion: @escaping ([Task], [String], NSError?) -> Void) {\n        \n        let changeToken = UserDefaults.standard.serverChangeToken\n        \n        fetchChangedRecords(token: changeToken, \n                            previousRecords: [], \n                            previousDeletedRecordsIds: [], \n                            completion: { (changedRecords, deletedRecordsIds) in\n                                \n            completion(self.tasksFromRecords(changedRecords), self.stringIdsFromCKRecordIds(deletedRecordsIds), nil)\n        })\n    }\n    \n    func deleteTask (_ task: Task, permanently: Bool, completion: @escaping ((_ success: Bool) -> Void)) {\n        \n        guard let privateDB = self.privateDB else {\n            RCLog(\"Not logged in\")\n            return\n        }\n        \n        fetchCKRecordOfTask(task) { (record) in\n            if let cktask = record {\n                \n                privateDB.delete(withRecordID: cktask.recordID, completionHandler: { (recordID, error) in\n                    RCLogO(recordID)\n                    RCLogErrorO(error)\n                    completion(error != nil)\n                })\n            } else {\n                completion(false)\n            }\n        }\n    }\n    \n    func deleteTask (objectId: String, completion: @escaping ((_ success: Bool) -> Void)) {\n        \n    }\n    \n    func saveTask (_ task: Task, completion: @escaping ((_ task: Task?) -> Void)) {\n        RCLogO(\"1. Save to cloudkit \\(task)\")\n        \n        guard let customZone = self.customZone, let privateDB = self.privateDB else {\n            RCLog(\"Can't save, not logged in to iCloud\")\n            return\n        }\n        \n        // Query for the task from server if exists\n        fetchCKRecordOfTask(task) { record in\n            var record: CKRecord? = record\n            // No record found on server, creating one now\n            if record == nil {\n                let recordId = CKRecord.ID(recordName: task.objectId!, zoneID: customZone.zoneID)\n                record = CKRecord(recordType: \"Task\", recordID: recordId)\n            }\n            record = self.updatedRecord(record!, withTask: task)\n            \n            privateDB.save(record!, completionHandler: { savedRecord, error in\n                \n                RCLog(\"2. Record after saving to CloudKit\")\n                RCLogO(savedRecord)\n                RCLogErrorO(error)\n                \n                if let record = savedRecord {\n                    let uploadedTask = self.taskFromRecord(record)\n                    completion(uploadedTask)\n                }\n                if let ckerror = error as? CKError {\n                    switch ckerror {\n                    case CKError.quotaExceeded:\n                        // The user has run out of iCloud storage space.\n                        // Prompt the user to go to iCloud Settings to manage storage.\n                        #warning(\"Present quotaExceeded message to the user\")\n                        break\n                    default:\n                        break\n                    }\n                    completion(nil)\n                }\n            })\n        }\n    }\n}\n\nextension CloudKitRepository {\n    \n    func fetchCKRecordOfTask (_ task: Task, completion: @escaping ((_ ctask: CKRecord?) -> Void)) {\n        \n        guard let customZone = self.customZone, let privateDB = self.privateDB else {\n            RCLog(\"Not logged in\")\n            return\n        }\n        \n        let predicate = NSPredicate(format: \"objectId == %@\", task.objectId! as CVarArg)\n        let query = CKQuery(recordType: \"Task\", predicate: predicate)\n        privateDB.perform(query, inZoneWith: customZone.zoneID) { (results: [CKRecord]?, error) in\n            \n            RCLogErrorO(error)\n            \n            if let result = results?.first {\n                completion(result)\n            } else {\n                completion(nil)\n            }\n        }\n    }\n    \n    private func tasksFromRecords (_ records: [CKRecord]) -> [Task] {\n        \n        var tasks = [Task]()\n        for record in records {\n            tasks.append( taskFromRecord(record) )\n        }\n        \n        return tasks\n    }\n    \n    private func taskFromRecord (_ record: CKRecord) -> Task {\n        \n        return Task(lastModifiedDate: record.modificationDate,\n                    startDate: record[\"startDate\"] as? Date,\n                    endDate: record[\"endDate\"] as! Date,\n                    notes: record[\"notes\"] as? String,\n                    taskNumber: record[\"taskNumber\"] as? String,\n                    taskTitle: record[\"taskTitle\"] as? String,\n                    taskType: TaskType(rawValue: (record[\"taskType\"] as! NSNumber).intValue)!,\n                    objectId: record[\"objectId\"] as? String\n        )\n    }\n    \n    private func updatedRecord (_ record: CKRecord, withTask task: Task) -> CKRecord {\n        \n        record[\"startDate\"] = task.startDate as CKRecordValue?\n        record[\"endDate\"] = task.endDate as CKRecordValue\n        record[\"notes\"] = task.notes as CKRecordValue?\n        record[\"taskNumber\"] = task.taskNumber as CKRecordValue?\n        record[\"taskTitle\"] = task.taskTitle as CKRecordValue?\n        record[\"taskType\"] = task.taskType.rawValue as CKRecordValue\n        record[\"objectId\"] = task.objectId as CKRecordValue?\n        \n        return record\n    }\n    \n    private func stringIdsFromCKRecordIds (_ ckrecords: [CKRecord.ID]) -> [String] {\n        \n        var ids = [String]()\n        for ckrecord in ckrecords {\n            ids.append( ckrecord.recordName )\n        }\n        \n        return ids\n    }\n}\n"
  },
  {
    "path": "External/CloudKit/CloudKitRepository+User.swift",
    "content": "//\n//  CloudKitRepository+User.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 02/04/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport CloudKit\n\nextension CloudKitRepository: RepositoryUser {\n    \n    func getUser (_ completion: @escaping ((_ user: User?) -> Void)) {\n        \n        CKContainer.default().accountStatus(completionHandler: { (accountStatus, error) in\n            DispatchQueue.main.async {\n                if accountStatus == .available {\n                    completion( User(email: nil, userId: nil) )\n                } else {\n                    completion( nil )\n                }\n            }\n        })\n    }\n    \n    func loginWithCredentials (_ credentials: UserCredentials, completion: (NSError?) -> Void) {\n        \n    }\n    \n    func registerWithCredentials (_ credentials: UserCredentials, completion: (NSError?) -> Void) {\n        \n    }\n    \n    func logout() {\n        user = nil\n        privateDB = nil\n        customZone = nil\n    }\n}\n"
  },
  {
    "path": "External/CloudKit/CloudKitRepository.swift",
    "content": "//\n//  CloudKitRepository.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 09/06/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\nimport CloudKit\nimport RCLog\n\nclass CloudKitRepository {\n    \n    internal var user: User?\n    internal let container = CKContainer(identifier: \"iCloud.com.jirassic.macos\")\n    internal var privateDB: CKDatabase?\n    internal var customZone: CKRecordZone?\n    \n    init() {\n        getUser { [weak self] (user) in\n            if let user = user {\n                self?.user = user\n                self?.initDB()\n            }\n        }\n    }\n    \n    func initDB() {\n        \n        privateDB = container.privateCloudDatabase\n        customZone = CKRecordZone(zoneName: \"TasksZone\")\n        \n        privateDB!.save(customZone!) { (recordZone, err) in\n            RCLogO(recordZone)\n            RCLogErrorO(err)\n        }\n    }\n}\n\nextension CloudKitRepository {\n    \n    func fetchChangedRecords (token: CKServerChangeToken?, \n                              previousRecords: [CKRecord], \n                              previousDeletedRecordsIds: [CKRecord.ID],\n                              completion: @escaping ((_ changedRecords: [CKRecord], _ deletedRecordsIds: [CKRecord.ID]) -> Void)) {\n        \n        guard let customZone = self.customZone, let privateDB = self.privateDB else {\n            RCLog(\"Not logged in\")\n            return\n        }\n        \n        var changedRecords = previousRecords\n        var deletedRecordsIds = previousDeletedRecordsIds\n        \n        let options = CKFetchRecordZoneChangesOperation.ZoneOptions()\n        options.previousServerChangeToken = token\n        \n        //        let op = CKFetchRecordZoneChangesOperation(recordZoneIDs: [customZone.zoneID], previousServerChangeToken: token)\n        let op = CKFetchRecordZoneChangesOperation(recordZoneIDs: [customZone.zoneID], optionsByRecordZoneID: [customZone.zoneID: options])\n        op.fetchAllChanges = true\n//        let op = CKFetchDatabaseChangesOperation(previousServerChangeToken: token)\n        \n        op.recordChangedBlock = { record in\n            RCLog(\"Changed record: \\(record)\")\n            changedRecords.append(record)\n        }\n        op.recordZoneChangeTokensUpdatedBlock = { zoneId, serverChangeToken, data in\n            \n        }\n        op.recordZoneFetchCompletionBlock = { zoneId, serverChangeToken, data, moreComing, error in\n            RCLogO(serverChangeToken)\n            RCLogO(data)\n            RCLogErrorO(error)\n            \n            guard error == nil else {\n                if let ckerror = error as? CKError {\n                    switch ckerror {\n                    case CKError.changeTokenExpired:\n                        // Reset the token and try to do the request again\n                        UserDefaults.standard.serverChangeToken = nil\n                        self.fetchChangedRecords(token: nil,\n                                                 previousRecords: changedRecords,\n                                                 previousDeletedRecordsIds: deletedRecordsIds,\n                                                 completion: completion)\n                        return\n                    default:\n                        break\n                    }\n                }\n                completion(changedRecords, deletedRecordsIds)\n                return\n            }\n            UserDefaults.standard.serverChangeToken = serverChangeToken\n            \n            if moreComing {\n                self.fetchChangedRecords(token: serverChangeToken,\n                                         previousRecords: changedRecords,\n                                         previousDeletedRecordsIds: deletedRecordsIds,\n                                         completion: completion)\n            } else {\n                completion(changedRecords, deletedRecordsIds)\n            }\n        }\n        op.fetchRecordZoneChangesCompletionBlock = { error in\n            \n        }\n        op.recordWithIDWasDeletedBlock = { recordID, recordType in\n            RCLog(\"Deleted recordID: \\(recordID)\")\n            deletedRecordsIds.append(recordID)\n        }\n//        op.fetchRecordChangesCompletionBlock = { serverChangeToken, data, error in\n//            \n//            \n//        }\n        \n        privateDB.add(op)\n    }\n    \n    func fetchRecords (ofType type: String, predicate: NSPredicate, completion: @escaping ((_ ctask: [CKRecord]?) -> Void)) {\n        \n        guard let customZone = self.customZone, let privateDB = self.privateDB else {\n            RCLog(\"Not logged in\")\n            return\n        }\n        \n        let query = CKQuery(recordType: type, predicate: predicate)\n        privateDB.perform(query, inZoneWith: customZone.zoneID) { (results: [CKRecord]?, error) in\n            \n            RCLogErrorO(error)\n            \n            if let results = results {\n                completion(results)\n            } else {\n                completion(nil)\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "External/CloudKit/UserDefaults+token.swift",
    "content": "//\n//  UserDefaults+token.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 09/04/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport CloudKit\n\npublic extension UserDefaults {\n    \n    var serverChangeToken: CKServerChangeToken? {\n        get {\n            guard let data = self.value(forKey: \"ChangeToken\") as? Data else {\n                return nil\n            }\n            guard let token = NSKeyedUnarchiver.unarchiveObject(with: data) as? CKServerChangeToken else {\n                return nil\n            }\n            \n            return token\n        }\n        set {\n            if let token = newValue {\n                let data = NSKeyedArchiver.archivedData(withRootObject: token)\n                self.set(data, forKey: \"ChangeToken\")\n                self.synchronize()\n            } else {\n                self.removeObject(forKey: \"ChangeToken\")\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "External/CoreData/CSettings.swift",
    "content": "//\n//  CSettings.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 17/09/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\nimport CoreData\n\nclass CSettings: NSManagedObject {\n    \n    @NSManaged var autotrack: NSNumber?\n    @NSManaged var autotrackingMode: NSNumber?\n    @NSManaged var trackLunch: NSNumber?\n    @NSManaged var trackScrum: NSNumber?\n    @NSManaged var trackMeetings: NSNumber?\n    @NSManaged var trackCodeReviews: NSNumber?\n    @NSManaged var trackWastedTime: NSNumber?\n    @NSManaged var trackStartOfDay: NSNumber?\n    @NSManaged var enableBackup: NSNumber?\n    \n    @NSManaged var startOfDayTime: Date?\n    @NSManaged var endOfDayTime: Date?\n    @NSManaged var lunchTime: Date?\n    @NSManaged var scrumTime: Date?\n    @NSManaged var minSleepDuration: NSNumber?\n    @NSManaged var minCodeRevDuration: NSNumber?\n    @NSManaged var codeRevLink: String?\n    @NSManaged var minWasteDuration: NSNumber?\n    @NSManaged var wasteLinks: [String]?\n    \n}\n"
  },
  {
    "path": "External/CoreData/CTask.swift",
    "content": "//\n//  CTask.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 01/05/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\nimport CoreData\n\n\nclass CTask: NSManagedObject {\n    \n    @NSManaged var lastModifiedDate: Date?\n    @NSManaged var markedForDeletion: NSNumber?\n    @NSManaged var startDate: Date?\n    @NSManaged var endDate: Date?\n    @NSManaged var notes: String?\n    @NSManaged var taskNumber: String?\n    @NSManaged var taskTitle: String?\n    @NSManaged var taskType: NSNumber?\n    @NSManaged var objectId: String?\n    \n}\n"
  },
  {
    "path": "External/CoreData/CUser.swift",
    "content": "//\n//  CUser.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 04/05/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\nimport CoreData\n\n\nclass CUser: NSManagedObject {\n    \n    @NSManaged var userId: String?\n    @NSManaged var email: String?\n\n}\n"
  },
  {
    "path": "External/CoreData/CoreDataRepository+Settings.swift",
    "content": "//\n//  CoreDataRepository+Settings.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 02/04/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport CoreData\n\nextension CoreDataRepository: RepositorySettings {\n    \n    func settings() -> Settings {\n        \n        let results: [CSettings] = queryWithPredicate(nil, sortDescriptors: nil)\n        var csettings: CSettings? = results.first\n        if csettings == nil {\n            // Default values\n            csettings = NSEntityDescription.insertNewObject(forEntityName: String(describing: CSettings.self),\n                                                            into: managedObjectContext!) as? CSettings\n            csettings?.autotrack = 1\n            csettings?.autotrackingMode = 1\n            csettings?.trackLunch = 1\n            csettings?.trackScrum = 1\n            csettings?.trackMeetings = 1\n            csettings?.trackCodeReviews = 1\n            csettings?.trackWastedTime = 1\n            csettings?.trackStartOfDay = 1\n            csettings?.enableBackup = 1\n            csettings?.startOfDayTime = Date(hour: 9, minute: 0)\n            csettings?.endOfDayTime = Date(hour: 17, minute: 0)\n            csettings?.lunchTime = Date(hour: 13, minute: 0)\n            csettings?.scrumTime = Date(hour: 10, minute: 30)\n            csettings?.minSleepDuration = NSNumber(value: 13)\n            csettings?.minCodeRevDuration = NSNumber(value: 3)\n            csettings?.minWasteDuration = NSNumber(value: 5)\n            csettings?.codeRevLink = \"(http|https)://(.+)/projects/(.+)/repos/(.+)/pull-requests\"\n            csettings?.wasteLinks = [\"facebook.com\", \"youtube.com\", \"twitter.com\"]\n            \n            saveContext()\n        }\n        return settingsFromCSettings(csettings!)\n    }\n    \n    func saveSettings (_ settings: Settings) {\n        \n        let _ = csettingsFromSettings(settings)\n        saveContext()\n    }\n    \n    fileprivate func settingsFromCSettings (_ csettings: CSettings) -> Settings {\n        \n        return Settings(\n            \n            enableBackup: csettings.enableBackup!.boolValue,\n            settingsTracking: SettingsTracking(\n                autotrack: csettings.autotrack!.boolValue,\n                autotrackingMode: TrackingMode(rawValue: csettings.autotrackingMode!.intValue)!,\n                trackLunch: csettings.trackLunch!.boolValue,\n                trackScrum: csettings.trackScrum!.boolValue,\n                trackMeetings: csettings.trackMeetings!.boolValue,\n                trackStartOfDay: csettings.trackStartOfDay!.boolValue,\n                startOfDayTime: csettings.startOfDayTime!,\n                endOfDayTime: csettings.endOfDayTime!,\n                lunchTime: csettings.lunchTime!,\n                scrumTime: csettings.scrumTime!,\n                minSleepDuration: csettings.minSleepDuration!.intValue\n            ),\n            settingsBrowser: SettingsBrowser(\n                trackCodeReviews: csettings.trackCodeReviews!.boolValue,\n                trackWastedTime: csettings.trackWastedTime!.boolValue,\n                minCodeRevDuration: csettings.minCodeRevDuration!.intValue,\n                codeRevLink: csettings.codeRevLink!,\n                minWasteDuration: csettings.minWasteDuration!.intValue,\n                wasteLinks: csettings.wasteLinks!\n            )\n        )\n    }\n    \n    fileprivate func csettingsFromSettings (_ settings: Settings) -> CSettings {\n        \n        let results: [CSettings] = queryWithPredicate(nil, sortDescriptors: nil)\n        var csettings: CSettings? = results.first\n        if csettings == nil {\n            csettings = NSEntityDescription.insertNewObject(forEntityName: String(describing: CSettings.self),\n                                                            into: managedObjectContext!) as? CSettings\n        }\n        \n        csettings?.autotrack = NSNumber(value: settings.settingsTracking.autotrack)\n        csettings?.autotrackingMode = NSNumber(value: settings.settingsTracking.autotrackingMode.rawValue)\n        csettings?.trackLunch = NSNumber(value: settings.settingsTracking.trackLunch)\n        csettings?.trackScrum = NSNumber(value: settings.settingsTracking.trackScrum)\n        csettings?.trackMeetings = NSNumber(value: settings.settingsTracking.trackMeetings)\n        csettings?.trackCodeReviews = NSNumber(value: settings.settingsBrowser.trackCodeReviews)\n        csettings?.trackWastedTime = NSNumber(value: settings.settingsBrowser.trackWastedTime)\n        csettings?.trackStartOfDay = NSNumber(value: settings.settingsTracking.trackStartOfDay)\n        csettings?.enableBackup = NSNumber(value: settings.enableBackup)\n        csettings?.startOfDayTime = settings.settingsTracking.startOfDayTime\n        csettings?.endOfDayTime = settings.settingsTracking.endOfDayTime\n        csettings?.lunchTime = settings.settingsTracking.lunchTime\n        csettings?.scrumTime = settings.settingsTracking.scrumTime\n        csettings?.minSleepDuration = NSNumber(value: settings.settingsTracking.minSleepDuration)\n        csettings?.minCodeRevDuration = NSNumber(value: settings.settingsBrowser.minCodeRevDuration)\n        csettings?.codeRevLink = settings.settingsBrowser.codeRevLink\n        csettings?.minWasteDuration = NSNumber(value: settings.settingsBrowser.minWasteDuration)\n        csettings?.wasteLinks = settings.settingsBrowser.wasteLinks\n        \n        return csettings!\n    }\n}\n"
  },
  {
    "path": "External/CoreData/CoreDataRepository+Tasks.swift",
    "content": "//\n//  CoreDataRepository+Tasks.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 02/04/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport CoreData\n\nextension CoreDataRepository: RepositoryTasks {\n\n    func queryTask (withId objectId: String) -> Task? {\n        #warning(\"To be implemented for ios\")\n        return nil\n    }\n    \n    func queryTasks (startDate: Date, endDate: Date, predicate: NSPredicate? = nil) -> [Task] {\n\n        let tasks = tasksBetween(startDate: startDate, endDate: endDate)\n        return tasks\n    }\n\n    func queryTasks (startDate: Date, endDate: Date, predicate: NSPredicate? = nil, completion: @escaping ([Task], NSError?) -> Void) {\n\n        let tasks = tasksBetween(startDate: startDate, endDate: endDate)\n        completion(tasks, nil)\n    }\n    \n    func queryUnsyncedTasks() -> [Task] {\n        \n        var subpredicates = [\n            NSPredicate(format: \"markedForDeletion == NO || markedForDeletion == nil\")\n        ]\n        if let lastSyncDateWithRemote = UserDefaults.standard.lastSyncDateWithRemote {\n            subpredicates.append(NSPredicate(format: \"lastModifiedDate == nil || lastModifiedDate > %@\", lastSyncDateWithRemote as CVarArg))\n        } else {\n            subpredicates.append(NSPredicate(format: \"lastModifiedDate == nil\"))\n        }\n        let compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: subpredicates)\n        let results: [CTask] = queryWithPredicate(compoundPredicate, sortDescriptors: nil)\n        let tasks = tasksFromCTasks(results)\n        \n        return tasks\n    }\n    \n    func queryDeletedTasks (_ completion: @escaping ([Task]) -> Void) {\n        \n        let predicate = NSPredicate(format: \"markedForDeletion == YES\")\n        let results: [CTask] = queryWithPredicate(predicate, sortDescriptors: nil)\n        let tasks = tasksFromCTasks(results)\n        \n        completion(tasks)\n    }\n    \n    func queryUpdates (_ completion: @escaping ([Task], [String], NSError?) -> Void) {\n        \n        completion(queryUnsyncedTasks(), [], nil)\n    }\n    \n    func deleteTask (_ task: Task, permanently: Bool, completion: @escaping ((_ success: Bool) -> Void)) {\n        \n        guard let context = managedObjectContext else {\n            return\n        }\n        \n        let ctask = ctaskFromTask(task)\n        if permanently {\n            context.delete(ctask)\n        } else {\n            ctask.markedForDeletion = NSNumber(value: true)\n        }\n        saveContext()\n        completion(true)\n    }\n    \n    func deleteTask (objectId: String, completion: @escaping ((_ success: Bool) -> Void)) {\n        \n    }\n    \n    func saveTask (_ task: Task, completion: @escaping ((_ task: Task?) -> Void)) {\n        \n        let ctask = ctaskFromTask(task)\n        saveContext()\n        \n        completion( taskFromCTask(ctask))\n    }\n}\n\nextension CoreDataRepository {\n\n    fileprivate func tasksBetween (startDate: Date, endDate: Date) -> [Task] {\n\n        let compoundPredicate = NSCompoundPredicate(andPredicateWithSubpredicates: [\n            NSPredicate(format: \"endDate >= %@ AND endDate <= %@\", startDate as CVarArg, endDate as CVarArg),\n            NSPredicate(format: \"markedForDeletion == NO || markedForDeletion == nil\")\n            ])\n        let sortDescriptors = [NSSortDescriptor(key: \"endDate\", ascending: true)]\n        let results: [CTask] = queryWithPredicate(compoundPredicate, sortDescriptors: sortDescriptors)\n        let tasks = tasksFromCTasks(results)\n\n        return tasks\n    }\n\n    fileprivate func taskFromCTask (_ ctask: CTask) -> Task {\n        \n        return Task(lastModifiedDate: ctask.lastModifiedDate,\n                    startDate: ctask.startDate,\n                    endDate: ctask.endDate!,\n                    notes: ctask.notes,\n                    taskNumber: ctask.taskNumber,\n                    taskTitle: ctask.taskTitle,\n                    taskType: TaskType(rawValue: ctask.taskType!.intValue)!,\n                    objectId: ctask.objectId!\n        )\n    }\n    \n    fileprivate func tasksFromCTasks (_ ctasks: [CTask]) -> [Task] {\n        \n        var tasks = [Task]()\n        for ctask in ctasks {\n            tasks.append(self.taskFromCTask(ctask))\n        }\n        \n        return tasks\n    }\n    \n    fileprivate func ctaskFromTask (_ task: Task) -> CTask {\n        \n        let taskPredicate = NSPredicate(format: \"objectId == %@\", task.objectId!)\n        let tasks: [CTask] = queryWithPredicate(taskPredicate, sortDescriptors: nil)\n        var ctask: CTask? = tasks.first\n        if ctask == nil {\n            ctask = NSEntityDescription.insertNewObject(forEntityName: String(describing: CTask.self),\n                                                        into: managedObjectContext!) as? CTask\n            ctask?.objectId = task.objectId\n        }\n        \n        return updatedCTask(ctask!, withTask: task)\n    }\n    \n    // Update only updatable properties. objectId can't be updated\n    fileprivate func updatedCTask (_ ctask: CTask, withTask task: Task) -> CTask {\n        \n        ctask.taskNumber = task.taskNumber\n        ctask.taskType = NSNumber(value: task.taskType.rawValue)\n        ctask.taskTitle = task.taskTitle\n        ctask.notes = task.notes\n        ctask.startDate = task.startDate\n        ctask.endDate = task.endDate\n        ctask.lastModifiedDate = task.lastModifiedDate\n        \n        return ctask\n    }\n}\n"
  },
  {
    "path": "External/CoreData/CoreDataRepository+User.swift",
    "content": "//\n//  CoreDataRepository+User.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 02/04/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport CoreData\n\nextension CoreDataRepository: RepositoryUser {\n    \n    func getUser (_ completion: @escaping ((_ user: User?) -> Void)) {\n        fatalError(\"This method is not applicable to local Repository\")\n    }\n    \n    func loginWithCredentials (_ credentials: UserCredentials, completion: (NSError?) -> Void) {\n        fatalError(\"This method is not applicable to local Repository\")\n    }\n    \n    func registerWithCredentials (_ credentials: UserCredentials, completion: (NSError?) -> Void) {\n        fatalError(\"This method is not applicable to local Repository\")\n    }\n    \n    func logout() {\n        fatalError(\"This method is not applicable to local Repository\")\n    }\n}\n"
  },
  {
    "path": "External/CoreData/CoreDataRepository.swift",
    "content": "//\n//  CoreDataRepository.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 15/04/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\nimport CoreData\nimport RCLog\n\nclass CoreDataRepository {\n    \n    internal let databaseName = \"Jirassic\"\n    \n    internal lazy var applicationDocumentsDirectory: URL = {\n        \n        #if os(iOS)\n            \n            let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)\n            return urls.last!\n            \n        #else\n            \n            let urls = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)\n            let baseUrl = urls.last!\n            let url = baseUrl.appendingPathComponent(self.databaseName)\n            RCLog(url)\n            \n            if !FileManager.default.fileExists(atPath: url.path) {\n                do {\n                    try FileManager.default.createDirectory(at: url, withIntermediateDirectories: false, attributes: nil)\n                } catch _ {\n                    return baseUrl\n                }\n            }\n            return url\n            \n        #endif\n    }()\n    \n    lazy var managedObjectContext: NSManagedObjectContext? = {\n        return self.persistentContainer.viewContext\n    }()\n    \n    lazy var persistentContainer: NSPersistentContainer = {\n        return container()\n    }()\n    \n    internal func container() -> NSPersistentContainer {\n        let url = self.applicationDocumentsDirectory.appendingPathComponent(\"\\(self.databaseName).coredata\")\n        let storeDescriptor = NSPersistentStoreDescription(url: url)\n        storeDescriptor.shouldMigrateStoreAutomatically = true\n        storeDescriptor.shouldInferMappingModelAutomatically = true\n        storeDescriptor.type = NSSQLiteStoreType\n        \n        let container = NSPersistentContainer(name: self.databaseName)\n        container.persistentStoreDescriptions = [storeDescriptor]\n        container.loadPersistentStores(completionHandler: { (storeDescription, error) in\n            if let error = error as NSError? {\n                print(\"Unresolved error \\(error), \\(error.userInfo)\")\n            }\n        })\n        container.viewContext.automaticallyMergesChangesFromParent = true\n        return container\n    }\n    \n    func saveContext () {\n        if let moc = self.managedObjectContext, moc.hasChanges {\n            try? moc.save()\n        }\n    }\n    \n    convenience init (documentsDirectory: String) {\n        self.init()\n        applicationDocumentsDirectory = URL(fileURLWithPath: documentsDirectory)\n    }\n}\n\nextension CoreDataRepository {\n    \n    internal func queryWithPredicate<T:NSManagedObject> (_ predicate: NSPredicate?, sortDescriptors: [NSSortDescriptor]?) -> [T] {\n        \n        guard let context = managedObjectContext else {\n            return []\n        }\n        \n        let request = NSFetchRequest<T>(entityName: String(describing: T.self))\n        //let request = T.fetchRequest()\n        request.returnsObjectsAsFaults = false\n        request.predicate = predicate\n        request.sortDescriptors = sortDescriptors\n        \n        do {\n            let results = try context.fetch(request)\n            return results\n        } catch _ {\n            return []\n        }\n    }\n}\n"
  },
  {
    "path": "External/CoreData/Jirassic.xcdatamodeld/.xccurrentversion",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>_XCCurrentVersionName</key>\n\t<string>Jirassic.xcdatamodel</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "External/CoreData/Jirassic.xcdatamodeld/Jirassic.xcdatamodel/contents",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<model type=\"com.apple.IDECoreDataModeler.DataModel\" documentVersion=\"1.0\" lastSavedToolsVersion=\"14460.32\" systemVersion=\"18B75\" minimumToolsVersion=\"Xcode 7.0\" sourceLanguage=\"Objective-C\" userDefinedModelVersionIdentifier=\"\">\n    <entity name=\"CSettings\" representedClassName=\".CSettings\" syncable=\"YES\">\n        <attribute name=\"autotrack\" optional=\"YES\" attributeType=\"Boolean\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n        <attribute name=\"autotrackingMode\" optional=\"YES\" attributeType=\"Integer 16\" defaultValueString=\"0\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n        <attribute name=\"codeRevLink\" optional=\"YES\" attributeType=\"String\" syncable=\"YES\"/>\n        <attribute name=\"enableBackup\" optional=\"YES\" attributeType=\"Boolean\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n        <attribute name=\"endOfDayTime\" optional=\"YES\" attributeType=\"Date\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n        <attribute name=\"lunchTime\" optional=\"YES\" attributeType=\"Date\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n        <attribute name=\"minCodeRevDuration\" optional=\"YES\" attributeType=\"Integer 16\" defaultValueString=\"0\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n        <attribute name=\"minSleepDuration\" optional=\"YES\" attributeType=\"Integer 16\" defaultValueString=\"0\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n        <attribute name=\"minWasteDuration\" optional=\"YES\" attributeType=\"Integer 16\" defaultValueString=\"0\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n        <attribute name=\"scrumTime\" optional=\"YES\" attributeType=\"Date\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n        <attribute name=\"startOfDayTime\" optional=\"YES\" attributeType=\"Date\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n        <attribute name=\"trackCodeReviews\" optional=\"YES\" attributeType=\"Boolean\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n        <attribute name=\"trackLunch\" optional=\"YES\" attributeType=\"Boolean\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n        <attribute name=\"trackMeetings\" optional=\"YES\" attributeType=\"Boolean\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n        <attribute name=\"trackScrum\" optional=\"YES\" attributeType=\"Boolean\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n        <attribute name=\"trackStartOfDay\" optional=\"YES\" attributeType=\"Boolean\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n        <attribute name=\"trackWastedTime\" optional=\"YES\" attributeType=\"Boolean\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n        <attribute name=\"wasteLinks\" optional=\"YES\" attributeType=\"Transformable\" syncable=\"YES\"/>\n    </entity>\n    <entity name=\"CTask\" representedClassName=\".CTask\" syncable=\"YES\">\n        <attribute name=\"endDate\" optional=\"YES\" attributeType=\"Date\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n        <attribute name=\"lastModifiedDate\" optional=\"YES\" attributeType=\"Date\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n        <attribute name=\"markedForDeletion\" optional=\"YES\" attributeType=\"Boolean\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n        <attribute name=\"notes\" optional=\"YES\" attributeType=\"String\" syncable=\"YES\"/>\n        <attribute name=\"objectId\" optional=\"YES\" attributeType=\"String\" syncable=\"YES\"/>\n        <attribute name=\"startDate\" optional=\"YES\" attributeType=\"Date\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n        <attribute name=\"taskNumber\" optional=\"YES\" attributeType=\"String\" syncable=\"YES\"/>\n        <attribute name=\"taskTitle\" optional=\"YES\" attributeType=\"String\" syncable=\"YES\"/>\n        <attribute name=\"taskType\" optional=\"YES\" attributeType=\"Integer 16\" defaultValueString=\"0\" usesScalarValueType=\"NO\" syncable=\"YES\"/>\n    </entity>\n    <entity name=\"CUser\" representedClassName=\".CUser\" syncable=\"YES\">\n        <attribute name=\"email\" optional=\"YES\" attributeType=\"String\" syncable=\"YES\"/>\n        <attribute name=\"userId\" optional=\"YES\" attributeType=\"String\" syncable=\"YES\"/>\n    </entity>\n    <elements>\n        <element name=\"CSettings\" positionX=\"-54\" positionY=\"45\" width=\"128\" height=\"315\"/>\n        <element name=\"CTask\" positionX=\"-63\" positionY=\"-18\" width=\"128\" height=\"180\"/>\n        <element name=\"CUser\" positionX=\"-54\" positionY=\"54\" width=\"128\" height=\"75\"/>\n    </elements>\n</model>"
  },
  {
    "path": "External/InMemoryStorage/InMemoryCoreDataRepository.swift",
    "content": "//\n//  InMemoryRepository.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 29/03/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport CoreData\n//@testable import Jirassic_no_cloud\n\n// TODO  try  to configure this so the model does not need to be in the Jirassic Appstore target but in the tests target\nclass InMemoryCoreDataRepository: CoreDataRepository {\n\t\n    override func container() -> NSPersistentContainer {\n        let storeDescriptor = NSPersistentStoreDescription()\n        storeDescriptor.shouldAddStoreAsynchronously = false\n        storeDescriptor.type = NSInMemoryStoreType\n        \n        let container = NSPersistentContainer(name: self.databaseName, managedObjectModel: self.managedObjectModel)\n        container.persistentStoreDescriptions = [storeDescriptor]\n        container.loadPersistentStores(completionHandler: { (storeDescription, error) in\n            if let error = error as NSError? {\n                print(\"Unresolved error \\(error), \\(error.userInfo)\")\n            }\n        })\n        container.viewContext.automaticallyMergesChangesFromParent = true\n        return container\n    }\n    \n    lazy var managedObjectModel: NSManagedObjectModel = {\n        let testBundle = Bundle(for: type(of: self))\n//        return NSManagedObjectModel.mergedModel(from: nil)!\n        let managedObjectModel = NSManagedObjectModel.mergedModel(from: [testBundle])\n        return managedObjectModel!\n    }()\n}\n"
  },
  {
    "path": "External/Jira/JProject.swift",
    "content": "//\n//  JProject.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 24/01/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nstruct JProject {\n    \n    var id: String\n    var key: String\n    var name: String\n    var url: String\n}\n"
  },
  {
    "path": "External/Jira/JProjectIssue.swift",
    "content": "//\n//  JProjectIssue.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 24/01/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nstruct JProjectIssue {\n    \n    var id: String\n    var key: String\n    var url: String\n}\n"
  },
  {
    "path": "External/Jira/JReport.swift",
    "content": "//\n//  JReport.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 02/07/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nstruct JReport {\n    \n    var comment: String\n    var dateStarted: String//YYYY-MM-ddT00:00:00.000+0000\n    var timeSpentSeconds: Int\n//    var author: JAuthor\n//    var issue: JIssue\n    var workAttributeValues: [JWorkAttribute]\n}\n"
  },
  {
    "path": "External/Jira/JWorkAttribute.swift",
    "content": "//\n//  JWorkAttribute.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 02/07/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nstruct JWorkAttribute {\n    \n    var value: String\n}\n"
  },
  {
    "path": "External/Jira/JiraRepository+Projects.swift",
    "content": "//\n//  JiraRepository+Projects.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 24/01/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport RCHttp\n\nextension JiraRepository {\n    \n    // GET https://.../rest/api/2/project\n    // Returns an array of projects\n    func fetchProjects (success: @escaping ([JProject]) -> Void, failure: @escaping (Error) -> Void) {\n        \n        let path = \"rest/api/2/project\"\n        request?.get(at: path, success: { responseData in\n            \n            guard let responseJson = try? JSONSerialization.jsonObject(with: responseData, options: .allowFragments),\n                let projects = responseJson as? [[String: Any]] else {\n                failure(RCHttpError(errorDescription: \"Invalid json response\"))\n                return\n            }\n            \n            var jprojects: [JProject] = []\n            for project in projects {\n                let jproject = JProject(id: project[\"id\"] as? String ?? \"\",\n                                        key: project[\"key\"] as? String ?? \"\",\n                                        name: project[\"name\"] as? String ?? \"\",\n                                        url: project[\"self\"] as? String ?? \"\")\n                jprojects.append(jproject)\n            }\n            success(jprojects)\n            \n        }, failure: { err in\n            failure(err)\n        })\n    }\n    \n    // GET https://.../rest/api/2/search?jql=project=PROJECT_KEY&fields=*none&maxResults=-1\n    // Returns a dictionary that includes an array of issues\n    func fetchProjectIssues (projectKey: String, success: @escaping ([JProjectIssue]) -> Void, failure: @escaping (Error) -> Void) {\n        \n        let path = \"rest/api/2/search?jql=project=\\(projectKey)&fields=*none&maxResults=-1\"\n        request?.get(at: path, success: { responseData in\n            \n            guard let responseJson = try? JSONSerialization.jsonObject(with: responseData, options: .allowFragments),\n                let response = responseJson as? [String: Any],\n                let issues = response[\"issues\"] as? [[String: Any]] else {\n                failure(RCHttpError(errorDescription: \"Invalid json response\"))\n                return\n            }\n            \n            var jissues: [JProjectIssue] = []\n            for issue in issues {\n                let jissue = JProjectIssue(id: issue[\"id\"] as? String ?? \"\",\n                                           key: issue[\"key\"] as? String ?? \"\",\n                                           url: issue[\"self\"] as? String ?? \"\")\n                jissues.append(jissue)\n            }\n            success(jissues)\n            \n        }, failure: { err in\n            failure(err)\n        })\n    }\n}\n"
  },
  {
    "path": "External/Jira/JiraRepository+Reports.swift",
    "content": "//\n//  Jira+Reports.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 02/07/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport RCHttp\n\nextension JiraRepository {\n    \n//    // https://.../rest/tempo-timesheets/3/worklogs/?dateFrom=2017-06-01&dateTo=2017-06-30&username=cristianbal\n//    func fetchReports (ofDay day: Date, completion: (() -> Void)?) {\n//        \n//        \n//    }\n//    \n//    func deleteReports (ofDay day: Date, completion: ((Bool) -> Void)?) {\n//        \n//    }\n    \n    // POST https://.../rest/tempo-timesheets/3/worklogs/\n    func postWorklog (_ worklog: String,\n                      duration: Double,\n                      in project: JProject,\n                      to issue: JProjectIssue,\n                      date: Date,\n                      success: @escaping (() -> Void),\n                      failure: @escaping (Error) -> Void) {\n\n        let dateStarted = date.YYYYMMddT00()//\"2017-07-03T00:00:00.000+0000\"\n        let path = \"rest/tempo-timesheets/3/worklogs\"\n        let parameters: [String: Any] = [\n            \"issue\": [\n                \"key\": issue.key,\n                \"projectId\": project.id\n            ],\n            \"author\": [\n                \"name\": self.user\n            ],\n            \"comment\": worklog,\n            \"dateStarted\": dateStarted,\n            \"timeSpentSeconds\": duration\n        ]\n        request?.post(at: path, parameters: parameters, success: { responseData in\n            \n            guard let _ = try? JSONSerialization.jsonObject(with: responseData, options: .allowFragments) else {\n                failure(RCHttpError(errorDescription: \"Invalid json response\"))\n                return\n            }\n            success()\n            \n        }, failure: { (err) in\n            failure(err)\n        })\n    }\n}\n\n//extension JiraRepository {\n//    \n//    fileprivate func reportsToJReports(_ reports: [Report]) -> [JReport] {\n//        return reports.map({ reportToJReport($0) })\n//    }\n//    \n//    fileprivate func reportToJReport(_ report: Report) -> JReport {\n//        \n//        let author = JAuthor(name: \"self.user\")\n//        let issue = JIssue(key: \"\", projectId: 0)\n//        let jreport = JReport(comment: report.notes, \n//                              dateStarted: \"\", \n//                              timeSpentSeconds: Int(report.duration), \n//                              author: author, \n//                              issue: issue, \n//                              workAttributeValues: [])\n//        \n//        return jreport\n//    }\n//    \n//    fileprivate func serializedJReports (_ jreports: [JReport]) -> [String: Any] {\n//        \n//        return [String: Any]()\n//    }\n//}\n"
  },
  {
    "path": "External/Jira/JiraRepository.swift",
    "content": "//\n//  JiraRepository.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 02/07/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport RCHttp\n\nclass JiraRepository {\n    \n    var request: RCHttp?\n    var user: String!\n    \n    init (url: String, user: String, password: String) {\n        \n        self.user = user\n        self.request = RCHttp(baseURL: url)\n        self.request?.authenticate(user: user, password: password)\n    }\n}\n"
  },
  {
    "path": "External/Keychain/Keychain.swift",
    "content": "//\n//  Keychain.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 25/03/2018.\n//  Copyright © 2018 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport SwiftKeychainWrapper\n\nclass Keychain {\n    \n    private static let key = \"jira_password\"\n    \n    class func getPassword() -> String {\n        return KeychainWrapper.standard.string(forKey: key) ?? \"\"\n    }\n    \n    class func setPassword(_ password: String?) {\n        if let password = password {\n            _ = KeychainWrapper.standard.set(password, forKey: key)\n        } else {\n            KeychainWrapper.standard.removeObject(forKey: key)\n        }\n    }\n}\n"
  },
  {
    "path": "External/RCSync.swift",
    "content": "//\n//  SyncTasks.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 02/04/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport RCLog\n\nclass RCSync<T> {\n    \n    private let localRepository: Repository!\n    private let remoteRepository: Repository!\n    private var objectsToUpload = [Task]()\n    private var objectsToDelete = [Task]()\n    \n    init (localRepository: Repository, remoteRepository: Repository) {\n        self.localRepository = localRepository\n        self.remoteRepository = remoteRepository\n    }\n    \n    func start (_ completion: @escaping ((_ hasIncomingChanges: Bool) -> Void)) {\n        \n        RCLog(\"1. Start iCloud sync\")\n        guard objectsToUpload.count == 0 || objectsToDelete.count == 0 else {\n            RCLog(\"1. Sync already in progress, not starting it again\")\n            return\n        }\n        objectsToUpload = localRepository.queryUnsyncedTasks()\n        RCLog(\"1. Nr of unsynced tasks: \\(objectsToUpload.count)\")\n        localRepository.queryDeletedTasks { deletedTasks in\n            RCLog(\"1. Nr of deleted tasks: \\(deletedTasks.count)\")\n            self.objectsToDelete = deletedTasks\n            self.syncNext { (success) in\n                self.getLatestServerChanges(completion)\n            }\n        }\n    }\n    \n    // Send to CloudKit the changes recursivelly then call the completion block\n    private func syncNext (_ completion: @escaping ((_ success: Bool) -> Void)) {\n        \n        var task = objectsToUpload.first\n        if task != nil {\n            objectsToUpload.remove(at: 0)\n            uploadTask(task!, completion: { (success) in\n                self.syncNext(completion)\n            })\n        } else {\n            task = objectsToDelete.first\n            if task != nil {\n                objectsToDelete.remove(at: 0)\n                deleteTask(task!, completion: { (success) in\n                    self.syncNext(completion)\n                })\n            } else {\n                UserDefaults.standard.lastSyncDateWithRemote = Date()\n                completion(true)\n            }\n        }\n    }\n    \n    func uploadTask (_ task: Task, completion: @escaping ((_ success: Bool) -> Void)) {\n        \n        RCLog(\"1.1 >>> Save \\(task)\")\n        _ = remoteRepository.saveTask(task) { uploadedTask in\n            guard let uploadedTask = uploadedTask else {\n                completion(false)\n                return\n            }\n            RCLog(\"1.1 Save <<< uploadedTask \\(String(describing: uploadedTask.objectId))\")\n            // After task was saved to server update it to local datastore\n            _ = self.localRepository.saveTask(uploadedTask, completion: { savedTask in\n                // If task was saved locally successful update the last sync date\n                // Otherwise last sync date will be an older date than the tasks last modified date\n                if let savedTask = savedTask {\n                    UserDefaults.standard.lastSyncDateWithRemote = savedTask.lastModifiedDate\n                }\n                completion(savedTask != nil)\n            })\n        }\n    }\n    \n    func deleteTask (_ task: Task, completion: @escaping ((_ success: Bool) -> Void)) {\n        \n        RCLog(\"1.1 Delete \\(task)\")\n        _ = remoteRepository.deleteTask(task, permanently: true) { (uploadedTask) in\n            // After task was marked as deleted to server, delete it permanently from local db\n            _ = self.localRepository.deleteTask(task, permanently: true, completion: { (task) in\n                completion(true)\n            })\n        }\n    }\n    \n    private func getLatestServerChanges (_ completion: @escaping ((_ hasIncomingChanges: Bool) -> Void)) {\n        \n        RCLog(\"2. Request latest server changes\")\n        remoteRepository.queryUpdates { changedTasks, deletedTasksIds, error in\n            RCLog(\"2. Number of changes: \\(changedTasks.count)\")\n            for task in changedTasks {\n                self.localRepository.saveTask(task, completion: { (task) in\n                    RCLog(\"2. Saved to local db \\(String(describing: task?.objectId))\")\n                })\n            }\n            RCLog(\"2. Number of deletes: \\(deletedTasksIds.count)\")\n            for remoteId in deletedTasksIds {\n                self.localRepository.deleteTask(objectId: remoteId, completion: { (success) in\n                    RCLog(\"2. Deleted from local db: \\(remoteId) \\(success)\")\n                })\n            }\n            completion(changedTasks.count > 0 || deletedTasksIds.count > 0)\n        }\n    }\n}\n"
  },
  {
    "path": "External/Realm/RSettings.swift",
    "content": "//\n//  CSettings.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 17/09/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\nimport RealmSwift\n\nclass RSettings: Object {\n    \n    dynamic var startOfDayEnabled: Bool = false\n    dynamic var lunchEnabled: Bool = false\n    dynamic var scrumEnabled: Bool = false\n    dynamic var meetingEnabled: Bool = false\n    dynamic var autoTrackEnabled: Bool = false\n    dynamic var trackingMode: Int = 0\n    \n    dynamic var startOfDayTime: Date?\n    dynamic var endOfDayTime: Date?\n    dynamic var lunchTime: Date?\n    dynamic var scrumTime: Date?\n    dynamic var minSleepDuration: Date?\n    \n}\n"
  },
  {
    "path": "External/Realm/RTask.swift",
    "content": "//\n//  CTask.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 01/05/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\nimport RealmSwift\n\nclass RTask: Object {\n    \n    dynamic var lastModifiedDate: Date?\n    dynamic var creationDate: Date?\n    dynamic var startDate: Date?\n    dynamic var endDate: Date?\n    dynamic var notes: String?\n    dynamic var taskNumber: String?\n    dynamic var taskType: Int = 0\n    dynamic var objectId: String?\n    \n}\n"
  },
  {
    "path": "External/Realm/RUser.swift",
    "content": "//\n//  CUser.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 04/05/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\nimport RealmSwift\n\nclass RUser: Object {\n    \n    dynamic var userId: String?\n    dynamic var email: String?\n    dynamic var lastSyncDate: Date?\n    dynamic var isLoggedIn: Bool = false\n\n}\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/NSError+RLMSync.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2017 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// NSError category extension providing methods to get data out of Realm's\n/// \"client reset\" error.\n@interface NSError (RLMSync)\n\n/**\n Given a Realm Object Server client reset error, return the block that can\n be called to manually initiate the client reset process, or nil if the\n error isn't a client reset error.\n */\n- (nullable void(^)(void))rlmSync_clientResetBlock NS_REFINED_FOR_SWIFT;\n\n/**\n Given a Realm Object Server client reset error, return the path where the\n backup copy of the Realm will be placed once the client reset process is\n complete.\n */\n- (nullable NSString *)rlmSync_clientResetBackedUpRealmPath NS_SWIFT_UNAVAILABLE(\"\");\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMArray.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n\n#import <Realm/RLMCollection.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@class RLMObject, RLMRealm, RLMResults<RLMObjectType: RLMObject *>, RLMNotificationToken;\n\n/**\n `RLMArray` is the container type in Realm used to define to-many relationships.\n\n Unlike an `NSArray`, `RLMArray`s hold a single type, specified by the `objectClassName` property.\n This is referred to in these docs as the “type” of the array.\n\n When declaring an `RLMArray` property, the type must be marked as conforming to a\n protocol by the same name as the objects it should contain (see the\n `RLM_ARRAY_TYPE` macro). In addition, the property can be declared using Objective-C\n generics for better compile-time type safety.\n\n     RLM_ARRAY_TYPE(ObjectType)\n     ...\n     @property RLMArray<ObjectType *><ObjectType> *arrayOfObjectTypes;\n\n `RLMArray`s can be queried with the same predicates as `RLMObject` and `RLMResult`s.\n\n `RLMArray`s cannot be created directly. `RLMArray` properties on `RLMObject`s are\n lazily created when accessed, or can be obtained by querying a Realm.\n\n ### Key-Value Observing\n\n `RLMArray` supports array key-value observing on `RLMArray` properties on `RLMObject`\n subclasses, and the `invalidated` property on `RLMArray` instances themselves is\n key-value observing compliant when the `RLMArray` is attached to a managed\n `RLMObject` (`RLMArray`s on unmanaged `RLMObject`s will never become invalidated).\n\n Because `RLMArray`s are attached to the object which they are a property of, they\n do not require using the mutable collection proxy objects from\n `-mutableArrayValueForKey:` or KVC-compatible mutation methods on the containing\n object. Instead, you can call the mutation methods on the `RLMArray` directly.\n */\n\n@interface RLMArray<RLMObjectType: RLMObject *> : NSObject<RLMCollection, NSFastEnumeration>\n\n#pragma mark - Properties\n\n/**\n The number of objects in the array.\n */\n@property (nonatomic, readonly, assign) NSUInteger count;\n\n/**\n The class name (i.e. type) of the `RLMObject`s contained in the array.\n */\n@property (nonatomic, readonly, copy) NSString *objectClassName;\n\n/**\n The Realm which manages the array. Returns `nil` for unmanaged arrays.\n */\n@property (nonatomic, readonly, nullable) RLMRealm *realm;\n\n/**\n Indicates if the array can no longer be accessed.\n */\n@property (nonatomic, readonly, getter = isInvalidated) BOOL invalidated;\n\n#pragma mark - Accessing Objects from an Array\n\n/**\n Returns the object at the index specified.\n\n @param index   The index to look up.\n\n @return An `RLMObject` of the type contained in the array.\n */\n- (RLMObjectType)objectAtIndex:(NSUInteger)index;\n\n/**\n Returns the first object in the array.\n\n Returns `nil` if called on an empty array.\n\n @return An `RLMObject` of the type contained in the array.\n */\n- (nullable RLMObjectType)firstObject;\n\n/**\n Returns the last object in the array.\n\n Returns `nil` if called on an empty array.\n\n @return An `RLMObject` of the type contained in the array.\n */\n- (nullable RLMObjectType)lastObject;\n\n\n\n#pragma mark - Adding, Removing, and Replacing Objects in an Array\n\n/**\n Adds an object to the end of the array.\n\n @warning This method may only be called during a write transaction.\n\n @param object  An `RLMObject` of the type contained in the array.\n */\n- (void)addObject:(RLMObjectType)object;\n\n/**\n Adds an array of objects to the end of the array.\n\n @warning This method may only be called during a write transaction.\n\n @param objects     An enumerable object such as `NSArray` or `RLMResults` which contains objects of the\n                    same class as the array.\n */\n- (void)addObjects:(id<NSFastEnumeration>)objects;\n\n/**\n Inserts an object at the given index.\n\n Throws an exception if the index exceeds the bounds of the array.\n\n @warning This method may only be called during a write transaction.\n\n @param anObject  An `RLMObject` of the type contained in the array.\n @param index   The index at which to insert the object.\n */\n- (void)insertObject:(RLMObjectType)anObject atIndex:(NSUInteger)index;\n\n/**\n Removes an object at the given index.\n\n Throws an exception if the index exceeds the bounds of the array.\n\n @warning This method may only be called during a write transaction.\n\n @param index   The array index identifying the object to be removed.\n */\n- (void)removeObjectAtIndex:(NSUInteger)index;\n\n/**\n Removes the last object in the array.\n\n @warning This method may only be called during a write transaction.\n*/\n- (void)removeLastObject;\n\n/**\n Removes all objects from the array.\n\n @warning This method may only be called during a write transaction.\n */\n- (void)removeAllObjects;\n\n/**\n Replaces an object at the given index with a new object.\n\n Throws an exception if the index exceeds the bounds of the array.\n\n @warning This method may only be called during a write transaction.\n\n @param index       The index of the object to be replaced.\n @param anObject    An object (of the same type as returned from the `objectClassName` selector).\n */\n- (void)replaceObjectAtIndex:(NSUInteger)index withObject:(RLMObjectType)anObject;\n\n/**\n Moves the object at the given source index to the given destination index.\n\n Throws an exception if the index exceeds the bounds of the array.\n\n @warning This method may only be called during a write transaction.\n\n @param sourceIndex      The index of the object to be moved.\n @param destinationIndex The index to which the object at `sourceIndex` should be moved.\n */\n- (void)moveObjectAtIndex:(NSUInteger)sourceIndex toIndex:(NSUInteger)destinationIndex;\n\n/**\n Exchanges the objects in the array at given indices.\n\n Throws an exception if either index exceeds the bounds of the array.\n\n @warning This method may only be called during a write transaction.\n\n @param index1 The index of the object which should replace the object at index `index2`.\n @param index2 The index of the object which should replace the object at index `index1`.\n */\n- (void)exchangeObjectAtIndex:(NSUInteger)index1 withObjectAtIndex:(NSUInteger)index2;\n\n#pragma mark - Querying an Array\n\n/**\n Returns the index of an object in the array.\n\n Returns `NSNotFound` if the object is not found in the array.\n\n @param object  An object (of the same type as returned from the `objectClassName` selector).\n */\n- (NSUInteger)indexOfObject:(RLMObjectType)object;\n\n/**\n Returns the index of the first object in the array matching the predicate.\n\n @param predicateFormat A predicate format string, optionally followed by a variable number of arguments.\n\n @return    The index of the object, or `NSNotFound` if the object is not found in the array.\n */\n- (NSUInteger)indexOfObjectWhere:(NSString *)predicateFormat, ...;\n\n/// :nodoc:\n- (NSUInteger)indexOfObjectWhere:(NSString *)predicateFormat args:(va_list)args;\n\n/**\n Returns the index of the first object in the array matching the predicate.\n\n @param predicate   The predicate with which to filter the objects.\n\n @return    The index of the object, or `NSNotFound` if the object is not found in the array.\n */\n- (NSUInteger)indexOfObjectWithPredicate:(NSPredicate *)predicate;\n\n/**\n Returns all the objects matching the given predicate in the array.\n\n @param predicateFormat A predicate format string, optionally followed by a variable number of arguments.\n\n @return                An `RLMResults` of objects that match the given predicate.\n */\n- (RLMResults<RLMObjectType> *)objectsWhere:(NSString *)predicateFormat, ...;\n\n/// :nodoc:\n- (RLMResults<RLMObjectType> *)objectsWhere:(NSString *)predicateFormat args:(va_list)args;\n\n/**\n Returns all the objects matching the given predicate in the array.\n\n @param predicate   The predicate with which to filter the objects.\n\n @return            An `RLMResults` of objects that match the given predicate\n */\n- (RLMResults<RLMObjectType> *)objectsWithPredicate:(NSPredicate *)predicate;\n\n/**\n Returns a sorted `RLMResults` from the array.\n\n @param keyPath     The key path to sort by.\n @param ascending   The direction to sort in.\n\n @return    An `RLMResults` sorted by the specified key path.\n */\n- (RLMResults<RLMObjectType> *)sortedResultsUsingKeyPath:(NSString *)keyPath ascending:(BOOL)ascending;\n\n/**\n Returns a sorted `RLMResults` from the array.\n\n @param property    The property name to sort by.\n @param ascending   The direction to sort in.\n\n @return    An `RLMResults` sorted by the specified property.\n */\n- (RLMResults<RLMObjectType> *)sortedResultsUsingProperty:(NSString *)property ascending:(BOOL)ascending\n    __deprecated_msg(\"Use `-sortedResultsUsingKeyPath:ascending:`\");\n\n/**\n Returns a sorted `RLMResults` from the array.\n\n @param properties  An array of `RLMSortDescriptor`s to sort by.\n\n @return    An `RLMResults` sorted by the specified properties.\n */\n- (RLMResults<RLMObjectType> *)sortedResultsUsingDescriptors:(NSArray<RLMSortDescriptor *> *)properties;\n\n/// :nodoc:\n- (RLMObjectType)objectAtIndexedSubscript:(NSUInteger)index;\n\n/// :nodoc:\n- (void)setObject:(RLMObjectType)newValue atIndexedSubscript:(NSUInteger)index;\n\n#pragma mark - Notifications\n\n/**\n Registers a block to be called each time the array changes.\n\n The block will be asynchronously called with the initial array, and then\n called again after each write transaction which changes any of the objects in\n the array, which objects are in the results, or the order of the objects in the\n array.\n\n The `changes` parameter will be `nil` the first time the block is called.\n For each call after that, it will contain information about\n which rows in the array were added, removed or modified. If a write transaction\n did not modify any objects in the array, the block is not called at all.\n See the `RLMCollectionChange` documentation for information on how the changes\n are reported and an example of updating a `UITableView`.\n\n If an error occurs the block will be called with `nil` for the results\n parameter and a non-`nil` error. Currently the only errors that can occur are\n when opening the Realm on the background worker thread.\n\n Notifications are delivered via the standard run loop, and so can't be\n delivered while the run loop is blocked by other activity. When\n notifications can't be delivered instantly, multiple notifications may be\n coalesced into a single notification. This can include the notification\n with the initial results. For example, the following code performs a write\n transaction immediately after adding the notification block, so there is no\n opportunity for the initial notification to be delivered first. As a\n result, the initial notification will reflect the state of the Realm after\n the write transaction.\n\n     Person *person = [[Person allObjectsInRealm:realm] firstObject];\n     NSLog(@\"person.dogs.count: %zu\", person.dogs.count); // => 0\n     self.token = [person.dogs addNotificationBlock(RLMArray<Dog *> *dogs,\n                                                    RLMCollectionChange *changes,\n                                                    NSError *error) {\n         // Only fired once for the example\n         NSLog(@\"dogs.count: %zu\", dogs.count) // => 1\n     }];\n     [realm transactionWithBlock:^{\n         Dog *dog = [[Dog alloc] init];\n         dog.name = @\"Rex\";\n         [person.dogs addObject:dog];\n     }];\n     // end of run loop execution context\n\n You must retain the returned token for as long as you want updates to continue\n to be sent to the block. To stop receiving updates, call `-stop` on the token.\n\n @warning This method cannot be called during a write transaction, or when the\n          containing Realm is read-only.\n @warning This method may only be called on a managed array.\n\n @param block The block to be called each time the array changes.\n @return A token which must be held for as long as you want updates to be delivered.\n */\n- (RLMNotificationToken *)addNotificationBlock:(void (^)(RLMArray<RLMObjectType> *__nullable array,\n                                                         RLMCollectionChange *__nullable changes,\n                                                         NSError *__nullable error))block __attribute__((warn_unused_result));\n\n#pragma mark - Unavailable Methods\n\n/**\n `-[RLMArray init]` is not available because `RLMArray`s cannot be created directly.\n `RLMArray` properties on `RLMObject`s are lazily created when accessed, or can be obtained by querying a Realm.\n */\n- (instancetype)init __attribute__((unavailable(\"RLMArrays cannot be created directly\")));\n\n/**\n `+[RLMArray new]` is not available because `RLMArray`s cannot be created directly.\n `RLMArray` properties on `RLMObject`s are lazily created when accessed, or can be obtained by querying a Realm.\n */\n+ (instancetype)new __attribute__((unavailable(\"RLMArrays cannot be created directly\")));\n\n@end\n\n/// :nodoc:\n@interface RLMArray (Swift)\n// for use only in Swift class definitions\n- (instancetype)initWithObjectClassName:(NSString *)objectClassName;\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMCollection.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n\n#import \"RLMThreadSafeReference.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@class RLMRealm, RLMResults, RLMObject, RLMSortDescriptor, RLMNotificationToken, RLMCollectionChange;\n\n/**\n A homogenous collection of `RLMObject` instances. Examples of conforming types include `RLMArray`,\n `RLMResults`, and `RLMLinkingObjects`.\n */\n@protocol RLMCollection <NSFastEnumeration, RLMThreadConfined>\n\n@required\n\n#pragma mark - Properties\n\n/**\n The number of objects in the collection.\n */\n@property (nonatomic, readonly, assign) NSUInteger count;\n\n/**\n The class name (i.e. type) of the `RLMObject`s contained in the collection.\n */\n@property (nonatomic, readonly, copy) NSString *objectClassName;\n\n/**\n The Realm which manages the collection, or `nil` for unmanaged collections.\n */\n@property (nonatomic, readonly) RLMRealm *realm;\n\n#pragma mark - Accessing Objects from a Collection\n\n/**\n Returns the object at the index specified.\n\n @param index   The index to look up.\n\n @return An `RLMObject` of the type contained in the collection.\n */\n- (id)objectAtIndex:(NSUInteger)index;\n\n/**\n Returns the first object in the collection.\n\n Returns `nil` if called on an empty collection.\n\n @return An `RLMObject` of the type contained in the collection.\n */\n- (nullable id)firstObject;\n\n/**\n Returns the last object in the collection.\n\n Returns `nil` if called on an empty collection.\n\n @return An `RLMObject` of the type contained in the collection.\n */\n- (nullable id)lastObject;\n\n#pragma mark - Querying a Collection\n\n/**\n Returns the index of an object in the collection.\n\n Returns `NSNotFound` if the object is not found in the collection.\n\n @param object  An object (of the same type as returned from the `objectClassName` selector).\n */\n- (NSUInteger)indexOfObject:(RLMObject *)object;\n\n/**\n Returns the index of the first object in the collection matching the predicate.\n\n @param predicateFormat A predicate format string, optionally followed by a variable number of arguments.\n\n @return    The index of the object, or `NSNotFound` if the object is not found in the collection.\n */\n- (NSUInteger)indexOfObjectWhere:(NSString *)predicateFormat, ...;\n\n/// :nodoc:\n- (NSUInteger)indexOfObjectWhere:(NSString *)predicateFormat args:(va_list)args;\n\n/**\n Returns the index of the first object in the collection matching the predicate.\n\n @param predicate   The predicate with which to filter the objects.\n\n @return    The index of the object, or `NSNotFound` if the object is not found in the collection.\n */\n- (NSUInteger)indexOfObjectWithPredicate:(NSPredicate *)predicate;\n\n/**\n Returns all objects matching the given predicate in the collection.\n\n @param predicateFormat A predicate format string, optionally followed by a variable number of arguments.\n\n @return    An `RLMResults` containing objects that match the given predicate.\n */\n- (RLMResults *)objectsWhere:(NSString *)predicateFormat, ...;\n\n/// :nodoc:\n- (RLMResults *)objectsWhere:(NSString *)predicateFormat args:(va_list)args;\n\n/**\n Returns all objects matching the given predicate in the collection.\n\n @param predicate   The predicate with which to filter the objects.\n\n @return            An `RLMResults` containing objects that match the given predicate.\n */\n- (RLMResults *)objectsWithPredicate:(NSPredicate *)predicate;\n\n/**\n Returns a sorted `RLMResults` from the collection.\n\n @param keyPath     The keyPath to sort by.\n @param ascending   The direction to sort in.\n\n @return    An `RLMResults` sorted by the specified key path.\n */\n- (RLMResults *)sortedResultsUsingKeyPath:(NSString *)keyPath ascending:(BOOL)ascending;\n\n/**\n Returns a sorted `RLMResults` from the collection.\n\n @param property    The property name to sort by.\n @param ascending   The direction to sort in.\n\n @return    An `RLMResults` sorted by the specified property.\n */\n- (RLMResults *)sortedResultsUsingProperty:(NSString *)property ascending:(BOOL)ascending\n    __deprecated_msg(\"Use `-sortedResultsUsingKeyPath:ascending:`\");\n\n/**\n Returns a sorted `RLMResults` from the collection.\n\n @param properties  An array of `RLMSortDescriptor`s to sort by.\n\n @return    An `RLMResults` sorted by the specified properties.\n */\n- (RLMResults *)sortedResultsUsingDescriptors:(NSArray<RLMSortDescriptor *> *)properties;\n\n/// :nodoc:\n- (id)objectAtIndexedSubscript:(NSUInteger)index;\n\n/**\n Returns an `NSArray` containing the results of invoking `valueForKey:` using `key` on each of the collection's objects.\n\n @param key The name of the property.\n\n @return An `NSArray` containing results.\n */\n- (nullable id)valueForKey:(NSString *)key;\n\n/**\n Invokes `setValue:forKey:` on each of the collection's objects using the specified `value` and `key`.\n\n @warning This method may only be called during a write transaction.\n\n @param value The object value.\n @param key   The name of the property.\n */\n- (void)setValue:(nullable id)value forKey:(NSString *)key;\n\n#pragma mark - Notifications\n\n/**\n Registers a block to be called each time the collection changes.\n\n The block will be asynchronously called with the initial collection, and then\n called again after each write transaction which changes either any of the\n objects in the collection, or which objects are in the collection.\n\n The `change` parameter will be `nil` the first time the block is called.\n For each call after that, it will contain information about\n which rows in the collection were added, removed or modified. If a write transaction\n did not modify any objects in this collection, the block is not called at all.\n See the `RLMCollectionChange` documentation for information on how the changes\n are reported and an example of updating a `UITableView`.\n\n If an error occurs the block will be called with `nil` for the collection\n parameter and a non-`nil` error. Currently the only errors that can occur are\n when opening the Realm on the background worker thread.\n\n At the time when the block is called, the collection object will be fully\n evaluated and up-to-date, and as long as you do not perform a write transaction\n on the same thread or explicitly call `-[RLMRealm refresh]`, accessing it will\n never perform blocking work.\n\n Notifications are delivered via the standard run loop, and so can't be\n delivered while the run loop is blocked by other activity. When\n notifications can't be delivered instantly, multiple notifications may be\n coalesced into a single notification. This can include the notification\n with the initial collection. For example, the following code performs a write\n transaction immediately after adding the notification block, so there is no\n opportunity for the initial notification to be delivered first. As a\n result, the initial notification will reflect the state of the Realm after\n the write transaction.\n\n     id<RLMCollection> collection = [Dog allObjects];\n     NSLog(@\"dogs.count: %zu\", dogs.count); // => 0\n     self.token = [collection addNotificationBlock:^(id<RLMCollection> dogs,\n                                                  RLMCollectionChange *changes,\n                                                  NSError *error) {\n         // Only fired once for the example\n         NSLog(@\"dogs.count: %zu\", dogs.count); // => 1\n     }];\n     [realm transactionWithBlock:^{\n         Dog *dog = [[Dog alloc] init];\n         dog.name = @\"Rex\";\n         [realm addObject:dog];\n     }];\n     // end of run loop execution context\n\n You must retain the returned token for as long as you want updates to continue\n to be sent to the block. To stop receiving updates, call `-stop` on the token.\n\n @warning This method cannot be called during a write transaction, or when the\n          containing Realm is read-only.\n\n @param block The block to be called each time the collection changes.\n @return A token which must be held for as long as you want collection notifications to be delivered.\n */\n- (RLMNotificationToken *)addNotificationBlock:(void (^)(id<RLMCollection> __nullable collection,\n                                                         RLMCollectionChange *__nullable change,\n                                                         NSError *__nullable error))block __attribute__((warn_unused_result));\n\n@end\n\n/**\n An `RLMSortDescriptor` stores a property name and a sort order for use with\n `sortedResultsUsingDescriptors:`. It is similar to `NSSortDescriptor`, but supports\n only the subset of functionality which can be efficiently run by Realm's query\n engine.\n \n `RLMSortDescriptor` instances are immutable.\n */\n@interface RLMSortDescriptor : NSObject\n\n#pragma mark - Properties\n\n/**\n The key path which the sort descriptor orders results by.\n */\n@property (nonatomic, readonly) NSString *keyPath;\n\n/**\n Whether the descriptor sorts in ascending or descending order.\n */\n@property (nonatomic, readonly) BOOL ascending;\n\n#pragma mark - Methods\n\n/**\n Returns a new sort descriptor for the given key path and sort direction.\n */\n+ (instancetype)sortDescriptorWithKeyPath:(NSString *)keyPath ascending:(BOOL)ascending;\n\n/**\n Returns a copy of the receiver with the sort direction reversed.\n */\n- (instancetype)reversedSortDescriptor;\n\n#pragma mark - Deprecated\n\n/**\n The name of the property which the sort descriptor orders results by.\n */\n@property (nonatomic, readonly) NSString *property __deprecated_msg(\"Use `-keyPath`\");\n\n/**\n Returns a new sort descriptor for the given property name and sort direction.\n */\n+ (instancetype)sortDescriptorWithProperty:(NSString *)propertyName ascending:(BOOL)ascending\n    __deprecated_msg(\"Use `+sortDescriptorWithKeyPath:ascending:`\");\n\n@end\n\n/**\n A `RLMCollectionChange` object encapsulates information about changes to collections\n that are reported by Realm notifications.\n\n `RLMCollectionChange` is passed to the notification blocks registered with\n `-addNotificationBlock` on `RLMArray` and `RLMResults`, and reports what rows in the\n collection changed since the last time the notification block was called.\n\n The change information is available in two formats: a simple array of row\n indices in the collection for each type of change, and an array of index paths\n in a requested section suitable for passing directly to `UITableView`'s batch\n update methods. A complete example of updating a `UITableView` named `tv`:\n\n     [tv beginUpdates];\n     [tv deleteRowsAtIndexPaths:[changes deletionsInSection:0] withRowAnimation:UITableViewRowAnimationAutomatic];\n     [tv insertRowsAtIndexPaths:[changes insertionsInSection:0] withRowAnimation:UITableViewRowAnimationAutomatic];\n     [tv reloadRowsAtIndexPaths:[changes modificationsInSection:0] withRowAnimation:UITableViewRowAnimationAutomatic];\n     [tv endUpdates];\n\n All of the arrays in an `RLMCollectionChange` are always sorted in ascending order.\n */\n@interface RLMCollectionChange : NSObject\n/// The indices of objects in the previous version of the collection which have\n/// been removed from this one.\n@property (nonatomic, readonly) NSArray<NSNumber *> *deletions;\n\n/// The indices in the new version of the collection which were newly inserted.\n@property (nonatomic, readonly) NSArray<NSNumber *> *insertions;\n\n/**\n The indices in the new version of the collection which were modified.\n \n For `RLMResults`, this means that one or more of the properties of the object at\n that index were modified (or an object linked to by that object was\n modified).\n \n For `RLMArray`, the array itself being modified to contain a\n different object at that index will also be reported as a modification.\n */\n@property (nonatomic, readonly) NSArray<NSNumber *> *modifications;\n\n/// Returns the index paths of the deletion indices in the given section.\n- (NSArray<NSIndexPath *> *)deletionsInSection:(NSUInteger)section;\n\n/// Returns the index paths of the insertion indices in the given section.\n- (NSArray<NSIndexPath *> *)insertionsInSection:(NSUInteger)section;\n\n/// Returns the index paths of the modification indices in the given section.\n- (NSArray<NSIndexPath *> *)modificationsInSection:(NSUInteger)section;\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMConstants.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n// For compatibility with Xcode 7, before extensible string enums were introduced,\n#ifdef NS_EXTENSIBLE_STRING_ENUM\n#define RLM_EXTENSIBLE_STRING_ENUM NS_EXTENSIBLE_STRING_ENUM\n#define RLM_EXTENSIBLE_STRING_ENUM_CASE_SWIFT_NAME(_, extensible_string_enum) NS_SWIFT_NAME(extensible_string_enum)\n#else\n#define RLM_EXTENSIBLE_STRING_ENUM\n#define RLM_EXTENSIBLE_STRING_ENUM_CASE_SWIFT_NAME(fully_qualified, _) NS_SWIFT_NAME(fully_qualified)\n#endif\n\n#if __has_attribute(ns_error_domain) && (!defined(__cplusplus) || !__cplusplus || __cplusplus >= 201103L)\n#define RLM_ERROR_ENUM(type, name, domain) \\\n    _Pragma(\"clang diagnostic push\") \\\n    _Pragma(\"clang diagnostic ignored \\\"-Wignored-attributes\\\"\") \\\n    NS_ENUM(type, __attribute__((ns_error_domain(domain))) name) \\\n    _Pragma(\"clang diagnostic pop\")\n#else\n#define RLM_ERROR_ENUM(type, name, domain) NS_ENUM(type, name)\n#endif\n\n\n#pragma mark - Enums\n\n/**\n `RLMPropertyType` is an enumeration describing all property types supported in Realm models.\n\n For more information, see [Realm Models](https://realm.io/docs/objc/latest/#models).\n */\n// Make sure numbers match those in <realm/data_type.hpp>\ntypedef NS_ENUM(int32_t, RLMPropertyType) {\n\n#pragma mark - Primitive types\n\n    /** Integers: `NSInteger`, `int`, `long`, `Int` (Swift) */\n    RLMPropertyTypeInt    = 0,\n    /** Booleans: `BOOL`, `bool`, `Bool` (Swift) */\n    RLMPropertyTypeBool   = 1,\n    /** Floating-point numbers: `float`, `Float` (Swift) */\n    RLMPropertyTypeFloat  = 9,\n    /** Double-precision floating-point numbers: `double`, `Double` (Swift) */\n    RLMPropertyTypeDouble = 10,\n\n#pragma mark - Object types\n\n    /** Strings: `NSString`, `String` (Swift) */\n    RLMPropertyTypeString = 2,\n    /** Binary data: `NSData` */\n    RLMPropertyTypeData   = 4,\n    /** \n     Any object: `id`.\n     \n     This property type is no longer supported for new models. However, old models with any-typed properties are still\n     supported for migration purposes.\n     */\n    RLMPropertyTypeAny    = 6,\n    /** Dates: `NSDate` */\n    RLMPropertyTypeDate   = 8,\n\n#pragma mark - Array/Linked object types\n\n    /** Realm model objects. See [Realm Models](https://realm.io/docs/objc/latest/#models) for more information. */\n    RLMPropertyTypeObject = 12,\n    /** Realm arrays. See [Realm Models](https://realm.io/docs/objc/latest/#models) for more information. */\n    RLMPropertyTypeArray  = 13,\n    /** Realm linking objects. See [Realm Models](https://realm.io/docs/objc/latest/#models) for more information. */\n    RLMPropertyTypeLinkingObjects = 14,\n};\n\n/** An error domain identifying Realm-specific errors. */\nextern NSString * const RLMErrorDomain;\n\n/** An error domain identifying non-specific system errors. */\nextern NSString * const RLMUnknownSystemErrorDomain;\n\n/**\n `RLMError` is an enumeration representing all recoverable errors. It is associated with the\n Realm error domain specified in `RLMErrorDomain`.\n */\ntypedef RLM_ERROR_ENUM(NSInteger, RLMError, RLMErrorDomain) {\n    /** Denotes a general error that occurred when trying to open a Realm. */\n    RLMErrorFail                  = 1,\n\n    /** Denotes a file I/O error that occurred when trying to open a Realm. */\n    RLMErrorFileAccess            = 2,\n\n    /** \n     Denotes a file permission error that ocurred when trying to open a Realm.\n     \n     This error can occur if the user does not have permission to open or create\n     the specified file in the specified access mode when opening a Realm.\n     */\n    RLMErrorFilePermissionDenied  = 3,\n\n    /** Denotes an error where a file was to be written to disk, but another file with the same name already exists. */\n    RLMErrorFileExists            = 4,\n\n    /**\n     Denotes an error that occurs if a file could not be found.\n     \n     This error may occur if a Realm file could not be found on disk when trying to open a\n     Realm as read-only, or if the directory part of the specified path was not found when\n     trying to write a copy.\n     */\n    RLMErrorFileNotFound          = 5,\n\n    /** \n     Denotes an error that occurs if a file format upgrade is required to open the file,\n     but upgrades were explicitly disabled.\n     */\n    RLMErrorFileFormatUpgradeRequired = 6,\n\n    /** \n     Denotes an error that occurs if the database file is currently open in another\n     process which cannot share with the current process due to an\n     architecture mismatch.\n     \n     This error may occur if trying to share a Realm file between an i386 (32-bit) iOS\n     Simulator and the Realm Browser application. In this case, please use the 64-bit\n     version of the iOS Simulator.\n     */\n    RLMErrorIncompatibleLockFile  = 8,\n\n    /** Denotes an error that occurs when there is insufficient available address space. */\n    RLMErrorAddressSpaceExhausted = 9,\n\n    /** Denotes an error that occurs if there is a schema version mismatch, so that a migration is required. */\n    RLMErrorSchemaMismatch = 10,\n};\n\n#pragma mark - Constants\n\n#pragma mark - Notification Constants\n\n/**\n A notification indicating that changes were made to a Realm.\n*/\ntypedef NSString * RLMNotification RLM_EXTENSIBLE_STRING_ENUM;\n\n/**\n This notification is posted by a Realm when the data in that Realm has changed.\n\n More specifically, this notification is posted after a Realm has been refreshed to\n reflect a write transaction. This can happen when an autorefresh occurs, when\n `-[RLMRealm refresh]` is called, after an implicit refresh from `-[RLMRealm beginWriteTransaction]`,\n or after a local write transaction is completed.\n */\nextern RLMNotification const RLMRealmRefreshRequiredNotification\nRLM_EXTENSIBLE_STRING_ENUM_CASE_SWIFT_NAME(RLMRealmRefreshRequiredNotification, RefreshRequired);\n\n/**\n This notification is posted by a Realm when a write transaction has been\n committed to a Realm on a different thread for the same file.\n\n It is not posted if `-[RLMRealm autorefresh]` is enabled, or if the Realm is\n refreshed before the notification has a chance to run.\n\n Realms with autorefresh disabled should normally install a handler for this\n notification which calls `-[RLMRealm refresh]` after doing some work. Refreshing\n the Realm is optional, but not refreshing the Realm may lead to large Realm\n files. This is because Realm must keep an extra copy of the data for the stale\n Realm.\n */\nextern RLMNotification const RLMRealmDidChangeNotification\nRLM_EXTENSIBLE_STRING_ENUM_CASE_SWIFT_NAME(RLMRealmDidChangeNotification, DidChange);\n\n#pragma mark - Other Constants\n\n/** The schema version used for uninitialized Realms */\nextern const uint64_t RLMNotVersioned;\n\n/** The corresponding value is the name of an exception thrown by Realm. */\nextern NSString * const RLMExceptionName;\n\n/** The corresponding value is a Realm file version. */\nextern NSString * const RLMRealmVersionKey;\n\n/** The corresponding key is the version of the underlying database engine. */\nextern NSString * const RLMRealmCoreVersionKey;\n\n/** The corresponding key is the Realm invalidated property name. */\nextern NSString * const RLMInvalidatedKey;\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMMigration.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@class RLMSchema;\n@class RLMArray;\n@class RLMObject;\n\n/**\n A block type which provides both the old and new versions of an object in the Realm. Object \n properties can only be accessed using keyed subscripting.\n \n @see `-[RLMMigration enumerateObjects:block:]`\n \n @param oldObject The object from the original Realm (read-only).\n @param newObject The object from the migrated Realm (read-write).\n*/\ntypedef void (^RLMObjectMigrationBlock)(RLMObject * __nullable oldObject, RLMObject * __nullable newObject);\n\n/**\n `RLMMigration` instances encapsulate information intended to facilitate a schema migration.\n \n A `RLMMigration` instance is passed into a user-defined `RLMMigrationBlock` block when updating\n the version of a Realm. This instance provides access to the old and new database schemas, the\n objects in the Realm, and provides functionality for modifying the Realm during the migration.\n */\n@interface RLMMigration : NSObject\n\n#pragma mark - Properties\n\n/**\n Returns the old `RLMSchema`. This is the schema which describes the Realm before the\n migration is applied.\n */\n@property (nonatomic, readonly) RLMSchema *oldSchema;\n\n/**\n Returns the new `RLMSchema`. This is the schema which describes the Realm after the\n migration is applied.\n */\n@property (nonatomic, readonly) RLMSchema *newSchema;\n\n\n#pragma mark - Altering Objects during a Migration\n\n/**\n Enumerates all the objects of a given type in the Realm, providing both the old and new versions\n of each object. Within the block, object properties can only be accessed using keyed subscripting.\n\n @param className   The name of the `RLMObject` class to enumerate.\n\n @warning   All objects returned are of a type specific to the current migration and should not be cast\n            to `className`. Instead, treat them as `RLMObject`s and use keyed subscripting to access\n            properties.\n */\n- (void)enumerateObjects:(NSString *)className block:(__attribute__((noescape)) RLMObjectMigrationBlock)block;\n\n/**\n Creates and returns an `RLMObject` instance of type `className` in the Realm being migrated.\n \n The `value` argument is used to populate the object. It can be a key-value coding compliant object, an array or \n dictionary returned from the methods in `NSJSONSerialization`, or an array containing one element for each managed\n property. An exception will be thrown if any required properties are not present and those properties were not defined\n with default values.\n\n When passing in an `NSArray` as the `value` argument, all properties must be present, valid and in the same order as\n the properties defined in the model.\n\n @param className   The name of the `RLMObject` class to create.\n @param value       The value used to populate the object.\n */\n- (RLMObject *)createObject:(NSString *)className withValue:(id)value;\n\n/**\n Deletes an object from a Realm during a migration.\n\n It is permitted to call this method from within the block passed to `-[enumerateObjects:block:]`.\n\n @param object  Object to be deleted from the Realm being migrated.\n */\n- (void)deleteObject:(RLMObject *)object;\n\n/**\n Deletes the data for the class with the given name.\n\n All objects of the given class will be deleted. If the `RLMObject` subclass no longer exists in your program,\n any remaining metadata for the class will be removed from the Realm file.\n\n @param  name The name of the `RLMObject` class to delete.\n\n @return A Boolean value indicating whether there was any data to delete.\n */\n- (BOOL)deleteDataForClassName:(NSString *)name;\n\n/**\n Renames a property of the given class from `oldName` to `newName`.\n\n @param className The name of the class whose property should be renamed. This class must be present\n                  in both the old and new Realm schemas.\n @param oldName   The old name for the property to be renamed. There must not be a property with this name in the\n                  class as defined by the new Realm schema.\n @param newName   The new name for the property to be renamed. There must not be a property with this name in the\n                  class as defined by the old Realm schema.\n */\n- (void)renamePropertyForClass:(NSString *)className oldName:(NSString *)oldName newName:(NSString *)newName;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMObject.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n\n#import <Realm/RLMObjectBase.h>\n#import <Realm/RLMThreadSafeReference.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@class RLMNotificationToken;\n@class RLMObjectSchema;\n@class RLMPropertyChange;\n@class RLMPropertyDescriptor;\n@class RLMRealm;\n@class RLMResults;\n\n/**\n `RLMObject` is a base class for model objects representing data stored in Realms.\n\n Define your model classes by subclassing `RLMObject` and adding properties to be managed.\n Then instantiate and use your custom subclasses instead of using the `RLMObject` class directly.\n\n     // Dog.h\n     @interface Dog : RLMObject\n     @property NSString *name;\n     @property BOOL      adopted;\n     @end\n\n     // Dog.m\n     @implementation Dog\n     @end //none needed\n\n ### Supported property types\n\n - `NSString`\n - `NSInteger`, `int`, `long`, `float`, and `double`\n - `BOOL` or `bool`\n - `NSDate`\n - `NSData`\n - `NSNumber<X>`, where `X` is one of `RLMInt`, `RLMFloat`, `RLMDouble` or `RLMBool`, for optional number properties\n - `RLMObject` subclasses, to model many-to-one relationships.\n - `RLMArray<X>`, where `X` is an `RLMObject` subclass, to model many-to-many relationships.\n\n ### Querying\n\n You can initiate queries directly via the class methods: `allObjects`, `objectsWhere:`, and `objectsWithPredicate:`.\n These methods allow you to easily query a custom subclass for instances of that class in the default Realm.\n\n To search in a Realm other than the default Realm, use the `allObjectsInRealm:`, `objectsInRealm:where:`,\n and `objectsInRealm:withPredicate:` class methods.\n\n @see `RLMRealm`\n\n ### Relationships\n\n See our [Cocoa guide](https://realm.io/docs/objc/latest#relationships) for more details.\n\n ### Key-Value Observing\n\n All `RLMObject` properties (including properties you create in subclasses) are\n [Key-Value Observing compliant](https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/KeyValueObserving/KeyValueObserving.html),\n except for `realm` and `objectSchema`.\n\n Keep the following tips in mind when observing Realm objects:\n\n 1. Unlike `NSMutableArray` properties, `RLMArray` properties do not require\n    using the proxy object returned from `-mutableArrayValueForKey:`, or defining\n    KVC mutation methods on the containing class. You can simply call methods on\n    the `RLMArray` directly; any changes will be automatically observed by the containing\n    object.\n 2. Unmanaged `RLMObject` instances cannot be added to a Realm while they have any\n    observed properties.\n 3. Modifying managed `RLMObject`s within `-observeValueForKeyPath:ofObject:change:context:`\n    is not recommended. Properties may change even when the Realm is not in a write\n    transaction (for example, when `-[RLMRealm refresh]` is called after changes\n    are made on a different thread), and notifications sent prior to the change\n    being applied (when `NSKeyValueObservingOptionPrior` is used) may be sent at\n    times when you *cannot* begin a write transaction.\n */\n\n@interface RLMObject : RLMObjectBase <RLMThreadConfined>\n\n#pragma mark - Creating & Initializing Objects\n\n/**\n Creates an unmanaged instance of a Realm object.\n\n Call `addObject:` on an `RLMRealm` instance to add an unmanaged object into that Realm.\n\n @see `[RLMRealm addObject:]`\n */\n- (instancetype)init NS_DESIGNATED_INITIALIZER;\n\n\n/**\n Creates an unmanaged instance of a Realm object.\n\n Pass in an `NSArray` or `NSDictionary` instance to set the values of the object's properties.\n\n Call `addObject:` on an `RLMRealm` instance to add an unmanaged object into that Realm.\n\n @see `[RLMRealm addObject:]`\n */\n- (instancetype)initWithValue:(id)value NS_DESIGNATED_INITIALIZER;\n\n\n/**\n Returns the class name for a Realm object subclass.\n\n @warning Do not override. Realm relies on this method returning the exact class\n          name.\n\n @return  The class name for the model class.\n */\n+ (NSString *)className;\n\n/**\n Creates an instance of a Realm object with a given value, and adds it to the default Realm.\n\n If nested objects are included in the argument, `createInDefaultRealmWithValue:` will be recursively called\n on them.\n\n The `value` argument can be a key-value coding compliant object, an array or dictionary returned from the methods in\n `NSJSONSerialization`, or an array containing one element for each managed property. An exception will be thrown if\n any required properties are not present and those properties were not defined with default values.\n\n When passing in an array as the `value` argument, all properties must be present, valid and in the same order as the\n properties defined in the model.\n\n @param value    The value used to populate the object.\n\n @see   `defaultPropertyValues`\n */\n+ (instancetype)createInDefaultRealmWithValue:(id)value;\n\n/**\n Creates an instance of a Realm object with a given value, and adds it to the specified Realm.\n\n If nested objects are included in the argument, `createInRealm:withValue:` will be recursively called\n on them.\n\n The `value` argument can be a key-value coding compliant object, an array or dictionary returned from the methods in\n `NSJSONSerialization`, or an array containing one element for each managed property. An exception will be thrown if any\n required properties are not present and those properties were not defined with default values.\n\n When passing in an array as the `value` argument, all properties must be present, valid and in the same order as the\n properties defined in the model.\n\n @param realm    The Realm which should manage the newly-created object.\n @param value    The value used to populate the object.\n\n @see   `defaultPropertyValues`\n */\n+ (instancetype)createInRealm:(RLMRealm *)realm withValue:(id)value;\n\n/**\n Creates or updates a Realm object within the default Realm.\n\n This method may only be called on Realm object types with a primary key defined. If there is already\n an object with the same primary key value in the default Realm, its values are updated and the object\n is returned. Otherwise, this method creates and populates a new instance of the object in the default Realm.\n\n If nested objects are included in the argument, `createOrUpdateInDefaultRealmWithValue:` will be\n recursively called on them if they have primary keys, `createInDefaultRealmWithValue:` if they do not.\n\n If the argument is a Realm object already managed by the default Realm, the argument's type is the same\n as the receiver, and the objects have identical values for their managed properties, this method does nothing.\n\n The `value` argument is used to populate the object. It can be a key-value coding compliant object, an array or\n dictionary returned from the methods in `NSJSONSerialization`, or an array containing one element for each managed\n property. An exception will be thrown if any required properties are not present and those properties were not defined\n with default values.\n\n When passing in an array as the `value` argument, all properties must be present, valid and in the same order as the\n properties defined in the model.\n\n @param value    The value used to populate the object.\n\n @see   `defaultPropertyValues`, `primaryKey`\n */\n+ (instancetype)createOrUpdateInDefaultRealmWithValue:(id)value;\n\n/**\n Creates or updates an Realm object within a specified Realm.\n\n This method may only be called on Realm object types with a primary key defined. If there is already\n an object with the same primary key value in the given Realm, its values are updated and the object\n is returned. Otherwise this method creates and populates a new instance of this object in the given Realm.\n\n If nested objects are included in the argument, `createOrUpdateInRealm:withValue:` will be\n recursively called on them if they have primary keys, `createInRealm:withValue:` if they do not.\n\n If the argument is a Realm object already managed by the given Realm, the argument's type is the same\n as the receiver, and the objects have identical values for their managed properties, this method does nothing.\n\n The `value` argument is used to populate the object. It can be a key-value coding compliant object, an array or\n dictionary returned from the methods in `NSJSONSerialization`, or an array containing one element for each managed\n property. An exception will be thrown if any required properties are not present and those properties were not defined\n with default values.\n\n When passing in an array as the `value` argument, all properties must be present, valid and in the same order as the\n properties defined in the model.\n\n @param realm    The Realm which should own the object.\n @param value    The value used to populate the object.\n\n @see   `defaultPropertyValues`, `primaryKey`\n */\n+ (instancetype)createOrUpdateInRealm:(RLMRealm *)realm withValue:(id)value;\n\n#pragma mark - Properties\n\n/**\n The Realm which manages the object, or `nil` if the object is unmanaged.\n */\n@property (nonatomic, readonly, nullable) RLMRealm *realm;\n\n/**\n The object schema which lists the managed properties for the object.\n */\n@property (nonatomic, readonly) RLMObjectSchema *objectSchema;\n\n/**\n Indicates if the object can no longer be accessed because it is now invalid.\n\n An object can no longer be accessed if the object has been deleted from the Realm that manages it, or\n if `invalidate` is called on that Realm.\n */\n@property (nonatomic, readonly, getter = isInvalidated) BOOL invalidated;\n\n\n#pragma mark - Customizing your Objects\n\n/**\n Returns an array of property names for properties which should be indexed.\n\n Only string, integer, boolean, and `NSDate` properties are supported.\n\n @return    An array of property names.\n */\n+ (NSArray<NSString *> *)indexedProperties;\n\n/**\n Override this method to specify the default values to be used for each property.\n\n @return    A dictionary mapping property names to their default values.\n */\n+ (nullable NSDictionary *)defaultPropertyValues;\n\n/**\n Override this method to specify the name of a property to be used as the primary key.\n\n Only properties of types `RLMPropertyTypeString` and `RLMPropertyTypeInt` can be designated as the primary key.\n Primary key properties enforce uniqueness for each value whenever the property is set, which incurs minor overhead.\n Indexes are created automatically for primary key properties.\n\n @return    The name of the property designated as the primary key.\n */\n+ (nullable NSString *)primaryKey;\n\n/**\n Override this method to specify the names of properties to ignore. These properties will not be managed by the Realm\n that manages the object.\n\n @return    An array of property names to ignore.\n */\n+ (nullable NSArray<NSString *> *)ignoredProperties;\n\n/**\n Override this method to specify the names of properties that are non-optional (i.e. cannot be assigned a `nil` value).\n\n By default, all properties of a type whose values can be set to `nil` are considered optional properties.\n To require that an object in a Realm always store a non-`nil` value for a property,\n add the name of the property to the array returned from this method.\n\n Properties of `RLMObject` type cannot be non-optional. Array and `NSNumber` properties\n can be non-optional, but there is no reason to do so: arrays do not support storing nil, and\n if you want a non-optional number you should instead use the primitive type.\n\n @return    An array of property names that are required.\n */\n+ (NSArray<NSString *> *)requiredProperties;\n\n/**\n Override this method to provide information related to properties containing linking objects.\n\n Each property of type `RLMLinkingObjects` must have a key in the dictionary returned by this method consisting\n of the property name. The corresponding value must be an instance of `RLMPropertyDescriptor` that describes the class\n and property that the property is linked to.\n\n     return @{ @\"owners\": [RLMPropertyDescriptor descriptorWithClass:Owner.class propertyName:@\"dogs\"] };\n\n @return     A dictionary mapping property names to `RLMPropertyDescriptor` instances.\n */\n+ (NSDictionary<NSString *, RLMPropertyDescriptor *> *)linkingObjectsProperties;\n\n\n#pragma mark - Getting & Querying Objects from the Default Realm\n\n/**\n Returns all objects of this object type from the default Realm.\n\n @return    An `RLMResults` containing all objects of this type in the default Realm.\n */\n+ (RLMResults *)allObjects;\n\n/**\n Returns all objects of this object type matching the given predicate from the default Realm.\n\n @param predicateFormat A predicate format string, optionally followed by a variable number of arguments.\n\n @return    An `RLMResults` containing all objects of this type in the default Realm that match the given predicate.\n */\n+ (RLMResults *)objectsWhere:(NSString *)predicateFormat, ...;\n\n/// :nodoc:\n+ (RLMResults *)objectsWhere:(NSString *)predicateFormat args:(va_list)args;\n\n\n/**\n Returns all objects of this object type matching the given predicate from the default Realm.\n\n @param predicate   The predicate with which to filter the objects.\n\n @return    An `RLMResults` containing all objects of this type in the default Realm that match the given predicate.\n */\n+ (RLMResults *)objectsWithPredicate:(nullable NSPredicate *)predicate;\n\n/**\n Retrieves the single instance of this object type with the given primary key from the default Realm.\n\n Returns the object from the default Realm which has the given primary key, or\n `nil` if the object does not exist. This is slightly faster than the otherwise\n equivalent `[[SubclassName objectsWhere:@\"primaryKeyPropertyName = %@\", key] firstObject]`.\n\n This method requires that `primaryKey` be overridden on the receiving subclass.\n\n @return    An object of this object type, or `nil` if an object with the given primary key does not exist.\n @see       `-primaryKey`\n */\n+ (nullable instancetype)objectForPrimaryKey:(nullable id)primaryKey;\n\n\n#pragma mark - Querying Specific Realms\n\n/**\n Returns all objects of this object type from the specified Realm.\n\n @param realm   The Realm to query.\n\n @return        An `RLMResults` containing all objects of this type in the specified Realm.\n */\n+ (RLMResults *)allObjectsInRealm:(RLMRealm *)realm;\n\n/**\n Returns all objects of this object type matching the given predicate from the specified Realm.\n\n @param predicateFormat A predicate format string, optionally followed by a variable number of arguments.\n @param realm           The Realm to query.\n\n @return    An `RLMResults` containing all objects of this type in the specified Realm that match the given predicate.\n */\n+ (RLMResults *)objectsInRealm:(RLMRealm *)realm where:(NSString *)predicateFormat, ...;\n\n/// :nodoc:\n+ (RLMResults *)objectsInRealm:(RLMRealm *)realm where:(NSString *)predicateFormat args:(va_list)args;\n\n/**\n Returns all objects of this object type matching the given predicate from the specified Realm.\n\n @param predicate   A predicate to use to filter the elements.\n @param realm       The Realm to query.\n\n @return    An `RLMResults` containing all objects of this type in the specified Realm that match the given predicate.\n */\n+ (RLMResults *)objectsInRealm:(RLMRealm *)realm withPredicate:(nullable NSPredicate *)predicate;\n\n/**\n Retrieves the single instance of this object type with the given primary key from the specified Realm.\n\n Returns the object from the specified Realm which has the given primary key, or\n `nil` if the object does not exist. This is slightly faster than the otherwise\n equivalent `[[SubclassName objectsInRealm:realm where:@\"primaryKeyPropertyName = %@\", key] firstObject]`.\n\n This method requires that `primaryKey` be overridden on the receiving subclass.\n\n @return    An object of this object type, or `nil` if an object with the given primary key does not exist.\n @see       `-primaryKey`\n */\n+ (nullable instancetype)objectInRealm:(RLMRealm *)realm forPrimaryKey:(nullable id)primaryKey;\n\n#pragma mark - Notifications\n\n/**\n A callback block for `RLMObject` notifications.\n\n If the object is deleted from the managing Realm, the block is called with\n `deleted` set to `YES` and the other two arguments are `nil`. The block will\n never be called again after this.\n\n If the object is modified, the block will be called with `deleted` set to\n `NO`, a `nil` error, and an array of `RLMPropertyChange` objects which\n indicate which properties of the objects were modified.\n\n If an error occurs, `deleted` will be `NO`, `changes` will be `nil`, and\n `error` will include information about the error. The block will never be\n called again after an error occurs.\n */\ntypedef void (^RLMObjectChangeBlock)(BOOL deleted,\n                                     NSArray<RLMPropertyChange *> *_Nullable changes,\n                                     NSError *_Nullable error);\n\n/**\n Registers a block to be called each time the object changes.\n\n The block will be asynchronously called after each write transaction which\n deletes the object or modifies any of the managed properties of the object,\n including self-assignments that set a property to its existing value.\n\n For write transactions performed on different threads or in differen\n processes, the block will be called when the managing Realm is\n (auto)refreshed to a version including the changes, while for local write\n transactions it will be called at some point in the future after the write\n transaction is committed.\n\n Notifications are delivered via the standard run loop, and so can't be\n delivered while the run loop is blocked by other activity. When notifications\n can't be delivered instantly, multiple notifications may be coalesced into a\n single notification.\n\n Unlike with `RLMArray` and `RLMResults`, there is no \"initial\" callback made\n after you add a new notification block.\n\n Only objects which are managed by a Realm can be observed in this way. You\n must retain the returned token for as long as you want updates to be sent to\n the block. To stop receiving updates, call `stop` on the token.\n\n It is safe to capture a strong reference to the observed object within the\n callback block. There is no retain cycle due to that the callback is retained\n by the returned token and not by the object itself.\n\n @warning This method cannot be called during a write transaction, when the\n          containing Realm is read-only, or on an unmanaged object.\n\n @param block The block to be called whenever a change occurs.\n @return A token which must be held for as long as you want updates to be delivered.\n */\n- (RLMNotificationToken *)addNotificationBlock:(RLMObjectChangeBlock)block;\n\n#pragma mark - Other Instance Methods\n\n/**\n Returns YES if another Realm object instance points to the same object as the receiver in the Realm managing\n the receiver.\n\n For object types with a primary, key, `isEqual:` is overridden to use this method (along with a corresponding\n implementation for `hash`).\n\n @param object  The object to compare the receiver to.\n\n @return    Whether the object represents the same object as the receiver.\n */\n- (BOOL)isEqualToObject:(RLMObject *)object;\n\n#pragma mark - Dynamic Accessors\n\n/// :nodoc:\n- (nullable id)objectForKeyedSubscript:(NSString *)key;\n\n/// :nodoc:\n- (void)setObject:(nullable id)obj forKeyedSubscript:(NSString *)key;\n\n@end\n\n/**\n Information about a specific property which changed in an `RLMObject` change notification.\n */\n@interface RLMPropertyChange : NSObject\n\n/**\n The name of the property which changed.\n */\n@property (nonatomic, readonly, strong) NSString *name;\n\n/**\n The value of the property before the change occurred. This will always be `nil`\n if the change happened on the same thread as the notification and for `RLMArray`\n properties.\n\n For object properties this will give the object which was previously linked to,\n but that object will have its new values and not the values it had before the\n changes. This means that `previousValue` may be a deleted object, and you will\n need to check `invalidated` before accessing any of its properties.\n */\n@property (nonatomic, readonly, strong, nullable) id previousValue;\n\n/**\n The value of the property after the change occurred. This will always be `nil`\n for `RLMArray` properties.\n */\n@property (nonatomic, readonly, strong, nullable) id value;\n@end\n\n#pragma mark - RLMArray Property Declaration\n\n/**\n Properties on `RLMObject`s of type `RLMArray` must have an associated type. A type is associated\n with an `RLMArray` property by defining a protocol for the object type that the array should contain.\n To define the protocol for an object, you can use the macro RLM_ARRAY_TYPE:\n\n     RLM_ARRAY_TYPE(ObjectType)\n     ...\n     @property RLMArray<ObjectType *><ObjectType> *arrayOfObjectTypes;\n  */\n#define RLM_ARRAY_TYPE(RLM_OBJECT_SUBCLASS)\\\n@protocol RLM_OBJECT_SUBCLASS <NSObject>   \\\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMObjectBase.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@class RLMRealm;\n@class RLMSchema;\n@class RLMObjectSchema;\n\n/// :nodoc:\n@interface RLMObjectBase : NSObject\n\n@property (nonatomic, readonly, getter = isInvalidated) BOOL invalidated;\n\n- (instancetype)init NS_DESIGNATED_INITIALIZER;\n\n+ (NSString *)className;\n\n// Returns whether the class is included in the default set of classes managed by a Realm.\n+ (BOOL)shouldIncludeInDefaultSchema;\n\n+ (nullable NSString *)_realmObjectName;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMObjectBase_Dynamic.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Realm/RLMObject.h>\n\n@class RLMObjectSchema, RLMRealm;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n Returns the Realm that manages the object, if one exists.\n \n @warning  This function is useful only in specialized circumstances, for example, when building components\n           that integrate with Realm. If you are simply building an app on Realm, it is\n           recommended to retrieve the Realm that manages the object via `RLMObject`.\n\n @param object\tAn `RLMObjectBase` obtained via a Swift `Object` or `RLMObject`.\n \n @return The Realm which manages this object. Returns `nil `for unmanaged objects.\n */\nFOUNDATION_EXTERN RLMRealm * _Nullable RLMObjectBaseRealm(RLMObjectBase * _Nullable object);\n\n/**\n Returns an `RLMObjectSchema` which describes the managed properties of the object.\n \n @warning  This function is useful only in specialized circumstances, for example, when building components\n           that integrate with Realm. If you are simply building an app on Realm, it is\n           recommended to retrieve `objectSchema` via `RLMObject`.\n\n @param object\tAn `RLMObjectBase` obtained via a Swift `Object` or `RLMObject`.\n \n @return The object schema which lists the managed properties for the object.\n */\nFOUNDATION_EXTERN RLMObjectSchema * _Nullable RLMObjectBaseObjectSchema(RLMObjectBase * _Nullable object);\n\n/**\n Returns the object corresponding to a key value.\n\n @warning  This function is useful only in specialized circumstances, for example, when building components\n           that integrate with Realm. If you are simply building an app on Realm, it is\n           recommended to retrieve key values via `RLMObject`.\n\n @warning Will throw an `NSUndefinedKeyException` if `key` is not present on the object.\n \n @param object\tAn `RLMObjectBase` obtained via a Swift `Object` or `RLMObject`.\n @param key\t\tThe name of the property.\n \n @return The object for the property requested.\n */\nFOUNDATION_EXTERN id _Nullable RLMObjectBaseObjectForKeyedSubscript(RLMObjectBase * _Nullable object, NSString *key);\n\n/**\n Sets a value for a key on the object.\n \n @warning  This function is useful only in specialized circumstances, for example, when building components\n           that integrate with Realm. If you are simply building an app on Realm, it is\n           recommended to set key values via `RLMObject`.\n\n @warning Will throw an `NSUndefinedKeyException` if `key` is not present on the object.\n \n @param object\tAn `RLMObjectBase` obtained via a Swift `Object` or `RLMObject`.\n @param key\t\tThe name of the property.\n @param obj\t\tThe object to set as the value of the key.\n */\nFOUNDATION_EXTERN void RLMObjectBaseSetObjectForKeyedSubscript(RLMObjectBase * _Nullable object, NSString *key, id _Nullable obj);\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMObjectSchema.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@class RLMProperty;\n\n/**\n This class represents Realm model object schemas.\n\n When using Realm, `RLMObjectSchema` instances allow performing migrations and\n introspecting the database's schema.\n\n Object schemas map to tables in the core database.\n */\n@interface RLMObjectSchema : NSObject<NSCopying>\n\n#pragma mark - Properties\n\n/**\n An array of `RLMProperty` instances representing the managed properties of a class described by the schema.\n \n @see `RLMProperty`\n */\n@property (nonatomic, readonly, copy) NSArray<RLMProperty *> *properties;\n\n/**\n The name of the class the schema describes.\n */\n@property (nonatomic, readonly) NSString *className;\n\n/**\n The property which serves as the primary key for the class the schema describes, if any.\n */\n@property (nonatomic, readonly, nullable) RLMProperty *primaryKeyProperty;\n\n#pragma mark - Methods\n\n/**\n Retrieves an `RLMProperty` object by the property name.\n \n @param propertyName The property's name.\n \n @return An `RLMProperty` object, or `nil` if there is no property with the given name.\n */\n- (nullable RLMProperty *)objectForKeyedSubscript:(NSString *)propertyName;\n\n/**\n Returns whether two `RLMObjectSchema` instances are equal.\n */\n- (BOOL)isEqualToObjectSchema:(RLMObjectSchema *)objectSchema;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMPlatform.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#if TARGET_OS_IPHONE\n#error Attempting to use Realm's OSX framework in an iOS project.\n#endif\n\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMProperty.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n#import <Realm/RLMConstants.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// :nodoc:\n@protocol RLMInt\n@end\n\n/// :nodoc:\n@protocol RLMBool\n@end\n\n/// :nodoc:\n@protocol RLMDouble\n@end\n\n/// :nodoc:\n@protocol RLMFloat\n@end\n\n/// :nodoc:\n@interface NSNumber ()<RLMInt, RLMBool, RLMDouble, RLMFloat>\n@end\n\n/**\n `RLMProperty` instances represent properties managed by a Realm in the context of an object schema. Such properties may\n be persisted to a Realm file or computed from other data from the Realm.\n \n When using Realm, `RLMProperty` instances allow performing migrations and introspecting the database's schema.\n \n These property instances map to columns in the core database.\n */\n@interface RLMProperty : NSObject\n\n#pragma mark - Properties\n\n/**\n The name of the property.\n */\n@property (nonatomic, readonly) NSString *name;\n\n/**\n The type of the property.\n \n @see `RLMPropertyType`\n */\n@property (nonatomic, readonly) RLMPropertyType type;\n\n/**\n Indicates whether this property is indexed.\n \n @see `RLMObject`\n */\n@property (nonatomic, readonly) BOOL indexed;\n\n/**\n For `RLMObject` and `RLMArray` properties, the name of the class of object stored in the property.\n */\n@property (nonatomic, readonly, copy, nullable) NSString *objectClassName;\n\n/**\n For linking objects properties, the property name of the property the linking objects property is linked to.\n */\n@property (nonatomic, readonly, copy, nullable) NSString *linkOriginPropertyName;\n\n/**\n Indicates whether this property is optional.\n */\n@property (nonatomic, readonly) BOOL optional;\n\n#pragma mark - Methods\n\n/**\n Returns whether a given property object is equal to the receiver.\n */\n- (BOOL)isEqualToProperty:(RLMProperty *)property;\n\n@end\n\n\n/**\n An `RLMPropertyDescriptor` instance represents a specific property on a given class.\n */\n@interface RLMPropertyDescriptor : NSObject\n\n/**\n Creates and returns a property descriptor.\n\n @param objectClass  The class of this property descriptor.\n @param propertyName The name of this property descriptor.\n */\n+ (instancetype)descriptorWithClass:(Class)objectClass propertyName:(NSString *)propertyName;\n\n/// The class of the property.\n@property (nonatomic, readonly) Class objectClass;\n\n/// The name of the property.\n@property (nonatomic, readonly) NSString *propertyName;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMRealm.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n#import \"RLMConstants.h\"\n\n@class RLMRealmConfiguration, RLMObject, RLMSchema, RLMMigration, RLMNotificationToken, RLMThreadSafeReference;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n An `RLMRealm` instance (also referred to as \"a Realm\") represents a Realm\n database.\n\n Realms can either be stored on disk (see `+[RLMRealm realmWithURL:]`) or in\n memory (see `RLMRealmConfiguration`).\n\n `RLMRealm` instances are cached internally, and constructing equivalent `RLMRealm`\n objects (for example, by using the same path or identifier) multiple times on a single thread\n within a single iteration of the run loop will normally return the same\n `RLMRealm` object.\n\n If you specifically want to ensure an `RLMRealm` instance is\n destroyed (for example, if you wish to open a Realm, check some property, and\n then possibly delete the Realm file and re-open it), place the code which uses\n the Realm within an `@autoreleasepool {}` and ensure you have no other\n strong references to it.\n\n @warning `RLMRealm` instances are not thread safe and cannot be shared across\n threads or dispatch queues. Trying to do so will cause an exception to be thrown.\n You must call this method on each thread you want\n to interact with the Realm on. For dispatch queues, this means that you must\n call it in each block which is dispatched, as a queue is not guaranteed to run\n all of its blocks on the same thread.\n */\n\n@interface RLMRealm : NSObject\n\n#pragma mark - Creating & Initializing a Realm\n\n/**\n Obtains an instance of the default Realm.\n\n The default Realm is used by the `RLMObject` class methods\n which do not take an `RLMRealm` parameter, but is otherwise not special. The\n default Realm is persisted as *default.realm* under the *Documents* directory of\n your Application on iOS, and in your application's *Application Support*\n directory on OS X.\n\n The default Realm is created using the default `RLMRealmConfiguration`, which\n can be changed via `+[RLMRealmConfiguration setDefaultConfiguration:]`.\n\n @return The default `RLMRealm` instance for the current thread.\n */\n+ (instancetype)defaultRealm;\n\n/**\n Obtains an `RLMRealm` instance with the given configuration.\n\n @param configuration A configuration object to use when creating the Realm.\n @param error         If an error occurs, upon return contains an `NSError` object\n                      that describes the problem. If you are not interested in\n                      possible errors, pass in `NULL`.\n\n @return An `RLMRealm` instance.\n */\n+ (nullable instancetype)realmWithConfiguration:(RLMRealmConfiguration *)configuration error:(NSError **)error;\n\n/**\n Obtains an `RLMRealm` instance persisted at a specified file URL.\n\n @param fileURL The local URL of the file the Realm should be saved at.\n\n @return An `RLMRealm` instance.\n */\n+ (instancetype)realmWithURL:(NSURL *)fileURL;\n\n/**\n The `RLMSchema` used by the Realm.\n */\n@property (nonatomic, readonly) RLMSchema *schema;\n\n/**\n Indicates if the Realm is currently engaged in a write transaction.\n\n @warning   Do not simply check this property and then start a write transaction whenever an object needs to be\n            created, updated, or removed. Doing so might cause a large number of write transactions to be created,\n            degrading performance. Instead, always prefer performing multiple updates during a single transaction.\n */\n@property (nonatomic, readonly) BOOL inWriteTransaction;\n\n/**\n The `RLMRealmConfiguration` object that was used to create this `RLMRealm` instance.\n */\n@property (nonatomic, readonly) RLMRealmConfiguration *configuration;\n\n/**\n Indicates if this Realm contains any objects.\n */\n@property (nonatomic, readonly) BOOL isEmpty;\n\n#pragma mark - Notifications\n\n/**\n The type of a block to run whenever the data within the Realm is modified.\n\n @see `-[RLMRealm addNotificationBlock:]`\n */\ntypedef void (^RLMNotificationBlock)(RLMNotification notification, RLMRealm *realm);\n\n#pragma mark - Receiving Notification when a Realm Changes\n\n/**\n Adds a notification handler for changes in this Realm, and returns a notification token.\n\n Notification handlers are called after each write transaction is committed,\n either on the current thread or other threads.\n\n Handler blocks are called on the same thread that they were added on, and may\n only be added on threads which are currently within a run loop. Unless you are\n specifically creating and running a run loop on a background thread, this will\n normally only be the main thread.\n\n The block has the following definition:\n\n     typedef void(^RLMNotificationBlock)(RLMNotification notification, RLMRealm *realm);\n\n It receives the following parameters:\n\n - `NSString` \\***notification**:    The name of the incoming notification. See\n                                     `RLMRealmNotification` for information on what\n                                     notifications are sent.\n - `RLMRealm` \\***realm**:           The Realm for which this notification occurred.\n\n @param block   A block which is called to process Realm notifications.\n\n @return A token object which must be retained as long as you wish to continue\n         receiving change notifications.\n */\n- (RLMNotificationToken *)addNotificationBlock:(RLMNotificationBlock)block __attribute__((warn_unused_result));\n\n#pragma mark - Transactions\n\n\n#pragma mark - Writing to a Realm\n\n/**\n Begins a write transaction on the Realm.\n\n Only one write transaction can be open at a time for each Realm file. Write\n transactions cannot be nested, and trying to begin a write transaction on a\n Realm which is already in a write transaction will throw an exception. Calls to\n `beginWriteTransaction` from `RLMRealm` instances for the same Realm file in\n other threads or other processes will block until the current write transaction\n completes or is cancelled.\n\n Before beginning the write transaction, `beginWriteTransaction` updates the\n `RLMRealm` instance to the latest Realm version, as if `refresh` had been\n called, and generates notifications if applicable. This has no effect if the\n Realm was already up to date.\n\n It is rarely a good idea to have write transactions span multiple cycles of\n the run loop, but if you do wish to do so you will need to ensure that the\n Realm participating in the write transaction is kept alive until the write\n transaction is committed.\n */\n- (void)beginWriteTransaction;\n\n/**\n Commits all write operations in the current write transaction, and ends the\n transaction.\n\n After saving the changes, all notification blocks registered on this specific\n `RLMRealm` instance are invoked synchronously. Notification blocks registered\n on other threads or on collections are invoked asynchronously. If you do not\n want to receive a specific notification for this write tranaction, see\n `commitWriteTransactionWithoutNotifying:error:`.\n\n This method can fail if there is insufficient disk space available to save the\n writes made, or due to unexpected i/o errors. This version of the method throws\n an exception when errors occur. Use the version with a `NSError` out parameter\n instead if you wish to handle errors.\n\n @warning This method may only be called during a write transaction.\n */\n- (void)commitWriteTransaction NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Commits all write operations in the current write transaction, and ends the\n transaction.\n\n After saving the changes, all notification blocks registered on this specific\n `RLMRealm` instance are invoked synchronously. Notification blocks registered\n on other threads or on collections are invoked asynchronously. If you do not\n want to receive a specific notification for this write tranaction, see\n `commitWriteTransactionWithoutNotifying:error:`.\n\n This method can fail if there is insufficient disk space available to save the\n writes made, or due to unexpected i/o errors.\n\n @warning This method may only be called during a write transaction.\n\n @param error If an error occurs, upon return contains an `NSError` object\n              that describes the problem. If you are not interested in\n              possible errors, pass in `NULL`.\n\n @return Whether the transaction succeeded.\n */\n- (BOOL)commitWriteTransaction:(NSError **)error;\n\n/**\n Commits all write operations in the current write transaction, without\n notifying specific notification blocks of the changes.\n\n After saving the changes, all notification blocks registered on this specific\n `RLMRealm` instance are invoked synchronously. Notification blocks registered\n on other threads or on collections are scheduled to be invoked asynchronously.\n\n You can skip notifiying specific notification blocks about the changes made\n in this write transaction by passing in their associated notification tokens.\n This is primarily useful when the write transaction is saving changes already\n made in the UI and you do not want to have the notification block attempt to\n re-apply the same changes.\n\n The tokens passed to this method must be for notifications for this specific\n `RLMRealm` instance. Notifications for different threads cannot be skipped\n using this method.\n\n This method can fail if there is insufficient disk space available to save the\n writes made, or due to unexpected i/o errors.\n\n @warning This method may only be called during a write transaction.\n\n @param tokens An array of notification tokens which were returned from adding\n               callbacks which you do not want to be notified for the changes\n               made in this write transaction.\n @param error If an error occurs, upon return contains an `NSError` object\n              that describes the problem. If you are not interested in\n              possible errors, pass in `NULL`.\n\n @return Whether the transaction succeeded.\n */\n- (BOOL)commitWriteTransactionWithoutNotifying:(NSArray<RLMNotificationToken *> *)tokens error:(NSError **)error;\n\n/**\n Reverts all writes made during the current write transaction and ends the transaction.\n\n This rolls back all objects in the Realm to the state they were in at the\n beginning of the write transaction, and then ends the transaction.\n\n This restores the data for deleted objects, but does not revive invalidated\n object instances. Any `RLMObject`s which were added to the Realm will be\n invalidated rather than becoming unmanaged.\n Given the following code:\n\n     ObjectType *oldObject = [[ObjectType objectsWhere:@\"...\"] firstObject];\n     ObjectType *newObject = [[ObjectType alloc] init];\n\n     [realm beginWriteTransaction];\n     [realm addObject:newObject];\n     [realm deleteObject:oldObject];\n     [realm cancelWriteTransaction];\n\n Both `oldObject` and `newObject` will return `YES` for `isInvalidated`,\n but re-running the query which provided `oldObject` will once again return\n the valid object.\n\n KVO observers on any objects which were modified during the transaction will\n be notified about the change back to their initial values, but no other\n notifcations are produced by a cancelled write transaction.\n\n @warning This method may only be called during a write transaction.\n */\n- (void)cancelWriteTransaction;\n\n/**\n Performs actions contained within the given block inside a write transaction.\n\n @see `[RLMRealm transactionWithBlock:error:]`\n */\n- (void)transactionWithBlock:(__attribute__((noescape)) void(^)(void))block NS_SWIFT_UNAVAILABLE(\"\");\n\n/**\n Performs actions contained within the given block inside a write transaction.\n\n Write transactions cannot be nested, and trying to execute a write transaction\n on a Realm which is already participating in a write transaction will throw an\n exception. Calls to `transactionWithBlock:` from `RLMRealm` instances in other\n threads will block until the current write transaction completes.\n\n Before beginning the write transaction, `transactionWithBlock:` updates the\n `RLMRealm` instance to the latest Realm version, as if `refresh` had been called, and\n generates notifications if applicable. This has no effect if the Realm\n was already up to date.\n\n @param block The block containing actions to perform.\n @param error If an error occurs, upon return contains an `NSError` object\n              that describes the problem. If you are not interested in\n              possible errors, pass in `NULL`.\n\n @return Whether the transaction succeeded.\n */\n- (BOOL)transactionWithBlock:(__attribute__((noescape)) void(^)(void))block error:(NSError **)error;\n\n/**\n Updates the Realm and outstanding objects managed by the Realm to point to the\n most recent data.\n\n If the version of the Realm is actually changed, Realm and collection\n notifications will be sent to reflect the changes. This may take some time, as\n collection notifications are prepared on a background thread. As a result,\n calling this method on the main thread is not advisable.\n\n @return Whether there were any updates for the Realm. Note that `YES` may be\n         returned even if no data actually changed.\n */\n- (BOOL)refresh;\n\n/**\n Set this property to `YES` to automatically update this Realm when changes\n happen in other threads.\n\n If set to `YES` (the default), changes made on other threads will be reflected\n in this Realm on the next cycle of the run loop after the changes are\n committed.  If set to `NO`, you must manually call `-refresh` on the Realm to\n update it to get the latest data.\n\n Note that by default, background threads do not have an active run loop and you\n will need to manually call `-refresh` in order to update to the latest version,\n even if `autorefresh` is set to `YES`.\n\n Even with this property enabled, you can still call `-refresh` at any time to\n update the Realm before the automatic refresh would occur.\n\n Write transactions will still always advance a Realm to the latest version and\n produce local notifications on commit even if autorefresh is disabled.\n\n Disabling `autorefresh` on a Realm without any strong references to it will not\n have any effect, and `autorefresh` will revert back to `YES` the next time the\n Realm is created. This is normally irrelevant as it means that there is nothing\n to refresh (as managed `RLMObject`s, `RLMArray`s, and `RLMResults` have strong\n references to the Realm that manages them), but it means that setting\n `RLMRealm.defaultRealm.autorefresh = NO` in\n `application:didFinishLaunchingWithOptions:` and only later storing Realm\n objects will not work.\n\n Defaults to `YES`.\n */\n@property (nonatomic) BOOL autorefresh;\n\n/**\n Writes a compacted and optionally encrypted copy of the Realm to the given local URL.\n\n The destination file cannot already exist.\n\n Note that if this method is called from within a write transaction, the\n *current* data is written, not the data from the point when the previous write\n transaction was committed.\n\n @param fileURL Local URL to save the Realm to.\n @param key     Optional 64-byte encryption key to encrypt the new file with.\n @param error   If an error occurs, upon return contains an `NSError` object\n                that describes the problem. If you are not interested in\n                possible errors, pass in `NULL`.\n\n @return `YES` if the Realm was successfully written to disk, `NO` if an error occurred.\n*/\n- (BOOL)writeCopyToURL:(NSURL *)fileURL encryptionKey:(nullable NSData *)key error:(NSError **)error;\n\n/**\n Invalidates all `RLMObject`s, `RLMResults`, `RLMLinkingObjects`, and `RLMArray`s managed by the Realm.\n\n A Realm holds a read lock on the version of the data accessed by it, so\n that changes made to the Realm on different threads do not modify or delete the\n data seen by this Realm. Calling this method releases the read lock,\n allowing the space used on disk to be reused by later write transactions rather\n than growing the file. This method should be called before performing long\n blocking operations on a background thread on which you previously read data\n from the Realm which you no longer need.\n\n All `RLMObject`, `RLMResults` and `RLMArray` instances obtained from this\n `RLMRealm` instance on the current thread are invalidated. `RLMObject`s and `RLMArray`s\n cannot be used. `RLMResults` will become empty. The Realm itself remains valid,\n and a new read transaction is implicitly begun the next time data is read from the Realm.\n\n Calling this method multiple times in a row without reading any data from the\n Realm, or before ever reading any data from the Realm, is a no-op. This method\n may not be called on a read-only Realm.\n */\n- (void)invalidate;\n\n#pragma mark - Accessing Objects\n\n/**\n Returns the same object as the one referenced when the `RLMThreadSafeReference` was first created,\n but resolved for the current Realm for this thread. Returns `nil` if this object was deleted after\n the reference was created.\n\n @param reference The thread-safe reference to the thread-confined object to resolve in this Realm.\n\n @warning A `RLMThreadSafeReference` object must be resolved at most once.\n          Failing to resolve a `RLMThreadSafeReference` will result in the source version of the\n          Realm being pinned until the reference is deallocated.\n          An exception will be thrown if a reference is resolved more than once.\n\n @warning Cannot call within a write transaction.\n\n @note Will refresh this Realm if the source Realm was at a later version than this one.\n\n @see `+[RLMThreadSafeReference referenceWithThreadConfined:]`\n */\n- (nullable id)resolveThreadSafeReference:(RLMThreadSafeReference *)reference\nNS_REFINED_FOR_SWIFT;\n\n#pragma mark - Adding and Removing Objects from a Realm\n\n/**\n Adds an object to the Realm.\n\n Once added, this object is considered to be managed by the Realm. It can be retrieved\n using the `objectsWhere:` selectors on `RLMRealm` and on subclasses of `RLMObject`.\n\n When added, all child relationships referenced by this object will also be added to\n the Realm if they are not already in it.\n\n If the object or any related objects are already being managed by a different Realm\n an exception will be thrown. Use `-[RLMObject createInRealm:withObject:]` to insert a copy of a managed object\n into a different Realm.\n\n The object to be added must be valid and cannot have been previously deleted\n from a Realm (i.e. `isInvalidated` must be `NO`).\n\n @warning This method may only be called during a write transaction.\n\n @param object  The object to be added to this Realm.\n */\n- (void)addObject:(RLMObject *)object;\n\n/**\n Adds all the objects in a collection to the Realm.\n\n This is the equivalent of calling `addObject:` for every object in a collection.\n\n @warning This method may only be called during a write transaction.\n\n @param array   An enumerable object such as `NSArray` or `RLMResults` which contains objects to be added to\n                the Realm.\n\n @see   `addObject:`\n */\n- (void)addObjects:(id<NSFastEnumeration>)array;\n\n/**\n Adds or updates an existing object into the Realm.\n\n The object provided must have a designated primary key. If no objects exist in the Realm\n with the same primary key value, the object is inserted. Otherwise, the existing object is\n updated with any changed values.\n\n As with `addObject:`, the object cannot already be managed by a different\n Realm. Use `-[RLMObject createOrUpdateInRealm:withValue:]` to copy values to\n a different Realm.\n\n @warning This method may only be called during a write transaction.\n\n @param object  The object to be added or updated.\n */\n- (void)addOrUpdateObject:(RLMObject *)object;\n\n/**\n Adds or updates all the objects in a collection into the Realm.\n\n This is the equivalent of calling `addOrUpdateObject:` for every object in a collection.\n\n @warning This method may only be called during a write transaction.\n\n @param array  An `NSArray`, `RLMArray`, or `RLMResults` of `RLMObject`s (or subclasses) to be added to the Realm.\n\n @see   `addOrUpdateObject:`\n */\n- (void)addOrUpdateObjectsFromArray:(id)array;\n\n/**\n Deletes an object from the Realm. Once the object is deleted it is considered invalidated.\n\n @warning This method may only be called during a write transaction.\n\n @param object  The object to be deleted.\n */\n- (void)deleteObject:(RLMObject *)object;\n\n/**\n Deletes one or more objects from the Realm.\n\n This is the equivalent of calling `deleteObject:` for every object in a collection.\n\n @warning This method may only be called during a write transaction.\n\n @param array  An `RLMArray`, `NSArray`, or `RLMResults` of `RLMObject`s (or subclasses) to be deleted.\n\n @see `deleteObject:`\n */\n- (void)deleteObjects:(id)array;\n\n/**\n Deletes all objects from the Realm.\n\n @warning This method may only be called during a write transaction.\n\n @see `deleteObject:`\n */\n- (void)deleteAllObjects;\n\n\n#pragma mark - Migrations\n\n/**\n The type of a migration block used to migrate a Realm.\n\n @param migration   A `RLMMigration` object used to perform the migration. The\n                    migration object allows you to enumerate and alter any\n                    existing objects which require migration.\n\n @param oldSchemaVersion    The schema version of the Realm being migrated.\n */\ntypedef void (^RLMMigrationBlock)(RLMMigration *migration, uint64_t oldSchemaVersion);\n\n/**\n Returns the schema version for a Realm at a given local URL.\n\n @param fileURL Local URL to a Realm file.\n @param key     64-byte key used to encrypt the file, or `nil` if it is unencrypted.\n @param error   If an error occurs, upon return contains an `NSError` object\n                that describes the problem. If you are not interested in\n                possible errors, pass in `NULL`.\n\n @return The version of the Realm at `fileURL`, or `RLMNotVersioned` if the version cannot be read.\n */\n+ (uint64_t)schemaVersionAtURL:(NSURL *)fileURL encryptionKey:(nullable NSData *)key error:(NSError **)error\nNS_REFINED_FOR_SWIFT;\n\n/**\n Performs the given Realm configuration's migration block on a Realm at the given path.\n\n This method is called automatically when opening a Realm for the first time and does\n not need to be called explicitly. You can choose to call this method to control\n exactly when and how migrations are performed.\n\n @param configuration The Realm configuration used to open and migrate the Realm.\n @return              The error that occurred while applying the migration, if any.\n\n @see                 RLMMigration\n */\n+ (nullable NSError *)migrateRealm:(RLMRealmConfiguration *)configuration\n__deprecated_msg(\"Use `performMigrationForConfiguration:error:`\") NS_REFINED_FOR_SWIFT;\n\n/**\n Performs the given Realm configuration's migration block on a Realm at the given path.\n\n This method is called automatically when opening a Realm for the first time and does\n not need to be called explicitly. You can choose to call this method to control\n exactly when and how migrations are performed.\n\n @param configuration The Realm configuration used to open and migrate the Realm.\n @return              The error that occurred while applying the migration, if any.\n\n @see                 RLMMigration\n */\n+ (BOOL)performMigrationForConfiguration:(RLMRealmConfiguration *)configuration error:(NSError **)error;\n\n@end\n\n/**\n A token which is returned from methods which subscribe to changes to a Realm.\n\n Change subscriptions in Realm return an `RLMNotificationToken` instance,\n which can be used to unsubscribe from the changes. You must store a strong\n reference to the token for as long as you want to continue to receive notifications.\n When you wish to stop, call the `-stop` method. Notifications are also stopped if\n the token is deallocated.\n */\n@interface RLMNotificationToken : NSObject\n/// Stops notifications for the change subscription that returned this token.\n- (void)stop;\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMRealmConfiguration+Sync.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2016 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Realm/RLMRealmConfiguration.h>\n\n#import \"RLMSyncUtil.h\"\n\n@class RLMSyncConfiguration;\n\n/// :nodoc:\n@interface RLMRealmConfiguration (Sync)\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n A configuration object representing configuration state for Realms intended to sync with a Realm Object Server.\n \n This property is mutually exclusive with both `inMemoryIdentifier` and `fileURL`; setting one will nil out the other\n two.\n \n @see `RLMSyncConfiguration`\n */\n@property (nullable, nonatomic) RLMSyncConfiguration *syncConfiguration;\n\nNS_ASSUME_NONNULL_END\n\n@end\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMRealmConfiguration.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2015 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n#import <Realm/RLMRealm.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n An `RLMRealmConfiguration` instance describes the different options used to\n create an instance of a Realm.\n\n `RLMRealmConfiguration` instances are just plain `NSObject`s. Unlike `RLMRealm`s\n and `RLMObject`s, they can be freely shared between threads as long as you do not\n mutate them.\n \n Creating configuration objects for class subsets (by setting the\n `objectClasses` property) can be expensive. Because of this, you will normally want to\n cache and reuse a single configuration object for each distinct configuration rather than \n creating a new object each time you open a Realm.\n */\n@interface RLMRealmConfiguration : NSObject<NSCopying>\n\n#pragma mark - Default Configuration\n\n/**\n Returns the default configuration used to create Realms when no other\n configuration is explicitly specified (i.e. `+[RLMRealm defaultRealm]`).\n\n @return The default Realm configuration.\n */\n+ (instancetype)defaultConfiguration;\n\n/**\n Sets the default configuration to the given `RLMRealmConfiguration`.\n\n @param configuration The new default Realm configuration.\n */\n+ (void)setDefaultConfiguration:(RLMRealmConfiguration *)configuration;\n\n#pragma mark - Properties\n\n/// The local URL of the Realm file. Mutually exclusive with `inMemoryIdentifier`.\n@property (nonatomic, copy, nullable) NSURL *fileURL;\n\n/// A string used to identify a particular in-memory Realm. Mutually exclusive with `fileURL`.\n@property (nonatomic, copy, nullable) NSString *inMemoryIdentifier;\n\n/// A 64-byte key to use to encrypt the data, or `nil` if encryption is not enabled.\n@property (nonatomic, copy, nullable) NSData *encryptionKey;\n\n/// Whether to open the Realm in read-only mode.\n///\n/// This is required to be able to open Realm files which are not writeable or\n/// are in a directory which is not writeable. This should only be used on files\n/// which will not be modified by anyone while they are open, and not just to\n/// get a read-only view of a file which may be written to by another thread or\n/// process. Opening in read-only mode requires disabling Realm's reader/writer\n/// coordination, so committing a write transaction from another process will\n/// result in crashes.\n@property (nonatomic) BOOL readOnly;\n\n/// The current schema version.\n@property (nonatomic) uint64_t schemaVersion;\n\n/// The block which migrates the Realm to the current version.\n@property (nonatomic, copy, nullable) RLMMigrationBlock migrationBlock;\n\n/**\n Whether to recreate the Realm file with the provided schema if a migration is required.\n This is the case when the stored schema differs from the provided schema or\n the stored schema version differs from the version on this configuration.\n Setting this property to `YES` deletes the file if a migration would otherwise be required or executed.\n\n @note Setting this property to `YES` doesn't disable file format migrations.\n */\n@property (nonatomic) BOOL deleteRealmIfMigrationNeeded;\n\n/// The classes managed by the Realm.\n@property (nonatomic, copy, nullable) NSArray *objectClasses;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMRealm_Dynamic.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Realm/RLMRealm.h>\n\n#import <Realm/RLMObjectSchema.h>\n#import <Realm/RLMProperty.h>\n\n@class RLMResults;\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface RLMRealm (Dynamic)\n\n#pragma mark - Getting Objects from a Realm\n\n/**\n Returns all objects of a given type from the Realm.\n\n @warning This method is useful only in specialized circumstances, for example, when building components\n          that integrate with Realm. The preferred way to get objects of a single class is to use the class\n          methods on `RLMObject`.\n\n @param className   The name of the `RLMObject` subclass to retrieve on (e.g. `MyClass.className`).\n\n @return    An `RLMResults` containing all objects in the Realm of the given type.\n\n @see       `+[RLMObject allObjects]`\n */\n- (RLMResults *)allObjects:(NSString *)className;\n\n/**\n Returns all objects matching the given predicate from the Realm.\n\n @warning This method is useful only in specialized circumstances, for example, when building components\n          that integrate with Realm. The preferred way to get objects of a single class is to use the class\n          methods on `RLMObject`.\n\n @param className       The type of objects you are looking for (name of the class).\n @param predicateFormat A predicate format string, optionally followed by a variable number of arguments.\n\n @return    An `RLMResults` containing results matching the given predicate.\n\n @see       `+[RLMObject objectsWhere:]`\n */\n- (RLMResults *)objects:(NSString *)className where:(NSString *)predicateFormat, ...;\n\n/**\n Returns all objects matching the given predicate from the Realm.\n\n @warning This method is useful only in specialized circumstances, for example, when building components\n          that integrate with Realm. The preferred way to get objects of a single class is to use the class\n          methods on `RLMObject`.\n\n @param className   The type of objects you are looking for (name of the class).\n @param predicate   The predicate with which to filter the objects.\n\n @return    An `RLMResults` containing results matching the given predicate.\n\n @see       `+[RLMObject objectsWhere:]`\n */\n- (RLMResults *)objects:(NSString *)className withPredicate:(NSPredicate *)predicate;\n\n/**\n Returns the object of the given type with the given primary key from the Realm.\n\n @warning This method is useful only in specialized circumstances, for example, when building components \n          that integrate with Realm. The preferred way to get an object of a single class is to use the class\n          methods on `RLMObject`.\n \n @param className   The class name for the object you are looking for.\n @param primaryKey  The primary key value for the object you are looking for.\n \n @return    An object, or `nil` if an object with the given primary key does not exist.\n \n @see       `+[RLMObject objectForPrimaryKey:]`\n */\n- (nullable RLMObject *)objectWithClassName:(NSString *)className forPrimaryKey:(id)primaryKey;\n\n/**\n Creates an `RLMObject` instance of type `className` in the Realm, and populates it using a given object.\n \n The `value` argument is used to populate the object. It can be a key-value coding compliant object, an array or\n dictionary returned from the methods in `NSJSONSerialization`, or an array containing one element for each managed\n property. An exception will be thrown if any required properties are not present and those properties were not defined\n with default values.\n\n When passing in an array as the `value` argument, all properties must be present, valid and in the same order as the\n properties defined in the model.\n\n @warning This method is useful only in specialized circumstances, for example, when building components\n          that integrate with Realm. If you are simply building an app on Realm, it is recommended to\n          use `[RLMObject createInDefaultRealmWithValue:]`.\n\n @param value    The value used to populate the object.\n\n @return    An `RLMObject` instance of type `className`.\n */\n-(RLMObject *)createObject:(NSString *)className withValue:(id)value;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMResults.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n#import <Realm/RLMCollection.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@class RLMObject, RLMRealm, RLMNotificationToken;\n\n/**\n `RLMResults` is an auto-updating container type in Realm returned from object\n queries. It represents the results of the query in the form of a collection of objects.\n\n `RLMResults` can be queried using the same predicates as `RLMObject` and `RLMArray`,\n and you can chain queries to further filter results.\n\n `RLMResults` always reflect the current state of the Realm on the current thread,\n including during write transactions on the current thread. The one exception to\n this is when using `for...in` fast enumeration, which will always enumerate\n over the objects which matched the query when the enumeration is begun, even if\n some of them are deleted or modified to be excluded by the filter during the\n enumeration.\n\n `RLMResults` are lazily evaluated the first time they are accessed; they only\n run queries when the result of the query is requested. This means that \n chaining several temporary `RLMResults` to sort and filter your data does not \n perform any extra work processing the intermediate state.\n\n Once the results have been evaluated or a notification block has been added,\n the results are eagerly kept up-to-date, with the work done to keep them\n up-to-date done on a background thread whenever possible.\n\n `RLMResults` cannot be directly instantiated.\n */\n@interface RLMResults<RLMObjectType: RLMObject *> : NSObject<RLMCollection, NSFastEnumeration>\n\n#pragma mark - Properties\n\n/**\n The number of objects in the results collection.\n */\n@property (nonatomic, readonly, assign) NSUInteger count;\n\n/**\n The class name (i.e. type) of the `RLMObject`s contained in the results collection.\n */\n@property (nonatomic, readonly, copy) NSString *objectClassName;\n\n/**\n The Realm which manages this results collection.\n */\n@property (nonatomic, readonly) RLMRealm *realm;\n\n/**\n Indicates if the results collection is no longer valid.\n\n The results collection becomes invalid if `invalidate` is called on the containing `realm`.\n An invalidated results collection can be accessed, but will always be empty.\n */\n@property (nonatomic, readonly, getter = isInvalidated) BOOL invalidated;\n\n#pragma mark - Accessing Objects from an RLMResults\n\n/**\n Returns the object at the index specified.\n\n @param index   The index to look up.\n\n @return An `RLMObject` of the type contained in the results collection.\n */\n- (RLMObjectType)objectAtIndex:(NSUInteger)index;\n\n/**\n Returns the first object in the results collection.\n\n Returns `nil` if called on an empty results collection.\n\n @return An `RLMObject` of the type contained in the results collection.\n */\n- (nullable RLMObjectType)firstObject;\n\n/**\n Returns the last object in the results collection.\n\n Returns `nil` if called on an empty results collection.\n\n @return An `RLMObject` of the type contained in the results collection.\n */\n- (nullable RLMObjectType)lastObject;\n\n#pragma mark - Querying Results\n\n/**\n Returns the index of an object in the results collection.\n\n Returns `NSNotFound` if the object is not found in the results collection.\n\n @param object  An object (of the same type as returned from the `objectClassName` selector).\n */\n- (NSUInteger)indexOfObject:(RLMObjectType)object;\n\n/**\n Returns the index of the first object in the results collection matching the predicate.\n\n @param predicateFormat A predicate format string, optionally followed by a variable number of arguments.\n\n @return    The index of the object, or `NSNotFound` if the object is not found in the results collection.\n */\n- (NSUInteger)indexOfObjectWhere:(NSString *)predicateFormat, ...;\n\n/// :nodoc:\n- (NSUInteger)indexOfObjectWhere:(NSString *)predicateFormat args:(va_list)args;\n\n/**\n Returns the index of the first object in the results collection matching the predicate.\n\n @param predicate   The predicate with which to filter the objects.\n\n @return    The index of the object, or `NSNotFound` if the object is not found in the results collection.\n */\n- (NSUInteger)indexOfObjectWithPredicate:(NSPredicate *)predicate;\n\n/**\n Returns all the objects matching the given predicate in the results collection.\n\n @param predicateFormat A predicate format string, optionally followed by a variable number of arguments.\n\n @return                An `RLMResults` of objects that match the given predicate.\n */\n- (RLMResults<RLMObjectType> *)objectsWhere:(NSString *)predicateFormat, ...;\n\n/// :nodoc:\n- (RLMResults<RLMObjectType> *)objectsWhere:(NSString *)predicateFormat args:(va_list)args;\n\n/**\n Returns all the objects matching the given predicate in the results collection.\n\n @param predicate   The predicate with which to filter the objects.\n\n @return            An `RLMResults` of objects that match the given predicate.\n */\n- (RLMResults<RLMObjectType> *)objectsWithPredicate:(NSPredicate *)predicate;\n\n/**\n Returns a sorted `RLMResults` from an existing results collection.\n\n @param keyPath     The key path to sort by.\n @param ascending   The direction to sort in.\n\n @return    An `RLMResults` sorted by the specified key path.\n */\n- (RLMResults<RLMObjectType> *)sortedResultsUsingKeyPath:(NSString *)keyPath ascending:(BOOL)ascending;\n\n/**\n Returns a sorted `RLMResults` from an existing results collection.\n\n @param property    The property name to sort by.\n @param ascending   The direction to sort in.\n\n @return    An `RLMResults` sorted by the specified property.\n */\n- (RLMResults<RLMObjectType> *)sortedResultsUsingProperty:(NSString *)property ascending:(BOOL)ascending\n    __deprecated_msg(\"Use `-sortedResultsUsingKeyPath:ascending:`\");\n\n/**\n Returns a sorted `RLMResults` from an existing results collection.\n\n @param properties  An array of `RLMSortDescriptor`s to sort by.\n\n @return    An `RLMResults` sorted by the specified properties.\n */\n- (RLMResults<RLMObjectType> *)sortedResultsUsingDescriptors:(NSArray<RLMSortDescriptor *> *)properties;\n\n#pragma mark - Notifications\n\n/**\n Registers a block to be called each time the results collection changes.\n\n The block will be asynchronously called with the initial results collection,\n and then called again after each write transaction which changes either any\n of the objects in the results, or which objects are in the results.\n\n The `change` parameter will be `nil` the first time the block is called.\n For each call after that, it will contain information about\n which rows in the results collection were added, removed or modified. If a\n write transaction did not modify any objects in the results collection,\n the block is not called at all. See the `RLMCollectionChange` documentation for\n information on how the changes are reported and an example of updating a \n `UITableView`.\n\n If an error occurs the block will be called with `nil` for the results\n parameter and a non-`nil` error. Currently the only errors that can occur are\n when opening the Realm on the background worker thread.\n\n At the time when the block is called, the `RLMResults` object will be fully\n evaluated and up-to-date, and as long as you do not perform a write transaction\n on the same thread or explicitly call `-[RLMRealm refresh]`, accessing it will\n never perform blocking work.\n\n Notifications are delivered via the standard run loop, and so can't be\n delivered while the run loop is blocked by other activity. When\n notifications can't be delivered instantly, multiple notifications may be\n coalesced into a single notification. This can include the notification\n with the initial results. For example, the following code performs a write\n transaction immediately after adding the notification block, so there is no\n opportunity for the initial notification to be delivered first. As a\n result, the initial notification will reflect the state of the Realm after\n the write transaction.\n\n     RLMResults<Dog *> *results = [Dog allObjects];\n     NSLog(@\"dogs.count: %zu\", dogs.count); // => 0\n     self.token = [results addNotificationBlock:^(RLMResults *dogs,\n                                                  RLMCollectionChange *changes,\n                                                  NSError *error) {\n         // Only fired once for the example\n         NSLog(@\"dogs.count: %zu\", dogs.count); // => 1\n     }];\n     [realm transactionWithBlock:^{\n         Dog *dog = [[Dog alloc] init];\n         dog.name = @\"Rex\";\n         [realm addObject:dog];\n     }];\n     // end of run loop execution context\n\n You must retain the returned token for as long as you want updates to continue\n to be sent to the block. To stop receiving updates, call `-stop` on the token.\n\n @warning This method cannot be called during a write transaction, or when the\n          containing Realm is read-only.\n\n @param block The block to be called whenever a change occurs.\n @return A token which must be held for as long as you want updates to be delivered.\n */\n- (RLMNotificationToken *)addNotificationBlock:(void (^)(RLMResults<RLMObjectType> *__nullable results,\n                                                         RLMCollectionChange *__nullable change,\n                                                         NSError *__nullable error))block __attribute__((warn_unused_result));\n\n#pragma mark - Aggregating Property Values\n\n/**\n Returns the minimum (lowest) value of the given property among all the objects\n represented by the results collection.\n\n     NSNumber *min = [results minOfProperty:@\"age\"];\n\n @warning You cannot use this method on `RLMObject`, `RLMArray`, and `NSData` properties.\n\n @param property The property whose minimum value is desired. Only properties of types `int`, `float`, `double`, and\n                 `NSDate` are supported.\n\n @return The minimum value of the property.\n */\n- (nullable id)minOfProperty:(NSString *)property;\n\n/**\n Returns the maximum (highest) value of the given property among all the objects represented by the results collection.\n\n     NSNumber *max = [results maxOfProperty:@\"age\"];\n\n @warning You cannot use this method on `RLMObject`, `RLMArray`, and `NSData` properties.\n\n @param property The property whose maximum value is desired. Only properties of types `int`, `float`, `double`, and \n                 `NSDate` are supported.\n\n @return The maximum value of the property.\n */\n- (nullable id)maxOfProperty:(NSString *)property;\n\n/**\n Returns the sum of the values of a given property over all the objects represented by the results collection.\n\n     NSNumber *sum = [results sumOfProperty:@\"age\"];\n\n @warning You cannot use this method on `RLMObject`, `RLMArray`, and `NSData` properties.\n\n @param property The property whose values should be summed. Only properties of types `int`, `float`, and `double` are\n                 supported.\n\n @return The sum of the given property.\n */\n- (NSNumber *)sumOfProperty:(NSString *)property;\n\n/**\n Returns the average value of a given property over the objects represented by the results collection.\n\n     NSNumber *average = [results averageOfProperty:@\"age\"];\n\n @warning You cannot use this method on `RLMObject`, `RLMArray`, and `NSData` properties.\n\n @param property The property whose average value should be calculated. Only properties of types `int`, `float`, and\n                 `double` are supported.\n\n @return    The average value of the given property. This will be of type `double` for both `float` and `double`\n            properties.\n */\n- (nullable NSNumber *)averageOfProperty:(NSString *)property;\n\n/// :nodoc:\n- (RLMObjectType)objectAtIndexedSubscript:(NSUInteger)index;\n\n#pragma mark - Unavailable Methods\n\n/**\n `-[RLMResults init]` is not available because `RLMResults` cannot be created directly.\n `RLMResults` can be obtained by querying a Realm.\n */\n- (instancetype)init __attribute__((unavailable(\"RLMResults cannot be created directly\")));\n\n/**\n `+[RLMResults new]` is not available because `RLMResults` cannot be created directly.\n `RLMResults` can be obtained by querying a Realm.\n */\n+ (instancetype)new __attribute__((unavailable(\"RLMResults cannot be created directly\")));\n\n@end\n\n/**\n `RLMLinkingObjects` is an auto-updating container type. It represents a collection of objects that link to its\n parent object.\n \n For more information, please see the \"Inverse Relationships\" section in the\n [documentation](https://realm.io/docs/objc/latest/#relationships).\n */\n@interface RLMLinkingObjects<RLMObjectType: RLMObject *> : RLMResults\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMSchema.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@class RLMObjectSchema;\n\n/**\n `RLMSchema` instances represent collections of model object schemas managed by a Realm.\n\n When using Realm, `RLMSchema` instances allow performing migrations and\n introspecting the database's schema.\n\n Schemas map to collections of tables in the core database.\n */\n@interface RLMSchema : NSObject<NSCopying>\n\n#pragma mark - Properties\n\n/**\n An `NSArray` containing `RLMObjectSchema`s for all object types in the Realm.\n \n This property is intended to be used during migrations for dynamic introspection.\n\n @see `RLMObjectSchema`\n */\n@property (nonatomic, readonly, copy) NSArray<RLMObjectSchema *> *objectSchema;\n\n#pragma mark - Methods\n\n/**\n Returns an `RLMObjectSchema` for the given class name in the schema.\n\n @param className   The object class name.\n @return            An `RLMObjectSchema` for the given class in the schema.\n\n @see               `RLMObjectSchema`\n */\n- (nullable RLMObjectSchema *)schemaForClassName:(NSString *)className;\n\n/**\n Looks up and returns an `RLMObjectSchema` for the given class name in the Realm.\n \n If there is no object of type `className` in the schema, an exception will be thrown.\n\n @param className   The object class name.\n @return            An `RLMObjectSchema` for the given class in this Realm.\n\n @see               `RLMObjectSchema`\n */\n- (RLMObjectSchema *)objectForKeyedSubscript:(NSString *)className;\n\n/**\n Returns whether two `RLMSchema` instances are equivalent.\n */\n- (BOOL)isEqualToSchema:(RLMSchema *)schema;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMSyncConfiguration.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2016 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n\n@class RLMSyncUser;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n A configuration object representing configuration state for a Realm which is intended to sync with a Realm Object\n Server.\n */\n@interface RLMSyncConfiguration : NSObject\n\n/// The user to which the remote Realm belongs.\n@property (nonatomic, readonly) RLMSyncUser *user;\n\n/**\n The URL of the remote Realm upon the Realm Object Server.\n \n @warning The URL cannot end with `.realm`, `.realm.lock` or `.realm.management`.\n */\n@property (nonatomic, readonly) NSURL *realmURL;\n\n/**\n Create a sync configuration instance.\n\n @param user    A `RLMSyncUser` that owns the Realm at the given URL.\n @param url     The unresolved absolute URL to the Realm on the Realm Object Server, e.g.\n                `realm://example.org/~/path/to/realm`. \"Unresolved\" means the path should\n                contain the wildcard marker `~`, which will automatically be filled in with\n                the user identity by the Realm Object Server.\n */\n- (instancetype)initWithUser:(RLMSyncUser *)user realmURL:(NSURL *)url;\n\n/// :nodoc:\n- (instancetype)init __attribute__((unavailable(\"This type cannot be created directly\")));\n\n/// :nodoc:\n+ (instancetype)new __attribute__((unavailable(\"This type cannot be created directly\")));\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMSyncCredentials.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2016 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n\n#import \"RLMSyncUtil.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// A token representing an identity provider's credentials.\ntypedef NSString *RLMSyncCredentialsToken;\n\n/// A type representing the unique identifier of a Realm Object Server identity provider.\ntypedef NSString *RLMIdentityProvider RLM_EXTENSIBLE_STRING_ENUM;\n\n/// The debug identity provider, which accepts any token string and creates a user associated with that token if one\n/// does not yet exist. Not enabled for Realm Object Server configured for production.\nextern RLMIdentityProvider const RLMIdentityProviderDebug;\n\n/// The username/password identity provider. User accounts are handled by the Realm Object Server directly without the\n/// involvement of a third-party identity provider.\nextern RLMIdentityProvider const RLMIdentityProviderUsernamePassword;\n\n/// A Facebook account as an identity provider.\nextern RLMIdentityProvider const RLMIdentityProviderFacebook;\n\n/// A Google account as an identity provider.\nextern RLMIdentityProvider const RLMIdentityProviderGoogle;\n\n/// A CloudKit account as an identity provider.\nextern RLMIdentityProvider const RLMIdentityProviderCloudKit;\n\n/**\n Opaque credentials representing a specific Realm Object Server user.\n */\n@interface RLMSyncCredentials : NSObject\n\n/// An opaque credentials token containing information that uniquely identifies a Realm Object Server user.\n@property (nonatomic, readonly) RLMSyncCredentialsToken token;\n\n/// The name of the identity provider which generated the credentials token.\n@property (nonatomic, readonly) RLMIdentityProvider provider;\n\n/// A dictionary containing additional pertinent information. In most cases this is automatically configured.\n@property (nonatomic, readonly) NSDictionary<NSString *, id> *userInfo;\n\n/**\n Construct and return credentials from a Facebook account token.\n */\n+ (instancetype)credentialsWithFacebookToken:(RLMSyncCredentialsToken)token;\n\n/**\n Construct and return credentials from a Google account token.\n */\n+ (instancetype)credentialsWithGoogleToken:(RLMSyncCredentialsToken)token;\n\n/**\n Construct and return credentials from an CloudKit account token.\n */\n+ (instancetype)credentialsWithCloudKitToken:(RLMSyncCredentialsToken)token;\n\n/**\n Construct and return credentials from a Realm Object Server username and password.\n */\n+ (instancetype)credentialsWithUsername:(NSString *)username\n                               password:(NSString *)password\n                               register:(BOOL)shouldRegister;\n\n/**\n Construct and return special credentials representing a token that can be directly used to open a Realm. The identity\n is used to uniquely identify the user across application launches.\n */\n+ (instancetype)credentialsWithAccessToken:(RLMServerToken)accessToken identity:(NSString *)identity;\n\n/**\n Construct and return credentials with a custom token string, identity provider string, and optional user info. In most\n cases, the convenience initializers should be used instead.\n */\n- (instancetype)initWithCustomToken:(RLMSyncCredentialsToken)token\n                           provider:(RLMIdentityProvider)provider\n                           userInfo:(nullable NSDictionary *)userInfo NS_DESIGNATED_INITIALIZER;\n\n/// :nodoc:\n- (instancetype)init __attribute__((unavailable(\"RLMSyncCredentials cannot be created directly\")));\n\n/// :nodoc:\n+ (instancetype)new __attribute__((unavailable(\"RLMSyncCredentials cannot be created directly\")));\n\nNS_ASSUME_NONNULL_END\n\n@end\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMSyncManager.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2016 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n\n#import \"RLMSyncUtil.h\"\n\n@class RLMSyncSession;\n\n/// An enum representing different levels of sync-related logging that can be configured.\ntypedef NS_ENUM(NSUInteger, RLMSyncLogLevel) {\n    /// Nothing will ever be logged.\n    RLMSyncLogLevelOff,\n    /// Only fatal errors will be logged.\n    RLMSyncLogLevelFatal,\n    /// Only errors will be logged.\n    RLMSyncLogLevelError,\n    /// Warnings and errors will be logged.\n    RLMSyncLogLevelWarn,\n    /// Information about sync events will be logged. Fewer events will be logged in order to avoid overhead.\n    RLMSyncLogLevelInfo,\n    /// Information about sync events will be logged. More events will be logged than with `RLMSyncLogLevelInfo`.\n    RLMSyncLogLevelDetail,\n    /// Log information that can aid in debugging.\n    ///\n    /// - warning: Will incur a measurable performance impact.\n    RLMSyncLogLevelDebug,\n    /// Log information that can aid in debugging. More events will be logged than with `RLMSyncLogLevelDebug`.\n    ///\n    /// - warning: Will incur a measurable performance impact.\n    RLMSyncLogLevelTrace,\n    /// Log information that can aid in debugging. More events will be logged than with `RLMSyncLogLevelTrace`.\n    ///\n    /// - warning: Will incur a measurable performance impact.\n    RLMSyncLogLevelAll\n};\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// A block type representing a block which can be used to report a sync-related error to the application. If the error\n/// pertains to a specific session, that session will also be passed into the block.\ntypedef void(^RLMSyncErrorReportingBlock)(NSError *, RLMSyncSession * _Nullable);\n\n/**\n A singleton manager which serves as a central point for sync-related configuration.\n */\n@interface RLMSyncManager : NSObject\n\n/**\n An optional block which can be used to report sync-related errors to your application. Errors reported through this\n mechanism are always fatal; they represent attempts to open sessions which are invalid (for example, using malformed\n URLs).\n */\n@property (nullable, nonatomic, copy) RLMSyncErrorReportingBlock errorHandler;\n\n/**\n A reverse-DNS string uniquely identifying this application. In most cases this is automatically set by the SDK, and\n does not have to be explicitly configured.\n */\n@property (nonatomic, copy) NSString *appID;\n\n/**\n Whether SSL certificate validation should be disabled. SSL certificate validation is ON by default. Setting this\n property after at least one synced Realm or standalone Session has been opened is a no-op.\n\n @warning NEVER disable certificate validation for clients and servers in production.\n */\n@property (nonatomic) BOOL disableSSLValidation;\n\n/**\n The logging threshold which newly opened synced Realms will use. Defaults to `RLMSyncLogLevelInfo`. Set this before\n any synced Realms are opened. Logging strings are output to ASL.\n */\n@property (nonatomic) RLMSyncLogLevel logLevel;\n\n/// The sole instance of the singleton.\n+ (instancetype)sharedManager NS_REFINED_FOR_SWIFT;\n\n/// :nodoc:\n- (instancetype)init __attribute__((unavailable(\"RLMSyncManager cannot be created directly\")));\n\n/// :nodoc:\n+ (instancetype)new __attribute__((unavailable(\"RLMSyncManager cannot be created directly\")));\n\nNS_ASSUME_NONNULL_END\n\n@end\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMSyncPermission.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2016 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n#import <Realm/RLMObject.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n This model is used to reflect permissions.\n\n It should be used in conjunction with a `RLMSyncUser`'s Permission Realm.\n You can only read this Realm. Use the objects in Management Realm to\n make request for modifications of permissions.\n\n See https://realm.io/docs/realm-object-server/#permissions for general\n documentation.\n */\n@interface RLMSyncPermission : RLMObject\n\n/// The date this object was last modified.\n@property (readonly) NSDate *updatedAt;\n\n/// The identity of a user affected by this permission.\n@property (readonly) NSString *userId;\n\n/// The path to the realm.\n@property (readonly) NSString *path;\n\n/// Whether the affected user is allowed to read from the Realm.\n@property (readonly) BOOL mayRead;\n/// Whether the affected user is allowed to write to the Realm.\n@property (readonly) BOOL mayWrite;\n/// Whether the affected user is allowed to manage the access rights for others.\n@property (readonly) BOOL mayManage;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMSyncPermissionChange.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2016 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n#import <Realm/RLMObject.h>\n#import <Realm/RLMProperty.h>\n#import <Realm/RLMSyncUtil.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n This model is used for requesting changes to a Realm's permissions.\n\n It should be used in conjunction with an `RLMSyncUser`'s Management Realm.\n\n See https://realm.io/docs/realm-object-server/#permissions for general\n documentation.\n */\n@interface RLMSyncPermissionChange : RLMObject\n\n/// The globally unique ID string of this permission change object.\n@property (readonly) NSString *id;\n\n/// The date this object was initially created.\n@property (readonly) NSDate *createdAt;\n\n/// The date this object was last modified.\n@property (readonly) NSDate *updatedAt;\n\n/// The status code of the object that was processed by Realm Object Server.\n@property (nullable, readonly) NSNumber<RLMInt> *statusCode;\n\n/// An error or informational message, typically written to by the Realm Object Server.\n@property (nullable, readonly) NSString *statusMessage;\n\n/// Sync management object status.\n@property (readonly) RLMSyncManagementObjectStatus status;\n\n/// The remote URL to the realm.\n@property (readonly) NSString *realmUrl;\n\n/// The identity of a user affected by this permission change.\n@property (readonly) NSString *userId;\n\n/// Define read access. Set to `YES` or `NO` to update this value. Leave unset to preserve the existing setting.\n@property (nullable, readonly) NSNumber<RLMBool> *mayRead;\n/// Define write access. Set to `YES` or `NO` to update this value. Leave unset to preserve the existing setting.\n@property (nullable, readonly) NSNumber<RLMBool> *mayWrite;\n/// Define management access. Set to `YES` or `NO` to update this value. Leave unset to preserve the existing setting.\n@property (nullable, readonly) NSNumber<RLMBool> *mayManage;\n\n/**\n Construct a permission change object used to change the access permissions for a user on a Realm.\n\n @param realmURL  The Realm URL whose permissions settings should be changed.\n                  Use `*` to change the permissions of all Realms managed by the Management Realm's `RLMSyncUser`.\n @param userID    The user or users who should be granted these permission changes.\n                  Use `*` to change the permissions for all users.\n @param mayRead   Define read access. Set to `YES` or `NO` to update this value.\n                  Leave unset to preserve the existing setting.\n @param mayWrite  Define write access. Set to `YES` or `NO` to update this value.\n                  Leave unset to preserve the existing setting.\n @param mayManage Define management access. Set to `YES` or `NO` to update this value.\n                  Leave unset to preserve the existing setting.\n */\n+ (instancetype)permissionChangeWithRealmURL:(NSString *)realmURL\n                                      userID:(NSString *)userID\n                                        read:(nullable NSNumber<RLMBool> *)mayRead\n                                       write:(nullable NSNumber<RLMBool> *)mayWrite\n                                      manage:(nullable NSNumber<RLMBool> *)mayManage;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMSyncPermissionOffer.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2016 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n#import <Realm/RLMObject.h>\n#import <Realm/RLMProperty.h>\n#import <Realm/RLMSyncUtil.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n This model is used for offering permission changes to other users.\n\n It should be used in conjunction with an `RLMSyncUser`'s Management Realm.\n\n See https://realm.io/docs/realm-object-server/#permissions for general\n documentation.\n */\n@interface RLMSyncPermissionOffer : RLMObject\n\n/// The globally unique ID string of this permission offer object.\n@property (readonly) NSString *id;\n\n/// The date this object was initially created.\n@property (readonly) NSDate *createdAt;\n\n/// The date this object was last modified.\n@property (readonly) NSDate *updatedAt;\n\n/// The status code of the object that was processed by Realm Object Server.\n@property (nullable, readonly) NSNumber<RLMInt> *statusCode;\n\n/// An error or informational message, typically written to by the Realm Object Server.\n@property (nullable, readonly) NSString *statusMessage;\n\n/// Sync management object status.\n@property (readonly) RLMSyncManagementObjectStatus status;\n\n/// A token which uniquely identifies this offer. Generated by the server.\n@property (nullable, readonly) NSString *token;\n\n/// The remote URL to the realm.\n@property (readonly) NSString *realmUrl;\n\n/// Whether this offer allows the receiver to read from the Realm.\n@property (readonly) BOOL mayRead;\n\n/// Whether this offer allows the receiver to write to the Realm.\n@property (readonly) BOOL mayWrite;\n\n/// Whether this offer allows the receiver to manage the access rights for others.\n@property (readonly) BOOL mayManage;\n\n/// When this token will expire and become invalid.\n@property (nullable, readonly) NSDate *expiresAt;\n\n/**\n Construct a permission offer object used to offer permission changes to other users.\n\n @param realmURL  The URL to the Realm on which to apply these permission changes\n                  to, once the offer is accepted.\n @param expiresAt When this token will expire and become invalid.\n                  Pass `nil` if this offer should not expire.\n @param mayRead   Grant or revoke read access.\n @param mayWrite  Grant or revoked read-write access.\n @param mayManage Grant or revoke administrative access.\n */\n+ (instancetype)permissionOfferWithRealmURL:(NSString *)realmURL\n                                  expiresAt:(nullable NSDate *)expiresAt\n                                       read:(BOOL)mayRead\n                                      write:(BOOL)mayWrite\n                                     manage:(BOOL)mayManage;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMSyncPermissionOfferResponse.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2016 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Realm/Realm.h>\n#import <Realm/RLMSyncUtil.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n This model is used to apply permission changes defined in the permission offer\n object represented by the specified token, which was created by another user's\n `RLMSyncPermissionOffer` object.\n\n It should be used in conjunction with an `RLMSyncUser`'s Management Realm.\n\n See https://realm.io/docs/realm-object-server/#permissions for general\n documentation.\n */\n@interface RLMSyncPermissionOfferResponse : RLMObject\n\n/// The globally unique ID string of this permission offer response object.\n@property (readonly) NSString *id;\n\n/// The date this object was initially created.\n@property (readonly) NSDate *createdAt;\n\n/// The date this object was last modified.\n@property (readonly) NSDate *updatedAt;\n\n/// The status code of the object that was processed by Realm Object Server.\n@property (nullable, readonly) NSNumber<RLMInt> *statusCode;\n\n/// An error or informational message, typically written to by the Realm Object Server.\n@property (nullable, readonly) NSString *statusMessage;\n\n/// Sync management object status.\n@property (readonly) RLMSyncManagementObjectStatus status;\n\n/// The received token which uniquely identifies another user's `RLMSyncPermissionOffer`.\n@property (readonly) NSString *token;\n\n/// The remote URL to the realm on which these permission changes were applied.\n/// Generated by the server.\n@property (nullable, readonly) NSString *realmUrl;\n\n/**\n Construct a permission offer response object used to apply permission changes\n defined in the permission offer object represented by the specified token,\n which was created by another user's `RLMSyncPermissionOffer` object.\n\n @param token The received token which uniquely identifies another user's\n              `RLMSyncPermissionOffer`.\n */\n+ (instancetype)permissionOfferResponseWithToken:(NSString *)token;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMSyncSession.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2016 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n\n#import \"RLMRealm.h\"\n\n/**\n The current state of the session represented by an `RLMSyncSession` object.\n */\ntypedef NS_ENUM(NSUInteger, RLMSyncSessionState) {\n    /// The sync session is bound to the Realm Object Server and communicating with it.\n    RLMSyncSessionStateActive,\n    /// The sync session is not currently communicating with the Realm Object Server.\n    RLMSyncSessionStateInactive,\n    /// The sync session encountered a fatal error and is permanently invalid; it should be discarded.\n    RLMSyncSessionStateInvalid\n};\n\n/**\n The transfer direction (upload or download) tracked by a given progress notification block.\n\n Progress notification blocks can be registered on sessions if your app wishes to be informed\n how many bytes have been uploaded or downloaded, for example to show progress indicator UIs.\n */\ntypedef NS_ENUM(NSUInteger, RLMSyncProgressDirection) {\n    /// For monitoring upload progress.\n    RLMSyncProgressDirectionUpload,\n    /// For monitoring download progress.\n    RLMSyncProgressDirectionDownload,\n};\n\n/**\n The desired behavior of a progress notification block.\n\n Progress notification blocks can be registered on sessions if your app wishes to be informed\n how many bytes have been uploaded or downloaded, for example to show progress indicator UIs.\n */\ntypedef NS_ENUM(NSUInteger, RLMSyncProgress) {\n    /**\n     The block will be called forever, or until it is unregistered by calling\n     `-[RLMProgressNotificationToken stop]`.\n\n     Notifications will always report the latest number of transferred bytes, and the\n     most up-to-date number of total transferrable bytes.\n     */\n    RLMSyncProgressReportIndefinitely,\n    /**\n     The block will, upon registration, store the total number of bytes\n     to be transferred. When invoked, it will always report the most up-to-date number\n     of transferrable bytes out of that original number of transferrable bytes.\n\n     When the number of transferred bytes reaches or exceeds the\n     number of transferrable bytes, the block will be unregistered.\n     */\n    RLMSyncProgressForCurrentlyOutstandingWork,\n};\n\n@class RLMSyncUser, RLMSyncConfiguration;\n\n/**\n The type of a progress notification block intended for reporting a session's network\n activity to the user.\n\n `transferredBytes` refers to the number of bytes that have been uploaded or downloaded.\n `transferrableBytes` refers to the total number of bytes transferred, and pending transfer.\n */\ntypedef void(^RLMProgressNotificationBlock)(NSUInteger transferredBytes, NSUInteger transferrableBytes);\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n A token object corresponding to a progress notification block on an `RLMSyncSession`.\n\n To stop notifications manually, call `-stop` on it. Notifications should be stopped before\n the token goes out of scope or is destroyed.\n */\n@interface RLMProgressNotificationToken : RLMNotificationToken\n@end\n\n/**\n An object encapsulating a Realm Object Server \"session\". Sessions represent the\n communication between the client (and a local Realm file on disk), and the server\n (and a remote Realm at a given URL stored on a Realm Object Server).\n\n Sessions are always created by the SDK and vended out through various APIs. The lifespans\n of sessions associated with Realms are managed automatically.\n */\n@interface RLMSyncSession : NSObject\n\n/// The session's current state.\n@property (nonatomic, readonly) RLMSyncSessionState state;\n\n/// The Realm Object Server URL of the remote Realm this session corresponds to.\n@property (nullable, nonatomic, readonly) NSURL *realmURL;\n\n/// The user that owns this session.\n- (nullable RLMSyncUser *)parentUser;\n\n/**\n If the session is valid, return a sync configuration that can be used to open the Realm\n associated with this session.\n */\n- (nullable RLMSyncConfiguration *)configuration;\n\n/**\n Register a progress notification block.\n\n Multiple blocks can be registered with the same session at once. Each block\n will be invoked on a side queue devoted to progress notifications.\n \n If the session has already received progress information from the\n synchronization subsystem, the block will be called immediately. Otherwise, it\n will be called as soon as progress information becomes available.\n\n The token returned by this method must be retained as long as progress\n notifications are desired, and the `-stop` method should be called on it\n when notifications are no longer needed and before the token is destroyed.\n\n If no token is returned, the notification block will never be called again.\n There are a number of reasons this might be true. If the session has previously\n experienced a fatal error it will not accept progress notification blocks. If\n the block was configured in the `RLMSyncProgressForCurrentlyOutstandingWork`\n mode but there is no additional progress to report (for example, the number\n of transferrable bytes and transferred bytes are equal), the block will not be\n called again.\n\n @param direction The transfer direction (upload or download) to track in this progress notification block.\n @param mode      The desired behavior of this progress notification block.\n @param block     The block to invoke when notifications are available.\n\n @return A token which must be held for as long as you want notifications to be delivered.\n\n @see `RLMSyncProgressDirection`, `RLMSyncProgress`, `RLMProgressNotificationBlock`, `RLMProgressNotificationToken`\n */\n- (nullable RLMProgressNotificationToken *)addProgressNotificationForDirection:(RLMSyncProgressDirection)direction\n                                                                          mode:(RLMSyncProgress)mode\n                                                                         block:(RLMProgressNotificationBlock)block\nNS_REFINED_FOR_SWIFT;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMSyncUser.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2016 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n\n@class RLMSyncUser, RLMSyncCredentials, RLMSyncSession, RLMRealm;\n\n/**\n The state of the user object.\n */\ntypedef NS_ENUM(NSUInteger, RLMSyncUserState) {\n    /// The user is logged out. Call `logInWithCredentials:...` with valid credentials to log the user back in.\n    RLMSyncUserStateLoggedOut,\n    /// The user is logged in, and any Realms associated with it are syncing with the Realm Object Server.\n    RLMSyncUserStateActive,\n    /// The user has encountered a fatal error state, and cannot be used.\n    RLMSyncUserStateError,\n};\n\n/// A block type used for APIs which asynchronously vend an `RLMSyncUser`.\ntypedef void(^RLMUserCompletionBlock)(RLMSyncUser * _Nullable, NSError * _Nullable);\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n A `RLMSyncUser` instance represents a single Realm Object Server user account (or just user).\n\n A user may have one or more credentials associated with it. These credentials uniquely identify the user to a\n third-party auth provider, and are used to sign into a Realm Object Server user account.\n\n Note that users are only vended out via SDK APIs, and only one user instance ever exists for a given user account.\n */\n@interface RLMSyncUser : NSObject\n\n/**\n A dictionary of all valid, logged-in user identities corresponding to their `RLMSyncUser` objects.\n */\n+ (NSDictionary<NSString *, RLMSyncUser *> *)allUsers NS_REFINED_FOR_SWIFT;\n\n/**\n The logged-in user. `nil` if none exists.\n\n @warning Throws an exception if more than one logged-in user exists.\n */\n+ (nullable RLMSyncUser *)currentUser NS_REFINED_FOR_SWIFT;\n\n/**\n The unique Realm Object Server user ID string identifying this user.\n */\n@property (nullable, nonatomic, readonly) NSString *identity;\n\n/**\n The URL of the authentication server this user will communicate with.\n */\n@property (nullable, nonatomic, readonly) NSURL *authenticationServer;\n\n/**\n The current state of the user.\n */\n@property (nonatomic, readonly) RLMSyncUserState state;\n\n/**\n Create, log in, and asynchronously return a new user object, specifying a custom timeout for the network request.\n Credentials identifying the user must be passed in. The user becomes available in the completion block, at which point\n it is ready for use.\n */\n+ (void)logInWithCredentials:(RLMSyncCredentials *)credentials\n               authServerURL:(NSURL *)authServerURL\n                     timeout:(NSTimeInterval)timeout\n                onCompletion:(RLMUserCompletionBlock)completion NS_REFINED_FOR_SWIFT;\n\n/**\n Create, log in, and asynchronously return a new user object. Credentials identifying the user must be passed in. The\n user becomes available in the completion block, at which point it is ready for use.\n */\n+ (void)logInWithCredentials:(RLMSyncCredentials *)credentials\n               authServerURL:(NSURL *)authServerURL\n                onCompletion:(RLMUserCompletionBlock)completion\nNS_SWIFT_UNAVAILABLE(\"Use the full version of this API.\");\n\n/**\n Log a user out, destroying their server state, deregistering them from the SDK, and removing any synced Realms\n associated with them from on-disk storage. If the user is already logged out or in an error state, this is a no-op.\n\n This method should be called whenever the application is committed to not using a user again unless they are recreated.\n Failing to call this method may result in unused files and metadata needlessly taking up space.\n */\n- (void)logOut;\n\n/**\n Retrieve a valid session object belonging to this user for a given URL, or `nil` if no such object exists.\n */\n- (nullable RLMSyncSession *)sessionForURL:(NSURL *)url;\n\n/**\n Retrieve all the valid sessions belonging to this user.\n */\n- (NSArray<RLMSyncSession *> *)allSessions;\n\n/**\n Returns an instance of the Management Realm owned by the user.\n\n This Realm can be used to control access permissions for Realms managed by the user.\n This includes granting other users access to Realms.\n */\n- (RLMRealm *)managementRealmWithError:(NSError **)error NS_REFINED_FOR_SWIFT;\n\n/**\n Returns an instance of the Permission Realm owned by the user.\n\n This read-only Realm contains `RLMSyncPermission` objects reflecting the\n synchronized Realms and permission details this user has access to.\n */\n- (RLMRealm *)permissionRealmWithError:(NSError **)error NS_REFINED_FOR_SWIFT;\n\n/// :nodoc:\n- (instancetype)init __attribute__((unavailable(\"RLMSyncUser cannot be created directly\")));\n\n/// :nodoc:\n+ (instancetype)new __attribute__((unavailable(\"RLMSyncUser cannot be created directly\")));\n\nNS_ASSUME_NONNULL_END\n\n@end\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMSyncUtil.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2016 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Realm/RLMConstants.h>\n\n/// A token originating from the Realm Object Server.\ntypedef NSString* RLMServerToken;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/// A user info key for use with `RLMSyncErrorClientResetError`.\nextern NSString *const kRLMSyncPathOfRealmBackupCopyKey;\n\n/// A user info key for use with `RLMSyncErrorClientResetError`.\nextern NSString *const kRLMSyncInitiateClientResetBlockKey;\n\n/// The error domain string for all SDK errors related to synchronization functionality.\nextern NSString *const RLMSyncErrorDomain;\n\n/// An error which is related to authentication to a Realm Object Server.\ntypedef RLM_ERROR_ENUM(NSInteger, RLMSyncAuthError, RLMSyncErrorDomain) {\n    /// An error that indicates that the provided credentials are invalid.\n    RLMSyncAuthErrorInvalidCredential   = 611,\n\n    /// An error that indicates that the user with provided credentials does not exist.\n    RLMSyncAuthErrorUserDoesNotExist    = 612,\n\n    /// An error that indicates that the user cannot be registered as it exists already.\n    RLMSyncAuthErrorUserAlreadyExists   = 613,\n};\n\n/// An error which is related to synchronization with a Realm Object Server.\ntypedef RLM_ERROR_ENUM(NSInteger, RLMSyncError, RLMSyncErrorDomain) {\n    /// An error that indicates that the response received from the authentication server was malformed.\n    RLMSyncErrorBadResponse             = 1,\n\n    /// An error that indicates that the supplied Realm path was invalid, or could not be resolved by the authentication\n    /// server.\n    RLMSyncErrorBadRemoteRealmPath      = 2,\n\n    /// An error that indicates that the response received from the authentication server was an HTTP error code. The\n    /// `userInfo` dictionary contains the actual error code value.\n    RLMSyncErrorHTTPStatusCodeError     = 3,\n\n    /// An error that indicates a problem with the session (a specific Realm opened for sync).\n    RLMSyncErrorClientSessionError      = 4,\n\n    /// An error that indicates a problem with a specific user.\n    RLMSyncErrorClientUserError         = 5,\n\n    /// An error that indicates an internal, unrecoverable error with the underlying synchronization engine.\n    RLMSyncErrorClientInternalError     = 6,\n\n    /**\n     An error that indicates the Realm needs to be reset.\n\n     A synced Realm may need to be reset because the Realm Object Server encountered an\n     error and had to be restored from a backup. If the backup copy of the remote Realm\n     is of an earlier version than the local copy of the Realm, the server will ask the\n     client to reset the Realm.\n\n     The reset process is as follows: the local copy of the Realm is copied into a recovery\n     directory for safekeeping, and then deleted from the original location. The next time\n     the Realm for that URL is opened, the Realm will automatically be re-downloaded from the\n     Realm Object Server, and can be used as normal.\n\n     Data written to the Realm after the local copy of the Realm diverged from the backup\n     remote copy will be present in the local recovery copy of the Realm file. The\n     re-downloaded Realm will initially contain only the data present at the time the Realm\n     was backed up on the server.\n\n     The client reset process can be initiated in one of two ways. The block provided in the\n     `userInfo` dictionary under `kRLMSyncInitiateClientResetBlockKey` can be called to\n     initiate the reset process. This block can be called any time after the error is\n     received, but should only be called if and when your app closes and invalidates every\n     instance of the offending Realm on all threads (note that autorelease pools may make this\n     difficult to guarantee).\n\n     If the block is not called, the client reset process will be automatically carried out\n     the next time the app is launched and the `RLMSyncManager` singleton is accessed.\n\n     The value for the `kRLMSyncPathOfRealmBackupCopyKey` key in the `userInfo` dictionary\n     describes the path of the recovered copy of the Realm. This copy will not actually be\n     created until the client reset process is initiated.\n\n     @see: `-[NSError rlmSync_clientResetBlock]`, `-[NSError rlmSync_clientResetBackedUpRealmPath]`\n     */\n    RLMSyncErrorClientResetError        = 7,\n};\n\n/// An enum representing the different states a sync management object can take.\ntypedef NS_ENUM(NSUInteger, RLMSyncManagementObjectStatus) {\n    /// The management object has not yet been processed by the object server.\n    RLMSyncManagementObjectStatusNotProcessed,\n    /// The operations encoded in the management object have been successfully\n    /// performed by the object server.\n    RLMSyncManagementObjectStatusSuccess,\n    /**\n     The operations encoded in the management object were not successfully\n     performed by the object server.\n     Refer to the `statusCode` and `statusMessage` properties for more details\n     about the error.\n     */\n    RLMSyncManagementObjectStatusError,\n};\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/RLMThreadSafeReference.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2016 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n\n@class RLMRealm;\n\nNS_ASSUME_NONNULL_BEGIN\n\n/**\n Objects of types which conform to `RLMThreadConfined` can be managed by a Realm, which will make\n them bound to a thread-specific `RLMRealm` instance. Managed objects must be explicitly exported\n and imported to be passed between threads.\n\n Managed instances of objects conforming to this protocol can be converted to a thread-safe\n reference for transport between threads by passing to the\n `+[RLMThreadSafeReference referenceWithThreadConfined:]` constructor.\n\n Note that only types defined by Realm can meaningfully conform to this protocol, and defining new\n classes which attempt to conform to it will not make them work with `RLMThreadSafeReference`.\n */\n@protocol RLMThreadConfined <NSObject>\n// Conformance to the `RLMThreadConfined_Private` protocol will be enforced at runtime.\n\n/**\n The Realm which manages the object, or `nil` if the object is unmanaged.\n\n Unmanaged objects are not confined to a thread and cannot be passed to methods expecting a\n `RLMThreadConfined` object.\n */\n@property (nonatomic, readonly, nullable) RLMRealm *realm;\n\n/// Indicates if the object can no longer be accessed because it is now invalid.\n@property (nonatomic, readonly, getter = isInvalidated) BOOL invalidated;\n\n@end\n\n/**\n An object intended to be passed between threads containing a thread-safe reference to its\n thread-confined object.\n\n To resolve a thread-safe reference on a target Realm on a different thread, pass to\n `-[RLMRealm resolveThreadSafeReference:]`.\n\n @warning A `RLMThreadSafeReference` object must be resolved at most once.\n          Failing to resolve a `RLMThreadSafeReference` will result in the source version of the\n          Realm being pinned until the reference is deallocated.\n\n @note Prefer short-lived `RLMThreadSafeReference`s as the data for the version of the source Realm\n       will be retained until all references have been resolved or deallocated.\n\n @see `RLMThreadConfined`\n @see `-[RLMRealm resolveThreadSafeReference:]`\n */\n@interface RLMThreadSafeReference<__covariant Confined : id<RLMThreadConfined>> : NSObject\n\n/**\n Create a thread-safe reference to the thread-confined object.\n\n @param threadConfined The thread-confined object to create a thread-safe reference to.\n\n @note You may continue to use and access the thread-confined object after passing it to this\n       constructor.\n */\n+ (instancetype)referenceWithThreadConfined:(Confined)threadConfined;\n\n/**\n Indicates if the reference can no longer be resolved because an attempt to resolve it has already\n occurred. References can only be resolved once.\n */\n@property (nonatomic, readonly, getter = isInvalidated) BOOL invalidated;\n\n#pragma mark - Unavailable Methods\n\n/**\n `-[RLMThreadSafeReference init]` is not available because `RLMThreadSafeReference` cannot be\n created directly. `RLMThreadSafeReference` instances must be obtained by calling\n `-[RLMRealm resolveThreadSafeReference:]`.\n */\n- (instancetype)init __attribute__((unavailable(\"RLMThreadSafeReference cannot be created directly\")));\n\n/**\n `-[RLMThreadSafeReference new]` is not available because `RLMThreadSafeReference` cannot be\n created directly. `RLMThreadSafeReference` instances must be obtained by calling\n `-[RLMRealm resolveThreadSafeReference:]`.\n */\n+ (instancetype)new __attribute__((unavailable(\"RLMThreadSafeReference cannot be created directly\")));\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Headers/Realm.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n\n#import <Realm/RLMArray.h>\n#import <Realm/RLMMigration.h>\n#import <Realm/RLMObject.h>\n#import <Realm/RLMObjectSchema.h>\n#import <Realm/RLMPlatform.h>\n#import <Realm/RLMProperty.h>\n#import <Realm/RLMRealm.h>\n#import <Realm/RLMRealmConfiguration.h>\n#import <Realm/RLMRealmConfiguration+Sync.h>\n#import <Realm/RLMResults.h>\n#import <Realm/RLMSchema.h>\n#import <Realm/RLMSyncConfiguration.h>\n#import <Realm/RLMSyncCredentials.h>\n#import <Realm/RLMSyncManager.h>\n#import <Realm/RLMSyncPermission.h>\n#import <Realm/RLMSyncPermissionChange.h>\n#import <Realm/RLMSyncPermissionOffer.h>\n#import <Realm/RLMSyncPermissionOfferResponse.h>\n#import <Realm/RLMSyncSession.h>\n#import <Realm/RLMSyncUser.h>\n#import <Realm/RLMSyncUtil.h>\n#import <Realm/NSError+RLMSync.h>\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Modules/module.modulemap",
    "content": "framework module Realm {\n    umbrella header \"Realm.h\"\n\n    export *\n    module * { export * }\n\n    explicit module Private {\n        header \"RLMAccessor.h\"\n        header \"RLMArray_Private.h\"\n        header \"RLMListBase.h\"\n        header \"RLMObjectBase_Dynamic.h\"\n        header \"RLMObjectSchema_Private.h\"\n        header \"RLMObjectStore.h\"\n        header \"RLMObject_Private.h\"\n        header \"RLMOptionalBase.h\"\n        header \"RLMProperty_Private.h\"\n        header \"RLMRealmConfiguration_Private.h\"\n        header \"RLMRealm_Private.h\"\n        header \"RLMResults_Private.h\"\n        header \"RLMSchema_Private.h\"\n        header \"RLMSyncConfiguration_Private.h\"\n        header \"RLMSyncUtil_Private.h\"\n    }\n\n    explicit module Dynamic {\n        header \"RLMRealm_Dynamic.h\"\n        header \"RLMObjectBase_Dynamic.h\"\n    }\n}\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/PrivateHeaders/RLMAccessor.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n\n\n@class RLMObjectSchema, RLMProperty, RLMObjectBase, RLMProperty;\n\n#ifdef __cplusplus\ntypedef NSUInteger RLMCreationOptions;\n#else\ntypedef NS_OPTIONS(NSUInteger, RLMCreationOptions);\n#endif\n\nNS_ASSUME_NONNULL_BEGIN\n\n//\n// Accessors Class Creation/Caching\n//\n\n// get accessor classes for an object class - generates classes if not cached\nClass RLMManagedAccessorClassForObjectClass(Class objectClass, RLMObjectSchema *schema, const char *name);\nClass RLMUnmanagedAccessorClassForObjectClass(Class objectClass, RLMObjectSchema *schema);\n\n//\n// Dynamic getters/setters\n//\nFOUNDATION_EXTERN void RLMDynamicValidatedSet(RLMObjectBase *obj, NSString *propName, id __nullable val);\nFOUNDATION_EXTERN id __nullable RLMDynamicGet(RLMObjectBase *obj, RLMProperty *prop);\nFOUNDATION_EXTERN id __nullable RLMDynamicGetByName(RLMObjectBase *obj, NSString *propName, bool asList);\n\n// by property/column\nvoid RLMDynamicSet(RLMObjectBase *obj, RLMProperty *prop, id val, RLMCreationOptions options);\n\n//\n// Class modification\n//\n\n// Replace className method for the given class\nvoid RLMReplaceClassNameMethod(Class accessorClass, NSString *className);\n\n// Replace sharedSchema method for the given class\nvoid RLMReplaceSharedSchemaMethod(Class accessorClass, RLMObjectSchema * __nullable schema);\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/PrivateHeaders/RLMArray_Private.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Realm/RLMArray.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface RLMArray ()\n- (instancetype)initWithObjectClassName:(NSString *)objectClassName;\n- (NSString *)descriptionWithMaxDepth:(NSUInteger)depth;\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/PrivateHeaders/RLMListBase.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n\n@class RLMArray;\n\nNS_ASSUME_NONNULL_BEGIN\n\n// A base class for Swift generic Lists to make it possible to interact with\n// them from obj-c\n@interface RLMListBase : NSObject <NSFastEnumeration>\n@property (nonatomic, strong) RLMArray *_rlmArray;\n\n- (instancetype)initWithArray:(RLMArray *)array;\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/PrivateHeaders/RLMMigration_Private.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Realm/RLMMigration.h>\n#import <Realm/RLMObjectBase.h>\n#import <Realm/RLMRealm.h>\n\nnamespace realm {\n    class Schema;\n}\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface RLMMigration ()\n\n@property (nonatomic, strong) RLMRealm *oldRealm;\n@property (nonatomic, strong) RLMRealm *realm;\n\n- (instancetype)initWithRealm:(RLMRealm *)realm oldRealm:(RLMRealm *)oldRealm schema:(realm::Schema &)schema;\n\n- (void)execute:(RLMMigrationBlock)block;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/PrivateHeaders/RLMObjectSchema_Private.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Realm/RLMObjectSchema.h>\n\n#import <objc/runtime.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n// RLMObjectSchema private\n@interface RLMObjectSchema () {\n@public\n    bool _isSwiftClass;\n}\n\n/// The object type name reported to the object store and core.\n@property (nonatomic, readonly) NSString *objectName;\n\n// writable redeclaration\n@property (nonatomic, readwrite, copy) NSArray<RLMProperty *> *properties;\n@property (nonatomic, readwrite, assign) bool isSwiftClass;\n\n// class used for this object schema\n@property (nonatomic, readwrite, assign) Class objectClass;\n@property (nonatomic, readwrite, assign) Class accessorClass;\n@property (nonatomic, readwrite, assign) Class unmanagedClass;\n\n@property (nonatomic, readwrite, nullable) RLMProperty *primaryKeyProperty;\n\n@property (nonatomic, copy) NSArray<RLMProperty *> *computedProperties;\n@property (nonatomic, readonly) NSArray<RLMProperty *> *swiftGenericProperties;\n\n// returns a cached or new schema for a given object class\n+ (instancetype)schemaForObjectClass:(Class)objectClass;\n@end\n\n@interface RLMObjectSchema (Dynamic)\n/**\n This method is useful only in specialized circumstances, for example, when accessing objects\n in a Realm produced externally. If you are simply building an app on Realm, it is not recommended\n to use this method as an [RLMObjectSchema](RLMObjectSchema) is generated automatically for every [RLMObject](RLMObject) subclass.\n \n Initialize an RLMObjectSchema with classname, objectClass, and an array of properties\n \n @warning This method is useful only in specialized circumstances.\n \n @param objectClassName     The name of the class used to refer to objects of this type.\n @param objectClass         The Objective-C class used when creating instances of this type.\n @param properties          An array of RLMProperty instances describing the managed properties for this type.\n \n @return    An initialized instance of RLMObjectSchema.\n */\n- (instancetype)initWithClassName:(NSString *)objectClassName objectClass:(Class)objectClass properties:(NSArray *)properties;\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/PrivateHeaders/RLMObjectStore.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n\n#ifdef __cplusplus\nextern \"C\" {\n#endif\n\n@class RLMRealm, RLMSchema, RLMObjectBase, RLMResults, RLMProperty;\n\nNS_ASSUME_NONNULL_BEGIN\n\n//\n// Accessor Creation\n//\n\n// create or get cached accessors for the given schema\nvoid RLMRealmCreateAccessors(RLMSchema *schema);\n\n\n//\n// Options for object creation\n//\ntypedef NS_OPTIONS(NSUInteger, RLMCreationOptions) {\n    // Normal object creation\n    RLMCreationOptionsNone = 0,\n    // If the property is a link or array property, upsert the linked objects\n    // if they have a primary key, and insert them otherwise.\n    RLMCreationOptionsCreateOrUpdate = 1 << 0,\n    // Allow unmanaged objects to be promoted to managed objects\n    // if false objects are copied during object creation\n    RLMCreationOptionsPromoteUnmanaged = 1 << 1,\n    // Use the SetDefault instruction.\n    RLMCreationOptionsSetDefault = 1 << 2,\n};\n\n\n//\n// Adding, Removing, Getting Objects\n//\n\n// add an object to the given realm\nvoid RLMAddObjectToRealm(RLMObjectBase *object, RLMRealm *realm, bool createOrUpdate);\n\n// delete an object from its realm\nvoid RLMDeleteObjectFromRealm(RLMObjectBase *object, RLMRealm *realm);\n\n// deletes all objects from a realm\nvoid RLMDeleteAllObjectsFromRealm(RLMRealm *realm);\n\n// get objects of a given class\nRLMResults *RLMGetObjects(RLMRealm *realm, NSString *objectClassName, NSPredicate * _Nullable predicate)\nNS_RETURNS_RETAINED;\n\n// get an object with the given primary key\nid _Nullable RLMGetObject(RLMRealm *realm, NSString *objectClassName, id _Nullable key) NS_RETURNS_RETAINED;\n\n// create object from array or dictionary\nRLMObjectBase *RLMCreateObjectInRealmWithValue(RLMRealm *realm, NSString *className, id _Nullable value, bool createOrUpdate)\nNS_RETURNS_RETAINED;\n    \n\n//\n// Accessor Creation\n//\n\n\n// switch List<> properties from being backed by unmanaged RLMArrays to RLMArrayLinkView\nvoid RLMInitializeSwiftAccessorGenerics(RLMObjectBase *object);\n\n#ifdef __cplusplus\n}\n\nnamespace realm {\n    class Table;\n    template<typename T> class BasicRowExpr;\n    using RowExpr = BasicRowExpr<Table>;\n}\nclass RLMClassInfo;\n\n// Create accessors\nRLMObjectBase *RLMCreateObjectAccessor(RLMRealm *realm, RLMClassInfo& info,\n                                       NSUInteger index) NS_RETURNS_RETAINED;\nRLMObjectBase *RLMCreateObjectAccessor(RLMRealm *realm, RLMClassInfo& info,\n                                       realm::RowExpr row) NS_RETURNS_RETAINED;\n#endif\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/PrivateHeaders/RLMObject_Private.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Realm/RLMObjectBase_Dynamic.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n// RLMObject accessor and read/write realm\n@interface RLMObjectBase () {\n@public\n    RLMRealm *_realm;\n    __unsafe_unretained RLMObjectSchema *_objectSchema;\n}\n\n// unmanaged initializer\n- (instancetype)initWithValue:(id)value schema:(RLMSchema *)schema NS_DESIGNATED_INITIALIZER;\n\n// live accessor initializer\n- (instancetype)initWithRealm:(__unsafe_unretained RLMRealm *const)realm\n                       schema:(RLMObjectSchema *)schema NS_DESIGNATED_INITIALIZER;\n\n// shared schema for this class\n+ (nullable RLMObjectSchema *)sharedSchema;\n\n// provide injection point for alternative Swift object util class\n+ (Class)objectUtilClass:(BOOL)isSwift;\n\n@end\n\n@interface RLMObject ()\n\n// unmanaged initializer\n- (instancetype)initWithValue:(id)value schema:(RLMSchema *)schema NS_DESIGNATED_INITIALIZER;\n\n// live accessor initializer\n- (instancetype)initWithRealm:(__unsafe_unretained RLMRealm *const)realm\n                       schema:(RLMObjectSchema *)schema NS_DESIGNATED_INITIALIZER;\n\n@end\n\n@interface RLMDynamicObject : RLMObject\n\n@end\n\n// A reference to an object's row that doesn't keep the object accessor alive.\n// Used by some Swift property types, such as LinkingObjects, to avoid retain cycles\n// with their containing object.\n@interface RLMWeakObjectHandle : NSObject<NSCopying>\n\n- (instancetype)initWithObject:(RLMObjectBase *)object;\n\n// Consumes the row, so can only usefully be called once.\n@property (nonatomic, readonly) RLMObjectBase *object;\n\n@end\n\n// Calls valueForKey: and re-raises NSUndefinedKeyExceptions\nFOUNDATION_EXTERN id _Nullable RLMValidatedValueForProperty(id object, NSString *key, NSString *className);\n\n// Compare two RLObjectBases\nFOUNDATION_EXTERN BOOL RLMObjectBaseAreEqual(RLMObjectBase * _Nullable o1, RLMObjectBase * _Nullable o2);\n\ntypedef void (^RLMObjectNotificationCallback)(NSArray<NSString *> *_Nullable propertyNames,\n                                              NSArray *_Nullable oldValues,\n                                              NSArray *_Nullable newValues,\n                                              NSError *_Nullable error);\nFOUNDATION_EXTERN RLMNotificationToken *RLMObjectAddNotificationBlock(RLMObjectBase *obj, RLMObjectNotificationCallback block);\n\n// Get ObjectUil class for objc or swift\nFOUNDATION_EXTERN Class RLMObjectUtilClass(BOOL isSwift);\n\nFOUNDATION_EXTERN const NSUInteger RLMDescriptionMaxDepth;\n\n@class RLMProperty, RLMArray;\n@interface RLMObjectUtil : NSObject\n\n+ (nullable NSArray<NSString *> *)ignoredPropertiesForClass:(Class)cls;\n+ (nullable NSArray<NSString *> *)indexedPropertiesForClass:(Class)cls;\n+ (nullable NSDictionary<NSString *, NSDictionary<NSString *, NSString *> *> *)linkingObjectsPropertiesForClass:(Class)cls;\n\n+ (nullable NSArray<NSString *> *)getGenericListPropertyNames:(id)obj;\n+ (nullable NSDictionary<NSString *, NSString *> *)getLinkingObjectsProperties:(id)object;\n\n+ (nullable NSDictionary<NSString *, NSNumber *> *)getOptionalProperties:(id)obj;\n+ (nullable NSArray<NSString *> *)requiredPropertiesForClass:(Class)cls;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/PrivateHeaders/RLMOptionalBase.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2015 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Foundation/Foundation.h>\n#import <Realm/RLMConstants.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@class RLMObjectBase, RLMProperty;\n\n@interface RLMOptionalBase : NSProxy\n\n- (instancetype)init;\n\n@property (nonatomic, weak) RLMObjectBase *object;\n\n@property (nonatomic, unsafe_unretained) RLMProperty *property;\n\n@property (nonatomic, strong, nullable) id underlyingValue;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/PrivateHeaders/RLMProperty_Private.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Realm/RLMProperty.h>\n\n#import <objc/runtime.h>\n\n@class RLMObjectBase;\n\nNS_ASSUME_NONNULL_BEGIN\n\nBOOL RLMPropertyTypeIsNullable(RLMPropertyType propertyType);\nBOOL RLMPropertyTypeIsComputed(RLMPropertyType propertyType);\nFOUNDATION_EXTERN void RLMValidateSwiftPropertyName(NSString *name);\n\n// private property interface\n@interface RLMProperty () {\n@public\n    RLMPropertyType _type;\n    Ivar _swiftIvar;\n}\n\n- (instancetype)initWithName:(NSString *)name\n                     indexed:(BOOL)indexed\n      linkPropertyDescriptor:(nullable RLMPropertyDescriptor *)linkPropertyDescriptor\n                    property:(objc_property_t)property;\n\n- (instancetype)initSwiftPropertyWithName:(NSString *)name\n                                  indexed:(BOOL)indexed\n                   linkPropertyDescriptor:(nullable RLMPropertyDescriptor *)linkPropertyDescriptor\n                                 property:(objc_property_t)property\n                                 instance:(RLMObjectBase *)objectInstance;\n\n- (instancetype)initSwiftListPropertyWithName:(NSString *)name\n                                         ivar:(Ivar)ivar\n                              objectClassName:(nullable NSString *)objectClassName;\n\n- (instancetype)initSwiftOptionalPropertyWithName:(NSString *)name\n                                          indexed:(BOOL)indexed\n                                             ivar:(Ivar)ivar\n                                     propertyType:(RLMPropertyType)propertyType;\n\n- (instancetype)initSwiftLinkingObjectsPropertyWithName:(NSString *)name\n                                                   ivar:(Ivar)ivar\n                                        objectClassName:(nullable NSString *)objectClassName\n                                 linkOriginPropertyName:(nullable NSString *)linkOriginPropertyName;\n\n// private setters\n@property (nonatomic, readwrite) NSString *name;\n@property (nonatomic, readwrite, assign) RLMPropertyType type;\n@property (nonatomic, readwrite) BOOL indexed;\n@property (nonatomic, readwrite) BOOL optional;\n@property (nonatomic, copy, nullable) NSString *objectClassName;\n\n// private properties\n@property (nonatomic, assign) NSUInteger index;\n@property (nonatomic, assign) BOOL isPrimary;\n@property (nonatomic, assign) Ivar swiftIvar;\n\n// getter and setter names\n@property (nonatomic, copy) NSString *getterName;\n@property (nonatomic, copy) NSString *setterName;\n@property (nonatomic) SEL getterSel;\n@property (nonatomic) SEL setterSel;\n\n- (RLMProperty *)copyWithNewName:(NSString *)name;\n\n@end\n\n@interface RLMProperty (Dynamic)\n/**\n This method is useful only in specialized circumstances, for example, in conjunction with\n +[RLMObjectSchema initWithClassName:objectClass:properties:]. If you are simply building an\n app on Realm, it is not recommened to use this method.\n \n Initialize an RLMProperty\n \n @warning This method is useful only in specialized circumstances.\n \n @param name            The property name.\n @param type            The property type.\n @param objectClassName The object type used for Object and Array types.\n @param linkOriginPropertyName The property name of the origin of a link. Used for linking objects properties.\n\n @return    An initialized instance of RLMProperty.\n */\n- (instancetype)initWithName:(NSString *)name\n                        type:(RLMPropertyType)type\n             objectClassName:(nullable NSString *)objectClassName\n      linkOriginPropertyName:(nullable NSString *)linkOriginPropertyName\n                     indexed:(BOOL)indexed\n                    optional:(BOOL)optional;\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/PrivateHeaders/RLMRealmConfiguration_Private.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2015 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Realm/RLMRealmConfiguration.h>\n\n@class RLMSchema;\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface RLMRealmConfiguration ()\n\n@property (nonatomic, readwrite) bool cache;\n@property (nonatomic, readwrite) bool dynamic;\n@property (nonatomic, readwrite) bool disableFormatUpgrade;\n@property (nonatomic, copy, nullable) RLMSchema *customSchema;\n\n// Get the default confiugration without copying it\n+ (RLMRealmConfiguration *)rawDefaultConfiguration;\n\n+ (void)resetRealmConfigurationState;\n@end\n\n// Get a path in the platform-appropriate documents directory with the given filename\nFOUNDATION_EXTERN NSString *RLMRealmPathForFile(NSString *fileName);\nFOUNDATION_EXTERN NSString *RLMRealmPathForFileAndBundleIdentifier(NSString *fileName, NSString *mainBundleIdentifier);\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/PrivateHeaders/RLMRealm_Private.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Realm/RLMRealm.h>\n\n@class RLMFastEnumerator;\n\nNS_ASSUME_NONNULL_BEGIN\n\n// Disable syncing files to disk. Cannot be re-enabled. Use only for tests.\nFOUNDATION_EXTERN void RLMDisableSyncToDisk();\n\nFOUNDATION_EXTERN NSData * _Nullable RLMRealmValidatedEncryptionKey(NSData *key);\n\n// Translate an in-flight exception resulting from opening a SharedGroup to\n// an NSError or NSException (if error is nil)\nvoid RLMRealmTranslateException(NSError **error);\n\n// RLMRealm private members\n@interface RLMRealm ()\n\n@property (nonatomic, readonly) BOOL dynamic;\n@property (nonatomic, readwrite) RLMSchema *schema;\n\n+ (void)resetRealmState;\n\n- (void)registerEnumerator:(RLMFastEnumerator *)enumerator;\n- (void)unregisterEnumerator:(RLMFastEnumerator *)enumerator;\n- (void)detachAllEnumerators;\n\n- (void)sendNotifications:(RLMNotification)notification;\n- (void)verifyThread;\n- (void)verifyNotificationsAreSupported;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/PrivateHeaders/RLMResults_Private.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Realm/RLMResults.h>\n\n@class RLMObjectSchema;\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface RLMResults ()\n@property (nonatomic, readonly, getter=isAttached) BOOL attached;\n\n+ (instancetype)emptyDetachedResults;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/PrivateHeaders/RLMSchema_Private.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2014 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Realm/RLMSchema.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\n@class RLMRealm;\n\n//\n// RLMSchema private interface\n//\n@interface RLMSchema ()\n\n/**\n Returns an `RLMSchema` containing only the given `RLMObject` subclasses.\n\n @param classes The classes to be included in the schema.\n\n @return An `RLMSchema` containing only the given classes.\n */\n+ (instancetype)schemaWithObjectClasses:(NSArray<Class> *)classes;\n\n@property (nonatomic, readwrite, copy) NSArray<RLMObjectSchema *> *objectSchema;\n\n// schema based on runtime objects\n+ (instancetype)sharedSchema;\n\n// schema based upon all currently registered object classes\n+ (instancetype)partialSharedSchema;\n\n// class for string\n+ (nullable Class)classForString:(NSString *)className;\n\n+ (nullable RLMObjectSchema *)sharedSchemaForClass:(Class)cls;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/PrivateHeaders/RLMSyncConfiguration_Private.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2016 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Realm/RLMSyncConfiguration.h>\n\nNS_ASSUME_NONNULL_BEGIN\n\ntypedef NS_ENUM(NSUInteger, RLMSyncStopPolicy) {\n    RLMSyncStopPolicyImmediately,\n    RLMSyncStopPolicyLiveIndefinitely,\n    RLMSyncStopPolicyAfterChangesUploaded,\n};\n\n@interface RLMSyncConfiguration ()\n\n@property (nonatomic, readwrite) RLMSyncStopPolicy stopPolicy;\n\n// Internal-only APIs\n@property (nullable, nonatomic) NSURL *customFileURL;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/PrivateHeaders/RLMSyncPermissionChange_Private.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2016 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import \"RLMSyncPermissionChange.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface RLMSyncPermissionChange()\n\n@property (readwrite) NSString *id;\n@property (readwrite) NSDate *createdAt;\n@property (readwrite) NSDate *updatedAt;\n@property (nullable, readwrite) NSNumber<RLMInt> *statusCode;\n@property (nullable, readwrite) NSString *statusMessage;\n@property (readwrite) NSString *realmUrl;\n@property (readwrite) NSString *userId;\n\n@property (nullable, readwrite) NSNumber<RLMBool> *mayRead;\n@property (nullable, readwrite) NSNumber<RLMBool> *mayWrite;\n@property (nullable, readwrite) NSNumber<RLMBool> *mayManage;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/PrivateHeaders/RLMSyncPermissionOfferResponse_Private.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2016 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import \"RLMSyncPermissionOfferResponse.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface RLMSyncPermissionOfferResponse()\n\n@property (readwrite) NSString *id;\n@property (readwrite) NSDate *createdAt;\n@property (readwrite) NSDate *updatedAt;\n@property (nullable, readwrite) NSNumber<RLMInt> *statusCode;\n@property (nullable, readwrite) NSString *statusMessage;\n\n@property (readwrite) NSString *token;\n@property (nullable, readwrite) NSString *realmUrl;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/PrivateHeaders/RLMSyncPermissionOffer_Private.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2016 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import \"RLMSyncPermissionOffer.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface RLMSyncPermissionOffer()\n\n@property (readwrite) NSString *id;\n@property (readwrite) NSDate *createdAt;\n@property (readwrite) NSDate *updatedAt;\n@property (nullable, readwrite) NSNumber<RLMInt> *statusCode;\n@property (nullable, readwrite) NSString *statusMessage;\n\n@property (nullable, readwrite) NSString *token;\n@property (readwrite) NSString *realmUrl;\n\n@property (readwrite) BOOL mayRead;\n@property (readwrite) BOOL mayWrite;\n@property (readwrite) BOOL mayManage;\n\n@property (nullable, readwrite) NSDate *expiresAt;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/PrivateHeaders/RLMSyncPermission_Private.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2016 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import \"RLMSyncPermission.h\"\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface RLMSyncPermission()\n\n@property (readwrite) NSDate *updatedAt;\n@property (readwrite) NSString *userId;\n@property (readwrite) NSString *path;\n\n@property (readwrite) BOOL mayRead;\n@property (readwrite) BOOL mayWrite;\n@property (readwrite) BOOL mayManage;\n\n@end\n\nNS_ASSUME_NONNULL_END\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/PrivateHeaders/RLMSyncUtil_Private.h",
    "content": "////////////////////////////////////////////////////////////////////////////\n//\n// Copyright 2016 Realm Inc.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");\n// you may not use this file except in compliance with the License.\n// You may obtain a copy of the License at\n//\n// http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n//\n////////////////////////////////////////////////////////////////////////////\n\n#import <Realm/RLMSyncUtil.h>\n\n#import <Realm/RLMProperty.h>\n#import <Realm/RLMRealmConfiguration.h>\n#import <Realm/RLMSyncCredentials.h>\n\n@class RLMSyncUser;\n\ntypedef void(^RLMSyncCompletionBlock)(NSError * _Nullable, NSDictionary * _Nullable);\ntypedef void(^RLMSyncBasicErrorReportingBlock)(NSError * _Nullable);\n\ntypedef NSString* RLMServerPath;\n\nNS_ASSUME_NONNULL_BEGIN\n\n@interface RLMRealmConfiguration (RealmSync)\n+ (instancetype)managementConfigurationForUser:(RLMSyncUser *)user;\n+ (instancetype)permissionConfigurationForUser:(RLMSyncUser *)user;\n@end\n\nextern RLMIdentityProvider const RLMIdentityProviderAccessToken;\nextern RLMIdentityProvider const RLMIdentityProviderRealm;\n\nextern NSString *const kRLMSyncAppIDKey;\nextern NSString *const kRLMSyncDataKey;\nextern NSString *const kRLMSyncErrorJSONKey;\nextern NSString *const kRLMSyncErrorStatusCodeKey;\nextern NSString *const kRLMSyncIdentityKey;\nextern NSString *const kRLMSyncPasswordKey;\nextern NSString *const kRLMSyncPathKey;\nextern NSString *const kRLMSyncProviderKey;\nextern NSString *const kRLMSyncRegisterKey;\nextern NSString *const kRLMSyncUnderlyingErrorKey;\n\n/// Convert sync management object status code (nil, 0 and others) to\n/// RLMSyncManagementObjectStatus enum\nFOUNDATION_EXTERN RLMSyncManagementObjectStatus RLMMakeSyncManagementObjectStatus(NSNumber<RLMInt> * _Nullable statusCode);\n\n#define RLM_SYNC_UNINITIALIZABLE \\\n- (instancetype)init __attribute__((unavailable(\"This type cannot be created directly\"))); \\\n+ (instancetype)new __attribute__((unavailable(\"This type cannot be created directly\")));\n\nNS_ASSUME_NONNULL_END\n\n/// A macro to parse a string out of a JSON dictionary, or return nil.\n#define RLM_SYNC_PARSE_STRING_OR_ABORT(json_macro_val, key_macro_val, prop_macro_val) \\\n{ \\\nid data = json_macro_val[key_macro_val]; \\\nif (![data isKindOfClass:[NSString class]]) { return nil; } \\\nself.prop_macro_val = data; \\\n} \\\n\n#define RLM_SYNC_PARSE_OPTIONAL_STRING(json_macro_val, key_macro_val, prop_macro_val) \\\n{ \\\nid data = json_macro_val[key_macro_val]; \\\nif (![data isKindOfClass:[NSString class]]) { data = nil; } \\\nself.prop_macro_val = data; \\\n} \\\n\n/// A macro to parse a double out of a JSON dictionary, or return nil.\n#define RLM_SYNC_PARSE_DOUBLE_OR_ABORT(json_macro_val, key_macro_val, prop_macro_val) \\\n{ \\\nid data = json_macro_val[key_macro_val]; \\\nif (![data isKindOfClass:[NSNumber class]]) { return nil; } \\\nself.prop_macro_val = [data doubleValue]; \\\n} \\\n\n/// A macro to build a sub-model out of a JSON dictionary, or return nil.\n#define RLM_SYNC_PARSE_MODEL_OR_ABORT(json_macro_val, key_macro_val, class_macro_val, prop_macro_val) \\\n{ \\\nid raw = json_macro_val[key_macro_val]; \\\nif (![raw isKindOfClass:[NSDictionary class]]) { return nil; } \\\nid model = [[class_macro_val alloc] initWithDictionary:raw]; \\\nif (!model) { return nil; } \\\nself.prop_macro_val = model; \\\n} \\\n\n#define RLM_SYNC_PARSE_OPTIONAL_MODEL(json_macro_val, key_macro_val, class_macro_val, prop_macro_val) \\\n{ \\\nid model; \\\nid raw = json_macro_val[key_macro_val]; \\\nif (![raw isKindOfClass:[NSDictionary class]]) { model = nil; } \\\nelse { model = [[class_macro_val alloc] initWithDictionary:raw]; } \\\nself.prop_macro_val = model; \\\n} \\\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Resources/CHANGELOG.md",
    "content": "2.4.4 Release notes (2017-03-13)\n=============================================================\n\n### API Breaking Changes\n\n* None.\n\n### Enhancements\n\n* Add `(RLM)SyncPermission` class to allow reviewing access permissions for\n  Realms. Requires any edition of the Realm Object Server 1.1.0 or later.\n* Further reduce the number of files opened per thread-specific Realm on macOS,\n  iOS and watchOS.\n\n### Bugfixes\n\n* Fix a crash that could occur if new Realm instances were created while the\n  application was exiting.\n* Fix a bug that could lead to bad version number errors when delivering\n  change notifications.\n* Fix a potential use-after-free bug when checking validity of results.\n* Fix an issue where a sync session might not close properly if it receives\n  an error while being torn down.\n* Fix some issues where a sync session might not reconnect to the server properly\n  or get into an inconsistent state if revived after invalidation.\n* Fix an issue where notifications might not fire when the children of an\n  observed object are changed.\n* Fix an issue where progress notifications on sync sessions might incorrectly\n  report out-of-date values.\n* Fix an issue where multiple threads accessing encrypted data could result in\n  corrupted data or crashes.\n* Fix an issue where certain `LIKE` queries could hang.\n* Fix an issue where `-[RLMRealm writeCopyToURL:encryptionKey:error]` could create\n  a corrupt Realm file.\n* Fix an issue where incrementing a synced Realm's schema version without actually\n  changing the schema could cause a crash.\n\n2.4.3 Release notes (2017-02-20)\n=============================================================\n\n### API Breaking Changes\n\n* None.\n\n### Enhancements\n\n* Avoid copying copy-on-write data structures, which can grow the file, when the\n  write does not actually change existing values.\n* Improve performance of deleting all objects in an RLMResults.\n* Reduce the number of files opened per thread-specific Realm on macOS.\n* Improve startup performance with large numbers of `RLMObject`/`Object`\n  subclasses.\n\n### Bugfixes\n\n* Fix synchronized Realms not downloading remote changes when an access token\n  expires and there are no local changes to upload.\n* Fix an issue where values set on a Realm object using `setValue(value:, forKey:)`\n  that were not themselves Realm objects were not properly converted into Realm\n  objects or checked for validity.\n* Fix an issue where `-[RLMSyncUser sessionForURL:]` could erroneously return a\n  non-nil value when passed in an invalid URL.\n* `SyncSession.Progress.fractionTransferred` now returns 1 if there are no\n  transferrable bytes.\n* Fix sync progress notifications registered on background threads by always\n  dispatching on a dedicated background queue.\n* Fix compilation issues with Xcode 8.3 beta 2.\n* Fix incorrect sync progress notification values for Realms originally created\n  using a version of Realm prior to 2.3.0.\n* Fix LLDB integration to be able to display summaries of `RLMResults` once more.\n* Reject Swift properties with names which cause them to fall in to ARC method\n  families rather than crashing when they are accessed.\n* Fix sorting by key path when the declared property order doesn't match the order\n  of properties in the Realm file, which can happen when properties are added in\n  different schema versions.\n\n2.4.2 Release notes (2017-01-30)\n=============================================================\n\n### Bugfixes\n\n* Fix an issue where RLMRealm instances could end up in the autorelease pool\n  for other threads.\n\n2.4.1 Release notes (2017-01-27)\n=============================================================\n\n### Bugfixes\n\n* Fix an issue where authentication tokens were not properly refreshed\n  automatically before expiring.\n\n2.4.0 Release notes (2017-01-26)\n=============================================================\n\nThis release drops support for compiling with Swift 2.x.\nSwift 3.0.0 is now the minimum Swift version supported.\n\n### API Breaking Changes\n\n* None.\n\n### Enhancements\n\n* Add change notifications for individual objects with an API similar to that\n  of collection notifications.\n\n### Bugfixes\n\n* Fix Realm Objective-C compilation errors with Xcode 8.3 beta 1.\n* Fix several error handling issues when renewing expired authentication\n  tokens for synchronized Realms.\n* Fix a race condition leading to bad_version exceptions being thrown in\n  Realm's background worker thread.\n\n2.3.0 Release notes (2017-01-19)\n=============================================================\n\n### Sync Breaking Changes\n\n* Make `PermissionChange`'s `id` property a primary key.\n\n### API Breaking Changes\n\n* None.\n\n### Enhancements\n\n* Add `SyncPermissionOffer` and `SyncPermissionOfferResponse` classes to allow\n  creating and accepting permission change events to synchronized Realms between\n  different users.\n* Support monitoring sync transfer progress by registering notification blocks\n  on `SyncSession`. Specify the transfer direction (`.upload`/`.download`) and\n  mode (`.reportIndefinitely`/`.forCurrentlyOutstandingWork`) to monitor.\n\n### Bugfixes\n\n* Fix a call to `commitWrite(withoutNotifying:)` committing a transaction that\n  would not have triggered a notification incorrectly skipping the next\n  notification.\n* Fix incorrect results and crashes when conflicting object insertions are\n  merged by the synchronization mechanism when there is a collection\n  notification registered for that object type.\n\n2.2.0 Release notes (2017-01-12)\n=============================================================\n\n### Sync Breaking Changes (In Beta)\n\n* Sync-related error reporting behavior has been changed. Errors not related\n  to a particular user or session are only reported if they are classed as\n  'fatal' by the underlying sync engine.\n* Added `RLMSyncErrorClientResetError` to `RLMSyncError` enum.\n\n### API Breaking Changes\n\n* The following Objective-C APIs have been deprecated in favor of newer or preferred versions:\n\n| Deprecated API                                              | New API                                                     |\n|:------------------------------------------------------------|:------------------------------------------------------------|\n| `-[RLMArray sortedResultsUsingProperty:]`                   | `-[RLMArray sortedResultsUsingKeyPath:]`                    |\n| `-[RLMCollection sortedResultsUsingProperty:]`              | `-[RLMCollection sortedResultsUsingKeyPath:]`               |\n| `-[RLMResults sortedResultsUsingProperty:]`                 | `-[RLMResults sortedResultsUsingKeyPath:]`                  |\n| `+[RLMSortDescriptor sortDescriptorWithProperty:ascending]` | `+[RLMSortDescriptor sortDescriptorWithKeyPath:ascending:]` |\n| `RLMSortDescriptor.property`                                | `RLMSortDescriptor.keyPath`                                 |\n\n* The following Swift APIs have been deprecated in favor of newer or preferred versions:\n\n| Deprecated API                                        | New API                                          |\n|:------------------------------------------------------|:-------------------------------------------------|\n| `LinkingObjects.sorted(byProperty:ascending:)`        | `LinkingObjects.sorted(byKeyPath:ascending:)`    |\n| `List.sorted(byProperty:ascending:)`                  | `List.sorted(byKeyPath:ascending:)`              |\n| `RealmCollection.sorted(byProperty:ascending:)`       | `RealmCollection.sorted(byKeyPath:ascending:)`   |\n| `Results.sorted(byProperty:ascending:)`               | `Results.sorted(byKeyPath:ascending:)`           |\n| `SortDescriptor(property:ascending:)`                 | `SortDescriptor(keyPath:ascending:)`             |\n| `SortDescriptor.property`                             | `SortDescriptor.keyPath`                         |\n\n### Enhancements\n\n* Introduce APIs for safely passing objects between threads. Create a\n  thread-safe reference to a thread-confined object by passing it to the\n  `+[RLMThreadSafeReference referenceWithThreadConfined:]`/`ThreadSafeReference(to:)`\n  constructor, which you can then safely pass to another thread to resolve in\n  the new Realm with `-[RLMRealm resolveThreadSafeReference:]`/`Realm.resolve(_:)`.\n* Realm collections can now be sorted by properties over to-one relationships.\n* Optimized `CONTAINS` queries to use Boyer-Moore algorithm\n  (around 10x speedup on large datasets).\n\n### Bugfixes\n\n* Setting `deleteRealmIfMigrationNeeded` now also deletes the Realm if a file\n  format migration is required, such as when moving from a file last accessed\n  with Realm 0.x to 1.x, or 1.x to 2.x.\n* Fix queries containing nested `SUBQUERY` expressions.\n* Fix spurious incorrect thread exceptions when a thread id happens to be\n  reused while an RLMRealm instance from the old thread still exists.\n* Fixed various bugs in aggregate methods (max, min, avg, sum).\n\n2.1.2 Release notes (2016--12-19)\n=============================================================\n\nThis release adds binary versions of Swift 3.0.2 frameworks built with Xcode 8.2.\n\n### Sync Breaking Changes (In Beta)\n\n* Rename occurences of \"iCloud\" with \"CloudKit\" in APIs and comments to match\n  naming in the Realm Object Server.\n\n### API Breaking Changes\n\n* None.\n\n### Enhancements\n\n* Add support for 'LIKE' queries (wildcard matching).\n\n### Bugfixes\n\n* Fix authenticating with CloudKit.\n* Fix linker warning about \"Direct access to global weak symbol\".\n\n2.1.1 Release notes (2016-12-02)\n=============================================================\n\n### Enhancements\n\n* Add `RealmSwift.ObjectiveCSupport.convert(object:)` methods to help write\n  code that interoperates between Realm Objective-C and Realm Swift APIs.\n* Throw exceptions when opening a Realm with an incorrect configuration, like:\n    * `readOnly` set with a sync configuration.\n    * `readOnly` set with a migration block.\n    * migration block set with a sync configuration.\n* Greatly improve performance of write transactions which make a large number of\n  changes to indexed properties, including the automatic migration when opening\n  files written by Realm 1.x.\n\n### Bugfixes\n\n* Reset sync metadata Realm in case of decryption error.\n* Fix issue preventing using synchronized Realms in Xcode Playgrounds.\n* Fix assertion failure when migrating a model property from object type to\n  `RLMLinkingObjects` type.\n* Fix a `LogicError: Bad version number` exception when using `RLMResults` with\n  no notification blocks and explicitly called `-[RLMRealm refresh]` from that\n  thread.\n* Logged-out users are no longer returned from `+[RLMSyncUser currentUser]` or\n  `+[RLMSyncUser allUsers]`.\n* Fix several issues which could occur when the 1001st object of a given type\n  was created or added to an RLMArray/List, including crashes when rerunning\n  existing queries and possibly data corruption.\n* Fix a potential crash when the application exits due to a race condition in\n  the destruction of global static variables.\n* Fix race conditions when waiting for sync uploads or downloads to complete\n  which could result in crashes or the callback being called too early.\n\n2.1.0 Release notes (2016-11-18)\n=============================================================\n\n### Sync Breaking Changes (In Beta)\n\n* None.\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* Add the ability to skip calling specific notification blocks when committing\n  a write transaction.\n\n### Bugfixes\n\n* Deliver collection notifications when beginning a write transaction which\n  advances the read version of a Realm (previously only Realm-level\n  notifications were sent).\n* Fix some scenarios which would lead to inconsistent states when using\n  collection notifications.\n* Fix several race conditions in the notification functionality.\n* Don't send Realm change notifications when canceling a write transaction.\n\n2.0.4 Release notes (2016-11-14)\n=============================================================\n\n### Sync Breaking Changes (In Beta)\n\n* Remove `RLMAuthenticationActions` and replace\n  `+[RLMSyncCredential credentialWithUsername:password:actions:]` with\n  `+[RLMSyncCredential credentialsWithUsername:password:register:]`.\n* Rename `+[RLMSyncUser authenticateWithCredential:]` to\n  `+[RLMSyncUser logInWithCredentials:]`.\n* Rename \"credential\"-related types and methods to\n  `RLMSyncCredentials`/`SyncCredentials` and consistently refer to credentials\n  in the plural form.\n* Change `+[RLMSyncUser all]` to return a dictionary of identifiers to users and\n  rename to:\n  * `+[RLMSyncUser allUsers]` in Objective-C.\n  * `SyncUser.allUsers()` in Swift 2.\n  * `SyncUser.all` in Swift 3.\n* Rename `SyncManager.sharedManager()` to `SyncManager.shared` in Swift 3.\n* Change `Realm.Configuration.syncConfiguration` to take a `SyncConfiguration`\n  struct rather than a named tuple.\n* `+[RLMSyncUser logInWithCredentials:]` now invokes its callback block on a\n  background queue.\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* Add `+[RLMSyncUser currentUser]`.\n* Add the ability to change read, write and management permissions for\n  synchronized Realms using the management Realm obtained via the\n  `-[RLMSyncUser managementRealmWithError:]` API and the\n  `RLMSyncPermissionChange` class.\n\n### Bugfixes\n\n* None.\n\n2.0.3 Release notes (2016-10-27)\n=============================================================\n\nThis release adds binary versions of Swift 3.0.1 frameworks built with Xcode 8.1\nGM seed.\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* None.\n\n### Bugfixes\n\n* Fix a `BadVersion` exception caused by a race condition when delivering\n  collection change notifications.\n* Fix an assertion failure when additional model classes are added and\n  `deleteRealmIfMigrationNeeded` is enabled.\n* Fix a `BadTransactLog` exception when deleting an `RLMResults` in a synced\n  Realm.\n* Fix an assertion failure when a write transaction is in progress at the point\n  of process termination.\n* Fix a crash that could occur when working with a `RLMLinkingObject` property\n  of an unmanaged object.\n\n2.0.2 Release notes (2016-10-05)\n=============================================================\n\nThis release is not protocol-compatible with previous version of the Realm\nMobile Platform.\n\n### API breaking changes\n\n* Rename Realm Swift's `User` to `SyncUser` to make clear that it relates to the\n  Realm Mobile Platform, and to avoid potential conflicts with other `User` types.\n\n### Bugfixes\n\n* Fix Realm headers to be compatible with pre-C++11 dialects of Objective-C++.\n* Fix incorrect merging of RLMArray/List changes when objects with the same\n  primary key are created on multiple devices.\n* Fix bad transaction log errors after deleting objects on a different device.\n* Fix a BadVersion error when a background worker finishes running while older\n  results from that worker are being delivered to a different thread.\n\n2.0.1 Release notes (2016-09-29)\n=============================================================\n\n### Bugfixes\n\n* Fix an assertion failure when opening a Realm file written by a 1.x version\n  of Realm which has an indexed nullable int or bool property.\n\n2.0.0 Release notes (2016-09-27)\n=============================================================\n\nThis release introduces support for the Realm Mobile Platform!\nSee <https://realm.io/news/introducing-realm-mobile-platform/> for an overview\nof these great new features.\n\n### API breaking changes\n\n* By popular demand, `RealmSwift.Error` has been moved from the top-level\n  namespace into a `Realm` extension and is now `Realm.Error`, so that it no\n  longer conflicts with `Swift.Error`.\n* Files written by Realm 2.0 cannot be read by 1.x or earlier versions. Old\n  files can still be opened.\n\n### Enhancements\n\n* The .log, .log_a and .log_b files no longer exist and the state tracked in\n  them has been moved to the main Realm file. This reduces the number of open\n  files needed by Realm, improves performance of both opening and writing to\n  Realms, and eliminates a small window where committing write transactions\n  would prevent other processes from opening the file.\n\n### Bugfixes\n\n* Fix an assertion failure when sorting by zero properties.\n* Fix a mid-commit crash in one process also crashing all other processes with\n  the same Realm open.\n* Properly initialize new nullable float and double properties added to\n  existing objects to null rather than 0.\n* Fix a stack overflow when objects with indexed string properties had very\n  long common prefixes.\n* Fix a race condition which could lead to crashes when using async queries or\n  collection notifications.\n* Fix a bug which could lead to incorrect state when an object which links to\n  itself is deleted from the Realm.\n\n1.1.0 Release notes (2016-09-16)\n=============================================================\n\nThis release brings official support for Xcode 8, Swift 2.3 and Swift 3.0.\nPrebuilt frameworks are now built with Xcode 7.3.1 and Xcode 8.0.\n\n### API breaking changes\n\n* Deprecate `migrateRealm:` in favor of new `performMigrationForConfiguration:error:` method\n  that follows Cocoa's NSError conventions.\n* Fix issue where `RLMResults` used `id `instead of its generic type as the return\n  type of subscript.\n\n### Enhancements\n\n* Improve error message when using NSNumber incorrectly in Swift models.\n* Further reduce the download size of the prebuilt static libraries.\n* Improve sort performance, especially on non-nullable columns.\n* Allow partial initialization of object by `initWithValue:`, deferring\n  required property checks until object is added to Realm.\n\n### Bugfixes\n\n* Fix incorrect truncation of the constant value for queries of the form\n  `column < value` for `float` and `double` columns.\n* Fix crash when an aggregate is accessed as an `Int8`, `Int16`, `Int32`, or `Int64`.\n* Fix a race condition that could lead to a crash if an RLMArray or List was\n  deallocated on a different thread than it was created on.\n* Fix a crash when the last reference to an observed object is released from\n  within the observation.\n* Fix a crash when `initWithValue:` is used to create a nested object for a class\n  with an uninitialized schema.\n* Enforce uniqueness for `RealmOptional` primary keys when using the `value` setter.\n\n1.0.2 Release notes (2016-07-13)\n=============================================================\n\n### API breaking changes\n\n* Attempting to add an object with no properties to a Realm now throws rather than silently\n  doing nothing.\n\n### Enhancements\n\n* Swift: A `write` block may now `throw`, reverting any changes already made in\n  the transaction.\n* Reduce address space used when committing write transactions.\n* Significantly reduce the download size of prebuilt binaries and slightly\n  reduce the final size contribution of Realm to applications.\n* Improve performance of accessing RLMArray properties and creating objects\n  with List properties.\n\n### Bugfixes\n\n* Fix a crash when reading the shared schema from an observed Swift object.\n* Fix crashes or incorrect results when passing an array of values to\n  `createOrUpdate` after reordering the class's properties.\n* Ensure that the initial call of a Results notification block is always passed\n  .Initial even if there is a write transaction between when the notification\n  is added and when the first notification is delivered.\n* Fix a crash when deleting all objects in a Realm while fast-enumerating query\n  results from that Realm.\n* Handle EINTR from flock() rather than crashing.\n* Fix incorrect behavior following a call to `[RLMRealm compact]`.\n* Fix live updating and notifications for Results created from a predicate involving\n  an inverse relationship to be triggered when an object at the other end of the relationship\n  is modified.\n\n1.0.1 Release notes (2016-06-12)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* Significantly improve performance of opening Realm files, and slightly\n  improve performance of committing write transactions.\n\n### Bugfixes\n\n* Swift: Fix an error thrown when trying to create or update `Object` instances via\n  `add(:_update:)` with a primary key property of type `RealmOptional`.\n* Xcode playground in Swift release zip now runs successfully.\n* The `key` parameter of `Realm.objectForPrimaryKey(_:key:)`/ `Realm.dynamicObjectForPrimaryKey(_:key:)`\n is now marked as optional.\n* Fix a potential memory leak when closing Realms after a Realm file has been\n  opened on multiple threads which are running in active run loops.\n* Fix notifications breaking on tvOS after a very large number of write\n  transactions have been committed.\n* Fix a \"Destruction of mutex in use\" assertion failure after an error while\n  opening a file.\n* Realm now throws an exception if an `Object` subclass is defined with a managed Swift `lazy` property.\n  Objects with ignored `lazy` properties should now work correctly.\n* Update the LLDB script to work with recent changes to the implementation of `RLMResults`.\n* Fix an assertion failure when a Realm file is deleted while it is still open,\n  and then a new Realm is opened at the same path. Note that this is still not\n  a supported scenario, and may break in other ways.\n\n1.0.0 Release notes (2016-05-25)\n=============================================================\n\nNo changes since 0.103.2.\n\n0.103.2 Release notes (2016-05-24)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* Improve the error messages when an I/O error occurs in `writeCopyToURL`.\n\n### Bugfixes\n\n* Fix an assertion failure which could occur when opening a Realm after opening\n  that Realm failed previously in some specific ways in the same run of the\n  application.\n* Reading optional integers, floats, and doubles from within a migration block\n  now correctly returns `nil` rather than 0 when the stored value is `nil`.\n\n0.103.1 Release notes (2016-05-19)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* None.\n\n### Bugfixes\n\n* Fix a bug that sometimes resulted in a single object's NSData properties\n  changing from `nil` to a zero-length non-`nil` NSData when a different object\n  of the same type was deleted.\n\n0.103.0 Release notes (2016-05-18)\n=============================================================\n\n### API breaking changes\n\n* All functionality deprecated in previous releases has been removed entirely.\n* Support for Xcode 6.x & Swift prior to 2.2 has been completely removed.\n* `RLMResults`/`Results` now become empty when a `RLMArray`/`List` or object\n  they depend on is deleted, rather than throwing an exception when accessed.\n* Migrations are no longer run when `deleteRealmIfMigrationNeeded` is set,\n  recreating the file instead.\n\n### Enhancements\n\n* Added `invalidated` properties to `RLMResults`/`Results`, `RLMLinkingObjects`/`LinkingObjects`,\n  `RealmCollectionType` and `AnyRealmCollection`. These properties report whether the Realm\n  the object is associated with has been invalidated.\n* Some `NSError`s created by Realm now have more descriptive user info payloads.\n\n### Bugfixes\n\n* None.\n\n0.102.1 Release notes (2016-05-13)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* Return `RLMErrorSchemaMismatch` error rather than the more generic `RLMErrorFail`\n  when a migration is required.\n* Improve the performance of allocating instances of `Object` subclasses\n  that have `LinkingObjects` properties.\n\n### Bugfixes\n\n* `RLMLinkingObjects` properties declared in Swift subclasses of `RLMObject`\n  now work correctly.\n* Fix an assertion failure when deleting all objects of a type, inserting more\n  objects, and then deleting some of the newly inserted objects within a single\n  write transaction when there is an active notification block for a different\n  object type which links to the objects being deleted.\n* Fix crashes and/or incorrect results when querying over multiple levels of\n  `LinkingObjects` properties.\n* Fix opening read-only Realms on multiple threads at once.\n* Fix a `BadTransactLog` exception when storing dates before the unix epoch (1970-01-01).\n\n0.102.0 Release notes (2016-05-09)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* Add a method to rename properties during migrations:\n  * Swift: `Migration.renamePropertyForClass(_:oldName:newName:)`\n  * Objective-C: `-[RLMMigration renamePropertyForClass:oldName:newName:]`\n* Add `deleteRealmIfMigrationNeeded` to\n  `RLMRealmConfiguration`/`Realm.Configuration`. When this is set to `true`,\n  the Realm file will be automatically deleted and recreated when there is a\n  schema mismatch rather than migrated to the new schema.\n\n### Bugfixes\n\n* Fix `BETWEEN` queries that traverse `RLMArray`/`List` properties to ensure that\n  a single related object satisfies the `BETWEEN` criteria, rather than allowing\n  different objects in the array to satisfy the lower and upper bounds.\n* Fix a race condition when a Realm is opened on one thread while it is in the\n  middle of being closed on another thread which could result in crashes.\n* Fix a bug which could result in changes made on one thread being applied\n  incorrectly on other threads when those threads are refreshed.\n* Fix crash when migrating to the new date format introduced in 0.101.0.\n* Fix crash when querying inverse relationships when objects are deleted.\n\n0.101.0 Release notes (2016-05-04)\n=============================================================\n\n### API breaking changes\n\n* Files written by this version of Realm cannot be read by older versions of\n  Realm. Existing files will automatically be upgraded when they are opened.\n\n### Enhancements\n\n* Greatly improve performance of collection change calculation for complex\n  object graphs, especially for ones with cycles.\n* NSDate properties now support nanoseconds precision.\n* Opening a single Realm file on multiple threads now shares a single memory\n  mapping of the file for all threads, significantly reducing the memory\n  required to work with large files.\n* Crashing while in the middle of a write transaction no longer blocks other\n  processes from performing write transactions on the same file.\n* Improve the performance of refreshing a Realm (including via autorefresh)\n  when there are live Results/RLMResults objects for that Realm.\n\n### Bugfixes\n\n* Fix an assertion failure of \"!more_before || index >= std::prev(it)->second)\"\n  in `IndexSet::do_add()`.\n* Fix a crash when an `RLMArray` or `List` object is destroyed from the wrong\n  thread.\n\n0.100.0 Release notes (2016-04-29)\n=============================================================\n\n### API breaking changes\n\n* `-[RLMObject linkingObjectsOfClass:forProperty]` and `Object.linkingObjects(_:forProperty:)`\n  are deprecated in favor of properties of type `RLMLinkingObjects` / `LinkingObjects`.\n\n### Enhancements\n\n* The automatically-maintained inverse direction of relationships can now be exposed as\n  properties of type `RLMLinkingObjects` / `LinkingObjects`. These properties automatically\n  update to reflect the objects that link to the target object, can be used in queries, and\n  can be filtered like other Realm collection types.\n* Queries that compare objects for equality now support multi-level key paths.\n\n### Bugfixes\n\n* Fix an assertion failure when a second write transaction is committed after a\n  write transaction deleted the object containing an RLMArray/List which had an\n  active notification block.\n* Queries that compare `RLMArray` / `List` properties using != now give the correct results.\n\n0.99.1 Release notes (2016-04-26)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* None.\n\n### Bugfixes\n\n* Fix a scenario that could lead to the assertion failure\n  \"m_advancer_sg->get_version_of_current_transaction() ==\n  new_notifiers.front()->version()\".\n\n0.99.0 Release notes (2016-04-22)\n=============================================================\n\n### API breaking changes\n\n* Deprecate properties of type `id`/`AnyObject`. This type was rarely used,\n  rarely useful and unsupported in every other Realm binding.\n* The block for `-[RLMArray addNotificationBlock:]` and\n  `-[RLMResults addNotificationBlock:]` now takes another parameter.\n* The following Objective-C APIs have been deprecated in favor of newer or preferred versions:\n\n| Deprecated API                                         | New API                                               |\n|:-------------------------------------------------------|:------------------------------------------------------|\n| `-[RLMRealm removeNotification:]`                      | `-[RLMNotificationToken stop]`                        |\n| `RLMRealmConfiguration.path`                           | `RLMRealmConfiguration.fileURL`                       |\n| `RLMRealm.path`                                        | `RLMRealmConfiguration.fileURL`                       |\n| `RLMRealm.readOnly`                                    | `RLMRealmConfiguration.readOnly`                      |\n| `+[RLMRealm realmWithPath:]`                           | `+[RLMRealm realmWithURL:]`                           |\n| `+[RLMRealm writeCopyToPath:error:]`                   | `+[RLMRealm writeCopyToURL:encryptionKey:error:]`     |\n| `+[RLMRealm writeCopyToPath:encryptionKey:error:]`     | `+[RLMRealm writeCopyToURL:encryptionKey:error:]`     |\n| `+[RLMRealm schemaVersionAtPath:error:]`               | `+[RLMRealm schemaVersionAtURL:encryptionKey:error:]` |\n| `+[RLMRealm schemaVersionAtPath:encryptionKey:error:]` | `+[RLMRealm schemaVersionAtURL:encryptionKey:error:]` |\n\n* The following Swift APIs have been deprecated in favor of newer or preferred versions:\n\n| Deprecated API                                | New API                                  |\n|:----------------------------------------------|:-----------------------------------------|\n| `Realm.removeNotification(_:)`                | `NotificationToken.stop()`               |\n| `Realm.Configuration.path`                    | `Realm.Configuration.fileURL`            |\n| `Realm.path`                                  | `Realm.Configuration.fileURL`            |\n| `Realm.readOnly`                              | `Realm.Configuration.readOnly`           |\n| `Realm.writeCopyToPath(_:encryptionKey:)`     | `Realm.writeCopyToURL(_:encryptionKey:)` |\n| `schemaVersionAtPath(_:encryptionKey:error:)` | `schemaVersionAtURL(_:encryptionKey:)`   |\n\n### Enhancements\n\n* Add information about what rows were added, removed, or modified to the\n  notifications sent to the Realm collections.\n* Improve error when illegally appending to an `RLMArray` / `List` property from a default value\n  or the standalone initializer (`init()`) before the schema is ready.\n\n### Bugfixes\n\n* Fix a use-after-free when an associated object's dealloc method is used to\n  remove observers from an RLMObject.\n* Fix a small memory leak each time a Realm file is opened.\n* Return a recoverable `RLMErrorAddressSpaceExhausted` error rather than\n  crash when there is insufficient available address space on Realm\n  initialization or write commit.\n\n0.98.8 Release notes (2016-04-15)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* None.\n\n### Bugfixes\n\n* Fixed a bug that caused some encrypted files created using\n  `-[RLMRealm writeCopyToPath:encryptionKey:error:]` to fail to open.\n\n0.98.7 Release notes (2016-04-13)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* None.\n\n### Bugfixes\n\n* Mark further initializers in Objective-C as NS_DESIGNATED_INITIALIZER to prevent that these aren't\n  correctly defined in Swift Object subclasses, which don't qualify for auto-inheriting the required initializers.\n* `-[RLMResults indexOfObjectWithPredicate:]` now returns correct results\n  for `RLMResults` instances that were created by filtering an `RLMArray`.\n* Adjust how RLMObjects are destroyed in order to support using an associated\n  object on an RLMObject to remove KVO observers from that RLMObject.\n* `-[RLMResults indexOfObjectWithPredicate:]` now returns the index of the first matching object for a\n  sorted `RLMResults`, matching its documented behavior.\n* Fix a crash when canceling a transaction that set a relationship.\n* Fix a crash when a query referenced a deleted object.\n\n0.98.6 Release notes (2016-03-25)\n=============================================================\n\nPrebuilt frameworks are now built with Xcode 7.3.\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* None.\n\n### Bugfixes\n\n* Fix running unit tests on iOS simulators and devices with Xcode 7.3.\n\n0.98.5 Release notes (2016-03-14)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* None.\n\n### Bugfixes\n\n* Fix a crash when opening a Realm on 32-bit iOS devices.\n\n0.98.4 Release notes (2016-03-10)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* None.\n\n### Bugfixes\n\n* Properly report changes made by adding an object to a Realm with\n  addOrUpdate:/createOrUpdate: to KVO observers for existing objects with that\n  primary key.\n* Fix crashes and assorted issues when a migration which added object link\n  properties is rolled back due to an error in the migration block.\n* Fix assertion failures when deleting objects within a migration block of a\n  type which had an object link property added in that migration.\n* Fix an assertion failure in `Query::apply_patch` when updating certain kinds\n  of queries after a write transaction is committed.\n\n0.98.3 Release notes (2016-02-26)\n=============================================================\n\n### Enhancements\n\n* Initializing the shared schema is 3x faster.\n\n### Bugfixes\n\n* Using Realm Objective-C from Swift while having Realm Swift linked no longer causes that the\n  declared `ignoredProperties` are not taken into account.\n* Fix assertion failures when rolling back a migration which added Object link\n  properties to a class.\n* Fix potential errors when cancelling a write transaction which modified\n  multiple `RLMArray`/`List` properties.\n* Report the correct value for inWriteTransaction after attempting to commit a\n  write transaction fails.\n* Support CocoaPods 1.0 beginning from prerelease 1.0.0.beta.4 while retaining\n  backwards compatibility with 0.39.\n\n0.98.2 Release notes (2016-02-18)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* Aggregate operations (`ANY`, `NONE`, `@count`, `SUBQUERY`, etc.) are now supported for key paths\n  that begin with an object relationship so long as there is a `RLMArray`/`List` property at some\n  point in a key path.\n* Predicates of the form `%@ IN arrayProperty` are now supported.\n\n### Bugfixes\n\n* Use of KVC collection operators on Swift collection types no longer throws an exception.\n* Fix reporting of inWriteTransaction in notifications triggered by\n  `beginWriteTransaction`.\n* The contents of `List` and `Optional` properties are now correctly preserved when copying\n  a Swift object from one Realm to another, and performing other operations that result in a\n  Swift object graph being recursively traversed from Objective-C.\n* Fix a deadlock when queries are performed within a Realm notification block.\n* The `ANY` / `SOME` / `NONE` qualifiers are now required in comparisons involving a key path that\n  traverse a `RLMArray`/`List` property. Previously they were only required if the first key in the\n  key path was an `RLMArray`/`List` property.\n* Fix several scenarios where the default schema would be initialized\n  incorrectly if the first Realm opened used a restricted class subset (via\n  `objectClasses`/`objectTypes`).\n\n0.98.1 Release notes (2016-02-10)\n=============================================================\n\n### Bugfixes\n\n* Fix crashes when deleting an object containing an `RLMArray`/`List` which had\n  previously been queried.\n* Fix a crash when deleting an object containing an `RLMArray`/`List` with\n  active notification blocks.\n* Fix duplicate file warnings when building via CocoaPods.\n* Fix crash or incorrect results when calling `indexOfObject:` on an\n  `RLMResults` derived from an `RLMArray`.\n\n0.98.0 Release notes (2016-02-04)\n=============================================================\n\n### API breaking changes\n\n* `+[RLMRealm realmWithPath:]`/`Realm.init(path:)` now inherits from the default\n  configuration.\n* Swift 1.2 is no longer supported.\n\n### Enhancements\n\n* Add `addNotificationBlock` to `RLMResults`, `Results`, `RLMArray`, and\n  `List`, which calls the given block whenever the collection changes.\n* Do a lot of the work for keeping `RLMResults`/`Results` up-to-date after\n  write transactions on a background thread to help avoid blocking the main\n  thread.\n* `NSPredicate`'s `SUBQUERY` operator is now supported. It has the following limitations:\n  * `@count` is the only operator that may be applied to the `SUBQUERY` expression.\n  * The `SUBQUERY(…).@count` expression must be compared with a constant.\n  * Correlated subqueries are not yet supported.\n\n### Bugfixes\n\n* None.\n\n0.97.1 Release notes (2016-01-29)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* Swift: Added `Error` enum allowing to catch errors e.g. thrown on initializing\n  `RLMRealm`/`Realm` instances.\n* Fail with `RLMErrorFileNotFound` instead of the more generic `RLMErrorFileAccess`,\n  if no file was found when a realm was opened as read-only or if the directory part\n  of the specified path was not found when a copy should be written. \n* Greatly improve performance when deleting objects with one or more indexed\n  properties.\n* Indexing `BOOL`/`Bool` and `NSDate` properties are now supported.\n* Swift: Add support for indexing optional properties.\n\n### Bugfixes\n\n* Fix incorrect results or crashes when using `-[RLMResults setValue:forKey:]`\n  on an RLMResults which was filtered on the key being set.\n* Fix crashes when an RLMRealm is deallocated from the wrong thread.\n* Fix incorrect results from aggregate methods on `Results`/`RLMResults` after\n  objects which were previously in the results are deleted.\n* Fix a crash when adding a new property to an existing class with over a\n  million objects in the Realm.\n* Fix errors when opening encrypted Realm files created with writeCopyToPath.\n* Fix crashes or incorrect results for queries that use relationship equality\n  in cases where the `RLMResults` is kept alive and instances of the target class\n  of the relationship are deleted.\n\n0.97.0 Release notes (2015-12-17)\n=============================================================\n\n### API breaking changes\n\n* All functionality deprecated in previous releases has been removed entirely.\n* Add generic type annotations to NSArrays and NSDictionaries in public APIs.\n* Adding a Realm notification block on a thread not currently running from\n  within a run loop throws an exception rather than silently never calling the\n  notification block.\n\n### Enhancements\n\n* Support for tvOS.\n* Support for building Realm Swift from source when using Carthage.\n* The block parameter of `-[RLMRealm transactionWithBlock:]`/`Realm.write(_:)` is \n  now marked as `__attribute__((noescape))`/`@noescape`.\n* Many forms of queries with key paths on both sides of the comparison operator\n  are now supported.\n* Add support for KVC collection operators in `RLMResults` and `RLMArray`.\n* Fail instead of deadlocking in `+[RLMRealm sharedSchema]`, if a Swift property is initialized\n  to a computed value, which attempts to open a Realm on its own.\n\n### Bugfixes\n\n* Fix poor performance when calling `-[RLMRealm deleteObjects:]` on an\n  `RLMResults` which filtered the objects when there are other classes linking\n  to the type of the deleted objects.\n* An exception is now thrown when defining `Object` properties of an unsupported\n  type.\n\n0.96.3 Release notes (2015-12-04)\n=============================================================\n\n### Enhancements\n\n* Queries are no longer limited to 16 levels of grouping.\n* Rework the implementation of encrypted Realms to no longer interfere with\n  debuggers.\n\n### Bugfixes\n\n* Fix crash when trying to retrieve object instances via `dynamicObjects`.\n* Throw an exception when querying on a link providing objects, which are from a different Realm.\n* Return empty results when querying on a link providing an unattached object.\n* Fix crashes or incorrect results when calling `-[RLMRealm refresh]` during\n  fast enumeration.\n* Add `Int8` support for `RealmOptional`, `MinMaxType` and `AddableType`.\n* Set the default value for newly added non-optional NSData properties to a\n  zero-byte NSData rather than nil.\n* Fix a potential crash when deleting all objects of a class.\n* Fix performance problems when creating large numbers of objects with\n  `RLMArray`/`List` properties.\n* Fix memory leak when using Object(value:) for subclasses with\n  `List` or `RealmOptional` properties.\n* Fix a crash when computing the average of an optional integer property.\n* Fix incorrect search results for some queries on integer properties.\n* Add error-checking for nil realm parameters in many methods such as\n  `+[RLMObject allObjectsInRealm:]`.\n* Fix a race condition between commits and opening Realm files on new threads\n  that could lead to a crash.\n* Fix several crashes when opening Realm files.\n* `-[RLMObject createInRealm:withValue:]`, `-[RLMObject createOrUpdateInRealm:withValue:]`, and\n  their variants for the default Realm now always match the contents of an `NSArray` against properties\n  in the same order as they are defined in the model.\n\n0.96.2 Release notes (2015-10-26)\n=============================================================\n\nPrebuilt frameworks are now built with Xcode 7.1.\n\n### Bugfixes\n\n* Fix ignoring optional properties in Swift.\n* Fix CocoaPods installation on case-sensitive file systems.\n\n0.96.1 Release notes (2015-10-20)\n=============================================================\n\n### Bugfixes\n\n* Support assigning `Results` to `List` properties via KVC.\n* Honor the schema version set in the configuration in `+[RLMRealm migrateRealm:]`.\n* Fix crash when using optional Int16/Int32/Int64 properties in Swift.\n\n0.96.0 Release notes (2015-10-14)\n=============================================================\n\n* No functional changes since beta2.\n\n0.96.0-beta2 Release notes (2015-10-08)\n=============================================================\n\n### Bugfixes\n\n* Add RLMOptionalBase.h to the podspec.\n\n0.96.0-beta Release notes (2015-10-07)\n=============================================================\n\n### API breaking changes\n\n* CocoaPods v0.38 or greater is now required to install Realm and RealmSwift\n  as pods.\n\n### Enhancements\n\n* Functionality common to both `List` and `Results` is now declared in a\n  `RealmCollectionType` protocol that both types conform to.\n* `Results.realm` now returns an `Optional<Realm>` in order to conform to\n  `RealmCollectionType`, but will always return `.Some()` since a `Results`\n  cannot exist independently from a `Realm`.\n* Aggregate operations are now available on `List`: `min`, `max`, `sum`,\n  `average`.\n* Committing write transactions (via `commitWrite` / `commitWriteTransaction` and\n  `write` / `transactionWithBlock`) now optionally allow for handling errors when\n  the disk is out of space.\n* Added `isEmpty` property on `RLMRealm`/`Realm` to indicate if it contains any\n  objects.\n* The `@count`, `@min`, `@max`, `@sum` and `@avg` collection operators are now\n  supported in queries.\n\n### Bugfixes\n\n* Fix assertion failure when inserting NSData between 8MB and 16MB in size.\n* Fix assertion failure when rolling back a migration which removed an object\n  link or `RLMArray`/`List` property.\n* Add the path of the file being opened to file open errors.\n* Fix a crash that could be triggered by rapidly opening and closing a Realm\n  many times on multiple threads at once.\n* Fix several places where exception messages included the name of the wrong\n  function which failed.\n\n0.95.3 Release notes (2015-10-05)\n=============================================================\n\n### Bugfixes\n\n* Compile iOS Simulator framework architectures with `-fembed-bitcode-marker`.\n* Fix crashes when the first Realm opened uses a class subset and later Realms\n  opened do not.\n* Fix inconsistent errors when `Object(value: ...)` is used to initialize the\n  default value of a property of an `Object` subclass.\n* Throw an exception when a class subset has objects with array or object\n  properties of a type that are not part of the class subset.\n\n0.95.2 Release notes (2015-09-24)\n=============================================================\n\n* Enable bitcode for iOS and watchOS frameworks.\n* Build libraries with Xcode 7 final rather than the GM.\n\n0.95.1 Release notes (2015-09-23)\n=============================================================\n\n### Enhancements\n\n* Add missing KVO handling for moving and exchanging objects in `RLMArray` and\n  `List`.\n\n### Bugfixes\n\n* Setting the primary key property on persisted `RLMObject`s / `Object`s\n  via subscripting or key-value coding will cause an exception to be thrown.\n* Fix crash due to race condition in `RLMRealmConfiguration` where the default\n  configuration was in the process of being copied in one thread, while\n  released in another.\n* Fix crash when a migration which removed an object or array property is\n  rolled back due to an error.\n\n0.95.0 Release notes (2015-08-25)\n=============================================================\n\n### API breaking changes\n\n* The following APIs have been deprecated in favor of the new `RLMRealmConfiguration` class in Realm Objective-C:\n\n| Deprecated API                                                    | New API                                                                          |\n|:------------------------------------------------------------------|:---------------------------------------------------------------------------------|\n| `+[RLMRealm realmWithPath:readOnly:error:]`                       | `+[RLMRealm realmWithConfiguration:error:]`                                      |\n| `+[RLMRealm realmWithPath:encryptionKey:readOnly:error:]`         | `+[RLMRealm realmWithConfiguration:error:]`                                      |\n| `+[RLMRealm setEncryptionKey:forRealmsAtPath:]`                   | `-[RLMRealmConfiguration setEncryptionKey:]`                                     |\n| `+[RLMRealm inMemoryRealmWithIdentifier:]`                        | `+[RLMRealm realmWithConfiguration:error:]`                                      |\n| `+[RLMRealm defaultRealmPath]`                                    | `+[RLMRealmConfiguration defaultConfiguration]`                                  |\n| `+[RLMRealm setDefaultRealmPath:]`                                | `+[RLMRealmConfiguration setDefaultConfiguration:]`                              |\n| `+[RLMRealm setDefaultRealmSchemaVersion:withMigrationBlock]`     | `RLMRealmConfiguration.schemaVersion` and `RLMRealmConfiguration.migrationBlock` |\n| `+[RLMRealm setSchemaVersion:forRealmAtPath:withMigrationBlock:]` | `RLMRealmConfiguration.schemaVersion` and `RLMRealmConfiguration.migrationBlock` |\n| `+[RLMRealm migrateRealmAtPath:]`                                 | `+[RLMRealm migrateRealm:]`                                                      |\n| `+[RLMRealm migrateRealmAtPath:encryptionKey:]`                   | `+[RLMRealm migrateRealm:]`                                                      |\n\n* The following APIs have been deprecated in favor of the new `Realm.Configuration` struct in Realm Swift for Swift 1.2:\n\n| Deprecated API                                                | New API                                                                      |\n|:--------------------------------------------------------------|:-----------------------------------------------------------------------------|\n| `Realm.defaultPath`                                           | `Realm.Configuration.defaultConfiguration`                                   |\n| `Realm(path:readOnly:encryptionKey:error:)`                   | `Realm(configuration:error:)`                                                |\n| `Realm(inMemoryIdentifier:)`                                  | `Realm(configuration:error:)`                                                |\n| `Realm.setEncryptionKey(:forPath:)`                           | `Realm(configuration:error:)`                                                |\n| `setDefaultRealmSchemaVersion(schemaVersion:migrationBlock:)` | `Realm.Configuration.schemaVersion` and `Realm.Configuration.migrationBlock` |\n| `setSchemaVersion(schemaVersion:realmPath:migrationBlock:)`   | `Realm.Configuration.schemaVersion` and `Realm.Configuration.migrationBlock` |\n| `migrateRealm(path:encryptionKey:)`                           | `migrateRealm(configuration:)`                                               |\n\n* The following APIs have been deprecated in favor of the new `Realm.Configuration` struct in Realm Swift for Swift 2.0:\n\n| Deprecated API                                                | New API                                                                      |\n|:--------------------------------------------------------------|:-----------------------------------------------------------------------------|\n| `Realm.defaultPath`                                           | `Realm.Configuration.defaultConfiguration`                                   |\n| `Realm(path:readOnly:encryptionKey:) throws`                  | `Realm(configuration:) throws`                                               |\n| `Realm(inMemoryIdentifier:)`                                  | `Realm(configuration:) throws`                                               |\n| `Realm.setEncryptionKey(:forPath:)`                           | `Realm(configuration:) throws`                                               |\n| `setDefaultRealmSchemaVersion(schemaVersion:migrationBlock:)` | `Realm.Configuration.schemaVersion` and `Realm.Configuration.migrationBlock` |\n| `setSchemaVersion(schemaVersion:realmPath:migrationBlock:)`   | `Realm.Configuration.schemaVersion` and `Realm.Configuration.migrationBlock` |\n| `migrateRealm(path:encryptionKey:)`                           | `migrateRealm(configuration:)`                                               |\n\n* `List.extend` in Realm Swift for Swift 2.0 has been replaced with `List.appendContentsOf`,\n  mirroring changes to `RangeReplaceableCollectionType`.\n\n* Object properties on `Object` subclasses in Realm Swift must be marked as optional,\n  otherwise a runtime exception will be thrown.\n\n### Enhancements\n\n* Persisted properties of `RLMObject`/`Object` subclasses are now Key-Value\n  Observing compliant.\n* The different options used to create Realm instances have been consolidated\n  into a single `RLMRealmConfiguration`/`Realm.Configuration` object.\n* Enumerating Realm collections (`RLMArray`, `RLMResults`, `List<>`,\n  `Results<>`) now enumerates over a copy of the collection, making it no\n  longer an error to modify a collection during enumeration (either directly,\n  or indirectly by modifying objects to make them no longer match a query).\n* Improve performance of object insertion in Swift to bring it roughly in line\n  with Objective-C.\n* Allow specifying a specific list of `RLMObject` / `Object` subclasses to include\n  in a given Realm via `RLMRealmConfiguration.objectClasses` / `Realm.Configuration.objectTypes`.\n\n### Bugfixes\n\n* Subscripting on `RLMObject` is now marked as nullable.\n\n0.94.1 Release notes (2015-08-10)\n=============================================================\n\n### API breaking changes\n\n* Building for watchOS requires Xcode 7 beta 5.\n\n### Enhancements\n\n* `Object.className` is now marked as `final`.\n\n### Bugfixes\n\n* Fix crash when adding a property to a model without updating the schema\n  version.\n* Fix unnecessary redownloading of the core library when building from source.\n* Fix crash when sorting by an integer or floating-point property on iOS 7.\n\n0.94.0 Release notes (2015-07-29)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* Reduce the amount of memory used by RLMRealm notification listener threads.\n* Avoid evaluating results eagerly when filtering and sorting.\n* Add nullability annotations to the Objective-C API to provide enhanced compiler\n  warnings and bridging to Swift.\n* Make `RLMResult`s and `RLMArray`s support Objective-C generics.\n* Add support for building watchOS and bitcode-compatible apps.\n* Make the exceptions thrown in getters and setters more informative.\n* Add `-[RLMArray exchangeObjectAtIndex:withObjectAtIndex]` and `List.swap(_:_:)`\n  to allow exchanging the location of two objects in the given `RLMArray` / `List`.\n* Added anonymous analytics on simulator/debugger runs.\n* Add `-[RLMArray moveObjectAtIndex:toIndex:]` and `List.move(from:to:)` to\n  allow moving objects in the given `RLMArray` / `List`.\n\n### Bugfixes\n\n* Processes crashing due to an uncaught exception inside a write transaction will\n  no longer cause other processes using the same Realm to hang indefinitely.\n* Fix incorrect results when querying for < or <= on ints that\n  require 64 bits to represent with a CPU that supports SSE 4.2.\n* An exception will no longer be thrown when attempting to reset the schema\n  version or encryption key on an open Realm to the current value.\n* Date properties on 32 bit devices will retain 64 bit second precision.\n* Wrap calls to the block passed to `enumerate` in an autoreleasepool to reduce\n  memory growth when migrating a large amount of objects.\n* In-memory realms no longer write to the Documents directory on iOS or\n  Application Support on OS X.\n\n0.93.2 Release notes (2015-06-12)\n=============================================================\n\n### Bugfixes\n\n* Fixed an issue where the packaged OS X Realm.framework was built with\n  `GCC_GENERATE_TEST_COVERAGE_FILES` and `GCC_INSTRUMENT_PROGRAM_FLOW_ARCS`\n  enabled.\n* Fix a memory leak when constructing standalone Swift objects with NSDate\n  properties.\n* Throw an exception rather than asserting when an invalidated object is added\n  to an RLMArray.\n* Fix a case where data loss would occur if a device was hard-powered-off\n  shortly after a write transaction was committed which had to expand the Realm\n  file.\n\n0.93.1 Release notes (2015-05-29)\n=============================================================\n\n### Bugfixes\n\n* Objects are no longer copied into standalone objects during object creation. This fixes an issue where\n  nested objects with a primary key are sometimes duplicated rather than updated.\n* Comparison predicates with a constant on the left of the operator and key path on the right now give\n  correct results. An exception is now thrown for predicates that do not yet support this ordering.\n* Fix some crashes in `index_string.cpp` with int primary keys or indexed int properties.\n\n0.93.0 Release notes (2015-05-27)\n=============================================================\n\n### API breaking changes\n\n* Schema versions are now represented as `uint64_t` (Objective-C) and `UInt64` (Swift) so that they have\n  the same representation on all architectures.\n\n### Enhancements\n\n* Swift: `Results` now conforms to `CVarArgType` so it can\n  now be passed as an argument to `Results.filter(_:...)`\n  and `List.filter(_:...)`.\n* Swift: Made `SortDescriptor` conform to the `Equatable` and\n  `StringLiteralConvertible` protocols.\n* Int primary keys are once again automatically indexed.\n* Improve error reporting when attempting to mark a property of a type that\n  cannot be indexed as indexed.\n\n### Bugfixes\n\n* Swift: `RealmSwift.framework` no longer embeds `Realm.framework`,\n  which now allows apps using it to pass iTunes Connect validation.\n\n0.92.4 Release notes (2015-05-22)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* Swift: Made `Object.init()` a required initializer.\n* `RLMObject`, `RLMResults`, `Object` and `Results` can now be safely\n  deallocated (but still not used) from any thread.\n* Improve performance of `-[RLMArray indexOfObjectWhere:]` and `-[RLMArray\n  indexOfObjectWithPredicate:]`, and implement them for standalone RLMArrays.\n* Improved performance of most simple queries.\n\n### Bugfixes\n\n* The interprocess notification mechanism no longer uses dispatch worker threads, preventing it from\n  starving other GCD clients of the opportunity to execute blocks when dozens of Realms are open at once.\n\n0.92.3 Release notes (2015-05-13)\n=============================================================\n\n### API breaking changes\n\n* Swift: `Results.average(_:)` now returns an optional, which is `nil` if and only if the results\n  set is empty.\n\n### Enhancements\n\n* Swift: Added `List.invalidated`, which returns if the given `List` is no longer\n  safe to be accessed, and is analogous to `-[RLMArray isInvalidated]`.\n* Assertion messages are automatically logged to Crashlytics if it's loaded\n  into the current process to make it easier to diagnose crashes.\n\n### Bugfixes\n\n* Swift: Enumerating through a standalone `List` whose objects themselves\n  have list properties won't crash.\n* Swift: Using a subclass of `RealmSwift.Object` in an aggregate operator of a predicate\n  no longer throws a spurious type error.\n* Fix incorrect results for when using OR in a query on a `RLMArray`/`List<>`.\n* Fix incorrect values from `[RLMResults count]`/`Results.count` when using\n  `!=` on an int property with no other query conditions.\n* Lower the maximum doubling threshold for Realm file sizes from 128MB to 16MB\n  to reduce the amount of wasted space.\n\n0.92.2 Release notes (2015-05-08)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* Exceptions raised when incorrect object types are used with predicates now contain more detailed information.\n* Added `-[RLMMigration deleteDataForClassName:]` and `Migration.deleteData(_:)`\n  to enable cleaning up after removing object subclasses\n\n### Bugfixes\n\n* Prevent debugging of an application using an encrypted Realm to work around\n  frequent LLDB hangs. Until the underlying issue is addressed you may set\n  REALM_DISABLE_ENCRYPTION=YES in your application's environment variables to\n  have requests to open an encrypted Realm treated as a request for an\n  unencrypted Realm.\n* Linked objects are properly updated in `createOrUpdateInRealm:withValue:`.\n* List properties on Objects are now properly initialized during fast enumeration.\n\n0.92.1 Release notes (2015-05-06)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* `-[RLMRealm inWriteTransaction]` is now public.\n* Realm Swift is now available on CoocaPods.\n\n### Bugfixes\n\n* Force code re-signing after stripping architectures in `strip-frameworks.sh`.\n\n0.92.0 Release notes (2015-05-05)\n=============================================================\n\n### API breaking changes\n\n* Migration blocks are no longer called when a Realm file is first created.\n* The following APIs have been deprecated in favor of newer method names:\n\n| Deprecated API                                         | New API                                               |\n|:-------------------------------------------------------|:------------------------------------------------------|\n| `-[RLMMigration createObject:withObject:]`             | `-[RLMMigration createObject:withValue:]`             |\n| `-[RLMObject initWithObject:]`                         | `-[RLMObject initWithValue:]`                         |\n| `+[RLMObject createInDefaultRealmWithObject:]`         | `+[RLMObject createInDefaultRealmWithValue:]`         |\n| `+[RLMObject createInRealm:withObject:]`               | `+[RLMObject createInRealm:withValue:]`               |\n| `+[RLMObject createOrUpdateInDefaultRealmWithObject:]` | `+[RLMObject createOrUpdateInDefaultRealmWithValue:]` |\n| `+[RLMObject createOrUpdateInRealm:withObject:]`       | `+[RLMObject createOrUpdateInRealm:withValue:]`       |\n\n### Enhancements\n\n* `Int8` properties defined in Swift are now treated as integers, rather than\n  booleans.\n* NSPredicates created using `+predicateWithValue:` are now supported.\n\n### Bugfixes\n\n* Compound AND predicates with no subpredicates now correctly match all objects.\n\n0.91.5 Release notes (2015-04-28)\n=============================================================\n\n### Bugfixes\n\n* Fix issues with removing search indexes and re-enable it.\n\n0.91.4 Release notes (2015-04-27)\n=============================================================\n\n### Bugfixes\n\n* Temporarily disable removing indexes from existing columns due to bugs.\n\n0.91.3 Release notes (2015-04-17)\n=============================================================\n\n### Bugfixes\n\n* Fix `Extra argument 'objectClassName' in call` errors when building via\n  CocoaPods.\n\n0.91.2 Release notes (2015-04-16)\n=============================================================\n\n* Migration blocks are no longer called when a Realm file is first created.\n\n### Enhancements\n\n* `RLMCollection` supports collection KVC operations.\n* Sorting `RLMResults` is 2-5x faster (typically closer to 2x).\n* Refreshing `RLMRealm` after a write transaction which inserts or modifies\n  strings or `NSData` is committed on another thread is significantly faster.\n* Indexes are now added and removed from existing properties when a Realm file\n  is opened, rather than only when properties are first added.\n\n### Bugfixes\n\n* `+[RLMSchema dynamicSchemaForRealm:]` now respects search indexes.\n* `+[RLMProperty isEqualToProperty:]` now checks for equal `indexed` properties.\n\n0.91.1 Release notes (2015-03-12)\n=============================================================\n\n### Enhancements\n\n* The browser will automatically refresh when the Realm has been modified\n  from another process.\n* Allow using Realm in an embedded framework by setting\n  `APPLICATION_EXTENSION_API_ONLY` to YES.\n\n### Bugfixes\n\n* Fix a crash in CFRunLoopSourceInvalidate.\n\n0.91.0 Release notes (2015-03-10)\n=============================================================\n\n### API breaking changes\n\n* `attributesForProperty:` has been removed from `RLMObject`. You now specify indexed\n  properties by implementing the `indexedProperties` method.\n* An exception will be thrown when calling `setEncryptionKey:forRealmsAtPath:`,\n  `setSchemaVersion:forRealmAtPath:withMigrationBlock:`, and `migrateRealmAtPath:`\n  when a Realm at the given path is already open.\n* Object and array properties of type `RLMObject` will no longer be allowed.\n\n### Enhancements\n\n* Add support for sharing Realm files between processes.\n* The browser will no longer show objects that have no persisted properties.\n* `RLMSchema`, `RLMObjectSchema`, and `RLMProperty` now have more useful descriptions.\n* Opening an encrypted Realm while a debugger is attached to the process no\n  longer throws an exception.\n* `RLMArray` now exposes an `isInvalidated` property to indicate if it can no\n  longer be accessed.\n\n### Bugfixes\n\n* An exception will now be thrown when calling `-beginWriteTransaction` from within a notification\n  triggered by calling `-beginWriteTransaction` elsewhere.\n* When calling `delete:` we now verify that the object being deleted is persisted in the target Realm.\n* Fix crash when calling `createOrUpdate:inRealm` with nested linked objects.\n* Use the key from `+[RLMRealm setEncryptionKey:forRealmsAtPath:]` in\n  `-writeCopyToPath:error:` and `+migrateRealmAtPath:`.\n* Comparing an RLMObject to a non-RLMObject using `-[RLMObject isEqual:]` or\n  `-isEqualToObject:` now returns NO instead of crashing.\n* Improved error message when an `RLMObject` subclass is defined nested within\n  another Swift declaration.\n* Fix crash when the process is terminated by the OS on iOS while encrypted realms are open.\n* Fix crash after large commits to encrypted realms.\n\n0.90.6 Release notes (2015-02-20)\n=============================================================\n\n### Enhancements\n\n* Improve compatiblity of encrypted Realms with third-party crash reporters.\n\n### Bugfixes\n\n* Fix incorrect results when using aggregate functions on sorted RLMResults.\n* Fix data corruption when using writeCopyToPath:encryptionKey:.\n* Maybe fix some assertion failures.\n\n0.90.5 Release notes (2015-02-04)\n=============================================================\n\n### Bugfixes\n\n* Fix for crashes when encryption is enabled on 64-bit iOS devices.\n\n0.90.4 Release notes (2015-01-29)\n=============================================================\n\n### Bugfixes\n\n* Fix bug that resulted in columns being dropped and recreated during migrations.\n\n0.90.3 Release notes (2015-01-27)\n=============================================================\n\n### Enhancements\n\n* Calling `createInDefaultRealmWithObject:`, `createInRealm:withObject:`,\n  `createOrUpdateInDefaultRealmWithObject:` or `createOrUpdateInRealm:withObject:`\n  is a no-op if the argument is an RLMObject of the same type as the receiver\n  and is already backed by the target realm.\n\n### Bugfixes\n\n* Fix incorrect column type assertions when the first Realm file opened is a\n  read-only file that is missing tables.\n* Throw an exception when adding an invalidated or deleted object as a link.\n* Throw an exception when calling `createOrUpdateInRealm:withObject:` when the\n  receiver has no primary key defined.\n\n0.90.1 Release notes (2015-01-22)\n=============================================================\n\n### Bugfixes\n\n* Fix for RLMObject being treated as a model object class and showing up in the browser.\n* Fix compilation from the podspec.\n* Fix for crash when calling `objectsWhere:` with grouping in the query on `allObjects`.\n\n0.90.0 Release notes (2015-01-21)\n=============================================================\n\n### API breaking changes\n\n* Rename `-[RLMRealm encryptedRealmWithPath:key:readOnly:error:]` to\n  `-[RLMRealm realmWithPath:encryptionKey:readOnly:error:]`.\n* `-[RLMRealm setSchemaVersion:withMigrationBlock]` is no longer global and must be called\n  for each individual Realm path used. You can now call `-[RLMRealm setDefaultRealmSchemaVersion:withMigrationBlock]`\n  for the default Realm and `-[RLMRealm setSchemaVersion:forRealmAtPath:withMigrationBlock:]` for all others;\n\n### Enhancements\n\n* Add `-[RLMRealm writeCopyToPath:encryptionKey:error:]`.\n* Add support for comparing string columns to other string columns in queries.\n\n### Bugfixes\n\n* Roll back changes made when an exception is thrown during a migration.\n* Throw an exception if the number of items in a RLMResults or RLMArray changes\n  while it's being fast-enumerated.\n* Also encrypt the temporary files used when encryption is enabled for a Realm.\n* Fixed crash in JSONImport example on OS X with non-en_US locale.\n* Fixed infinite loop when opening a Realm file in the Browser at the same time\n  as it is open in a 32-bit simulator.\n* Fixed a crash when adding primary keys to older realm files with no primary\n  keys on any objects.\n* Fixed a crash when removing a primary key in a migration.\n* Fixed a crash when multiple write transactions with no changes followed by a\n  write transaction with changes were committed without the main thread\n  RLMRealm getting a chance to refresh.\n* Fixed incomplete results when querying for non-null relationships.\n* Improve the error message when a Realm file is opened in multiple processes\n  at once.\n\n0.89.2 Release notes (2015-01-02)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* None.\n\n### Bugfixes\n\n* Fix an assertion failure when invalidating a Realm which is in a write\n  transaction, has already been invalidated, or has never been used.\n* Fix an assertion failure when sorting an empty RLMArray property.\n* Fix a bug resulting in the browser never becoming visible on 10.9.\n* Write UTF-8 when generating class files from a realm file in the Browser.\n\n0.89.1 Release notes (2014-12-22)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* Improve the error message when a Realm can't be opened due to lacking write\n  permissions.\n\n### Bugfixes\n\n* Fix an assertion failure when inserting rows after calling `deleteAllObjects`\n  on a Realm.\n* Separate dynamic frameworks are now built for the simulator and devices to\n  work around App Store submission errors due to the simulator version not\n  being automatically stripped from dynamic libraries.\n\n0.89.0 Release notes (2014-12-18)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* Add support for encrypting Realm files on disk.\n* Support using KVC-compliant objects without getters or with custom getter\n  names to initialize RLMObjects with `createObjectInRealm` and friends.\n\n### Bugfixes\n\n* Merge native Swift default property values with defaultPropertyValues().\n* Don't leave the database schema partially updated when opening a realm fails\n  due to a migration being needed.\n* Fixed issue where objects with custom getter names couldn't be used to\n  initialize other objects.\n* Fix a major performance regression on queries on string properties.\n* Fix a memory leak when circularly linked objects are added to a Realm.\n\n0.88.0 Release notes (2014-12-02)\n=============================================================\n\n### API breaking changes\n\n* Deallocating an RLMRealm instance in a write transaction lacking an explicit\n  commit/cancel will now be automatically cancelled instead of committed.\n* `-[RLMObject isDeletedFromRealm]` has been renamed to `-[RLMObject isInvalidated]`.\n\n### Enhancements\n\n* Add `-[RLMRealm writeCopyToPath:]` to write a compacted copy of the Realm\n  another file.\n* Add support for case insensitive, BEGINSWITH, ENDSWITH and CONTAINS string\n  queries on array properties.\n* Make fast enumeration of `RLMArray` and `RLMResults` ~30% faster and\n  `objectAtIndex:` ~55% faster.\n* Added a lldb visualizer script for displaying the contents of persisted\n  RLMObjects when debugging.\n* Added method `-setDefaultRealmPath:` to change the default Realm path.\n* Add `-[RLMRealm invalidate]` to release data locked by the current thread.\n\n### Bugfixes\n\n* Fix for crash when running many simultaneous write transactions on background threads.\n* Fix for crashes caused by opening Realms at multiple paths simultaneously which have had\n  properties re-ordered during migration.\n* Don't run the query twice when `firstObject` or `lastObject` are called on an\n  `RLMResults` which has not had its results accessed already.\n* Fix for bug where schema version is 0 for new Realm created at the latest version.\n* Fix for error message where no migration block is specified when required.\n\n0.87.4 Release notes (2014-11-07)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* None.\n\n### Bugfixes\n\n* Fix browser location in release zip.\n\n0.87.3 Release notes (2014-11-06)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* Added method `-linkingObjectsOfClass:forProperty:` to RLMObject to expose inverse\n  relationships/backlinks.\n\n### Bugfixes\n\n* Fix for crash due to missing search index when migrating an object with a string primary key\n  in a database created using an older versions (0.86.3 and earlier).\n* Throw an exception when passing an array containing a\n  non-RLMObject to -[RLMRealm addObjects:].\n* Fix for crash when deleting an object from multiple threads.\n\n0.87.0 Release notes (2014-10-21)\n=============================================================\n\n### API breaking changes\n\n* RLMArray has been split into two classes, `RLMArray` and `RLMResults`. RLMArray is\n  used for object properties as in previous releases. Moving forward all methods used to\n  enumerate, query, and sort objects return an instance of a new class `RLMResults`. This\n  change was made to support diverging apis and the future addition of change notifications\n  for queries.\n* The api for migrations has changed. You now call `setSchemaVersion:withMigrationBlock:` to\n  register a global migration block and associated version. This block is applied to Realms as\n  needed when opened for Realms at a previous version. The block can be applied manually if\n  desired by calling `migrateRealmAtPath:`.\n* `arraySortedByProperty:ascending:` was renamed to `sortedResultsUsingProperty:ascending`\n* `addObjectsFromArray:` on both `RLMRealm` and `RLMArray` has been renamed to `addObjects:`\n  and now accepts any container class which implements `NSFastEnumeration`\n* Building with Swift support now requires Xcode 6.1\n\n### Enhancements\n\n* Add support for sorting `RLMArray`s by multiple columns with `sortedResultsUsingDescriptors:`\n* Added method `deleteAllObjects` on `RLMRealm` to clear a Realm.\n* Added method `createObject:withObject:` on `RLMMigration` which allows object creation during migrations.\n* Added method `deleteObject:` on `RLMMigration` which allows object deletion during migrations.\n* Updating to core library version 0.85.0.\n* Implement `objectsWhere:` and `objectsWithPredicate:` for array properties.\n* Add `cancelWriteTransaction` to revert all changes made in a write transaction and end the transaction.\n* Make creating `RLMRealm` instances on background threads when an instance\n  exists on another thread take a fifth of the time.\n* Support for partial updates when calling `createOrUpdateWithObject:` and `addOrUpdateObject:`\n* Re-enable Swift support on OS X\n\n### Bugfixes\n\n* Fix exceptions when trying to set `RLMObject` properties after rearranging\n  the properties in a `RLMObject` subclass.\n* Fix crash on IN query with several thousand items.\n* Fix crash when querying indexed `NSString` properties.\n* Fixed an issue which prevented in-memory Realms from being used accross multiple threads.\n* Preserve the sort order when querying a sorted `RLMResults`.\n* Fixed an issue with migrations where if a Realm file is deleted after a Realm is initialized,\n  the newly created Realm can be initialized with an incorrect schema version.\n* Fix crash in `RLMSuperSet` when assigning to a `RLMArray` property on a standalone object.\n* Add an error message when the protocol for an `RLMArray` property is not a\n  valid object type.\n* Add an error message when an `RLMObject` subclass is defined nested within\n  another Swift class.\n\n0.86.3 Release notes (2014-10-09)\n=============================================================\n\n### Enhancements\n\n* Add support for != in queries on object relationships.\n\n### Bugfixes\n\n* Re-adding an object to its Realm no longer throws an exception and is now a no-op\n  (as it was previously).\n* Fix another bug which would sometimes result in subclassing RLMObject\n  subclasses not working.\n\n0.86.2 Release notes (2014-10-06)\n=============================================================\n\n### Bugfixes\n\n* Fixed issues with packaging \"Realm Browser.app\" for release.\n\n0.86.1 Release notes (2014-10-03)\n=============================================================\n\n### Bugfixes\n\n* Fix a bug which would sometimes result in subclassing RLMObject subclasses\n  not working.\n\n0.86.0 Release notes (2014-10-03)\n=============================================================\n\n### API breaking changes\n\n* Xcode 6 is now supported from the main Xcode project `Realm.xcodeproj`.\n  Xcode 5 is no longer supported.\n\n### Enhancements\n\n* Support subclassing RLMObject models. Although you can now persist subclasses,\n  polymorphic behavior is not supported (i.e. setting a property to an\n  instance of its subclass).\n* Add support for sorting RLMArray properties.\n* Speed up inserting objects with `addObject:` by ~20%.\n* `readonly` properties are automatically ignored rather than having to be\n  added to `ignoredProperties`.\n* Updating to core library version 0.83.1.\n* Return \"[deleted object]\" rather than throwing an exception when\n  `-description` is called on a deleted RLMObject.\n* Significantly improve performance of very large queries.\n* Allow passing any enumerable to IN clauses rather than just NSArray.\n* Add `objectForPrimaryKey:` and `objectInRealm:forPrimaryKey:` convenience\n  methods to fetch an object by primary key.\n\n### Bugfixes\n\n* Fix error about not being able to persist property 'hash' with incompatible\n  type when building for devices with Xcode 6.\n* Fix spurious notifications of new versions of Realm.\n* Fix for updating nested objects where some types do not have primary keys.\n* Fix for inserting objects from JSON with NSNull values when default values\n  should be used.\n* Trying to add a persisted RLMObject to a different Realm now throws an\n  exception rather than creating an uninitialized object.\n* Fix validation errors when using IN on array properties.\n* Fix errors when an IN clause has zero items.\n* Fix for chained queries ignoring all but the last query's conditions.\n\n0.85.0 Release notes (2014-09-15)\n=============================================================\n\n### API breaking changes\n\n* Notifications for a refresh being needed (when autorefresh is off) now send\n  the notification type RLMRealmRefreshRequiredNotification rather than\n  RLMRealmDidChangeNotification.\n\n### Enhancements\n\n* Updating to core library version 0.83.0.\n* Support for primary key properties (for int and string columns). Declaring a property\n  to be the primary key ensures uniqueness for that property for all objects of a given type.\n  At the moment indexes on primary keys are not yet supported but this will be added in a future\n  release.\n* Added methods to update or insert (upsert) for objects with primary keys defined.\n* `[RLMObject initWithObject:]` and `[RLMObject createInRealmWithObject:]` now support\n  any object type with kvc properties.\n* The Swift support has been reworked to work around Swift not being supported\n  in Frameworks on iOS 7.\n* Improve performance when getting the count of items matching a query but not\n  reading any of the objects in the results.\n* Add a return value to `-[RLMRealm refresh]` that indicates whether or not\n  there was anything to refresh.\n* Add the class name to the error message when an RLMObject is missing a value\n  for a property without a default.\n* Add support for opening Realms in read-only mode.\n* Add an automatic check for updates when using Realm in a simulator (the\n  checker code is not compiled into device builds). This can be disabled by\n  setting the REALM_DISABLE_UPDATE_CHECKER environment variable to any value.\n* Add support for Int16 and Int64 properties in Swift classes.\n\n### Bugfixes\n\n* Realm change notifications when beginning a write transaction are now sent\n  after updating rather than before, to match refresh.\n* `-isEqual:` now uses the default `NSObject` implementation unless a primary key\n  is specified for an RLMObject. When a primary key is specified, `-isEqual:` calls\n  `-isEqualToObject:` and a corresponding implementation for `-hash` is also implemented.\n\n0.84.0 Release notes (2014-08-28)\n=============================================================\n\n### API breaking changes\n\n* The timer used to trigger notifications has been removed. Notifications are now\n  only triggered by commits made in other threads, and can not currently be triggered\n  by changes made by other processes. Interprocess notifications will be re-added in\n  a future commit with an improved design.\n\n### Enhancements\n\n* Updating to core library version 0.82.2.\n* Add property `deletedFromRealm` to RLMObject to indicate objects which have been deleted.\n* Add support for the IN operator in predicates.\n* Add support for the BETWEEN operator in link queries.\n* Add support for multi-level link queries in predicates (e.g. `foo.bar.baz = 5`).\n* Switch to building the SDK from source when using CocoaPods and add a\n  Realm.Headers subspec for use in targets that should not link a copy of Realm\n  (such as test targets).\n* Allow unregistering from change notifications in the change notification\n  handler block.\n* Significant performance improvements when holding onto large numbers of RLMObjects.\n* Realm-Xcode6.xcodeproj now only builds using Xcode6-Beta6.\n* Improved performance during RLMArray iteration, especially when mutating\n  contained objects.\n\n### Bugfixes\n\n* Fix crashes and assorted bugs when sorting or querying a RLMArray returned\n  from a query.\n* Notifications are no longer sent when initializing new RLMRealm instances on background\n  threads.\n* Handle object cycles in -[RLMObject description] and -[RLMArray description].\n* Lowered the deployment target for the Xcode 6 projects and Swift examples to\n  iOS 7.0, as they didn't actually require 8.0.\n* Support setting model properties starting with the letter 'z'\n* Fixed crashes that could result from switching between Debug and Relase\n  builds of Realm.\n\n0.83.0 Release notes (2014-08-13)\n=============================================================\n\n### API breaking changes\n\n* Realm-Xcode6.xcodeproj now only builds using Xcode6-Beta5.\n* Properties to be persisted in Swift classes must be explicitly declared as `dynamic`.\n* Subclasses of RLMObject subclasses now throw an exception on startup, rather\n  than when added to a Realm.\n\n### Enhancements\n\n* Add support for querying for nil object properties.\n* Improve error message when specifying invalid literals when creating or\n  initializing RLMObjects.\n* Throw an exception when an RLMObject is used from the incorrect thread rather\n  than crashing in confusing ways.\n* Speed up RLMRealm instantiation and array property iteration.\n* Allow array and objection relation properties to be missing or null when\n  creating a RLMObject from a NSDictionary.\n\n### Bugfixes\n\n* Fixed a memory leak when querying for objects.\n* Fixed initializing array properties on standalone Swift RLMObject subclasses.\n* Fix for queries on 64bit integers.\n\n0.82.0 Release notes (2014-08-05)\n=============================================================\n\n### API breaking changes\n\n* Realm-Xcode6.xcodeproj now only builds using Xcode6-Beta4.\n\n### Enhancements\n\n* Updating to core library version 0.80.5.\n* Now support disabling the `autorefresh` property on RLMRealm instances.\n* Building Realm-Xcode6 for iOS now builds a universal framework for Simulator & Device.\n* Using NSNumber properties (unsupported) now throws a more informative exception.\n* Added `[RLMRealm defaultRealmPath]`\n* Proper implementation for [RLMArray indexOfObjectWhere:]\n* The default Realm path on OS X is now ~/Library/Application Support/[bundle\n  identifier]/default.realm rather than ~/Documents\n* We now check that the correct framework (ios or osx) is used at compile time.\n\n### Bugfixes\n\n* Fixed rapid growth of the realm file size.\n* Fixed a bug which could cause a crash during RLMArray destruction after a query.\n* Fixed bug related to querying on float properties: `floatProperty = 1.7` now works.\n* Fixed potential bug related to the handling of array properties (RLMArray).\n* Fixed bug where array properties accessed the wrong property.\n* Fixed bug that prevented objects with custom getters to be added to a Realm.\n* Fixed a bug where initializing a standalone object with an array literal would\n  trigger an exception.\n* Clarified exception messages when using unsupported NSPredicate operators.\n* Clarified exception messages when using unsupported property types on RLMObject subclasses.\n* Fixed a memory leak when breaking out of a for-in loop on RLMArray.\n* Fixed a memory leak when removing objects from a RLMArray property.\n* Fixed a memory leak when querying for objects.\n\n\n0.81.0 Release notes (2014-07-22)\n=============================================================\n\n### API breaking changes\n\n* None.\n\n### Enhancements\n\n* Updating to core library version 0.80.3.\n* Added support for basic querying of RLMObject and RLMArray properties (one-to-one and one-to-many relationships).\n  e.g. `[Person objectsWhere:@\"dog.name == 'Alfonso'\"]` or `[Person objectsWhere:@\"ANY dogs.name == 'Alfonso'\"]`\n  Supports all normal operators for numeric and date types. Does not support NSData properties or `BEGINSWITH`, `ENDSWITH`, `CONTAINS`\n  and other options for string properties.\n* Added support for querying for object equality in RLMObject and RLMArray properties (one-to-one and one-to-many relationships).\n  e.g. `[Person objectsWhere:@\"dog == %@\", myDog]` `[Person objectsWhere:@\"ANY dogs == %@\", myDog]` `[Person objectsWhere:@\"ANY friends.dog == %@\", dog]`\n  Only supports comparing objects for equality (i.e. ==)\n* Added a helper method to RLMRealm to perform a block inside a transaction.\n* OSX framework now supported in CocoaPods.\n\n### Bugfixes\n\n* Fixed Unicode support in property names and string contents (Chinese, Russian, etc.). Closing #612 and #604.\n* Fixed bugs related to migration when properties are removed.\n* Fixed keyed subscripting for standalone RLMObjects.\n* Fixed bug related to double clicking on a .realm file to launch the Realm Browser (thanks to Dean Moore).\n\n\n0.80.0 Release notes (2014-07-15)\n=============================================================\n\n### API breaking changes\n\n* Rename migration methods to -migrateDefaultRealmWithBlock: and -migrateRealmAtPath:withBlock:\n* Moved Realm specific query methods from RLMRealm to class methods on RLMObject (-allObjects: to +allObjectsInRealm: ect.)\n\n### Enhancements\n\n* Added +createInDefaultRealmWithObject: method to RLMObject.\n* Added support for array and object literals when calling -createWithObject: and -initWithObject: variants.\n* Added method -deleteObjects: to batch delete objects from a Realm\n* Support for defining RLMObject models entirely in Swift (experimental, see known issues).\n* RLMArrays in Swift support Sequence-style enumeration (for obj in array).\n* Implemented -indexOfObject: for RLMArray\n\n### Known Issues for Swift-defined models\n\n* Properties other than String, NSData and NSDate require a default value in the model. This can be an empty (but typed) array for array properties.\n* The previous caveat also implies that not all models defined in Objective-C can be used for object properties. Only Objective-C models with only implicit (i.e. primitives) or explicit default values can be used. However, any Objective-C model object can be used in a Swift array property.\n* Array property accessors don't work until its parent object has been added to a realm.\n* Realm-Bridging-Header.h is temporarily exposed as a public header. This is temporary and will be private again once rdar://17633863 is fixed.\n* Does not leverage Swift generics and still uses RLM-prefix everywhere. This is coming in #549.\n\n\n0.22.0 Release notes\n=============================================================\n\n### API breaking changes\n\n* Rename schemaForObject: to schemaForClassName: on RLMSchema\n* Removed -objects:where: and -objects:orderedBy:where: from RLMRealm\n* Removed -indexOfObjectWhere:, -objectsWhere: and -objectsOrderedBy:where: from RLMArray\n* Removed +objectsWhere: and +objectsOrderedBy:where: from RLMObject\n\n### Enhancements\n\n* New Xcode 6 project for experimental swift support.\n* New Realm Editor app for reading and editing Realm db files.\n* Added support for migrations.\n* Added support for RLMArray properties on objects.\n* Added support for creating in-memory default Realm.\n* Added -objectsWithClassName:predicateFormat: and -objectsWithClassName:predicate: to RLMRealm\n* Added -indexOfObjectWithPredicateFormat:, -indexOfObjectWithPredicate:, -objectsWithPredicateFormat:, -objectsWithPredi\n* Added +objectsWithPredicateFormat: and +objectsWithPredicate: to RLMObject\n* Now allows predicates comparing two object properties of the same type.\n\n\n0.20.0 Release notes (2014-05-28)\n=============================================================\n\nCompletely rewritten to be much more object oriented.\n\n### API breaking changes\n\n* Everything\n\n### Enhancements\n\n* None.\n\n### Bugfixes\n\n* None.\n\n\n0.11.0 Release notes (not released)\n=============================================================\n\nThe Objective-C API has been updated and your code will break!\n\n### API breaking changes\n\n* `RLMTable` objects can only be created with an `RLMRealm` object.\n* Renamed `RLMContext` to `RLMTransactionManager`\n* Renamed `RLMContextDidChangeNotification` to `RLMRealmDidChangeNotification`\n* Renamed `contextWithDefaultPersistence` to `managerForDefaultRealm`\n* Renamed `contextPersistedAtPath:` to `managerForRealmWithPath:`\n* Renamed `realmWithDefaultPersistence` to `defaultRealm`\n* Renamed `realmWithDefaultPersistenceAndInitBlock` to `defaultRealmWithInitBlock`\n* Renamed `find:` to `firstWhere:`\n* Renamed `where:` to `allWhere:`\n* Renamed `where:orderBy:` to `allWhere:orderBy:`\n\n### Enhancements\n\n* Added `countWhere:` on `RLMTable`\n* Added `sumOfColumn:where:` on `RLMTable`\n* Added `averageOfColumn:where:` on `RLMTable`\n* Added `minOfProperty:where:` on `RLMTable`\n* Added `maxOfProperty:where:` on `RLMTable`\n* Added `toJSONString` on `RLMRealm`, `RLMTable` and `RLMView`\n* Added support for `NOT` operator in predicates\n* Added support for default values\n* Added validation support in `createInRealm:withObject:`\n\n### Bugfixes\n\n* None.\n\n\n0.10.0 Release notes (2014-04-23)\n=============================================================\n\nTightDB is now Realm! The Objective-C API has been updated\nand your code will break!\n\n### API breaking changes\n\n* All references to TightDB have been changed to Realm.\n* All prefixes changed from `TDB` to `RLM`.\n* `TDBTransaction` and `TDBSmartContext` have merged into `RLMRealm`.\n* Write transactions now take an optional rollback parameter (rather than needing to return a boolean).\n* `addColumnWithName:` and variant methods now return the index of the newly created column if successful, `NSNotFound` otherwise.\n\n### Enhancements\n\n* `createTableWithName:columns:` has been added to `RLMRealm`.\n* Added keyed subscripting for RLMTable's first column if column is of type RLMPropertyTypeString.\n* `setRow:atIndex:` has been added to `RLMTable`.\n* `RLMRealm` constructors now have variants that take an writable initialization block\n* New object interface - tables created/retrieved using `tableWithName:objectClass:` return custom objects\n\n### Bugfixes\n\n* None.\n\n\n0.6.0 Release notes (2014-04-11)\n=============================================================\n\n### API breaking changes\n\n* `contextWithPersistenceToFile:error:` renamed to `contextPersistedAtPath:error:` in `TDBContext`\n* `readWithBlock:` renamed to `readUsingBlock:` in `TDBContext`\n* `writeWithBlock:error:` renamed to `writeUsingBlock:error:` in `TDBContext`\n* `readTable:withBlock:` renamed to `readTable:usingBlock:` in `TDBContext`\n* `writeTable:withBlock:error:` renamed to `writeTable:usingBlock:error:` in `TDBContext`\n* `findFirstRow` renamed to `indexOfFirstMatchingRow` on `TDBQuery`.\n* `findFirstRowFromIndex:` renamed to `indexOfFirstMatchingRowFromIndex:` on `TDBQuery`.\n* Return `NSNotFound` instead of -1 when appropriate.\n* Renamed `castClass` to `castToTytpedTableClass` on `TDBTable`.\n* `removeAllRows`, `removeRowAtIndex`, `removeLastRow`, `addRow` and `insertRow` methods\n  on table now return void instead of BOOL.\n\n### Enhancements\n* A `TDBTable` can now be queried using `where:` and `where:orderBy:` taking\n  `NSPredicate` and `NSSortDescriptor` as arguments.\n* Added `find:` method on `TDBTable` to find first row matching predicate.\n* `contextWithDefaultPersistence` class method added to `TDBContext`. Will create a context persisted\n  to a file in app/documents folder.\n* `renameColumnWithIndex:to:` has been added to `TDBTable`.\n* `distinctValuesInColumnWithIndex` has been added to `TDBTable`.\n* `dateIsBetween::`, `doubleIsBetween::`, `floatIsBetween::` and `intIsBetween::`\n  have been added to `TDBQuery`.\n* Column names in Typed Tables can begin with non-capital letters too. The generated `addX`\n  selector can look odd. For example, a table with one column with name `age`,\n  appending a new row will look like `[table addage:7]`.\n* Mixed typed values are better validated when rows are added, inserted,\n  or modified as object literals.\n* `addRow`, `insertRow`, and row updates can be done using objects\n   derived from `NSObject`.\n* `where` has been added to `TDBView`and `TDBViewProtocol`.\n* Adding support for \"smart\" contexts (`TDBSmartContext`).\n\n### Bugfixes\n\n* Modifications of a `TDBView` and `TDBQuery` now throw an exception in a readtransaction.\n\n\n0.5.0 Release notes (2014-04-02)\n=============================================================\n\nThe Objective-C API has been updated and your code will break!\nOf notable changes a fast interface has been added.\nThis interface includes specific methods to get and set values into Tightdb.\nTo use these methods import `<Tightdb/TightdbFast.h>`.\n\n### API breaking changes\n\n* `getTableWithName:` renamed to `tableWithName:` in `TDBTransaction`.\n* `addColumnWithName:andType:` renamed to `addColumnWithName:type:` in `TDBTable`.\n* `columnTypeOfColumn:` renamed to `columnTypeOfColumnWithIndex` in `TDBTable`.\n* `columnNameOfColumn:` renamed to `nameOfColumnWithIndex:` in `TDBTable`.\n* `addColumnWithName:andType:` renamed to `addColumnWithName:type:` in `TDBDescriptor`.\n* Fast getters and setters moved from `TDBRow.h` to `TDBRowFast.h`.\n\n### Enhancements\n\n* Added `minDateInColumnWithIndex` and `maxDateInColumnWithIndex` to `TDBQuery`.\n* Transactions can now be started directly on named tables.\n* You can create dynamic tables with initial schema.\n* `TDBTable` and `TDBView` now have a shared protocol so they can easier be used interchangeably.\n\n### Bugfixes\n\n* Fixed bug in 64 bit iOS when inserting BOOL as NSNumber.\n\n\n0.4.0 Release notes (2014-03-26)\n=============================================================\n\n### API breaking changes\n\n* Typed interface Cursor has now been renamed to Row.\n* TDBGroup has been renamed to TDBTransaction.\n* Header files are renamed so names match class names.\n* Underscore (_) removed from generated typed table classes.\n* TDBBinary has been removed; use NSData instead.\n* Underscope (_) removed from generated typed table classes.\n* Constructor for TDBContext has been renamed to contextWithPersistenceToFile:\n* Table findFirstRow and min/max/sum/avg operations has been hidden.\n* Table.appendRow has been renamed to addRow.\n* getOrCreateTable on Transaction has been removed.\n* set*:inColumnWithIndex:atRowIndex: methods have been prefixed with TDB\n* *:inColumnWithIndex:atRowIndex: methods have been prefixed with TDB\n* addEmptyRow on table has been removed. Use [table addRow:nil] instead.\n* TDBMixed removed. Use id and NSObject instead.\n* insertEmptyRow has been removed from table. Use insertRow:nil atIndex:index instead.\n\n#### Enhancements\n\n* Added firstRow, lastRow selectors on view.\n* firstRow and lastRow on table now return nil if table is empty.\n* getTableWithName selector added on group.\n* getting and creating table methods on group no longer take error argument.\n* [TDBQuery parent] and [TDBQuery subtable:] selectors now return self.\n* createTable method added on Transaction. Throws exception if table with same name already exists.\n* Experimental support for pinning transactions on Context.\n* TDBView now has support for object subscripting.\n\n### Bugfixes\n\n* None.\n\n\n0.3.0 Release notes (2014-03-14)\n=============================================================\n\nThe Objective-C API has been updated and your code will break!\n\n### API breaking changes\n\n* Most selectors have been renamed in the binding!\n* Prepend TDB-prefix on all classes and types.\n\n### Enhancements\n\n* Return types and parameters changed from size_t to NSUInteger.\n* Adding setObject to TightdbTable (t[2] = @[@1, @\"Hello\"] is possible).\n* Adding insertRow to TightdbTable.\n* Extending appendRow to accept NSDictionary.\n\n### Bugfixes\n\n* None.\n\n\n0.2.0 Release notes (2014-03-07)\n=============================================================\n\nThe Objective-C API has been updated and your code will break!\n\n### API breaking changes\n\n* addRow renamed to addEmptyRow\n\n### Enhancements\n\n* Adding a simple class for version numbering.\n* Adding get-version and set-version targets to build.sh.\n* tableview now supports sort on column with column type bool, date and int\n* tableview has method for checking the column type of a specified column\n* tableview has method for getting the number of columns\n* Adding methods getVersion, getCoreVersion and isAtLeast.\n* Adding appendRow to TightdbTable.\n* Adding object subscripting.\n* Adding method removeColumn on table.\n\n### Bugfixes\n\n* None.\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Resources/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>BuildMachineOSBuild</key>\n\t<string>16D32</string>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>English</string>\n\t<key>CFBundleExecutable</key>\n\t<string>Realm</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>io.Realm.Realm</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>Realm</string>\n\t<key>CFBundlePackageType</key>\n\t<string>FMWK</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>2.4.4</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleSupportedPlatforms</key>\n\t<array>\n\t\t<string>MacOSX</string>\n\t</array>\n\t<key>CFBundleVersion</key>\n\t<string>2.4.4</string>\n\t<key>DTCompiler</key>\n\t<string>com.apple.compilers.llvm.clang.1_0</string>\n\t<key>DTPlatformBuild</key>\n\t<string>8C38</string>\n\t<key>DTPlatformVersion</key>\n\t<string>GM</string>\n\t<key>DTSDKBuild</key>\n\t<string>16C58</string>\n\t<key>DTSDKName</key>\n\t<string>macosx10.12</string>\n\t<key>DTXcode</key>\n\t<string>0820</string>\n\t<key>DTXcodeBuild</key>\n\t<string>8C38</string>\n\t<key>NSHumanReadableCopyright</key>\n\t<string>Copyright © 2014 Realm. All rights reserved.</string>\n\t<key>UIDeviceFamily</key>\n\t<array>\n\t\t<integer>3</integer>\n\t\t<integer>2</integer>\n\t\t<integer>1</integer>\n\t\t<integer>4</integer>\n\t</array>\n</dict>\n</plist>\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Resources/LICENSE",
    "content": "TABLE OF CONTENTS\n\n1. Apache License version 2.0\n2. Realm Components\n3. Export Compliance\n\n-------------------------------------------------------------------------------\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\nREALM COMPONENTS\n\nThis software contains components with separate copyright and license terms.\nYour use of these components is subject to the terms and conditions of the\nfollowing licenses.\n\nFor the Realm Core component\n\n  Realm Core Binary License\n\n  Copyright (c) 2011-2016 Realm Inc All rights reserved\n\n  Redistribution and use in binary form, with or without modification, is\n  permitted provided that the following conditions are met:\n\n  1. You agree not to attempt to decompile, disassemble, reverse engineer or\n  otherwise discover the source code from which the binary code was derived.\n  You may, however, access and obtain a separate license for most of the\n  source code from which this Software was created, at\n  http://realm.io/pricing/.\n\n  2. Redistributions in binary form must reproduce the above copyright notice,\n  this list of conditions and the following disclaimer in the documentation\n  and/or other materials provided with the distribution.\n\n  3. Neither the name of the copyright holder nor the names of its\n  contributors may be used to endorse or promote products derived from this\n  software without specific prior written permission.\n\n  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"\n  AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n  IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n  ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE\n  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR\n  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF\n  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS\n  INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)\n  ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE\n  POSSIBILITY OF SUCH DAMAGE.\n\nEXPORT COMPLIANCE\n\nYou understand that the Software may contain cryptographic functions that may be\nsubject to export restrictions, and you represent and warrant that you are not\n(i) located in a jurisdiction that is subject to United States economic\nsanctions (“Prohibited Jurisdiction”), including Cuba, Iran, North Korea,\nSudan, Syria or the Crimea region, (ii) a person listed on any U.S. government\nblacklist (to include the List of Specially Designated Nationals and Blocked\nPersons or the Consolidated Sanctions List administered by the U.S. Department\nof the Treasury’s Office of Foreign Assets Control, or the Denied Persons List\nor Entity List administered by the U.S. Department of Commerce)\n(“Sanctioned Person”), or (iii) controlled or 50% or more owned by a Sanctioned\nPerson.\n\nYou agree to comply with all export, re-export and import restrictions and\nregulations of the U.S. Department of Commerce or other agency or authority of\nthe United States or other applicable countries. You also agree not to transfer,\nor authorize the transfer of, directly or indirectly, of the Software to any\nProhibited Jurisdiction, or otherwise in violation of any such restrictions or\nregulations.\n"
  },
  {
    "path": "External/Realm/Realm.framework/Versions/A/Resources/strip-frameworks.sh",
    "content": "################################################################################\n#\n# Copyright 2015 Realm Inc.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n#\n################################################################################\n\n# This script strips all non-valid architectures from dynamic libraries in\n# the application's `Frameworks` directory.\n#\n# The following environment variables are required:\n#\n# BUILT_PRODUCTS_DIR\n# FRAMEWORKS_FOLDER_PATH\n# VALID_ARCHS\n# EXPANDED_CODE_SIGN_IDENTITY\n\n\n# Signs a framework with the provided identity\ncode_sign() {\n  # Use the current code_sign_identitiy\n  echo \"Code Signing $1 with Identity ${EXPANDED_CODE_SIGN_IDENTITY_NAME}\"\n  echo \"/usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements $1\"\n  /usr/bin/codesign --force --sign ${EXPANDED_CODE_SIGN_IDENTITY} --preserve-metadata=identifier,entitlements \"$1\"\n}\n\n# Set working directory to product’s embedded frameworks \ncd \"${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}\"\n\nif [ \"$ACTION\" = \"install\" ]; then\n  echo \"Copy .bcsymbolmap files to .xcarchive\"\n  find . -name '*.bcsymbolmap' -type f -exec mv {} \"${CONFIGURATION_BUILD_DIR}\" \\;\nelse\n  # Delete *.bcsymbolmap files from framework bundle unless archiving\n  find . -name '*.bcsymbolmap' -type f -exec rm -rf \"{}\" +\\;\nfi\n\necho \"Stripping frameworks\"\n\nfor file in $(find . -type f -perm +111); do\n  # Skip non-dynamic libraries\n  if ! [[ \"$(file \"$file\")\" == *\"dynamically linked shared library\"* ]]; then\n    continue\n  fi\n  # Get architectures for current file\n  archs=\"$(lipo -info \"${file}\" | rev | cut -d ':' -f1 | rev)\"\n  stripped=\"\"\n  for arch in $archs; do\n    if ! [[ \"${VALID_ARCHS}\" == *\"$arch\"* ]]; then\n      # Strip non-valid architectures in-place\n      lipo -remove \"$arch\" -output \"$file\" \"$file\" || exit 1\n      stripped=\"$stripped $arch\"\n    fi\n  done\n  if [[ \"$stripped\" != \"\" ]]; then\n    echo \"Stripped $file of architectures:$stripped\"\n    if [ \"${CODE_SIGNING_REQUIRED}\" == \"YES\" ]; then\n      code_sign \"${file}\"\n    fi\n  fi\ndone\n"
  },
  {
    "path": "External/Realm/RealmRepository.swift",
    "content": "//\n//  CoreDataRepository.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 15/04/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\nimport RealmSwift\n\nclass RealmRepository {\n    \n    fileprivate let databaseName = \"Jirassic\"\n    var realm: Realm!\n    \n    init() {\n        var config = Realm.Configuration()\n        config.fileURL = config.fileURL!.deletingLastPathComponent().appendingPathComponent(\"\\(databaseName).realm\")\n        Realm.Configuration.defaultConfiguration = config\n        realm = try! Realm()\n    }\n    \n    convenience init (documentsDirectory: String) {\n        self.init()\n        var config = Realm.Configuration()\n        config.fileURL = config.fileURL!.deletingLastPathComponent().appendingPathComponent(\"\\(databaseName).realm\")\n        Realm.Configuration.defaultConfiguration = config\n        realm = try! Realm()\n    }\n}\n\nextension RealmRepository {\n    \n    fileprivate func queryWithPredicate<T:Object> (_ predicate: NSPredicate?, sortingKeyPath: String?) -> [T] {\n        \n        var results = [T]()\n        var resultsObjs = realm.objects(T.self)\n        \n        if let pred = predicate {\n            resultsObjs = resultsObjs.filter(pred)\n        }\n        if let key = sortingKeyPath {\n            resultsObjs = resultsObjs.sorted(byKeyPath: key)\n        }\n        for result in resultsObjs {\n            results.append(result)\n        }\n        return results\n    }\n}\n\nextension RealmRepository: RepositoryUser {\n    \n    func currentUser() -> User {\n        \n//        let userPredicate = NSPredicate(format: \"isLoggedIn == YES\")\n//        let cusers: [RUser] = queryWithPredicate(userPredicate, sortDescriptors: nil)\n//        if let cuser = cusers.last {\n//            return User(isLoggedIn: true, email: cuser.email, userId: cuser.userId, lastSyncDate: cuser.lastSyncDate)\n//        }\n        \n        return User(isLoggedIn: false, email: nil, userId: nil, lastSyncDate: nil)\n    }\n    \n    func loginWithCredentials (_ credentials: UserCredentials, completion: (NSError?) -> Void) {\n        fatalError(\"This method is not applicable to CoreDataRepository\")\n    }\n    \n    func registerWithCredentials (_ credentials: UserCredentials, completion: (NSError?) -> Void) {\n        fatalError(\"This method is not applicable to CoreDataRepository\")\n    }\n    \n    func logout() {\n    }\n}\n\nextension RealmRepository: RepositoryTasks {\n\n    func queryTasks (_ page: Int, completion: ([Task], NSError?) -> Void) {\n        \n        let results: [RTask] = queryWithPredicate(nil, sortingKeyPath: \"endDate\")\n        let tasks = tasksFromRTasks(results)\n        \n        completion(tasks, nil)\n    }\n    \n    func queryTasksInDay (_ day: Date) -> [Task] {\n        \n        let compoundPredicate = NSCompoundPredicate(orPredicateWithSubpredicates: [\n            NSPredicate(format: \"endDate >= %@ AND endDate <= %@\", day.startOfDay() as CVarArg, day.endOfDay() as CVarArg)\n        ])\n//        let sortDescriptors = [NSSortDescriptor(key: \"endDate\", ascending: true)]\n        let results: [RTask] = queryWithPredicate(compoundPredicate, sortingKeyPath: \"endDate\")\n        let tasks = tasksFromRTasks(results)\n        \n        return tasks\n    }\n    \n    func queryUnsyncedTasks() -> [Task] {\n        \n        let predicate = NSPredicate(format: \"lastModifiedDate == nil\")\n        let results: [RTask] = queryWithPredicate(predicate, sortingKeyPath: nil)\n        let tasks = tasksFromRTasks(results)\n        \n        return tasks\n    }\n    \n    func deleteTask (_ task: Task, completion: ((_ success: Bool) -> Void)) {\n        \n        realm.beginWrite()\n        let rtask = rtaskFromTask(task)\n        realm.delete(rtask)\n        try! realm.commitWrite()\n        completion(true)\n    }\n    \n    func saveTask (_ task: Task, completion: (_ success: Bool) -> Void) -> Task {\n        \n        realm.beginWrite()\n        let rtask = rtaskFromTask(task)\n        try! realm.commitWrite()\n        \n        return taskFromRTask(rtask)\n    }\n    \n    fileprivate func taskFromRTask (_ rtask: RTask) -> Task {\n        \n        return Task(startDate: rtask.startDate,\n                    endDate: rtask.endDate!,\n                    notes: rtask.notes,\n                    taskNumber: rtask.taskNumber,\n                    taskType: TaskType(rawValue: rtask.taskType)!,\n                    objectId: rtask.objectId!\n        )\n    }\n    \n    fileprivate func tasksFromRTasks (_ rtasks: [RTask]) -> [Task] {\n        \n        var tasks = [Task]()\n        for rtask in rtasks {\n            tasks.append(self.taskFromRTask(rtask))\n        }\n        \n        return tasks\n    }\n    \n    fileprivate func rtaskFromTask (_ task: Task) -> RTask {\n        \n        let taskPredicate = NSPredicate(format: \"objectId == %@\", task.objectId)\n        let tasks: [RTask] = queryWithPredicate(taskPredicate, sortingKeyPath: nil)\n        var rtask: RTask? = tasks.first\n        if rtask == nil {\n//            rtask = RTask()\n            rtask = realm.create(RTask.self)\n        }\n        if rtask?.objectId == nil {\n            rtask?.objectId = task.objectId\n        }\n        \n        return updatedRTask(rtask!, withTask: task)\n    }\n    \n    // Update only updatable properties. objectId can't be updated\n    fileprivate func updatedRTask (_ rtask: RTask, withTask task: Task) -> RTask {\n        \n        rtask.taskNumber = task.taskNumber\n        rtask.taskType = task.taskType.rawValue\n        rtask.notes = task.notes\n        rtask.startDate = task.startDate\n        rtask.endDate = task.endDate\n        \n        return rtask\n    }\n}\n\nextension RealmRepository: RepositorySettings {\n    \n    func settings() -> Settings {\n        \n        let results: [RSettings] = queryWithPredicate(nil, sortingKeyPath: nil)\n        var rsettings: RSettings? = results.first\n        if rsettings == nil {\n            \n            realm.beginWrite()\n            \n            rsettings = RSettings()\n            rsettings?.startOfDayEnabled = true\n            rsettings?.lunchEnabled = true\n            rsettings?.scrumEnabled = true\n            rsettings?.meetingEnabled = true\n            rsettings?.autoTrackEnabled = true\n            rsettings?.trackingMode = 1\n            rsettings?.startOfDayTime = Date(hour: 9, minute: 0)\n            rsettings?.endOfDayTime = Date(hour: 17, minute: 0)\n            rsettings?.lunchTime = Date(hour: 13, minute: 0)\n            rsettings?.scrumTime = Date(hour: 10, minute: 30)\n            rsettings?.minSleepDuration = Date(hour: 0, minute: 13)\n            \n            try! realm.commitWrite()\n        }\n        return settingsFromRSettings(rsettings!)\n    }\n    \n    func saveSettings (_ settings: Settings) {\n        \n        realm.beginWrite()\n        let _ = rsettingsFromSettings(settings)\n        try! realm.commitWrite()\n    }\n    \n    fileprivate func settingsFromRSettings (_ rsettings: RSettings) -> Settings {\n        \n        return Settings(startOfDayEnabled: rsettings.startOfDayEnabled,\n                        lunchEnabled: rsettings.lunchEnabled,\n                        scrumEnabled: rsettings.scrumEnabled,\n                        meetingEnabled: rsettings.meetingEnabled,\n                        autoTrackEnabled: rsettings.autoTrackEnabled,\n                        trackingMode: TaskTrackingMode(rawValue: rsettings.trackingMode)!,\n                        startOfDayTime: rsettings.startOfDayTime!,\n                        endOfDayTime: rsettings.endOfDayTime!,\n                        lunchTime: rsettings.lunchTime!,\n                        scrumTime: rsettings.scrumTime!,\n                        minSleepDuration: rsettings.minSleepDuration!\n        )\n    }\n    \n    fileprivate func rsettingsFromSettings (_ settings: Settings) -> RSettings {\n        \n        let results: [RSettings] = queryWithPredicate(nil, sortingKeyPath: nil)\n        var rsettings: RSettings? = results.first\n        if rsettings == nil {\n            rsettings = RSettings()\n        }\n        rsettings?.startOfDayEnabled = settings.startOfDayEnabled\n        rsettings?.lunchEnabled = settings.lunchEnabled\n        rsettings?.scrumEnabled = settings.scrumEnabled\n        rsettings?.meetingEnabled = settings.meetingEnabled\n        rsettings?.autoTrackEnabled = settings.autoTrackEnabled\n        rsettings?.trackingMode = settings.trackingMode.rawValue\n        rsettings?.startOfDayTime = settings.startOfDayTime\n        rsettings?.endOfDayTime = settings.endOfDayTime\n        rsettings?.lunchTime = settings.lunchTime\n        rsettings?.scrumTime = settings.scrumTime\n        rsettings?.minSleepDuration = settings.minSleepDuration\n        \n        return rsettings!\n    }\n}\n"
  },
  {
    "path": "External/Realm/RealmSwift.framework/Versions/A/Headers/RealmSwift-Swift.h",
    "content": "// Generated by Apple Swift version 3.0.2 (swiftlang-800.0.63 clang-800.0.42.1)\n#pragma clang diagnostic push\n\n#if defined(__has_include) && __has_include(<swift/objc-prologue.h>)\n# include <swift/objc-prologue.h>\n#endif\n\n#pragma clang diagnostic ignored \"-Wauto-import\"\n#include <objc/NSObject.h>\n#include <stdint.h>\n#include <stddef.h>\n#include <stdbool.h>\n\n#if !defined(SWIFT_TYPEDEFS)\n# define SWIFT_TYPEDEFS 1\n# if defined(__has_include) && __has_include(<uchar.h>)\n#  include <uchar.h>\n# elif !defined(__cplusplus) || __cplusplus < 201103L\ntypedef uint_least16_t char16_t;\ntypedef uint_least32_t char32_t;\n# endif\ntypedef float swift_float2  __attribute__((__ext_vector_type__(2)));\ntypedef float swift_float3  __attribute__((__ext_vector_type__(3)));\ntypedef float swift_float4  __attribute__((__ext_vector_type__(4)));\ntypedef double swift_double2  __attribute__((__ext_vector_type__(2)));\ntypedef double swift_double3  __attribute__((__ext_vector_type__(3)));\ntypedef double swift_double4  __attribute__((__ext_vector_type__(4)));\ntypedef int swift_int2  __attribute__((__ext_vector_type__(2)));\ntypedef int swift_int3  __attribute__((__ext_vector_type__(3)));\ntypedef int swift_int4  __attribute__((__ext_vector_type__(4)));\ntypedef unsigned int swift_uint2  __attribute__((__ext_vector_type__(2)));\ntypedef unsigned int swift_uint3  __attribute__((__ext_vector_type__(3)));\ntypedef unsigned int swift_uint4  __attribute__((__ext_vector_type__(4)));\n#endif\n\n#if !defined(SWIFT_PASTE)\n# define SWIFT_PASTE_HELPER(x, y) x##y\n# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y)\n#endif\n#if !defined(SWIFT_METATYPE)\n# define SWIFT_METATYPE(X) Class\n#endif\n#if !defined(SWIFT_CLASS_PROPERTY)\n# if __has_feature(objc_class_property)\n#  define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__\n# else\n#  define SWIFT_CLASS_PROPERTY(...)\n# endif\n#endif\n\n#if defined(__has_attribute) && __has_attribute(objc_runtime_name)\n# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X)))\n#else\n# define SWIFT_RUNTIME_NAME(X)\n#endif\n#if defined(__has_attribute) && __has_attribute(swift_name)\n# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X)))\n#else\n# define SWIFT_COMPILE_NAME(X)\n#endif\n#if defined(__has_attribute) && __has_attribute(objc_method_family)\n# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X)))\n#else\n# define SWIFT_METHOD_FAMILY(X)\n#endif\n#if defined(__has_attribute) && __has_attribute(noescape)\n# define SWIFT_NOESCAPE __attribute__((noescape))\n#else\n# define SWIFT_NOESCAPE\n#endif\n#if !defined(SWIFT_CLASS_EXTRA)\n# define SWIFT_CLASS_EXTRA\n#endif\n#if !defined(SWIFT_PROTOCOL_EXTRA)\n# define SWIFT_PROTOCOL_EXTRA\n#endif\n#if !defined(SWIFT_ENUM_EXTRA)\n# define SWIFT_ENUM_EXTRA\n#endif\n#if !defined(SWIFT_CLASS)\n# if defined(__has_attribute) && __has_attribute(objc_subclassing_restricted)\n#  define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA\n#  define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA\n# else\n#  define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA\n#  define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA\n# endif\n#endif\n\n#if !defined(SWIFT_PROTOCOL)\n# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA\n# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA\n#endif\n\n#if !defined(SWIFT_EXTENSION)\n# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__)\n#endif\n\n#if !defined(OBJC_DESIGNATED_INITIALIZER)\n# if defined(__has_attribute) && __has_attribute(objc_designated_initializer)\n#  define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))\n# else\n#  define OBJC_DESIGNATED_INITIALIZER\n# endif\n#endif\n#if !defined(SWIFT_ENUM)\n# define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum SWIFT_ENUM_EXTRA _name : _type\n# if defined(__has_feature) && __has_feature(generalized_swift_name)\n#  define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_EXTRA _name : _type\n# else\n#  define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) SWIFT_ENUM(_type, _name)\n# endif\n#endif\n#if !defined(SWIFT_UNAVAILABLE)\n# define SWIFT_UNAVAILABLE __attribute__((unavailable))\n#endif\n#if defined(__has_feature) && __has_feature(modules)\n@import Realm;\n@import ObjectiveC;\n@import Foundation;\n@import Realm.Private;\n#endif\n\n#pragma clang diagnostic ignored \"-Wproperty-attribute-mismatch\"\n#pragma clang diagnostic ignored \"-Wduplicate-method-arg\"\n@class RLMRealm;\n@class RLMObjectSchema;\n@class RLMSchema;\n\n/**\n  \\code\n  Object\n  \\endcode is a class used to define Realm model objects.\n  In Realm you define your model classes by subclassing \\code\n  Object\n  \\endcode and adding properties to be managed.\n  You then instantiate and use your custom subclasses instead of using the \\code\n  Object\n  \\endcode class directly.\n  \\code\n  class Dog: Object {\n      dynamic var name: String = \"\"\n      dynamic var adopted: Bool = false\n      let siblings = List<Dog>()\n  }\n\n  \\endcode<h3>Supported property types</h3>\n  <ul>\n    <li>\n      \\code\n      String\n      \\endcode, \\code\n      NSString\n      \\endcode\n    </li>\n    <li>\n      \\code\n      Int\n      \\endcode\n    </li>\n    <li>\n      \\code\n      Int8\n      \\endcode, \\code\n      Int16\n      \\endcode, \\code\n      Int32\n      \\endcode, \\code\n      Int64\n      \\endcode\n    </li>\n    <li>\n      \\code\n      Float\n      \\endcode\n    </li>\n    <li>\n      \\code\n      Double\n      \\endcode\n    </li>\n    <li>\n      \\code\n      Bool\n      \\endcode\n    </li>\n    <li>\n      \\code\n      Date\n      \\endcode, \\code\n      NSDate\n      \\endcode\n    </li>\n    <li>\n      \\code\n      Data\n      \\endcode, \\code\n      NSData\n      \\endcode\n    </li>\n    <li>\n      \\code\n      RealmOptional<T>\n      \\endcode for optional numeric properties\n    </li>\n    <li>\n      \\code\n      Object\n      \\endcode subclasses, to model many-to-one relationships\n    </li>\n    <li>\n      \\code\n      List<T>\n      \\endcode, to model many-to-many relationships\n    </li>\n  </ul>\n  \\code\n  String\n  \\endcode, \\code\n  NSString\n  \\endcode, \\code\n  Date\n  \\endcode, \\code\n  NSDate\n  \\endcode, \\code\n  Data\n  \\endcode, \\code\n  NSData\n  \\endcode and \\code\n  Object\n  \\endcode subclass properties can be declared as optional.\n  \\code\n  Int\n  \\endcode, \\code\n  Int8\n  \\endcode, \\code\n  Int16\n  \\endcode, \\code\n  Int32\n  \\endcode, \\code\n  Int64\n  \\endcode, \\code\n  Float\n  \\endcode, \\code\n  Double\n  \\endcode, \\code\n  Bool\n  \\endcode, and \\code\n  List\n  \\endcode properties cannot. To store an optional\n  number, use \\code\n  RealmOptional<Int>\n  \\endcode, \\code\n  RealmOptional<Float>\n  \\endcode, \\code\n  RealmOptional<Double>\n  \\endcode, or \\code\n  RealmOptional<Bool>\n  \\endcode instead,\n  which wraps an optional numeric value.\n  All property types except for \\code\n  List\n  \\endcode and \\code\n  RealmOptional\n  \\endcode <em>must</em> be declared as \\code\n  dynamic var\n  \\endcode. \\code\n  List\n  \\endcode and\n  \\code\n  RealmOptional\n  \\endcode properties must be declared as non-dynamic \\code\n  let\n  \\endcode properties. Swift \\code\n  lazy\n  \\endcode properties are not allowed.\n  Note that none of the restrictions listed above apply to properties that are configured to be ignored by Realm.\n  <h3>Querying</h3>\n  You can retrieve all objects of a given type from a Realm by calling the \\code\n  objects(_:)\n  \\endcode instance method.\n  <h3>Relationships</h3>\n  See our <a href=\"http://realm.io/docs/cocoa\">Cocoa guide</a> for more details.\n*/\nSWIFT_CLASS_NAMED(\"Object\")\n@interface RealmSwiftObject : RLMObjectBase\n/**\n  Creates an unmanaged instance of a Realm object.\n  Call \\code\n  add(_:)\n  \\endcode on a \\code\n  Realm\n  \\endcode instance to add an unmanaged object into that Realm.\n  <ul>\n    <li>\n      see: \\code\n      Realm().add(_:)\n      \\endcode\n    </li>\n  </ul>\n*/\n- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;\n/**\n  Creates an unmanaged instance of a Realm object.\n  The \\code\n  value\n  \\endcode argument is used to populate the object. It can be a key-value coding compliant object, an array or\n  dictionary returned from the methods in \\code\n  NSJSONSerialization\n  \\endcode, or an \\code\n  Array\n  \\endcode containing one element for each\n  managed property. An exception will be thrown if any required properties are not present and those properties were\n  not defined with default values.\n  When passing in an \\code\n  Array\n  \\endcode as the \\code\n  value\n  \\endcode argument, all properties must be present, valid and in the same order as\n  the properties defined in the model.\n  Call \\code\n  add(_:)\n  \\endcode on a \\code\n  Realm\n  \\endcode instance to add an unmanaged object into that Realm.\n  \\param value The value used to populate the object.\n\n*/\n- (nonnull instancetype)initWithValue:(id _Nonnull)value OBJC_DESIGNATED_INITIALIZER;\n/**\n  Indicates if the object can no longer be accessed because it is now invalid.\n  An object can no longer be accessed if the object has been deleted from the Realm that manages it, or if\n  \\code\n  invalidate()\n  \\endcode is called on that Realm.\n*/\n@property (nonatomic, readonly) BOOL isInvalidated;\n/**\n  A human-readable description of the object.\n*/\n@property (nonatomic, readonly, copy) NSString * _Nonnull description;\n/**\n  Helper to return the class name for an Object subclass.\n*/\n@property (nonatomic, readonly, copy) NSString * _Nonnull className;\n/**\n  WARNING: This is an internal helper method not intended for public use.\n  :nodoc:\n*/\n+ (Class _Nonnull)objectUtilClass:(BOOL)isSwift;\n/**\n  Override this method to specify the name of a property to be used as the primary key.\n  Only properties of types \\code\n  String\n  \\endcode and \\code\n  Int\n  \\endcode can be designated as the primary key. Primary key properties enforce\n  uniqueness for each value whenever the property is set, which incurs minor overhead. Indexes are created\n  automatically for primary key properties.\n\n  returns:\n  The name of the property designated as the primary key, or \\code\n  nil\n  \\endcode if the model has no primary key.\n*/\n+ (NSString * _Nullable)primaryKey;\n/**\n  Override this method to specify the names of properties to ignore. These properties will not be managed by\n  the Realm that manages the object.\n\n  returns:\n  An array of property names to ignore.\n*/\n+ (NSArray<NSString *> * _Nonnull)ignoredProperties;\n/**\n  Returns an array of property names for properties which should be indexed.\n  Only string, integer, boolean, \\code\n  Date\n  \\endcode, and \\code\n  NSDate\n  \\endcode properties are supported.\n\n  returns:\n  An array of property names.\n*/\n+ (NSArray<NSString *> * _Nonnull)indexedProperties;\n- (id _Nullable)objectForKeyedSubscript:(NSString * _Nonnull)key;\n- (void)setObject:(id _Nullable)value forKeyedSubscript:(NSString * _Nonnull)key;\n/**\n  Returns whether two Realm objects are equal.\n  Objects are considered equal if and only if they are both managed by the same Realm and point to the same\n  underlying object in the database.\n  \\param object The object to compare the receiver to.\n\n*/\n- (BOOL)isEqual:(id _Nullable)object;\n/**\n  WARNING: This is an internal initializer not intended for public use.\n  :nodoc:\n*/\n- (nonnull instancetype)initWithRealm:(RLMRealm * _Nonnull)realm schema:(RLMObjectSchema * _Nonnull)schema OBJC_DESIGNATED_INITIALIZER;\n/**\n  WARNING: This is an internal initializer not intended for public use.\n  :nodoc:\n*/\n- (nonnull instancetype)initWithValue:(id _Nonnull)value schema:(RLMSchema * _Nonnull)schema OBJC_DESIGNATED_INITIALIZER;\n@end\n\n\n/**\n  Object interface which allows untyped getters and setters for Objects.\n  :nodoc:\n*/\nSWIFT_CLASS(\"_TtC10RealmSwift13DynamicObject\")\n@interface DynamicObject : RealmSwiftObject\n- (id _Nullable)objectForKeyedSubscript:(NSString * _Nonnull)key;\n- (void)setObject:(id _Nullable)value forKeyedSubscript:(NSString * _Nonnull)key;\n/**\n  :nodoc:\n*/\n- (id _Nullable)valueForUndefinedKey:(NSString * _Nonnull)key;\n/**\n  :nodoc:\n*/\n- (void)setValue:(id _Nullable)value forUndefinedKey:(NSString * _Nonnull)key;\n/**\n  :nodoc:\n*/\n+ (BOOL)shouldIncludeInDefaultSchema;\n- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;\n- (nonnull instancetype)initWithValue:(id _Nonnull)value OBJC_DESIGNATED_INITIALIZER;\n- (nonnull instancetype)initWithRealm:(RLMRealm * _Nonnull)realm schema:(RLMObjectSchema * _Nonnull)schema OBJC_DESIGNATED_INITIALIZER;\n- (nonnull instancetype)initWithValue:(id _Nonnull)value schema:(RLMSchema * _Nonnull)schema OBJC_DESIGNATED_INITIALIZER;\n@end\n\n\n/**\n  :nodoc:\n  Internal class. Do not use directly. Used for reflection and initialization\n*/\nSWIFT_CLASS(\"_TtC10RealmSwift18LinkingObjectsBase\")\n@interface LinkingObjectsBase : NSObject <NSFastEnumeration>\n@property (nonatomic, readonly, copy) NSString * _Nonnull objectClassName;\n@property (nonatomic, readonly, copy) NSString * _Nonnull propertyName;\n@property (nonatomic, readonly, strong) RLMResults<RLMObject *> * _Nonnull rlmResults;\n- (nonnull instancetype)initFromClassName:(NSString * _Nonnull)objectClassName property:(NSString * _Nonnull)propertyName OBJC_DESIGNATED_INITIALIZER;\n- (NSInteger)countByEnumeratingWithState:(NSFastEnumerationState * _Nonnull)state objects:(id _Nullable * _Null_unspecified)buffer count:(NSInteger)len;\n- (nonnull instancetype)init SWIFT_UNAVAILABLE;\n@end\n\n\n/**\n  :nodoc:\n  Internal class. Do not use directly.\n*/\nSWIFT_CLASS(\"_TtC10RealmSwift8ListBase\")\n@interface ListBase : RLMListBase\n/**\n  Returns a human-readable description of the objects contained in the List.\n*/\n@property (nonatomic, readonly, copy) NSString * _Nonnull description;\n/**\n  Returns the number of objects in this List.\n*/\n@property (nonatomic, readonly) NSInteger count;\n- (nonnull instancetype)initWithArray:(RLMArray<RLMObject *> * _Nonnull)array OBJC_DESIGNATED_INITIALIZER;\n- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;\n@end\n\n\n@interface NSDate (SWIFT_EXTENSION(RealmSwift))\n@end\n\n\n@interface NSNumber (SWIFT_EXTENSION(RealmSwift))\n@end\n\n\n@interface NSNumber (SWIFT_EXTENSION(RealmSwift))\n@end\n\n\n\n@interface RealmSwiftObject (SWIFT_EXTENSION(RealmSwift))\n- (RLMObject * _Nonnull)unsafeCastToRLMObject;\n@end\n\n\n@interface RealmSwiftObject (SWIFT_EXTENSION(RealmSwift))\n+ (nonnull instancetype)bridgingFrom:(id _Nonnull)objectiveCValue with:(id _Nullable)metadata;\n@end\n\n\n/**\n  :nodoc:\n  Internal class. Do not use directly.\n*/\nSWIFT_CLASS_NAMED(\"ObjectUtil\")\n@interface RealmSwiftObjectUtil : NSObject\n- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;\n@end\n\n\n@interface RLMSyncCredentials (SWIFT_EXTENSION(RealmSwift))\n@end\n\n\n@interface RLMSyncManager (SWIFT_EXTENSION(RealmSwift))\n/**\n  The sole instance of the singleton.\n*/\nSWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, strong) RLMSyncManager * _Nonnull shared;)\n+ (RLMSyncManager * _Nonnull)shared;\n@end\n\n\n@interface RLMSyncSession (SWIFT_EXTENSION(RealmSwift))\n@end\n\n\n@interface RLMSyncUser (SWIFT_EXTENSION(RealmSwift))\n/**\n  A dictionary of all valid, logged-in user identities corresponding to their \\code\n  SyncUser\n  \\endcode objects.\n*/\nSWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, copy) NSDictionary<NSString *, RLMSyncUser *> * _Nonnull all;)\n+ (NSDictionary<NSString *, RLMSyncUser *> * _Nonnull)all;\n/**\n  The logged-in user. \\code\n  nil\n  \\endcode if none exists. Only use this property if your application expects\n  no more than one logged-in user at any given time.\n  warning:\n  Throws an Objective-C exception if more than one logged-in user exists.\n*/\nSWIFT_CLASS_PROPERTY(@property (nonatomic, class, readonly, strong) RLMSyncUser * _Nullable current;)\n+ (RLMSyncUser * _Nullable)current;\n@end\n\n\n/**\n  This model is used to reflect permissions.\n  It should be used in conjunction with a \\code\n  SyncUser\n  \\endcode’s Permission Realm.\n  You can only read this Realm. Use the objects in Management Realm to\n  make request for modifications of permissions.\n  See https://realm.io/docs/realm-object-server/#permissions for general\n  documentation.\n*/\nSWIFT_CLASS(\"_TtC10RealmSwift14SyncPermission\")\n@interface SyncPermission : RealmSwiftObject\n/**\n  The date this object was last modified.\n*/\n@property (nonatomic, copy) NSDate * _Nonnull updatedAt;\n/**\n  The ID of the affected user by the permission.\n*/\n@property (nonatomic, copy) NSString * _Nonnull userId;\n/**\n  The path to the realm.\n*/\n@property (nonatomic, copy) NSString * _Nonnull path;\n/**\n  Whether the affected user is allowed to read from the Realm.\n*/\n@property (nonatomic) BOOL mayRead;\n/**\n  Whether the affected user is allowed to write to the Realm.\n*/\n@property (nonatomic) BOOL mayWrite;\n/**\n  Whether the affected user is allowed to manage the access rights for others.\n*/\n@property (nonatomic) BOOL mayManage;\n/**\n  :nodoc:\n*/\n+ (BOOL)shouldIncludeInDefaultSchema;\n/**\n  :nodoc:\n*/\n+ (NSString * _Nullable)_realmObjectName;\n- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;\n- (nonnull instancetype)initWithValue:(id _Nonnull)value OBJC_DESIGNATED_INITIALIZER;\n- (nonnull instancetype)initWithRealm:(RLMRealm * _Nonnull)realm schema:(RLMObjectSchema * _Nonnull)schema OBJC_DESIGNATED_INITIALIZER;\n- (nonnull instancetype)initWithValue:(id _Nonnull)value schema:(RLMSchema * _Nonnull)schema OBJC_DESIGNATED_INITIALIZER;\n@end\n\n\n/**\n  This model is used for requesting changes to a Realm’s permissions.\n  It should be used in conjunction with a \\code\n  SyncUser\n  \\endcode’s Management Realm.\n  See https://realm.io/docs/realm-object-server/#permissions for general\n  documentation.\n*/\nSWIFT_CLASS(\"_TtC10RealmSwift20SyncPermissionChange\")\n@interface SyncPermissionChange : RealmSwiftObject\n/**\n  The globally unique ID string of this permission change object.\n*/\n@property (nonatomic, copy) NSString * _Nonnull id;\n/**\n  The date this object was initially created.\n*/\n@property (nonatomic, copy) NSDate * _Nonnull createdAt;\n/**\n  The date this object was last modified.\n*/\n@property (nonatomic, copy) NSDate * _Nonnull updatedAt;\n/**\n  An error or informational message, typically written to by the Realm Object Server.\n*/\n@property (nonatomic, copy) NSString * _Nullable statusMessage;\n/**\n  Sync management object status.\n*/\n@property (nonatomic, readonly) RLMSyncManagementObjectStatus status;\n/**\n  The remote URL to the realm.\n*/\n@property (nonatomic, copy) NSString * _Nonnull realmUrl;\n/**\n  The identity of a user affected by this permission change.\n*/\n@property (nonatomic, copy) NSString * _Nonnull userId;\n/**\n  :nodoc:\n*/\n+ (NSString * _Nullable)primaryKey;\n/**\n  :nodoc:\n*/\n+ (BOOL)shouldIncludeInDefaultSchema;\n/**\n  :nodoc:\n*/\n+ (NSString * _Nullable)_realmObjectName;\n- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;\n- (nonnull instancetype)initWithValue:(id _Nonnull)value OBJC_DESIGNATED_INITIALIZER;\n- (nonnull instancetype)initWithRealm:(RLMRealm * _Nonnull)realm schema:(RLMObjectSchema * _Nonnull)schema OBJC_DESIGNATED_INITIALIZER;\n- (nonnull instancetype)initWithValue:(id _Nonnull)value schema:(RLMSchema * _Nonnull)schema OBJC_DESIGNATED_INITIALIZER;\n@end\n\n\n/**\n  This model is used for offering permission changes to other users.\n  It should be used in conjunction with a \\code\n  SyncUser\n  \\endcode’s Management Realm.\n  See https://realm.io/docs/realm-object-server/#permissions for general\n  documentation.\n*/\nSWIFT_CLASS(\"_TtC10RealmSwift19SyncPermissionOffer\")\n@interface SyncPermissionOffer : RealmSwiftObject\n/**\n  The globally unique ID string of this permission offer object.\n*/\n@property (nonatomic, copy) NSString * _Nonnull id;\n/**\n  The date this object was initially created.\n*/\n@property (nonatomic, copy) NSDate * _Nonnull createdAt;\n/**\n  The date this object was last modified.\n*/\n@property (nonatomic, copy) NSDate * _Nonnull updatedAt;\n/**\n  An error or informational message, typically written to by the Realm Object Server.\n*/\n@property (nonatomic, copy) NSString * _Nullable statusMessage;\n/**\n  Sync management object status.\n*/\n@property (nonatomic, readonly) RLMSyncManagementObjectStatus status;\n/**\n  A token which uniquely identifies this offer. Generated by the server.\n*/\n@property (nonatomic, copy) NSString * _Nullable token;\n/**\n  The remote URL to the realm.\n*/\n@property (nonatomic, copy) NSString * _Nonnull realmUrl;\n/**\n  Whether this offer allows the receiver to read from the Realm.\n*/\n@property (nonatomic) BOOL mayRead;\n/**\n  Whether this offer allows the receiver to write to the Realm.\n*/\n@property (nonatomic) BOOL mayWrite;\n/**\n  Whether this offer allows the receiver to manage the access rights for others.\n*/\n@property (nonatomic) BOOL mayManage;\n/**\n  When this token will expire and become invalid.\n*/\n@property (nonatomic, copy) NSDate * _Nullable expiresAt;\n/**\n  Construct a permission offer object used to offer permission changes to other users.\n  \\param realmURL The URL to the Realm on which to apply these permission changes\n  to, once the offer is accepted.\n\n  \\param expiresAt When this token will expire and become invalid.\n  Pass \\code\n  nil\n  \\endcode if this offer should not expire.\n\n  \\param mayRead Grant or revoke read access.\n\n  \\param mayWrite Grant or revoked read-write access.\n\n  \\param mayManage Grant or revoke administrative access.\n\n*/\n- (nonnull instancetype)initWithRealmURL:(NSString * _Nonnull)realmURL expiresAt:(NSDate * _Nullable)expiresAt mayRead:(BOOL)mayRead mayWrite:(BOOL)mayWrite mayManage:(BOOL)mayManage;\n/**\n  :nodoc:\n*/\n+ (NSArray<NSString *> * _Nonnull)indexedProperties;\n/**\n  :nodoc:\n*/\n+ (NSString * _Nullable)primaryKey;\n/**\n  :nodoc:\n*/\n+ (BOOL)shouldIncludeInDefaultSchema;\n/**\n  :nodoc:\n*/\n+ (NSString * _Nullable)_realmObjectName;\n- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;\n- (nonnull instancetype)initWithValue:(id _Nonnull)value OBJC_DESIGNATED_INITIALIZER;\n- (nonnull instancetype)initWithRealm:(RLMRealm * _Nonnull)realm schema:(RLMObjectSchema * _Nonnull)schema OBJC_DESIGNATED_INITIALIZER;\n- (nonnull instancetype)initWithValue:(id _Nonnull)value schema:(RLMSchema * _Nonnull)schema OBJC_DESIGNATED_INITIALIZER;\n@end\n\n\n/**\n  This model is used to apply permission changes defined in the permission offer\n  object represented by the specified token, which was created by another user’s\n  \\code\n  SyncPermissionOffer\n  \\endcode object.\n  It should be used in conjunction with a \\code\n  SyncUser\n  \\endcode’s Management Realm.\n  See https://realm.io/docs/realm-object-server/#permissions for general\n  documentation.\n*/\nSWIFT_CLASS(\"_TtC10RealmSwift27SyncPermissionOfferResponse\")\n@interface SyncPermissionOfferResponse : RealmSwiftObject\n/**\n  The globally unique ID string of this permission offer response object.\n*/\n@property (nonatomic, copy) NSString * _Nonnull id;\n/**\n  The date this object was initially created.\n*/\n@property (nonatomic, copy) NSDate * _Nonnull createdAt;\n/**\n  The date this object was last modified.\n*/\n@property (nonatomic, copy) NSDate * _Nonnull updatedAt;\n/**\n  An error or informational message, typically written to by the Realm Object Server.\n*/\n@property (nonatomic, copy) NSString * _Nullable statusMessage;\n/**\n  Sync management object status.\n*/\n@property (nonatomic, readonly) RLMSyncManagementObjectStatus status;\n/**\n  The received token which uniquely identifies another user’s \\code\n  SyncPermissionOffer\n  \\endcode.\n*/\n@property (nonatomic, copy) NSString * _Nonnull token;\n/**\n  The remote URL to the realm on which these permission changes were applied.\n*/\n@property (nonatomic, copy) NSString * _Nullable realmUrl;\n/**\n  Construct a permission offer response object used to apply permission changes\n  defined in the permission offer object represented by the specified token,\n  which was created by another user’s \\code\n  SyncPermissionOffer\n  \\endcode object.\n  \\param token The received token which uniquely identifies another user’s\n  \\code\n  SyncPermissionOffer\n  \\endcode.\n\n*/\n- (nonnull instancetype)initWithToken:(NSString * _Nonnull)token;\n/**\n  :nodoc:\n*/\n+ (NSString * _Nullable)primaryKey;\n/**\n  :nodoc:\n*/\n+ (BOOL)shouldIncludeInDefaultSchema;\n/**\n  :nodoc:\n*/\n+ (NSString * _Nullable)_realmObjectName;\n- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;\n- (nonnull instancetype)initWithValue:(id _Nonnull)value OBJC_DESIGNATED_INITIALIZER;\n- (nonnull instancetype)initWithRealm:(RLMRealm * _Nonnull)realm schema:(RLMObjectSchema * _Nonnull)schema OBJC_DESIGNATED_INITIALIZER;\n- (nonnull instancetype)initWithValue:(id _Nonnull)value schema:(RLMSchema * _Nonnull)schema OBJC_DESIGNATED_INITIALIZER;\n@end\n\n#pragma clang diagnostic pop\n"
  },
  {
    "path": "External/Realm/RealmSwift.framework/Versions/A/Modules/module.modulemap",
    "content": "framework module RealmSwift {\n    header \"RealmSwift-Swift.h\"\n}\n"
  },
  {
    "path": "External/Realm/RealmSwift.framework/Versions/A/Resources/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>BuildMachineOSBuild</key>\n\t<string>16D32</string>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>English</string>\n\t<key>CFBundleExecutable</key>\n\t<string>RealmSwift</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>io.realm.RealmSwit</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>RealmSwift</string>\n\t<key>CFBundlePackageType</key>\n\t<string>FMWK</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>2.4.4</string>\n\t<key>CFBundleSignature</key>\n\t<string>????</string>\n\t<key>CFBundleSupportedPlatforms</key>\n\t<array>\n\t\t<string>MacOSX</string>\n\t</array>\n\t<key>CFBundleVersion</key>\n\t<string>2.4.4</string>\n\t<key>DTCompiler</key>\n\t<string>com.apple.compilers.llvm.clang.1_0</string>\n\t<key>DTPlatformBuild</key>\n\t<string>8C38</string>\n\t<key>DTPlatformVersion</key>\n\t<string>GM</string>\n\t<key>DTSDKBuild</key>\n\t<string>16C58</string>\n\t<key>DTSDKName</key>\n\t<string>macosx10.12</string>\n\t<key>DTXcode</key>\n\t<string>0820</string>\n\t<key>DTXcodeBuild</key>\n\t<string>8C38</string>\n\t<key>NSHumanReadableCopyright</key>\n\t<string>Copyright © 2014 Realm. All rights reserved.</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "External/Repository.swift",
    "content": "//\n//  Repository.swift\n//  Jirassic\n//\n//  Created by Baluta Cristian on 01/05/15.\n//  Copyright (c) 2015 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nprotocol RepositoryUser {\n    \n    func getUser (_ completion: @escaping ((_ user: User?) -> Void))\n    func loginWithCredentials (_ credentials: UserCredentials, completion: (NSError?) -> Void)\n    func registerWithCredentials (_ credentials: UserCredentials, completion: (NSError?) -> Void)\n    func logout()\n    \n}\n\nprotocol RepositoryTasks {\n\n    func queryTask (withId objectId: String) -> Task?\n    func queryTasks (startDate: Date, endDate: Date, predicate: NSPredicate?) -> [Task]\n    func queryTasks (startDate: Date, endDate: Date, predicate: NSPredicate?, completion: @escaping ([Task], NSError?) -> Void)\n    func queryUnsyncedTasks() -> [Task]\n    func queryDeletedTasks (_ completion: @escaping ([Task]) -> Void)\n    func queryUpdates (_ completion: @escaping ([Task], [String], NSError?) -> Void)\n    // Marks the Task as deleted. If permanently is true it will be removed from db\n    func deleteTask (_ task: Task, permanently: Bool, completion: @escaping ((_ success: Bool) -> Void))\n    func deleteTask (objectId: String, completion: @escaping ((_ success: Bool) -> Void))\n    // Save a task and returns the same task with a taskId generated if it didn't had. Return nil if task was not saved\n    func saveTask (_ task: Task, completion: @escaping ((_ task: Task?) -> Void))\n    \n}\n\nprotocol RepositorySettings {\n    \n    func settings() -> Settings\n    func saveSettings (_ settings: Settings)\n    \n}\n\ntypealias Repository = RepositoryUser & RepositoryTasks & RepositorySettings\n"
  },
  {
    "path": "External/RepositoryInteractor.swift",
    "content": "//\n//  RepositoryInteractor.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 01/05/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\n// Base class for any Interactor that wishes to use the repository\nclass RepositoryInteractor {\n    \n    var repository: Repository!\n    var remoteRepository: Repository?\n    \n    init (repository: Repository, remoteRepository: Repository?) {\n        self.repository = repository\n        self.remoteRepository = remoteRepository\n    }\n}\n"
  },
  {
    "path": "External/sqlite/SQLTable.swift",
    "content": "//\n//  SQLTable.swift\n//  SQLiteDB-iOS\n//\n//  Created by Fahim Farook on 6/11/15.\n//  Copyright © 2015 RookSoft Pte. Ltd. All rights reserved.\n//\n\nimport Foundation\n\n@objcMembers\nclass SQLTable: NSObject {\n    \n    /// Internal reference to the SQLite table name as determined based on the name of the `SQLTable` sub-class name. The sub-class name should be in the singular - for example, Task for a tasks table.\n    internal var table = \"\"\n    /// Internal dictionary to keep track of whether a specific table was verfied to be in existence in the database. This dictionary is used to automatically create the table if it does not exist in the DB.\n    private static var verified = [String: Bool]()\n    private var db = SQLiteDB.shared\n\t\n    /// Static variable indicating the table name - used in class methods since the instance variable `table` is not accessible in class methods.\n    private static var table: String {\n\t\tlet cls = \"\\(classForCoder())\".lowercased()\n\t\tlet ndx = cls.index(before: cls.endIndex)\n        let tnm = cls.hasSuffix(\"y\") ? cls[..<ndx] + \"ies\" : (cls.hasSuffix(\"s\") ? cls + \"s\" : cls + \"s\")\n\t\treturn tnm\n\t}\n\t\n\trequired override init() {\n\t\tsuper.init()\n        self.table = type(of: self).table\n        let verified = SQLTable.verified[table]\n        if verified == nil || !verified! {\n            // Verify that the table exists in DB\n            var sql = \"SELECT name FROM sqlite_master WHERE type='table' AND lower(name)='\\(table)'\"\n            let cnt = db?.query(sql:sql).count\n            if cnt == 1 {\n                // Table exists, proceed\n                SQLTable.verified[table] = true\n            } else if cnt == 0 {\n                // Table does not exist, create it\n                sql = \"CREATE TABLE IF NOT EXISTS \\(table) (\"\n                // Columns\n                let cols = values()\n                sql += getColumnSQL(columns:cols)\n                // Close query\n                sql += \")\"\n                let rc = db?.execute(sql:sql)\n                if rc == 0 {\n                    assert(false, \"Error creating table - \\(table) with SQL: \\(sql)\")\n                }\n                SQLTable.verified[table] = true\n            } else {\n                assert(false, \"Got more than one table in DB with same name! Count: \\(String(describing: cnt)) for \\(table)\")\n            }\n        }\n\t}\n\t\n\t// MARK:- Table property management\n\tfunc primaryKey() -> String {\n\t\treturn \"id\"\n\t}\n\t\n\tfunc ignoredKeys() -> [String] {\n\t\treturn []\n\t}\n\t\n\t// MARK:- Class Methods\n\tclass func rows (filter: String = \"\", order: String = \"\", limit: Int = 0) -> [SQLTable] {\n\t\tvar sql = \"SELECT * FROM \\(table)\"\n\t\tif !filter.isEmpty {\n\t\t\tsql += \" WHERE \\(filter)\"\n\t\t}\n\t\tif !order.isEmpty {\n\t\t\tsql += \" ORDER BY \\(order)\"\n\t\t}\n\t\tif limit > 0 {\n\t\t\tsql += \" LIMIT 0, \\(limit)\"\n\t\t}\n\t\treturn self.rowsFor(sql: sql)\n\t}\n    \n\tclass func rowsFor (sql: String = \"\") -> [SQLTable] {\n\t\tvar res = [SQLTable]()\n\t\tlet tmp = self.init()\n\t\tlet data = tmp.values()\n\t\tlet db = SQLiteDB.shared!\n\t\tlet fsql = sql.isEmpty ? \"SELECT * FROM \\(table)\" : sql\n\t\tlet arr = db.query(sql: fsql)\n\t\tfor row in arr {\n\t\t\tlet t = self.init()\n\t\t\tfor (key, _) in data {\n\t\t\t\tif let val = row[key] {\n\t\t\t\t\tt.setValue(val, forKey: key)\n\t\t\t\t}\n\t\t\t}\n\t\t\tres.append(t)\n\t\t}\n\t\treturn res\n\t}\n\t\n\tclass func rowBy (id: Any) -> SQLTable? {\n\t\tlet row = self.init()\n\t\tlet data = row.values()\n\t\tlet db = SQLiteDB.shared!\n\t\tvar val = \"\\(id)\"\n\t\tif id is String {\n\t\t\tval = \"'\\(id)'\"\n\t\t}\n\t\tlet sql = \"SELECT * FROM \\(table) WHERE \\(row.primaryKey())=\\(val)\"\n\t\tlet arr = db.query(sql: sql)\n\t\tif arr.count == 0 {\n\t\t\treturn nil\n\t\t}\n\t\tfor (key, _) in data {\n\t\t\tif let val = arr[0][key] {\n\t\t\t\trow.setValue(val, forKey: key)\n\t\t\t}\n\t\t}\n\t\treturn row\n\t}\n\t\n\tclass func count (filter: String = \"\") -> Int {\n\t\tlet db = SQLiteDB.shared!\n\t\tvar sql = \"SELECT COUNT(*) AS count FROM \\(table)\"\n\t\tif !filter.isEmpty {\n\t\t\tsql += \" WHERE \\(filter)\"\n\t\t}\n\t\tlet arr = db.query(sql:sql)\n\t\tif arr.count == 0 {\n\t\t\treturn 0\n\t\t}\n\t\tif let val = arr[0][\"count\"] as? Int {\n\t\t\treturn val\n\t\t}\n\t\treturn 0\n\t}\n\t\n\tclass func row (number: Int, filter: String = \"\", order: String = \"\") -> SQLTable? {\n\t\tlet row = self.init()\n\t\tlet data = row.values()\n\t\tlet db = SQLiteDB.shared!\n\t\tvar sql = \"SELECT * FROM \\(table)\"\n\t\tif !filter.isEmpty {\n\t\t\tsql += \" WHERE \\(filter)\"\n\t\t}\n\t\tif !order.isEmpty {\n\t\t\tsql += \" ORDER BY \\(order)\"\n\t\t}\n\t\t// Limit to specified row\n\t\tsql += \" LIMIT 1 OFFSET \\(number-1)\"\n\t\tlet arr = db.query(sql:sql)\n\t\tif arr.count == 0 {\n\t\t\treturn nil\n\t\t}\n\t\tfor (key, _) in data {\n\t\t\tif let val = arr[0][key] {\n\t\t\t\trow.setValue(val, forKey:key)\n\t\t\t}\n\t\t}\n\t\treturn row\n\t}\n\t\n\tclass func remove (filter: String = \"\") -> Bool {\n\t\tlet db = SQLiteDB.shared!\n\t\tlet sql: String\n\t\tif filter.isEmpty {\n\t\t\t// Delete all records\n\t\t\tsql = \"DELETE FROM \\(table)\"\n\t\t} else {\n\t\t\t// Use filter to delete\n\t\t\tsql = \"DELETE FROM \\(table) WHERE \\(filter)\"\n\t\t}\n\t\tlet rc = db.execute(sql: sql)\n\t\treturn (rc != 0)\n\t}\n\t\n\tclass func zap() {\n\t\tlet db = SQLiteDB.shared!\n\t\tlet sql = \"DELETE FROM \\(table)\"\n\t\t_ = db.execute(sql:sql)\n\t}\n\t\n\t// MARK:- Public Methods\n\tfunc save() -> Int {\n\t\tlet db = SQLiteDB.shared!\n\t\tlet key = primaryKey()\n\t\tlet data = values()\n\t\tvar insert = true\n\t\tif let rid = data[key] {\n\t\t\tvar val = \"\\(rid)\"\n\t\t\tif let _rid = rid as? String {\n\t\t\t\tval = \"'\\(_rid)'\"\n\t\t\t}\n\t\t\tlet sql = \"SELECT COUNT(*) AS count FROM \\(table) WHERE \\(primaryKey())=\\(val)\"\n\t\t\tlet arr = db.query(sql: sql)\n\t\t\tif arr.count == 1 {\n\t\t\t\tif let cnt = arr[0][\"count\"] as? Int {\n\t\t\t\t\tinsert = (cnt == 0)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\t// Insert or update\n\t\tlet (sql, params) = getSQL(data: data, forInsert: insert)\n\t\tlet rc = db.execute(sql: sql, parameters: params)\n\t\tif rc == 0 {\n            if SQLiteDB.sql_logs_enabled { print(\"Error saving record!\") }\n\t\t\treturn 0\n\t\t}\n\t\t// Update primary key\n\t\tlet pid = data[key]\n\t\tif insert {\n\t\t\tif pid is Int64 {\n\t\t\t\tsetValue(rc, forKey: key)\n\t\t\t} else if pid is Int {\n\t\t\t\tsetValue(Int(rc), forKey: key)\n\t\t\t}\n\t\t}\n\t\treturn rc\n\t}\n\t\n\tfunc delete() -> Bool {\n\t\tlet db = SQLiteDB.shared!\n\t\tlet key = primaryKey()\n\t\tlet data = values()\n\t\tif let rid = data[key] {\n            let v: String\n            if let s = rid as? String {\n                v = \"'\\(s)'\"\n            } else {\n                v = \"\\(rid)\"\n            }\n\t\t\tlet sql = \"DELETE FROM \\(table) WHERE \\(primaryKey())=\\(v)\"\n\t\t\tlet rc = db.execute(sql: sql)\n\t\t\treturn (rc != 0)\n\t\t}\n\t\treturn false\n\t}\n\t\n\tfunc refresh() {\n\t\tlet db = SQLiteDB.shared!\n\t\tlet key = primaryKey()\n\t\tlet data = values()\n\t\tif let rid = data[key] {\n\t\t\tlet sql = \"SELECT * FROM \\(table) WHERE \\(primaryKey())=\\(rid)\"\n\t\t\tlet arr = db.query(sql:sql)\n\t\t\tfor (key, _) in data {\n\t\t\t\tif let val = arr[0][key] {\n\t\t\t\t\tsetValue(val, forKey: key)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t\n\t// MARK:- Private Methods\n//\tprivate func properties() -> [String] {\n//\t\tvar res = [String]()\n//\t\tfor c in Mirror(reflecting:self).children {\n//\t\t\tif let name = c.label{\n//\t\t\t\tres.append(name)\n//\t\t\t}\n//\t\t}\n//\t\treturn res\n//\t}\n\t\n\tinternal func values() -> [String: Any] {\n\t\tvar res = [String: Any]()\n\t\tlet obj = Mirror(reflecting: self)\n\t\tfor (_, attr) in obj.children.enumerated() {\n\t\t\tif let name = attr.label {\n\t\t\t\t// Ignore special properties and lazy vars\n\t\t\t\tif ignoredKeys().contains(name) || name.hasSuffix(\".storage\") {\n\t\t\t\t\tcontinue\n\t\t\t\t}\n                res[name] = attr.value\n\t\t\t}\n\t\t}\n\t\treturn res\n\t}\n    \n    /// Returns a valid SQL statement and matching list of bound parameters needed to insert a new row into the database or to update an existing row of data.\n    ///\n    /// - Parameters:\n    ///   - data: A dictionary of property names and their corresponding values that need to be persisted to the underlying table.\n    ///   - forInsert: A boolean value indicating whether this is an insert or update action.\n    /// - Returns: A tuple containing a valid SQL command to persist data to the underlying table and the bound parameters for the SQL command, if any.\n\tprivate func getSQL (data: [String: Any], forInsert: Bool = true) -> (String, [Any]?) {\n\t\tvar sql = \"\"\n\t\tvar params: [Any]? = nil\n\t\tif forInsert {\n\t\t\t// INSERT INTO tasks(task, categoryID) VALUES ('\\(txtTask.text)', 1)\n\t\t\tsql = \"INSERT INTO \\(table) (\"\n\t\t} else {\n\t\t\t// UPDATE tasks SET task = ? WHERE categoryID = ?\n\t\t\tsql = \"UPDATE \\(table) SET \"\n\t\t}\n\t\tlet pkey = primaryKey()\n\t\tvar wsql = \"\"\n\t\tvar rid: Any?\n\t\tvar first = true\n\t\tfor (key, val) in data {\n\t\t\t// Primary key handling\n\t\t\tif pkey == key {\n\t\t\t\tif forInsert {\n\t\t\t\t\tif val is Int && (val as! Int) == -1 {\n\t\t\t\t\t\t// Do not add this since this is (could be?) an auto-increment value\n\t\t\t\t\t\tcontinue\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\t// Update - set up WHERE clause\n\t\t\t\t\twsql += \" WHERE \" + key + \" = ?\"\n\t\t\t\t\trid = val\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\t// Set up parameter array - if we get here, then there are parameters\n\t\t\tif first && params == nil {\n\t\t\t\tparams = [AnyObject]()\n\t\t\t}\n\t\t\tif forInsert {\n\t\t\t\tsql += first ? \"\\(key)\" : \", \\(key)\"\n\t\t\t\twsql += first ? \" VALUES (?\" : \", ?\"\n\t\t\t\tparams!.append(val)\n\t\t\t} else {\n\t\t\t\tsql += first ? \"\\(key) = ?\" : \", \\(key) = ?\"\n\t\t\t\tparams!.append(val)\n\t\t\t}\n\t\t\tfirst = false\n\t\t}\n\t\t// Finalize SQL\n\t\tif forInsert {\n\t\t\tsql += \")\" + wsql + \")\"\n\t\t} else if params != nil && !wsql.isEmpty {\n\t\t\tsql += wsql\n\t\t\tparams!.append(rid!)\n\t\t}\n        if SQLiteDB.sql_logs_enabled { print(\"Final SQL: \\(sql) with parameters: \\(String(describing: params))\") }\n\t\treturn (sql, params)\n\t}\n    \n    /// Returns a valid SQL fragment for creating the columns, with the correct data type, for the underlying table.\n    ///\n    /// - Parameter columns: A dictionary of property names and their corresponding values for the `SQLTable` sub-class\n    /// - Returns: A string containing an SQL fragment for delcaring the columns for the underlying table with the correct data type\n    private func getColumnSQL (columns: [String: Any]) -> String {\n        var sql = \"\"\n        for key in columns.keys {\n            let val = columns[key]!\n            var col = \"'\\(key)' \"\n            if val is Int {\n                // Integers\n                col += \"INTEGER\"\n                if key == primaryKey() {\n                    col += \" PRIMARY KEY AUTOINCREMENT NOT NULL UNIQUE\"\n                }\n            } else {\n                // Other values\n                if val is Float || val is Double {\n                    col += \"REAL\"\n                } else if val is Bool {\n                    col += \"BOOLEAN\"\n                } else if val is Date {\n                    col += \"DATE\"\n                } else if val is NSData {\n                    col += \"BLOB\"\n                } else {\n                    // Default to text\n                    col += \"TEXT\"\n                }\n                if key == primaryKey() {\n                    col += \" PRIMARY KEY NOT NULL UNIQUE\"\n                }\n            }\n            if sql.isEmpty {\n                sql = col\n            } else {\n                sql += \", \" + col\n            }\n        }\n        return sql\n    }\n}\n"
  },
  {
    "path": "External/sqlite/SQLiteDB.swift",
    "content": "//\n//  SQLiteDB.swift\n//  TasksGalore\n//\n//  Created by Fahim Farook on 12/6/14.\n//  Copyright (c) 2014 RookSoft Pte. Ltd. All rights reserved.\n//\n\nimport Foundation\n\nlet SQLITE_DATE = SQLITE_NULL + 1\nfileprivate let SQLITE_STATIC = unsafeBitCast(0, to: sqlite3_destructor_type.self)\nfileprivate let SQLITE_TRANSIENT = unsafeBitCast(-1, to: sqlite3_destructor_type.self)\n\n@objcMembers\nclass SQLiteDB: NSObject {\n    \n    static var sql_logs_enabled = false\n\tlet QUEUE_LABEL = \"SQLiteDB\"\n\tfileprivate var db: OpaquePointer? = nil\n\tfileprivate var queue: DispatchQueue!\n\tfileprivate let fmt = DateFormatter()\n\tfileprivate var path: String!\n    static var shared: SQLiteDB!\n\t\n    convenience init (url: URL) {\n\t\tself.init()\n\t\topenDB(path: url.path)\n        SQLiteDB.shared = self\n\t}\n\t\n\tdeinit {\n\t\tcloseDB()\n\t}\n \n\toverride var description: String {\n        return \"SQLiteDB: \\(String(describing: path))\"\n\t}\n\t\n\tfunc dbDate (dt: Date) -> String {\n\t\treturn fmt.string(from: dt)\n\t}\n\t\n\t// Execute SQL with parameters and return result code\n    func execute (sql: String, parameters: [Any]? = nil) -> Int {\n        if SQLiteDB.sql_logs_enabled { print(sql) }\n\t\tvar result = 0\n\t\tqueue.sync {\n\t\t\tif let stmt = self.prepare(sql: sql, params: parameters) {\n\t\t\t\tresult = self.execute(stmt: stmt, sql: sql)\n\t\t\t}\n\t\t}\n\t\treturn result\n\t}\n\t\n\t// Run SQL query with parameters\n    func query (sql: String, parameters: [Any]? = nil) -> [[String: Any]] {\n        if SQLiteDB.sql_logs_enabled { print(sql) }\n\t\tvar rows = [[String: Any]]()\n\t\tqueue.sync {\n\t\t\tif let stmt = self.prepare(sql: sql, params: parameters) {\n\t\t\t\trows = self.query(stmt: stmt, sql: sql)\n\t\t\t}\n\t\t}\n\t\treturn rows\n\t}\n\t\n    var version: Int {\n        get {\n            var version = 0\n            let arr = query(sql: \"PRAGMA user_version\")\n            if arr.count == 1 {\n                version = arr[0][\"user_version\"] as! Int\n            }\n            return version\n        }\n        set {\n            _ = execute(sql: \"PRAGMA user_version=\\(newValue)\")\n        }\n    }\n}\n\nextension SQLiteDB {\n\n    fileprivate func openDB (path: String) {\n\t\t// Set up essentials\n\t\tqueue = DispatchQueue(label: QUEUE_LABEL, attributes: [])\n\t\t// You need to set the locale in order for the 24-hour date format to work correctly on devices where 24-hour format is turned off\n\t\tfmt.locale = Locale(identifier: \"en_US_POSIX\")\n\t\tfmt.timeZone = TimeZone(secondsFromGMT: 0)\n\t\tfmt.dateFormat = \"yyyy-MM-dd HH:mm:ss\"\n\t\t// Open the DB\n\t\tlet cpath = path.cString(using: String.Encoding.utf8)\n\t\tlet error = sqlite3_open(cpath!, &db)\n\t\tif error != SQLITE_OK {\n\t\t\t// Open failed, close DB and fail\n            if SQLiteDB.sql_logs_enabled { print(\"SQLiteDB - failed to open DB!\") }\n\t\t\tsqlite3_close(db)\n\t\t\treturn\n\t\t}\n        if SQLiteDB.sql_logs_enabled { print(\"SQLiteDB opened!\") }\n\t}\n\t\n\tfileprivate func closeDB() {\n\t\tguard db != nil else {\n            return\n        }\n        // Get launch count value\n        let ud = UserDefaults.standard\n        var launchCount = ud.integer(forKey: \"LaunchCount\")\n        launchCount -= 1\n        if SQLiteDB.sql_logs_enabled { print(\"SQLiteDB - Launch count \\(launchCount)\") }\n        var clean = false\n        if launchCount < 0 {\n            clean = true\n            launchCount = 500\n        }\n        ud.set(launchCount, forKey: \"LaunchCount\")\n        ud.synchronize()\n        // Do we clean DB?\n        if !clean {\n            sqlite3_close(db)\n            return\n        }\n        // Clean DB\n        if SQLiteDB.sql_logs_enabled { print(\"SQLiteDB - Optimize DB\") }\n        let sql = \"VACUUM; ANALYZE\"\n        if CInt(execute(sql: sql)) != SQLITE_OK {\n            if SQLiteDB.sql_logs_enabled { print(\"SQLiteDB - Error cleaning DB\") }\n        }\n        sqlite3_close(db)\n\t}\n\t\n\t// fileprivate method which prepares the SQL\n\tfileprivate func prepare (sql: String, params: [Any]?) -> OpaquePointer? {\n\t\tvar stmt: OpaquePointer? = nil\n\t\tlet cSql = sql.cString(using: String.Encoding.utf8)\n\t\t// Prepare\n\t\tlet result = sqlite3_prepare_v2(self.db, cSql!, -1, &stmt, nil)\n\t\tif result != SQLITE_OK {\n\t\t\tsqlite3_finalize(stmt)\n\t\t\tif let error = String(validatingUTF8:sqlite3_errmsg(self.db)) {\n\t\t\t\tlet msg = \"SQLiteDB - failed to prepare SQL: \\(sql), Error: \\(error)\"\n\t\t\t\tNSLog(msg)\n\t\t\t}\n\t\t\treturn nil\n\t\t}\n\t\t// Bind parameters, if any\n\t\tif params != nil {\n\t\t\t// Validate parameters\n\t\t\tlet cntParams = sqlite3_bind_parameter_count(stmt)\n\t\t\tlet cnt = CInt(params!.count)\n\t\t\tif cntParams != cnt {\n\t\t\t\tlet msg = \"SQLiteDB - failed to bind parameters, counts did not match. SQL: \\(sql), Parameters: \\(String(describing: params))\"\n\t\t\t\tNSLog(msg)\n\t\t\t\treturn nil\n\t\t\t}\n\t\t\tvar flag: CInt = 0\n\t\t\t// Text & BLOB values passed to a C-API do not work correctly if they are not marked as transient.\n\t\t\tfor ndx in 1...cnt {\n//\t\t\t\tNSLog(\"Binding: \\(params![ndx-1]) at Index: \\(ndx)\")\n                let i: Int = Int(ndx) - 1\n\t\t\t\t// Check for data types\n\t\t\t\tif let txt = params![i] as? String {\n                    flag = sqlite3_bind_text(stmt, ndx, txt, -1, SQLITE_TRANSIENT)\n\t\t\t\t} else if let data = params![i] as? NSData {\n\t\t\t\t\tflag = sqlite3_bind_blob(stmt, ndx, data.bytes, CInt(data.length), SQLITE_TRANSIENT)\n\t\t\t\t} else if let date = params![i] as? Date {\n\t\t\t\t\tlet txt = fmt.string(from: date)\n\t\t\t\t\tflag = sqlite3_bind_text(stmt, ndx, txt, -1, SQLITE_TRANSIENT)\n\t\t\t\t} else if let val = params![i] as? Bool {\n\t\t\t\t\tlet num = val ? 1 : 0\n\t\t\t\t\tflag = sqlite3_bind_int(stmt, ndx, CInt(num))\n\t\t\t\t} else if let val = params![i] as? Double {\n\t\t\t\t\tflag = sqlite3_bind_double(stmt, ndx, CDouble(val))\n\t\t\t\t} else if let val = params![i] as? Int {\n\t\t\t\t\tflag = sqlite3_bind_int(stmt, ndx, CInt(val))\n\t\t\t\t} else {\n\t\t\t\t\tflag = sqlite3_bind_null(stmt, ndx)\n\t\t\t\t}\n\t\t\t\t// Check for errors\n\t\t\t\tif flag != SQLITE_OK {\n\t\t\t\t\tsqlite3_finalize(stmt)\n\t\t\t\t\tif let error = String(validatingUTF8:sqlite3_errmsg(self.db)) {\n\t\t\t\t\t\tlet msg = \"SQLiteDB - failed to bind for SQL: \\(sql), Parameters: \\(String(describing: params)), Index: \\(ndx) Error: \\(error)\"\n                        if SQLiteDB.sql_logs_enabled { print(msg) }\n\t\t\t\t\t}\n\t\t\t\t\treturn nil\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\treturn stmt\n\t}\n\t\n\t// fileprivate method which handles the actual execution of an SQL statement\n\tfileprivate func execute (stmt: OpaquePointer, sql: String) -> Int {\n\t\t// Step\n\t\tlet res = sqlite3_step(stmt)\n\t\tif res != SQLITE_OK && res != SQLITE_DONE {\n\t\t\tsqlite3_finalize(stmt)\n\t\t\tif let error = String(validatingUTF8: sqlite3_errmsg(self.db)) {\n\t\t\t\tlet msg = \"SQLiteDB - failed to execute SQL: \\(sql), Error: \\(error)\"\n                if SQLiteDB.sql_logs_enabled { print(msg) }\n\t\t\t}\n\t\t\treturn 0\n\t\t}\n\t\t// Is this an insert\n\t\tlet upp = sql.uppercased()\n\t\tvar result = 0\n\t\tif upp.hasPrefix(\"INSERT \") {\n\t\t\t// Known limitations: http://www.sqlite.org/c3ref/last_insert_rowid.html\n\t\t\tlet rid = sqlite3_last_insert_rowid(self.db)\n\t\t\tresult = Int(rid)\n\t\t} else if upp.hasPrefix(\"DELETE\") || upp.hasPrefix(\"UPDATE\") {\n\t\t\tvar cnt = sqlite3_changes(self.db)\n\t\t\tif cnt == 0 {\n\t\t\t\tcnt += 1\n\t\t\t}\n\t\t\tresult = Int(cnt)\n\t\t} else {\n\t\t\tresult = 1\n\t\t}\n\t\t// Finalize\n\t\tsqlite3_finalize(stmt)\n\t\treturn result\n\t}\n\t\n\t// fileprivate method which handles the actual execution of an SQL query\n\tfileprivate func query (stmt: OpaquePointer, sql: String) -> [[String: Any]] {\n\t\tvar rows = [[String:Any]]()\n\t\tvar fetchColumnInfo = true\n\t\tvar columnCount:CInt = 0\n\t\tvar columnNames = [String]()\n\t\tvar columnTypes = [CInt]()\n\t\tvar result = sqlite3_step(stmt)\n\t\twhile result == SQLITE_ROW {\n\t\t\t// Should we get column info?\n\t\t\tif fetchColumnInfo {\n\t\t\t\tcolumnCount = sqlite3_column_count(stmt)\n\t\t\t\tfor index in 0..<columnCount {\n\t\t\t\t\t// Get column name\n\t\t\t\t\tlet name = sqlite3_column_name(stmt, index)\n\t\t\t\t\tcolumnNames.append(String(validatingUTF8: name!)!)\n\t\t\t\t\t// Get column type\n\t\t\t\t\tcolumnTypes.append(self.getColumnType(index: index, stmt: stmt))\n\t\t\t\t}\n\t\t\t\tfetchColumnInfo = false\n\t\t\t}\n\t\t\t// Get row data for each column\n\t\t\tvar row = [String: Any]()\n\t\t\tfor index in 0..<columnCount {\n\t\t\t\tlet key = columnNames[Int(index)]\n\t\t\t\tlet type = columnTypes[Int(index)]\n\t\t\t\tif let val = getColumnValue(index: index, type: type, stmt: stmt) {\n//                    if SQLiteDB.sql_logs_enabled { print(\"Column type:\\(type) with value:\\(val)\") }\n\t\t\t\t\trow[key] = val\n\t\t\t\t}\n\t\t\t}\n\t\t\trows.append(row)\n\t\t\t// Next row\n\t\t\tresult = sqlite3_step(stmt)\n\t\t}\n\t\tsqlite3_finalize(stmt)\n\t\treturn rows\n\t}\n\t\n\t// Get column type\n\tfileprivate func getColumnType (index: CInt, stmt: OpaquePointer) -> CInt {\n\t\tvar type:CInt = 0\n\t\t// Column types - http://www.sqlite.org/datatype3.html (section 2.2 table column 1)\n\t\tlet blobTypes = [\"BINARY\", \"BLOB\", \"VARBINARY\"]\n\t\tlet charTypes = [\"CHAR\", \"CHARACTER\", \"CLOB\", \"NATIONAL VARYING CHARACTER\", \"NATIVE CHARACTER\", \"NCHAR\", \"NVARCHAR\", \"TEXT\", \"VARCHAR\", \"VARIANT\", \"VARYING CHARACTER\"]\n\t\tlet dateTypes = [\"DATE\", \"DATETIME\", \"TIME\", \"TIMESTAMP\"]\n\t\tlet intTypes  = [\"BIGINT\", \"BIT\", \"BOOL\", \"BOOLEAN\", \"INT\", \"INT2\", \"INT8\", \"INTEGER\", \"MEDIUMINT\", \"SMALLINT\", \"TINYINT\"]\n\t\tlet nullTypes = [\"NULL\"]\n\t\tlet realTypes = [\"DECIMAL\", \"DOUBLE\", \"DOUBLE PRECISION\", \"FLOAT\", \"NUMERIC\", \"REAL\"]\n\t\t// Determine type of column - http://www.sqlite.org/c3ref/c_blob.html\n\t\tlet buf = sqlite3_column_decltype(stmt, index)\n//\t\tNSLog(\"SQLiteDB - Got column type: \\(buf)\")\n\t\tif buf != nil {\n\t\t\tvar tmp = String(validatingUTF8:buf!)!.uppercased()\n\t\t\t// Remove bracketed section\n\t\t\tif let pos = tmp.range(of:\"(\") {\n\t\t\t\ttmp = String(tmp[..<pos.lowerBound])\n\t\t\t}\n\t\t\t// Remove unsigned?\n\t\t\t// Remove spaces\n\t\t\t// Is the data type in any of the pre-set values?\n//\t\t\tNSLog(\"SQLiteDB - Cleaned up column type: \\(tmp)\")\n\t\t\tif intTypes.contains(tmp) {\n\t\t\t\treturn SQLITE_INTEGER\n\t\t\t}\n\t\t\tif realTypes.contains(tmp) {\n\t\t\t\treturn SQLITE_FLOAT\n\t\t\t}\n\t\t\tif charTypes.contains(tmp) {\n\t\t\t\treturn SQLITE_TEXT\n\t\t\t}\n\t\t\tif blobTypes.contains(tmp) {\n\t\t\t\treturn SQLITE_BLOB\n\t\t\t}\n\t\t\tif nullTypes.contains(tmp) {\n\t\t\t\treturn SQLITE_NULL\n\t\t\t}\n\t\t\tif dateTypes.contains(tmp) {\n\t\t\t\treturn SQLITE_DATE\n\t\t\t}\n\t\t\treturn SQLITE_TEXT\n\t\t} else {\n\t\t\t// For expressions and sub-queries\n\t\t\ttype = sqlite3_column_type(stmt, index)\n\t\t}\n\t\treturn type\n\t}\n\t\n\tfileprivate func getColumnValue (index: CInt, type: CInt, stmt: OpaquePointer) -> Any? {\n\t\t// Integer\n\t\tif type == SQLITE_INTEGER {\n\t\t\tlet val = sqlite3_column_int(stmt, index)\n\t\t\treturn Int(val)\n\t\t}\n\t\t// Float\n\t\tif type == SQLITE_FLOAT {\n\t\t\tlet val = sqlite3_column_double(stmt, index)\n\t\t\treturn Double(val)\n\t\t}\n\t\t// Text - handled by default handler at end\n\t\t// Blob\n\t\tif type == SQLITE_BLOB {\n\t\t\tlet data = sqlite3_column_blob(stmt, index)\n\t\t\tlet size = sqlite3_column_bytes(stmt, index)\n\t\t\tlet val = NSData(bytes: data, length: Int(size))\n\t\t\treturn val\n\t\t}\n\t\t// Null\n\t\tif type == SQLITE_NULL {\n\t\t\treturn nil\n\t\t}\n\t\t// Date\n\t\tif type == SQLITE_DATE {\n\t\t\t// Is this a text date\n\t\t\tif let ptr = UnsafeRawPointer.init(sqlite3_column_text(stmt, index)) {\n\t\t\t\tlet uptr = ptr.bindMemory(to: CChar.self, capacity: 0)\n\t\t\t\tlet txt = String(validatingUTF8: uptr)!\n\t\t\t\tlet set = CharacterSet(charactersIn: \"-:\")\n\t\t\t\tif txt.rangeOfCharacter(from: set) != nil {\n                    let dateFormatter = DateFormatter()\n                    dateFormatter.timeZone = TimeZone(abbreviation: \"GMT\")\n                    dateFormatter.dateFormat = \"YYYY-MM-dd HH:mm:ss\"\n                    return dateFormatter.date(from: txt)!\n\t\t\t\t}\n\t\t\t}\n\t\t\t// If not a text date, then it's a time interval\n\t\t\tlet val = sqlite3_column_double(stmt, index)\n            if val == 0.0 {\n                return nil\n            }\n\t\t\tlet dt = Date(timeIntervalSince1970: val)\n\t\t\treturn dt\n\t\t}\n\t\t// If nothing works, return a string representation\n\t\tif let ptr = UnsafeRawPointer.init(sqlite3_column_text(stmt, index)) {\n\t\t\tlet uptr = ptr.bindMemory(to: CChar.self, capacity: 0)\n\t\t\tlet txt = String(validatingUTF8: uptr)\n\t\t\treturn txt\n\t\t}\n\t\treturn nil\n\t}\n}\n"
  },
  {
    "path": "External/sqlite/SQLiteSchema.swift",
    "content": "//\n//  SQLiteMigrator.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 01/04/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nenum SQLiteSchemaVersion: Int {\n    case v1 = 1\n}\n\nclass SQLiteSchema {\n    \n    fileprivate let expectedVersion: SQLiteSchemaVersion = .v1\n    \n    init (db: SQLiteDB) {\n        \n        if db.version != expectedVersion.rawValue {\n            migrate(db: db, toVersion: expectedVersion)\n            #warning(\"This should not be here\")\n//            UserDefaults.standard.serverChangeToken = nil\n        }\n    }\n}\n\nextension SQLiteSchema {\n    \n    func migrate (db: SQLiteDB, toVersion version: SQLiteSchemaVersion) {\n        \n        switch version {\n        case .v1:\n            let _ = db.execute(sql: \"CREATE TABLE IF NOT EXISTS stasks (lastModifiedDate DATETIME, markedForDeletion BOOL DEFAULT 0, startDate DATETIME, endDate DATETIME, notes TEXT, taskNumber TEXT, taskTitle TEXT, taskType INTEGER NOT NULL, objectId varchar(30) PRIMARY KEY);\")\n            \n            let _ = db.execute(sql: \"CREATE TABLE IF NOT EXISTS ssettingss (autotrack BOOL, autotrackingMode INTEGER, trackLunch BOOL, trackScrum BOOL, trackMeetings BOOL, trackCodeReviews BOOL, trackWastedTime BOOL, trackStartOfDay BOOL, enableBackup BOOL, startOfDayTime DATETIME, endOfDayTime DATETIME, lunchTime DATETIME, scrumTime DATETIME, minSleepDuration INTEGER, minCodeRevDuration INTEGER, codeRevLink TEXT, minWasteDuration INTEGER, wasteLinks TEXT, i INTEGER NOT NULL PRIMARY KEY);\")\n            \n            let _ = db.execute(sql: \"CREATE TABLE IF NOT EXISTS susers (userId TEXT, email TEXT, lastSyncDate DATETIME, isLoggedIn BOOL, i INTEGER NOT NULL PRIMARY KEY);\")\n            break\n        }\n        db.version = version.rawValue\n    }\n}\n"
  },
  {
    "path": "External/sqlite/SSettings.swift",
    "content": "//\n//  SSettings.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 17/09/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nclass SSettings: SQLTable {\n    \n    var autotrack: Bool = false\n    var autotrackingMode: Int = 0\n    var trackLunch: Bool = false\n    var trackScrum: Bool = false\n    var trackMeetings: Bool = false\n    var trackCodeReviews: Bool = false\n    var trackWastedTime: Bool = false\n    var trackStartOfDay: Bool = false\n    var enableBackup: Bool = false\n    \n    var startOfDayTime: Date? = nil\n    var endOfDayTime: Date? = nil\n    var lunchTime: Date? = nil\n    var scrumTime: Date? = nil\n    var minSleepDuration: Int = 0\n    var minCodeRevDuration: Int = 0\n    var codeRevLink: String? = nil\n    var minWasteDuration: Int = 0\n    var wasteLinks: String? = nil\n    \n    var i: Int = 0\n    \n    override func primaryKey() -> String {\n        return \"i\"\n    }\n    \n}\n"
  },
  {
    "path": "External/sqlite/STask.swift",
    "content": "//\n//  CTask.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 01/05/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nclass STask: SQLTable {\n    \n    var lastModifiedDate: Date?\n    var markedForDeletion = false\n    var startDate: Date?\n    var endDate: Date?\n    var notes: String?\n    var taskNumber: String?\n    var taskTitle: String?\n    var taskType: Int = 0\n    var objectId: String?\n    \n    override func primaryKey() -> String {\n        return \"objectId\"\n    }\n    \n    override var description: String {\n        return \"<STask: lastModifiedDate: \\(String(describing: lastModifiedDate ?? nil)) \\n markedForDeletion: \\(markedForDeletion) \\n startDate: \\(String(describing: startDate)) \\n endDate: \\(String(describing: endDate)) \\n notes: \\(String(describing: notes)) \\n taskNumber: \\(String(describing: taskNumber)) \\n taskTitle: \\(String(describing: taskTitle)) \\n taskType: \\(String(describing: taskType)) \\n objectId: \\(String(describing: objectId))>\"\n    }\n}\n"
  },
  {
    "path": "External/sqlite/SUser.swift",
    "content": "//\n//  SUser.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 04/05/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\n\nclass SUser: SQLTable {\n    \n    var userId: String?\n    var email: String?\n    var lastSyncDate: Date?\n    var isLoggedIn: Bool = false\n    \n    override func primaryKey() -> String {\n        return \"userId\"\n    }\n    \n}\n"
  },
  {
    "path": "External/sqlite/SqliteRepository+Settings.swift",
    "content": "//\n//  SqliteRepository+Settings.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 02/04/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nextension SqliteRepository: RepositorySettings {\n    \n    func settings() -> Settings {\n        \n        let results: [SSettings] = queryWithPredicate(nil, sortingKeyPath: nil)\n        var ssettings: SSettings? = results.first\n        if ssettings == nil {\n            // Default values\n            ssettings = SSettings()\n            ssettings?.autotrack = true\n            ssettings?.autotrackingMode = 1\n            ssettings?.trackLunch = true\n            ssettings?.trackScrum = true\n            ssettings?.trackMeetings = true\n            ssettings?.trackCodeReviews = true\n            ssettings?.trackWastedTime = true\n            ssettings?.trackStartOfDay = true\n            ssettings?.enableBackup = true\n            ssettings?.startOfDayTime = Date(hour: 9, minute: 0)\n            ssettings?.endOfDayTime = Date(hour: 17, minute: 0)\n            ssettings?.lunchTime = Date(hour: 13, minute: 0)\n            ssettings?.scrumTime = Date(hour: 10, minute: 30)\n            ssettings?.minSleepDuration = 13\n            ssettings?.minCodeRevDuration = 2\n            ssettings?.minWasteDuration = 5\n            ssettings?.codeRevLink = \"(http|https)://(.+)/projects/(.+)/repos/(.+)/pull-requests\"\n            ssettings?.wasteLinks = \"facebook.com,youtube.com,twitter.com\"\n        }\n\n        return settingsFromSSettings(ssettings!)\n    }\n    \n    func saveSettings (_ settings: Settings) {\n        \n        let ssettings = ssettingsFromSettings(settings)\n        _ = ssettings.save()\n    }\n    \n    fileprivate func settingsFromSSettings (_ ssettings: SSettings) -> Settings {\n        \n        return Settings(enableBackup: ssettings.enableBackup,\n                        settingsTracking: SettingsTracking(\n                            autotrack: ssettings.autotrack,\n                            autotrackingMode: TrackingMode(rawValue: ssettings.autotrackingMode)!,\n                            trackLunch: ssettings.trackLunch,\n                            trackScrum: ssettings.trackScrum,\n                            trackMeetings: ssettings.trackMeetings,\n                            trackStartOfDay: ssettings.trackStartOfDay,\n                            startOfDayTime: ssettings.startOfDayTime!,\n                            endOfDayTime: ssettings.endOfDayTime!,\n                            lunchTime: ssettings.lunchTime!,\n                            scrumTime: ssettings.scrumTime!,\n                            minSleepDuration: ssettings.minSleepDuration\n                        ),\n                        settingsBrowser: SettingsBrowser(\n                            trackCodeReviews: ssettings.trackCodeReviews,\n                            trackWastedTime: ssettings.trackWastedTime,\n                            minCodeRevDuration: ssettings.minCodeRevDuration,\n                            codeRevLink: ssettings.codeRevLink!,\n                            minWasteDuration: ssettings.minWasteDuration,\n                            wasteLinks: ssettings.wasteLinks!.toArray()\n                        )\n        )\n    }\n    \n    fileprivate func ssettingsFromSettings (_ settings: Settings) -> SSettings {\n        \n        let results: [SSettings] = queryWithPredicate(nil, sortingKeyPath: nil)\n        var ssettings: SSettings? = results.first\n        if ssettings == nil {\n            ssettings = SSettings()\n        }\n        ssettings?.autotrack = settings.settingsTracking.autotrack\n        ssettings?.autotrackingMode = settings.settingsTracking.autotrackingMode.rawValue\n        ssettings?.trackLunch = settings.settingsTracking.trackLunch\n        ssettings?.trackScrum = settings.settingsTracking.trackScrum\n        ssettings?.trackMeetings = settings.settingsTracking.trackMeetings\n        ssettings?.trackCodeReviews = settings.settingsBrowser.trackCodeReviews\n        ssettings?.trackWastedTime = settings.settingsBrowser.trackWastedTime\n        ssettings?.trackStartOfDay = settings.settingsTracking.trackStartOfDay\n        ssettings?.enableBackup = settings.enableBackup\n        ssettings?.startOfDayTime = settings.settingsTracking.startOfDayTime\n        ssettings?.endOfDayTime = settings.settingsTracking.endOfDayTime\n        ssettings?.lunchTime = settings.settingsTracking.lunchTime\n        ssettings?.scrumTime = settings.settingsTracking.scrumTime\n        ssettings?.minSleepDuration = settings.settingsTracking.minSleepDuration\n        ssettings?.minCodeRevDuration = settings.settingsBrowser.minCodeRevDuration\n        ssettings?.codeRevLink = settings.settingsBrowser.codeRevLink\n        ssettings?.minWasteDuration = settings.settingsBrowser.minWasteDuration\n        ssettings?.wasteLinks = settings.settingsBrowser.wasteLinks.toString()\n        \n        return ssettings!\n    }\n}\n"
  },
  {
    "path": "External/sqlite/SqliteRepository+Tasks.swift",
    "content": "//\n//  SqliteRepository+Tasks.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 02/04/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\nimport RCLog\n\nextension SqliteRepository: RepositoryTasks {\n\n    func queryTask (withId objectId: String) -> Task? {\n        \n        let taskPredicate = \"objectId == '\\(objectId)'\"\n        let tasks: [STask] = queryWithPredicate(taskPredicate, sortingKeyPath: nil)\n        if let stask = tasks.first {\n            return taskFromSTask(stask)\n        }\n        return nil\n    }\n    \n    func queryTasks (startDate: Date, endDate: Date, predicate: NSPredicate? = nil) -> [Task] {\n\n        let tasks = self.tasksBetween (startDate: startDate, endDate: endDate, predicate: predicate)\n        return tasks\n    }\n\n    func queryTasks (startDate: Date, endDate: Date, predicate: NSPredicate? = nil, completion: @escaping ([Task], NSError?) -> Void) {\n\n        queue.async {\n            let tasks = self.queryTasks (startDate: startDate, endDate: endDate, predicate: predicate)\n            completion(tasks, nil)\n        }\n    }\n    \n    func queryUnsyncedTasks() -> [Task] {\n\n        #if !CMD\n        RCLog(\"Query tasks since last sync date: \\(String(describing: UserDefaults.standard.lastSyncDateWithRemote))\")\n        #endif\n        var sinceDatePredicate = \"\"\n        if let lastSyncDateWithRemote = UserDefaults.standard.lastSyncDateWithRemote {\n            sinceDatePredicate = \" OR datetime(lastModifiedDate) > datetime('\\(lastSyncDateWithRemote.YYYYMMddHHmmssGMT())')\"\n        }\n        let predicate = \"(lastModifiedDate is NULL\\(sinceDatePredicate)) AND markedForDeletion == 0\"\n        let results: [STask] = queryWithPredicate(predicate, sortingKeyPath: nil)\n        let tasks = tasksFromSTasks(results)\n        \n        return tasks\n    }\n    \n    func queryDeletedTasks (_ completion: @escaping ([Task]) -> Void) {\n        \n        let predicate = \"markedForDeletion == 1\"\n        let results: [STask] = queryWithPredicate(predicate, sortingKeyPath: nil)\n        let tasks = tasksFromSTasks(results)\n        \n        completion(tasks)\n    }\n    \n    func queryUpdates (_ completion: @escaping ([Task], [String], NSError?) -> Void) {\n        \n        queryDeletedTasks { (deletedTasks) in\n            let unsyncedTasks = self.queryUnsyncedTasks()\n            let deletedTasksIds = deletedTasks.map{ $0.objectId! }\n            completion(unsyncedTasks, deletedTasksIds, nil)\n        }\n    }\n    \n    func deleteTask (_ task: Task, permanently: Bool, completion: @escaping ((_ success: Bool) -> Void)) {\n        \n        let stask = staskFromTask(task)\n        if permanently {\n            completion( stask.delete() )\n        } else {\n            stask.markedForDeletion = true\n            completion( stask.save() == 1 )\n        }\n    }\n    \n    func deleteTask (objectId: String, completion: @escaping ((_ success: Bool) -> Void)) {\n        \n        let taskPredicate = \"objectId == '\\(objectId)'\"\n        let tasks: [STask] = queryWithPredicate(taskPredicate, sortingKeyPath: nil)\n        if let stask = tasks.first {\n            completion( stask.delete() )\n        } else {\n            completion( false )\n        }\n    }\n    \n    func saveTask (_ task: Task, completion: @escaping ((_ task: Task?) -> Void)) {\n        \n        let stask = staskFromTask(task)\n        let saved = stask.save()\n        #if !CMD\n        RCLog(\"Saved to sqlite \\(saved) \\(task)\")\n        #endif\n        if saved == 1 {\n            completion( taskFromSTask(stask))\n        } else {\n            completion(nil)\n        }\n    }\n}\n\nextension SqliteRepository {\n\n    private func tasksBetween (startDate: Date, endDate: Date, predicate: NSPredicate? = nil) -> [Task] {\n\n        let startDateString = startDate.YYYYMMddHHmmssGMT()\n        let endDateString = endDate.YYYYMMddHHmmssGMT()\n        var predicateComponents = [\"datetime(endDate) BETWEEN datetime('\\(startDateString)') AND datetime('\\(endDateString)')\",\n                                    \"markedForDeletion == 0\"]\n        if let p = predicate {\n            predicateComponents.append(\"(\\(p.predicateFormat))\")\n        }\n        let sqlPredicate = predicateComponents.joined(separator: \" AND \")\n        \n        let results: [STask] = queryWithPredicate(sqlPredicate, sortingKeyPath: \"endDate\")\n        let tasks = tasksFromSTasks(results)\n\n        return tasks\n    }\n\n    private func taskFromSTask (_ stask: STask) -> Task {\n        \n        return Task(lastModifiedDate: stask.lastModifiedDate,\n                    startDate: stask.startDate,\n                    endDate: stask.endDate!,\n                    notes: stask.notes,\n                    taskNumber: stask.taskNumber,\n                    taskTitle: stask.taskTitle,\n                    taskType: TaskType(rawValue: stask.taskType)!,\n                    objectId: stask.objectId!\n        )\n    }\n    \n    private func tasksFromSTasks (_ rtasks: [STask]) -> [Task] {\n        \n        var tasks = [Task]()\n        for rtask in rtasks {\n            tasks.append( taskFromSTask(rtask) )\n        }\n        \n        return tasks\n    }\n    \n    private func staskFromTask (_ task: Task) -> STask {\n        \n        let taskPredicate = \"objectId == '\\(task.objectId!)'\"\n        let tasks: [STask] = queryWithPredicate(taskPredicate, sortingKeyPath: nil)\n        var stask: STask? = tasks.first\n        if stask == nil {\n            stask = STask()\n            stask!.objectId = task.objectId\n        }\n        \n        return updatedSTask(stask!, withTask: task)\n    }\n    \n    // Update only updatable properties. objectId can't be updated\n    private func updatedSTask (_ stask: STask, withTask task: Task) -> STask {\n        \n        stask.taskNumber = task.taskNumber\n        stask.taskType = task.taskType.rawValue\n        stask.taskTitle = task.taskTitle\n        stask.notes = task.notes\n        stask.startDate = task.startDate\n        stask.endDate = task.endDate\n        stask.lastModifiedDate = task.lastModifiedDate\n        \n        return stask\n    }\n}\n"
  },
  {
    "path": "External/sqlite/SqliteRepository+User.swift",
    "content": "//\n//  SqliteRepository+User.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 02/04/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\nextension SqliteRepository: RepositoryUser {\n    \n    func getUser(_ completion: @escaping ((_ user: User?) -> Void)) {\n        fatalError(\"This method is not applicable to local Repository\")\n    }\n    \n    func loginWithCredentials (_ credentials: UserCredentials, completion: (NSError?) -> Void) {\n        fatalError(\"This method is not applicable to local Repository\")\n    }\n    \n    func registerWithCredentials (_ credentials: UserCredentials, completion: (NSError?) -> Void) {\n        fatalError(\"This method is not applicable to local Repository\")\n    }\n    \n    func logout() {\n        fatalError(\"This method is not applicable to local Repository\")\n    }\n}\n"
  },
  {
    "path": "External/sqlite/SqliteRepository.swift",
    "content": "//\n//  CoreDataRepository.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 15/04/16.\n//  Copyright © 2016 Cristian Baluta. All rights reserved.\n//\n\nimport Foundation\nimport RCLog\n\nclass SqliteRepository {\n    \n    private let appName = \"Jirassic\"\n    private let databaseName = \"Jirassic\"\n    private var db: SQLiteDB!\n    internal let queue = DispatchQueue(label: \"fetch_tasks\", attributes: [])\n    \n    init() {\n        let urls = FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)\n        let baseUrl = urls.last!\n        let url = baseUrl.appendingPathComponent(appName)\n        open(atUrl: url)\n    }\n    \n    required init (documentsDirectory: URL) {\n        open(atUrl: documentsDirectory)\n    }\n    \n    private func open (atUrl url: URL) {\n        \n        if !FileManager.default.fileExists(atPath: url.path) {\n            try! FileManager.default.createDirectory(at: url, withIntermediateDirectories: false, attributes: nil)\n        }\n        let dbUrl = url.appendingPathComponent(\"\\(databaseName).sqlite\")\n        #if !CMD\n        RCLog(dbUrl)\n        #endif\n        \n        db = SQLiteDB(url: dbUrl)\n        _ = SQLiteSchema(db: db)\n    }\n    \n    internal func queryWithPredicate<T: SQLTable> (_ predicate: String?, sortingKeyPath: String?) -> [T] {\n        \n        var results = [T]()\n        \n        let resultsObjs = T.rows(filter: predicate ?? \"\", order: sortingKeyPath != nil ? \"\\(sortingKeyPath!) ASC\" : \"\") as! [T]\n//        RCLog(resultsObjs)\n        for result in resultsObjs {\n            results.append(result)\n        }\n        \n        return results\n    }\n}\n"
  },
  {
    "path": "External/sqlite/UserDefaults+uploadToken.swift",
    "content": "//\n//  UserDefaults+uploadToken.swift\n//  Jirassic\n//\n//  Created by Cristian Baluta on 23/04/2017.\n//  Copyright © 2017 Imagin soft. All rights reserved.\n//\n\nimport Foundation\n\npublic extension UserDefaults {\n    \n    var lastSyncDateWithRemote: Date? {\n        get {\n            return self.object(forKey: \"localChangeDate\") as? Date\n        }\n        set {\n            self.set(newValue, forKey: \"localChangeDate\")\n        }\n    }\n}\n"
  },
  {
    "path": "Jirassic macOS.entitlements",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>com.apple.security.personal-information.calendars</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "Jirassic.xcodeproj/project.pbxproj",
    "content": "// !$*UTF8*$!\n{\n\tarchiveVersion = 1;\n\tclasses = {\n\t};\n\tobjectVersion = 54;\n\tobjects = {\n\n/* Begin PBXBuildFile section */\n\t\t2801388F205F86460051B532 /* TimeBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2801388E205F86460051B532 /* TimeBox.swift */; };\n\t\t28013890205F86460051B532 /* TimeBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2801388E205F86460051B532 /* TimeBox.swift */; };\n\t\t280300D61EDB5ECA000A763E /* StatisticsInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 280300D51EDB5ECA000A763E /* StatisticsInteractor.swift */; };\n\t\t280300D71EDB5ECA000A763E /* StatisticsInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 280300D51EDB5ECA000A763E /* StatisticsInteractor.swift */; };\n\t\t280300D81EDB5ECA000A763E /* StatisticsInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 280300D51EDB5ECA000A763E /* StatisticsInteractor.swift */; };\n\t\t280300D91EDB5ECA000A763E /* StatisticsInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 280300D51EDB5ECA000A763E /* StatisticsInteractor.swift */; };\n\t\t2803A0CA1EC184FF005F9389 /* BrowserNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2803A0C91EC184FF005F9389 /* BrowserNotification.swift */; };\n\t\t280C1D431ED74EF900C126A1 /* BrowserSupport.scpt in Resources */ = {isa = PBXBuildFile; fileRef = 280C1D411ED74EF900C126A1 /* BrowserSupport.scpt */; };\n\t\t280C1D441ED74EF900C126A1 /* ShellSupport.scpt in Resources */ = {isa = PBXBuildFile; fileRef = 280C1D421ED74EF900C126A1 /* ShellSupport.scpt */; };\n\t\t280D70B11ECC09D9005D2689 /* AppTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 280D70B01ECC09D9005D2689 /* AppTheme.swift */; };\n\t\t280D70C81ECFE5AC005D2689 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3421DD3B44200B73201 /* AppDelegate.swift */; };\n\t\t280D70C91ECFE5B1005D2689 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 4065D3431DD3B44200B73201 /* LaunchScreen.xib */; };\n\t\t280D70CA1ECFE5BD005D2689 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4065D3451DD3B44200B73201 /* Main.storyboard */; };\n\t\t280D70CB1ECFE5D0005D2689 /* DaysViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3471DD3B44200B73201 /* DaysViewController.swift */; };\n\t\t280D70CD1ECFE5DC005D2689 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4065D3491DD3B44200B73201 /* Images.xcassets */; };\n\t\t280D70CE1ECFE5E3005D2689 /* LoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D34B1DD3B44200B73201 /* LoginViewController.swift */; };\n\t\t280D70CF1ECFE5E7005D2689 /* NonTaskCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D34D1DD3B44200B73201 /* NonTaskCell.swift */; };\n\t\t280D70D01ECFE5EA005D2689 /* TaskCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D34E1DD3B44200B73201 /* TaskCell.swift */; };\n\t\t280D70D11ECFE5EE005D2689 /* TasksViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D34F1DD3B44200B73201 /* TasksViewController.swift */; };\n\t\t280D70D21ECFE7ED005D2689 /* Day.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3181DD3B44200B73201 /* Day.swift */; };\n\t\t280D70D31ECFE7FB005D2689 /* Report.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3191DD3B44200B73201 /* Report.swift */; };\n\t\t280D70D41ECFE7FF005D2689 /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D31B1DD3B44200B73201 /* Task.swift */; };\n\t\t280D70D51ECFE803005D2689 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D31D1DD3B44200B73201 /* User.swift */; };\n\t\t280D70D61ECFE807005D2689 /* Week.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D31E1DD3B44200B73201 /* Week.swift */; };\n\t\t280D70D71ECFE817005D2689 /* DateExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3201DD3B44200B73201 /* DateExtension.swift */; };\n\t\t280D70D81ECFE82E005D2689 /* ViewAutolayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3231DD3B44200B73201 /* ViewAutolayout.swift */; };\n\t\t280D70D91ECFE835005D2689 /* Conversions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3261DD3B44200B73201 /* Conversions.swift */; };\n\t\t280D70DA1ECFE83F005D2689 /* CreateReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D32B1DD3B44200B73201 /* CreateReport.swift */; };\n\t\t280D70DB1ECFE847005D2689 /* ReadDaysInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D32E1DD3B44200B73201 /* ReadDaysInteractor.swift */; };\n\t\t280D70DC1ECFE84C005D2689 /* ReadTasksInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D32F1DD3B44200B73201 /* ReadTasksInteractor.swift */; };\n\t\t280D70DE1ECFE870005D2689 /* UserInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D33D1DD3B44200B73201 /* UserInteractor.swift */; };\n\t\t280D70DF1ECFE888005D2689 /* CoreDataRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D38C1DD3B44200B73201 /* CoreDataRepository.swift */; };\n\t\t280D70E01ECFE88F005D2689 /* CoreDataRepository+Tasks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928891E910F4D0022AB55 /* CoreDataRepository+Tasks.swift */; };\n\t\t280D70E11ECFE88F005D2689 /* CoreDataRepository+Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A9288C1E910F970022AB55 /* CoreDataRepository+Settings.swift */; };\n\t\t280D70E21ECFE88F005D2689 /* CoreDataRepository+User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A9288F1E910FF60022AB55 /* CoreDataRepository+User.swift */; };\n\t\t280D70E31ECFE88F005D2689 /* CSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D38D1DD3B44200B73201 /* CSettings.swift */; };\n\t\t280D70E41ECFE88F005D2689 /* CTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D38E1DD3B44200B73201 /* CTask.swift */; };\n\t\t280D70E51ECFE88F005D2689 /* CUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D38F1DD3B44200B73201 /* CUser.swift */; };\n\t\t280D70E71ECFE8B9005D2689 /* CloudKitRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D38A1DD3B44200B73201 /* CloudKitRepository.swift */; };\n\t\t280D70E81ECFE8B9005D2689 /* CloudKitRepository+Tasks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928921E91104B0022AB55 /* CloudKitRepository+Tasks.swift */; };\n\t\t280D70E91ECFE8B9005D2689 /* CloudKitRepository+Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928961E9110BF0022AB55 /* CloudKitRepository+Settings.swift */; };\n\t\t280D70EA1ECFE8B9005D2689 /* CloudKitRepository+User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928941E9110980022AB55 /* CloudKitRepository+User.swift */; };\n\t\t280D70EB1ECFE8B9005D2689 /* UserDefaults+token.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28AFE7301E9A594500BAAD8C /* UserDefaults+token.swift */; };\n\t\t280D70F01ECFE8CC005D2689 /* Repository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3941DD3B44200B73201 /* Repository.swift */; };\n\t\t280D70F11ECFE8D0005D2689 /* RepositoryInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3951DD3B44200B73201 /* RepositoryInteractor.swift */; };\n\t\t280D70F41ECFE96F005D2689 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D31A1DD3B44200B73201 /* Settings.swift */; };\n\t\t280D70F51ECFE98C005D2689 /* UserDefaults+uploadToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28C9C6211EAD37D0007EB3E6 /* UserDefaults+uploadToken.swift */; };\n\t\t280D70F61ECFE9B3005D2689 /* RegisterUserInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D33C1DD3B44200B73201 /* RegisterUserInteractor.swift */; };\n\t\t280D70F71ED0E6EC005D2689 /* StringIdGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3221DD3B44200B73201 /* StringIdGenerator.swift */; };\n\t\t280D70FA1ED0E7B0005D2689 /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 280D70F91ED0E7B0005D2689 /* CloudKit.framework */; };\n\t\t280D71021ED35A25005D2689 /* UserDefaults+token.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28AFE7301E9A594500BAAD8C /* UserDefaults+token.swift */; };\n\t\t280D71031ED35A3E005D2689 /* StringArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 280F507C1EC868B0007416AB /* StringArray.swift */; };\n\t\t280D712C1ED6043D005D2689 /* Day.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3181DD3B44200B73201 /* Day.swift */; };\n\t\t280D712D1ED6043D005D2689 /* Report.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3191DD3B44200B73201 /* Report.swift */; };\n\t\t280D712E1ED6043D005D2689 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D31A1DD3B44200B73201 /* Settings.swift */; };\n\t\t280D712F1ED6043D005D2689 /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D31B1DD3B44200B73201 /* Task.swift */; };\n\t\t280D71311ED6043D005D2689 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D31D1DD3B44200B73201 /* User.swift */; };\n\t\t280D71321ED6043D005D2689 /* Week.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D31E1DD3B44200B73201 /* Week.swift */; };\n\t\t280D71331ED6043D005D2689 /* DateExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3201DD3B44200B73201 /* DateExtension.swift */; };\n\t\t280D71351ED6043D005D2689 /* StringIdGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3221DD3B44200B73201 /* StringIdGenerator.swift */; };\n\t\t280D71361ED6043D005D2689 /* StringArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 280F507C1EC868B0007416AB /* StringArray.swift */; };\n\t\t280D71371ED6043D005D2689 /* ViewAutolayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3231DD3B44200B73201 /* ViewAutolayout.swift */; };\n\t\t280D71381ED6043D005D2689 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3241DD3B44200B73201 /* ViewController.swift */; };\n\t\t280D71391ED6043D005D2689 /* ViewControllerStoryboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3251DD3B44200B73201 /* ViewControllerStoryboard.swift */; };\n\t\t280D713A1ED6043D005D2689 /* Conversions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3261DD3B44200B73201 /* Conversions.swift */; };\n\t\t280D713B1ED6043D005D2689 /* ComputerWakeUpInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3291DD3B44200B73201 /* ComputerWakeUpInteractor.swift */; };\n\t\t280D713D1ED6043D005D2689 /* CreateReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D32B1DD3B44200B73201 /* CreateReport.swift */; };\n\t\t280D713F1ED6043D005D2689 /* ReadDaysInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D32E1DD3B44200B73201 /* ReadDaysInteractor.swift */; };\n\t\t280D71411ED6043D005D2689 /* ReadTasksInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D32F1DD3B44200B73201 /* ReadTasksInteractor.swift */; };\n\t\t280D71431ED6043D005D2689 /* TaskFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3301DD3B44200B73201 /* TaskFinder.swift */; };\n\t\t280D71451ED6043D005D2689 /* TaskInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3321DD3B44200B73201 /* TaskInteractor.swift */; };\n\t\t280D71471ED6043D005D2689 /* TaskTypeEstimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3341DD3B44200B73201 /* TaskTypeEstimator.swift */; };\n\t\t280D71491ED6043D005D2689 /* TaskTypeSelection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3361DD3B44200B73201 /* TaskTypeSelection.swift */; };\n\t\t280D714A1ED6043D005D2689 /* PredictiveTimeTyping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3391DD3B44200B73201 /* PredictiveTimeTyping.swift */; };\n\t\t280D714C1ED6043D005D2689 /* RegisterUserInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D33C1DD3B44200B73201 /* RegisterUserInteractor.swift */; };\n\t\t280D714D1ED6043D005D2689 /* UserInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D33D1DD3B44200B73201 /* UserInteractor.swift */; };\n\t\t280D71591ED6043D005D2689 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3541DD3B44200B73201 /* AppDelegate.swift */; };\n\t\t280D715A1ED6043D005D2689 /* AppWireframe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3551DD3B44200B73201 /* AppWireframe.swift */; };\n\t\t280D715B1ED6043D005D2689 /* AppViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 405B15651DEF75660009871C /* AppViewController.swift */; };\n\t\t280D715D1ED6043D005D2689 /* AppLauncher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4051D5F81E0EA48A002042BB /* AppLauncher.swift */; };\n\t\t280D715E1ED6043D005D2689 /* Versioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2823C9341E4F69970055D036 /* Versioning.swift */; };\n\t\t280D715F1ED6043D005D2689 /* AppTheme.swift in Sources */ = {isa = PBXBuildFile; fileRef = 280D70B01ECC09D9005D2689 /* AppTheme.swift */; };\n\t\t280D71601ED6043D005D2689 /* MenuBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3651DD3B44200B73201 /* MenuBarController.swift */; };\n\t\t280D71611ED6043D005D2689 /* MenuBarIconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3661DD3B44200B73201 /* MenuBarIconView.swift */; };\n\t\t280D71621ED6043D005D2689 /* FlipAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3521DD3B44200B73201 /* FlipAnimation.swift */; };\n\t\t280D71631ED6043D005D2689 /* Animatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40FCE42F1DFD7C8D00D4FD45 /* Animatable.swift */; };\n\t\t280D71641ED6043D005D2689 /* PlaceholderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28279E9B1E8300E200EAF9FC /* PlaceholderViewController.swift */; };\n\t\t280D71661ED6043D005D2689 /* WelcomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40FCE42B1DFC3F8700D4FD45 /* WelcomeViewController.swift */; };\n\t\t280D71681ED6043D005D2689 /* TaskSuggestionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 405B15601DEF3D080009871C /* TaskSuggestionViewController.swift */; };\n\t\t280D71691ED6043D005D2689 /* TaskSuggestionPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 405B15621DEF3F2A0009871C /* TaskSuggestionPresenter.swift */; };\n\t\t280D716B1ED6043D005D2689 /* AccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5685C76B1DE8724400CA545E /* AccountViewController.swift */; };\n\t\t280D716C1ED6043D005D2689 /* CloudKitLoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5685C7631DE8721100CA545E /* CloudKitLoginViewController.swift */; };\n\t\t280D716E1ED6043D005D2689 /* LoginPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5685C7651DE8721100CA545E /* LoginPresenter.swift */; };\n\t\t280D716F1ED6043D005D2689 /* LoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5685C7661DE8721100CA545E /* LoginViewController.swift */; };\n\t\t280D71701ED6043D005D2689 /* ExtensionsInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40FCE4231DF7646F00D4FD45 /* ExtensionsInteractor.swift */; };\n\t\t280D71711ED6043D005D2689 /* ExtensionsInstallerInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 280F507A1EC8541D007416AB /* ExtensionsInstallerInteractor.swift */; };\n\t\t280D71721ED6043D005D2689 /* AppleScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40FCE4221DF7646F00D4FD45 /* AppleScript.swift */; };\n\t\t280D71731ED6043D005D2689 /* SandboxedAppleScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40FCE4241DF7646F00D4FD45 /* SandboxedAppleScript.swift */; };\n\t\t280D71741ED6043D005D2689 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3751DD3B44200B73201 /* SettingsViewController.swift */; };\n\t\t280D71751ED6043D005D2689 /* SettingsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3741DD3B44200B73201 /* SettingsPresenter.swift */; };\n\t\t280D71761ED6043D005D2689 /* SettingsInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3731DD3B44200B73201 /* SettingsInteractor.swift */; };\n\t\t280D71781ED6043D005D2689 /* NewTaskViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3711DD3B44200B73201 /* NewTaskViewController.swift */; };\n\t\t280D717A1ED6043D005D2689 /* TasksViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3851DD3B44200B73201 /* TasksViewController.swift */; };\n\t\t280D717B1ED6043D005D2689 /* TasksPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3831DD3B44200B73201 /* TasksPresenter.swift */; };\n\t\t280D717C1ED6043D005D2689 /* CalendarScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3771DD3B44200B73201 /* CalendarScrollView.swift */; };\n\t\t280D717D1ED6043D005D2689 /* TasksScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3841DD3B44200B73201 /* TasksScrollView.swift */; };\n\t\t280D717E1ED6043D005D2689 /* TasksDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A5F27D1E5789FC002BE564 /* TasksDataSource.swift */; };\n\t\t280D71811ED6043D005D2689 /* DataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A5F2811E586426002BE564 /* DataSource.swift */; };\n\t\t280D71821ED6043D005D2689 /* CellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3781DD3B44200B73201 /* CellProtocol.swift */; };\n\t\t280D71831ED6043D005D2689 /* TasksView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28EDE9381E59EC1500B360A4 /* TasksView.swift */; };\n\t\t280D718D1ED6043D005D2689 /* InternalNotifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3681DD3B44200B73201 /* InternalNotifications.swift */; };\n\t\t280D718E1ED6043D005D2689 /* UserNotifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3691DD3B44200B73201 /* UserNotifications.swift */; };\n\t\t280D718F1ED6043D005D2689 /* SleepNotifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D36A1DD3B44200B73201 /* SleepNotifications.swift */; };\n\t\t280D71901ED6043D005D2689 /* BrowserNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2803A0C91EC184FF005F9389 /* BrowserNotification.swift */; };\n\t\t280D719D1ED6043D005D2689 /* SqliteRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28577EA71E8ADC53002B07FD /* SqliteRepository.swift */; };\n\t\t280D719E1ED6043D005D2689 /* SqliteRepository+Tasks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928801E910DA40022AB55 /* SqliteRepository+Tasks.swift */; };\n\t\t280D719F1ED6043D005D2689 /* SqliteRepository+User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928831E910E5E0022AB55 /* SqliteRepository+User.swift */; };\n\t\t280D71A01ED6043D005D2689 /* SqliteRepository+Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928861E910EA70022AB55 /* SqliteRepository+Settings.swift */; };\n\t\t280D71A11ED6043D005D2689 /* SSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28577EA81E8ADC53002B07FD /* SSettings.swift */; };\n\t\t280D71A21ED6043D005D2689 /* STask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28577EA91E8ADC53002B07FD /* STask.swift */; };\n\t\t280D71A31ED6043D005D2689 /* SUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28577EAA1E8ADC53002B07FD /* SUser.swift */; };\n\t\t280D71A41ED6043D005D2689 /* SQLiteDB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28577EB31E8AF08F002B07FD /* SQLiteDB.swift */; };\n\t\t280D71A51ED6043D005D2689 /* SQLTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28577EB41E8AF08F002B07FD /* SQLTable.swift */; };\n\t\t280D71A61ED6043D005D2689 /* SQLiteSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928771E8F78580022AB55 /* SQLiteSchema.swift */; };\n\t\t280D71A71ED6043D005D2689 /* UserDefaults+uploadToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28C9C6211EAD37D0007EB3E6 /* UserDefaults+uploadToken.swift */; };\n\t\t280D71B61ED6043D005D2689 /* Repository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3941DD3B44200B73201 /* Repository.swift */; };\n\t\t280D71B71ED6043D005D2689 /* RepositoryInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3951DD3B44200B73201 /* RepositoryInteractor.swift */; };\n\t\t280D71BC1ED60683005D2689 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 28577EB91E8AF379002B07FD /* libsqlite3.tbd */; };\n\t\t280D71BE1ED6069A005D2689 /* ServiceManagement.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4055B1381E0D82A900279430 /* ServiceManagement.framework */; };\n\t\t280D71BF1ED608D6005D2689 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4065D3591DD3B44200B73201 /* Main.storyboard */; };\n\t\t280D71C01ED608D6005D2689 /* Placeholder.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 28E896621E830D6700722032 /* Placeholder.storyboard */; };\n\t\t280D71C11ED608D6005D2689 /* Welcome.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 40FCE42D1DFC576C00D4FD45 /* Welcome.storyboard */; };\n\t\t280D71C21ED608D6005D2689 /* Login.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5685C7641DE8721100CA545E /* Login.storyboard */; };\n\t\t280D71C31ED608D6005D2689 /* Settings.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 40E092401DE385E4001EF5DA /* Settings.storyboard */; };\n\t\t280D71C41ED608D6005D2689 /* Tasks.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 406384881DE388C5004795A4 /* Tasks.storyboard */; };\n\t\t280D71C81ED608D6005D2689 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4065D35B1DD3B44200B73201 /* Images.xcassets */; };\n\t\t280D71C91ED60908005D2689 /* jirassic.sdef in Resources */ = {isa = PBXBuildFile; fileRef = 4065D3611DD3B44200B73201 /* jirassic.sdef */; };\n\t\t280F507D1EC868B0007416AB /* StringArray.swift in Sources */ = {isa = PBXBuildFile; fileRef = 280F507C1EC868B0007416AB /* StringArray.swift */; };\n\t\t2812F61E2145031B008EE81E /* IAPHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2812F61C2145031A008EE81E /* IAPHelper.swift */; };\n\t\t2812F61F2145031B008EE81E /* IAPHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2812F61C2145031A008EE81E /* IAPHelper.swift */; };\n\t\t2812F6202145031B008EE81E /* Store.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2812F61D2145031A008EE81E /* Store.swift */; };\n\t\t2812F6212145031B008EE81E /* Store.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2812F61D2145031A008EE81E /* Store.swift */; };\n\t\t2818848121A4A2F800B33B9C /* Jirassic.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 2818847F21A4A2F800B33B9C /* Jirassic.xcdatamodeld */; };\n\t\t2818848221A4A2F800B33B9C /* Jirassic.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 2818847F21A4A2F800B33B9C /* Jirassic.xcdatamodeld */; };\n\t\t2823C9351E4F69970055D036 /* Versioning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2823C9341E4F69970055D036 /* Versioning.swift */; };\n\t\t28279AD121BBF08C00376304 /* InMemoryCoreDataRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3931DD3B44200B73201 /* InMemoryCoreDataRepository.swift */; };\n\t\t28279AD221BBF08E00376304 /* InMemoryCoreDataRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3931DD3B44200B73201 /* InMemoryCoreDataRepository.swift */; };\n\t\t28279AD321BBF09900376304 /* Jirassic.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 2818847F21A4A2F800B33B9C /* Jirassic.xcdatamodeld */; };\n\t\t28279AD521C6245700376304 /* GitUsersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28279AD421C6245700376304 /* GitUsersViewController.swift */; };\n\t\t28279AD621C6245700376304 /* GitUsersViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28279AD421C6245700376304 /* GitUsersViewController.swift */; };\n\t\t28279E9C1E8300E200EAF9FC /* PlaceholderViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28279E9B1E8300E200EAF9FC /* PlaceholderViewController.swift */; };\n\t\t284192D72018841700E64A9A /* JProject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 284192D62018841700E64A9A /* JProject.swift */; };\n\t\t284192D82018841700E64A9A /* JProject.swift in Sources */ = {isa = PBXBuildFile; fileRef = 284192D62018841700E64A9A /* JProject.swift */; };\n\t\t284192DA2018855B00E64A9A /* JiraRepository+Projects.swift in Sources */ = {isa = PBXBuildFile; fileRef = 284192D92018855B00E64A9A /* JiraRepository+Projects.swift */; };\n\t\t284192DB2018855B00E64A9A /* JiraRepository+Projects.swift in Sources */ = {isa = PBXBuildFile; fileRef = 284192D92018855B00E64A9A /* JiraRepository+Projects.swift */; };\n\t\t284192DD2018A8B200E64A9A /* ModuleJiraTempo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 284192DC2018A8B200E64A9A /* ModuleJiraTempo.swift */; };\n\t\t284192DE2018A8B200E64A9A /* ModuleJiraTempo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 284192DC2018A8B200E64A9A /* ModuleJiraTempo.swift */; };\n\t\t2845B1352066C6E6006EFB3B /* AppleScriptProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B1342066C6E6006EFB3B /* AppleScriptProtocol.swift */; };\n\t\t2845B1362066C6E6006EFB3B /* AppleScriptProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B1342066C6E6006EFB3B /* AppleScriptProtocol.swift */; };\n\t\t2845B139206703C5006EFB3B /* Keychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B138206703C5006EFB3B /* Keychain.swift */; };\n\t\t2845B13A206703C5006EFB3B /* Keychain.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B138206703C5006EFB3B /* Keychain.swift */; };\n\t\t2845B13F2068351F006EFB3B /* TableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B13E2068351F006EFB3B /* TableViewCell.swift */; };\n\t\t2845B1402068351F006EFB3B /* TableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B13E2068351F006EFB3B /* TableViewCell.swift */; };\n\t\t2845B149206AE3A8006EFB3B /* ReportCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B144206AE3A8006EFB3B /* ReportCell.swift */; };\n\t\t2845B14A206AE3A8006EFB3B /* ReportCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B144206AE3A8006EFB3B /* ReportCell.swift */; };\n\t\t2845B14B206AE3A8006EFB3B /* ReportCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2845B145206AE3A8006EFB3B /* ReportCell.xib */; };\n\t\t2845B14C206AE3A8006EFB3B /* ReportCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2845B145206AE3A8006EFB3B /* ReportCell.xib */; };\n\t\t2845B14D206AE3A8006EFB3B /* ReportCellPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B146206AE3A8006EFB3B /* ReportCellPresenter.swift */; };\n\t\t2845B14E206AE3A8006EFB3B /* ReportCellPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B146206AE3A8006EFB3B /* ReportCellPresenter.swift */; };\n\t\t2845B14F206AE3A8006EFB3B /* ReportsDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B147206AE3A8006EFB3B /* ReportsDataSource.swift */; };\n\t\t2845B150206AE3A8006EFB3B /* ReportsDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B147206AE3A8006EFB3B /* ReportsDataSource.swift */; };\n\t\t2845B151206AE3A8006EFB3B /* ReportsHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B148206AE3A8006EFB3B /* ReportsHeaderView.swift */; };\n\t\t2845B152206AE3A8006EFB3B /* ReportsHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B148206AE3A8006EFB3B /* ReportsHeaderView.swift */; };\n\t\t2845B160206AE468006EFB3B /* TaskCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B155206AE467006EFB3B /* TaskCell.swift */; };\n\t\t2845B161206AE468006EFB3B /* TaskCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B155206AE467006EFB3B /* TaskCell.swift */; };\n\t\t2845B162206AE468006EFB3B /* TaskCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2845B156206AE467006EFB3B /* TaskCell.xib */; };\n\t\t2845B163206AE468006EFB3B /* TaskCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2845B156206AE467006EFB3B /* TaskCell.xib */; };\n\t\t2845B164206AE468006EFB3B /* TaskCellPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B157206AE467006EFB3B /* TaskCellPresenter.swift */; };\n\t\t2845B165206AE468006EFB3B /* TaskCellPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B157206AE467006EFB3B /* TaskCellPresenter.swift */; };\n\t\t2845B166206AE468006EFB3B /* TasksHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B159206AE467006EFB3B /* TasksHeaderView.swift */; };\n\t\t2845B167206AE468006EFB3B /* TasksHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B159206AE467006EFB3B /* TasksHeaderView.swift */; };\n\t\t2845B168206AE468006EFB3B /* TasksHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2845B15A206AE467006EFB3B /* TasksHeaderView.xib */; };\n\t\t2845B169206AE468006EFB3B /* TasksHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2845B15A206AE467006EFB3B /* TasksHeaderView.xib */; };\n\t\t2845B16A206AE468006EFB3B /* NonTaskCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B15C206AE467006EFB3B /* NonTaskCell.swift */; };\n\t\t2845B16B206AE468006EFB3B /* NonTaskCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B15C206AE467006EFB3B /* NonTaskCell.swift */; };\n\t\t2845B16C206AE468006EFB3B /* NonTaskCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2845B15D206AE467006EFB3B /* NonTaskCell.xib */; };\n\t\t2845B16D206AE468006EFB3B /* NonTaskCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2845B15D206AE467006EFB3B /* NonTaskCell.xib */; };\n\t\t2845B16E206AE46F006EFB3B /* TaskCellTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2845B154206AE467006EFB3B /* TaskCellTests.swift */; };\n\t\t285465A2216C84E10052CB6A /* CreateMonthReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 285465A1216C84E10052CB6A /* CreateMonthReport.swift */; };\n\t\t285465A3216C84E10052CB6A /* CreateMonthReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 285465A1216C84E10052CB6A /* CreateMonthReport.swift */; };\n\t\t285465A4216C84E10052CB6A /* CreateMonthReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 285465A1216C84E10052CB6A /* CreateMonthReport.swift */; };\n\t\t285465A7217858790052CB6A /* StoreView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 285465A6217858790052CB6A /* StoreView.swift */; };\n\t\t285465A8217858790052CB6A /* StoreView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 285465A6217858790052CB6A /* StoreView.swift */; };\n\t\t285465AD217858AF0052CB6A /* StoreView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 285465AC217858AF0052CB6A /* StoreView.xib */; };\n\t\t285465AE217858AF0052CB6A /* StoreView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 285465AC217858AF0052CB6A /* StoreView.xib */; };\n\t\t28577EAB1E8ADC53002B07FD /* SqliteRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28577EA71E8ADC53002B07FD /* SqliteRepository.swift */; };\n\t\t28577EAC1E8ADC53002B07FD /* SqliteRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28577EA71E8ADC53002B07FD /* SqliteRepository.swift */; };\n\t\t28577EAD1E8ADC53002B07FD /* SSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28577EA81E8ADC53002B07FD /* SSettings.swift */; };\n\t\t28577EAE1E8ADC53002B07FD /* SSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28577EA81E8ADC53002B07FD /* SSettings.swift */; };\n\t\t28577EAF1E8ADC53002B07FD /* STask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28577EA91E8ADC53002B07FD /* STask.swift */; };\n\t\t28577EB01E8ADC53002B07FD /* STask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28577EA91E8ADC53002B07FD /* STask.swift */; };\n\t\t28577EB11E8ADC53002B07FD /* SUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28577EAA1E8ADC53002B07FD /* SUser.swift */; };\n\t\t28577EB21E8ADC53002B07FD /* SUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28577EAA1E8ADC53002B07FD /* SUser.swift */; };\n\t\t28577EB51E8AF08F002B07FD /* SQLiteDB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28577EB31E8AF08F002B07FD /* SQLiteDB.swift */; };\n\t\t28577EB61E8AF08F002B07FD /* SQLiteDB.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28577EB31E8AF08F002B07FD /* SQLiteDB.swift */; };\n\t\t28577EB71E8AF08F002B07FD /* SQLTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28577EB41E8AF08F002B07FD /* SQLTable.swift */; };\n\t\t28577EB81E8AF08F002B07FD /* SQLTable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28577EB41E8AF08F002B07FD /* SQLTable.swift */; };\n\t\t28577EBA1E8AF379002B07FD /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 28577EB91E8AF379002B07FD /* libsqlite3.tbd */; };\n\t\t28667B5D1FCB7017007B98E3 /* ModuleHookup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28667B5C1FCB7017007B98E3 /* ModuleHookup.swift */; };\n\t\t28667B5E1FCB7017007B98E3 /* ModuleHookup.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28667B5C1FCB7017007B98E3 /* ModuleHookup.swift */; };\n\t\t286BC00421909F85004D4CDD /* CloseDay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 286BC00321909F85004D4CDD /* CloseDay.swift */; };\n\t\t286BC00521909F85004D4CDD /* CloseDay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 286BC00321909F85004D4CDD /* CloseDay.swift */; };\n\t\t287195152022E1E2001C237E /* HookupPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287195142022E1E2001C237E /* HookupPresenter.swift */; };\n\t\t287195162022E1E2001C237E /* HookupPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287195142022E1E2001C237E /* HookupPresenter.swift */; };\n\t\t287195182022E8BC001C237E /* OutputTableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287195172022E8BC001C237E /* OutputTableViewDataSource.swift */; };\n\t\t287195192022E8BC001C237E /* OutputTableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287195172022E8BC001C237E /* OutputTableViewDataSource.swift */; };\n\t\t2871951B2022ECF7001C237E /* OutputsScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2871951A2022ECF7001C237E /* OutputsScrollView.swift */; };\n\t\t2871951C2022ECF7001C237E /* OutputsScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2871951A2022ECF7001C237E /* OutputsScrollView.swift */; };\n\t\t2871951E2022FD14001C237E /* InputsScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2871951D2022FD14001C237E /* InputsScrollView.swift */; };\n\t\t2871951F2022FD14001C237E /* InputsScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2871951D2022FD14001C237E /* InputsScrollView.swift */; };\n\t\t287195212022FD87001C237E /* InputsTableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287195202022FD87001C237E /* InputsTableViewDataSource.swift */; };\n\t\t287195222022FD87001C237E /* InputsTableViewDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287195202022FD87001C237E /* InputsTableViewDataSource.swift */; };\n\t\t2871952820241A6C001C237E /* TrackingView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2871952720241A6C001C237E /* TrackingView.xib */; };\n\t\t2871952920241A6C001C237E /* TrackingView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2871952720241A6C001C237E /* TrackingView.xib */; };\n\t\t2871952B20241B25001C237E /* TrackingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2871952A20241B25001C237E /* TrackingView.swift */; };\n\t\t2871952C20241B25001C237E /* TrackingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2871952A20241B25001C237E /* TrackingView.swift */; };\n\t\t2871952D2025C353001C237E /* CoreDataRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D38C1DD3B44200B73201 /* CoreDataRepository.swift */; };\n\t\t2871952E2025C356001C237E /* CoreDataRepository+Tasks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928891E910F4D0022AB55 /* CoreDataRepository+Tasks.swift */; };\n\t\t2871952F2025C359001C237E /* CoreDataRepository+Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A9288C1E910F970022AB55 /* CoreDataRepository+Settings.swift */; };\n\t\t287195302025C35C001C237E /* CoreDataRepository+User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A9288F1E910FF60022AB55 /* CoreDataRepository+User.swift */; };\n\t\t287195312025C360001C237E /* CSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D38D1DD3B44200B73201 /* CSettings.swift */; };\n\t\t287195322025C364001C237E /* CTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D38E1DD3B44200B73201 /* CTask.swift */; };\n\t\t287195332025C367001C237E /* CUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D38F1DD3B44200B73201 /* CUser.swift */; };\n\t\t287195362027CAD9001C237E /* TimeInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287195352027CAD9001C237E /* TimeInteractor.swift */; };\n\t\t287195372027CAD9001C237E /* TimeInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287195352027CAD9001C237E /* TimeInteractor.swift */; };\n\t\t287558451EFE5969009A2503 /* ReadDaysInteractorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 280D71171ED4CFCB005D2689 /* ReadDaysInteractorTests.swift */; };\n\t\t287B358720FBAFC40022F43E /* WizardCalendarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287B358620FBAFC40022F43E /* WizardCalendarView.swift */; };\n\t\t287B358820FBAFC40022F43E /* WizardCalendarView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 287B358620FBAFC40022F43E /* WizardCalendarView.swift */; };\n\t\t287B358A20FBAFD60022F43E /* WizardCalendarView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 287B358920FBAFD60022F43E /* WizardCalendarView.xib */; };\n\t\t287B358B20FBAFD60022F43E /* WizardCalendarView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 287B358920FBAFD60022F43E /* WizardCalendarView.xib */; };\n\t\t288BB67E2085252900CF720A /* WizardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 288BB67D2085252900CF720A /* WizardViewController.swift */; };\n\t\t288BB67F2085252900CF720A /* WizardViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 288BB67D2085252900CF720A /* WizardViewController.swift */; };\n\t\t288BB6812087152B00CF720A /* WizardAppleScriptView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 288BB6802087152B00CF720A /* WizardAppleScriptView.xib */; };\n\t\t288BB6822087152B00CF720A /* WizardAppleScriptView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 288BB6802087152B00CF720A /* WizardAppleScriptView.xib */; };\n\t\t288BB6842087157F00CF720A /* WizardAppleScriptView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 288BB6832087157F00CF720A /* WizardAppleScriptView.swift */; };\n\t\t288BB6852087157F00CF720A /* WizardAppleScriptView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 288BB6832087157F00CF720A /* WizardAppleScriptView.swift */; };\n\t\t288BB6872087169F00CF720A /* ViewXib.swift in Sources */ = {isa = PBXBuildFile; fileRef = 288BB6862087169F00CF720A /* ViewXib.swift */; };\n\t\t288BB6882087169F00CF720A /* ViewXib.swift in Sources */ = {isa = PBXBuildFile; fileRef = 288BB6862087169F00CF720A /* ViewXib.swift */; };\n\t\t2892B2981F094A170085BAC2 /* JiraRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2892B2971F094A170085BAC2 /* JiraRepository.swift */; };\n\t\t2892B2991F094A170085BAC2 /* JiraRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2892B2971F094A170085BAC2 /* JiraRepository.swift */; };\n\t\t2892B29B1F094A760085BAC2 /* JiraRepository+Reports.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2892B29A1F094A760085BAC2 /* JiraRepository+Reports.swift */; };\n\t\t2892B29C1F094A760085BAC2 /* JiraRepository+Reports.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2892B29A1F094A760085BAC2 /* JiraRepository+Reports.swift */; };\n\t\t2892B29E1F094B0D0085BAC2 /* JReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2892B29D1F094B0D0085BAC2 /* JReport.swift */; };\n\t\t2892B29F1F094B0D0085BAC2 /* JReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2892B29D1F094B0D0085BAC2 /* JReport.swift */; };\n\t\t2892B2A71F094C800085BAC2 /* JWorkAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2892B2A61F094C800085BAC2 /* JWorkAttribute.swift */; };\n\t\t2892B2A81F094C800085BAC2 /* JWorkAttribute.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2892B2A61F094C800085BAC2 /* JWorkAttribute.swift */; };\n\t\t2892E80B208D9B42004E5298 /* InputsScrollView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2892E80A208D9B42004E5298 /* InputsScrollView.xib */; };\n\t\t2892E80C208D9B42004E5298 /* InputsScrollView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2892E80A208D9B42004E5298 /* InputsScrollView.xib */; };\n\t\t2892E80E208D9DD0004E5298 /* OutputsScrollView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2892E80D208D9DD0004E5298 /* OutputsScrollView.xib */; };\n\t\t2892E80F208D9DD0004E5298 /* OutputsScrollView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 2892E80D208D9DD0004E5298 /* OutputsScrollView.xib */; };\n\t\t2892E811208E6275004E5298 /* LocalPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2892E810208E6275004E5298 /* LocalPreferences.swift */; };\n\t\t2892E812208E6275004E5298 /* LocalPreferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2892E810208E6275004E5298 /* LocalPreferences.swift */; };\n\t\t2898D3A82181907700CF5AD4 /* MonthReportsHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2898D3A72181907700CF5AD4 /* MonthReportsHeaderView.swift */; };\n\t\t2898D3A92181907700CF5AD4 /* MonthReportsHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2898D3A72181907700CF5AD4 /* MonthReportsHeaderView.swift */; };\n\t\t2898D3AB2184D1DB00CF5AD4 /* TimeBoxViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2898D3AA2184D1DB00CF5AD4 /* TimeBoxViewController.swift */; };\n\t\t2898D3AC2184D1DB00CF5AD4 /* TimeBoxViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2898D3AA2184D1DB00CF5AD4 /* TimeBoxViewController.swift */; };\n\t\t2898D3AE2184ED3000CF5AD4 /* Components.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2898D3AD2184ED3000CF5AD4 /* Components.storyboard */; };\n\t\t2898D3AF2184ED3000CF5AD4 /* Components.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 2898D3AD2184ED3000CF5AD4 /* Components.storyboard */; };\n\t\t2898D3B12185959300CF5AD4 /* EditableTimeBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2898D3B02185959300CF5AD4 /* EditableTimeBox.swift */; };\n\t\t2898D3B22185959300CF5AD4 /* EditableTimeBox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2898D3B02185959300CF5AD4 /* EditableTimeBox.swift */; };\n\t\t28A283942037874600DDCB63 /* ModuleGitLogs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A283932037874600DDCB63 /* ModuleGitLogs.swift */; };\n\t\t28A283952037874600DDCB63 /* ModuleGitLogs.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A283932037874600DDCB63 /* ModuleGitLogs.swift */; };\n\t\t28A283972037975600DDCB63 /* Saveable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A283962037975600DDCB63 /* Saveable.swift */; };\n\t\t28A283982037975600DDCB63 /* Saveable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A283962037975600DDCB63 /* Saveable.swift */; };\n\t\t28A2839A20382BBB00DDCB63 /* GitCommit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A2839920382BBB00DDCB63 /* GitCommit.swift */; };\n\t\t28A2839B20382BBB00DDCB63 /* GitCommit.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A2839920382BBB00DDCB63 /* GitCommit.swift */; };\n\t\t28A2839F20385BE000DDCB63 /* GitCommitsParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A2839E20385BE000DDCB63 /* GitCommitsParser.swift */; };\n\t\t28A283A020385BE000DDCB63 /* GitCommitsParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A2839E20385BE000DDCB63 /* GitCommitsParser.swift */; };\n\t\t28A283A220385F8C00DDCB63 /* GitCommitsParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A283A120385F8C00DDCB63 /* GitCommitsParserTests.swift */; };\n\t\t28A283A52038AFB100DDCB63 /* JirassicCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A283A42038AFB100DDCB63 /* JirassicCell.swift */; };\n\t\t28A283A62038AFB100DDCB63 /* JirassicCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A283A42038AFB100DDCB63 /* JirassicCell.swift */; };\n\t\t28A283A82038AFC500DDCB63 /* JirassicCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28A283A72038AFC500DDCB63 /* JirassicCell.xib */; };\n\t\t28A283A92038AFC500DDCB63 /* JirassicCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28A283A72038AFC500DDCB63 /* JirassicCell.xib */; };\n\t\t28A283AB203A93AB00DDCB63 /* GitBranchParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A283AA203A93AB00DDCB63 /* GitBranchParser.swift */; };\n\t\t28A283AC203A93AB00DDCB63 /* GitBranchParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A283AA203A93AB00DDCB63 /* GitBranchParser.swift */; };\n\t\t28A283AE203C069F00DDCB63 /* GitBranchParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A283AD203C069F00DDCB63 /* GitBranchParserTests.swift */; };\n\t\t28A283B0203CB1A100DDCB63 /* MergeTasksInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A283AF203CB1A100DDCB63 /* MergeTasksInteractor.swift */; };\n\t\t28A283B1203CB1A100DDCB63 /* MergeTasksInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A283AF203CB1A100DDCB63 /* MergeTasksInteractor.swift */; };\n\t\t28A283B3203CB1B900DDCB63 /* MergeTasksInteractorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A283B2203CB1B900DDCB63 /* MergeTasksInteractorTests.swift */; };\n\t\t28A5F27E1E5789FC002BE564 /* TasksDataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A5F27D1E5789FC002BE564 /* TasksDataSource.swift */; };\n\t\t28A5F2821E586426002BE564 /* DataSource.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A5F2811E586426002BE564 /* DataSource.swift */; };\n\t\t28A928781E8F78580022AB55 /* SQLiteSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928771E8F78580022AB55 /* SQLiteSchema.swift */; };\n\t\t28A928791E8F78580022AB55 /* SQLiteSchema.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928771E8F78580022AB55 /* SQLiteSchema.swift */; };\n\t\t28A9287A1E8FA8E90022AB55 /* libsqlite3.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 28577EB91E8AF379002B07FD /* libsqlite3.tbd */; };\n\t\t28A9287B1E8FC9B90022AB55 /* CreateReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D32B1DD3B44200B73201 /* CreateReport.swift */; };\n\t\t28A9287D1E9030BA0022AB55 /* CloudKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 28A9287C1E9030BA0022AB55 /* CloudKit.framework */; };\n\t\t28A928811E910DA40022AB55 /* SqliteRepository+Tasks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928801E910DA40022AB55 /* SqliteRepository+Tasks.swift */; };\n\t\t28A928821E910DA40022AB55 /* SqliteRepository+Tasks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928801E910DA40022AB55 /* SqliteRepository+Tasks.swift */; };\n\t\t28A928841E910E5E0022AB55 /* SqliteRepository+User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928831E910E5E0022AB55 /* SqliteRepository+User.swift */; };\n\t\t28A928851E910E5E0022AB55 /* SqliteRepository+User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928831E910E5E0022AB55 /* SqliteRepository+User.swift */; };\n\t\t28A928871E910EA70022AB55 /* SqliteRepository+Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928861E910EA70022AB55 /* SqliteRepository+Settings.swift */; };\n\t\t28A928881E910EA70022AB55 /* SqliteRepository+Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928861E910EA70022AB55 /* SqliteRepository+Settings.swift */; };\n\t\t28A928931E91104B0022AB55 /* CloudKitRepository+Tasks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928921E91104B0022AB55 /* CloudKitRepository+Tasks.swift */; };\n\t\t28A928951E9110980022AB55 /* CloudKitRepository+User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928941E9110980022AB55 /* CloudKitRepository+User.swift */; };\n\t\t28A928971E9110BF0022AB55 /* CloudKitRepository+Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928961E9110BF0022AB55 /* CloudKitRepository+Settings.swift */; };\n\t\t28AA50081EDCD51300AAF03D /* CoreDataRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D38C1DD3B44200B73201 /* CoreDataRepository.swift */; };\n\t\t28AA50091EDCD51300AAF03D /* CoreDataRepository+Tasks.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A928891E910F4D0022AB55 /* CoreDataRepository+Tasks.swift */; };\n\t\t28AA500A1EDCD51300AAF03D /* CoreDataRepository+Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A9288C1E910F970022AB55 /* CoreDataRepository+Settings.swift */; };\n\t\t28AA500B1EDCD51300AAF03D /* CoreDataRepository+User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28A9288F1E910FF60022AB55 /* CoreDataRepository+User.swift */; };\n\t\t28AA500C1EDCD51300AAF03D /* CSettings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D38D1DD3B44200B73201 /* CSettings.swift */; };\n\t\t28AA500D1EDCD51300AAF03D /* CTask.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D38E1DD3B44200B73201 /* CTask.swift */; };\n\t\t28AA500E1EDCD51300AAF03D /* CUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D38F1DD3B44200B73201 /* CUser.swift */; };\n\t\t28AFE7311E9A594500BAAD8C /* UserDefaults+token.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28AFE7301E9A594500BAAD8C /* UserDefaults+token.swift */; };\n\t\t28B116B821AE5C45004ACE01 /* ReportsHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28B116B721AE5C45004ACE01 /* ReportsHeaderView.xib */; };\n\t\t28B116B921AE5C45004ACE01 /* ReportsHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28B116B721AE5C45004ACE01 /* ReportsHeaderView.xib */; };\n\t\t28B116BB21AE6179004ACE01 /* MonthReportsHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28B116BA21AE6179004ACE01 /* MonthReportsHeaderView.xib */; };\n\t\t28B116BC21AE6179004ACE01 /* MonthReportsHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28B116BA21AE6179004ACE01 /* MonthReportsHeaderView.xib */; };\n\t\t28C6A38421D359E60036DB29 /* RemoveDuplicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28C6A38321D359E60036DB29 /* RemoveDuplicate.swift */; };\n\t\t28C6A38521D359E60036DB29 /* RemoveDuplicate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28C6A38321D359E60036DB29 /* RemoveDuplicate.swift */; };\n\t\t28C9C6221EAD37D0007EB3E6 /* UserDefaults+uploadToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28C9C6211EAD37D0007EB3E6 /* UserDefaults+uploadToken.swift */; };\n\t\t28C9C6231EAD37D0007EB3E6 /* UserDefaults+uploadToken.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28C9C6211EAD37D0007EB3E6 /* UserDefaults+uploadToken.swift */; };\n\t\t28CBB596204554A2006F9D3A /* ParseGitBranch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28CBB595204554A2006F9D3A /* ParseGitBranch.swift */; };\n\t\t28CBB597204554A2006F9D3A /* ParseGitBranch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28CBB595204554A2006F9D3A /* ParseGitBranch.swift */; };\n\t\t28CBB598204554A2006F9D3A /* ParseGitBranch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28CBB595204554A2006F9D3A /* ParseGitBranch.swift */; };\n\t\t28CBB59A20474755006F9D3A /* ParseGitBranchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28CBB59920474755006F9D3A /* ParseGitBranchTests.swift */; };\n\t\t28DCA4552018B6E700DFAE29 /* JProjectIssue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28DCA4542018B6E700DFAE29 /* JProjectIssue.swift */; };\n\t\t28DCA4562018B6E700DFAE29 /* JProjectIssue.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28DCA4542018B6E700DFAE29 /* JProjectIssue.swift */; };\n\t\t28E896631E830D6700722032 /* Placeholder.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 28E896621E830D6700722032 /* Placeholder.storyboard */; };\n\t\t28E896711E83732200722032 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 28E8966F1E83732200722032 /* AppDelegate.m */; };\n\t\t28E896721E83732200722032 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 28E896701E83732200722032 /* main.m */; };\n\t\t28E896751E83770D00722032 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28E896731E83770D00722032 /* MainMenu.xib */; };\n\t\t28EDE9391E59EC1500B360A4 /* TasksView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28EDE9381E59EC1500B360A4 /* TasksView.swift */; };\n\t\t28EE1F5E20EE8D1000C5C1D6 /* CalendarCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28EE1F5D20EE8D1000C5C1D6 /* CalendarCell.swift */; };\n\t\t28EE1F5F20EE8D1000C5C1D6 /* CalendarCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28EE1F5D20EE8D1000C5C1D6 /* CalendarCell.swift */; };\n\t\t28EE1F6120EE8D6100C5C1D6 /* CalendarCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28EE1F6020EE8D6100C5C1D6 /* CalendarCell.xib */; };\n\t\t28EE1F6220EE8D6100C5C1D6 /* CalendarCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28EE1F6020EE8D6100C5C1D6 /* CalendarCell.xib */; };\n\t\t28EE1F6420EE92DA00C5C1D6 /* CalendarPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28EE1F6320EE92DA00C5C1D6 /* CalendarPresenter.swift */; };\n\t\t28EE1F6520EE92DA00C5C1D6 /* CalendarPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28EE1F6320EE92DA00C5C1D6 /* CalendarPresenter.swift */; };\n\t\t28FB265120224E3A00AEA38D /* JiraTempoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28FB265020224E3A00AEA38D /* JiraTempoCell.swift */; };\n\t\t28FB265220224E3A00AEA38D /* JiraTempoCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28FB265020224E3A00AEA38D /* JiraTempoCell.swift */; };\n\t\t28FB265420224E5B00AEA38D /* JiraTempoCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28FB265320224E5B00AEA38D /* JiraTempoCell.xib */; };\n\t\t28FB265520224E5B00AEA38D /* JiraTempoCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28FB265320224E5B00AEA38D /* JiraTempoCell.xib */; };\n\t\t28FB265820224E9B00AEA38D /* HookupCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28FB265720224E9B00AEA38D /* HookupCell.xib */; };\n\t\t28FB265920224E9B00AEA38D /* HookupCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28FB265720224E9B00AEA38D /* HookupCell.xib */; };\n\t\t28FB265B20224EA700AEA38D /* HookupCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28FB265A20224EA700AEA38D /* HookupCell.swift */; };\n\t\t28FB265C20224EA700AEA38D /* HookupCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28FB265A20224EA700AEA38D /* HookupCell.swift */; };\n\t\t28FB265E2022DC2B00AEA38D /* JiraTempoPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28FB265D2022DC2B00AEA38D /* JiraTempoPresenter.swift */; };\n\t\t28FB265F2022DC2B00AEA38D /* JiraTempoPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28FB265D2022DC2B00AEA38D /* JiraTempoPresenter.swift */; };\n\t\t28FE1887207A520B00DF796E /* NewTaskCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28FE1886207A520B00DF796E /* NewTaskCommand.swift */; };\n\t\t28FE1888207A520B00DF796E /* NewTaskCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28FE1886207A520B00DF796E /* NewTaskCommand.swift */; };\n\t\t28FE18A5207B369800DF796E /* CocoaHookupCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28FE18A4207B369800DF796E /* CocoaHookupCell.swift */; };\n\t\t28FE18A6207B369800DF796E /* CocoaHookupCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28FE18A4207B369800DF796E /* CocoaHookupCell.swift */; };\n\t\t28FE18A8207B36CB00DF796E /* CocoaHookupCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28FE18A7207B36CB00DF796E /* CocoaHookupCell.xib */; };\n\t\t28FE18A9207B36CB00DF796E /* CocoaHookupCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 28FE18A7207B36CB00DF796E /* CocoaHookupCell.xib */; };\n\t\t28FE18AB207B375A00DF796E /* CocoaHookupPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28FE18AA207B375A00DF796E /* CocoaHookupPresenter.swift */; };\n\t\t28FE18AC207B375A00DF796E /* CocoaHookupPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 28FE18AA207B375A00DF796E /* CocoaHookupPresenter.swift */; };\n\t\t4051D5F91E0EA48A002042BB /* AppLauncher.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4051D5F81E0EA48A002042BB /* AppLauncher.swift */; };\n\t\t4055B1361E0D821500279430 /* JirassicLauncher.app in CopyFiles */ = {isa = PBXBuildFile; fileRef = 4055B1231E0D802300279430 /* JirassicLauncher.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };\n\t\t4055B1391E0D82A900279430 /* ServiceManagement.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4055B1381E0D82A900279430 /* ServiceManagement.framework */; };\n\t\t405B15611DEF3D080009871C /* TaskSuggestionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 405B15601DEF3D080009871C /* TaskSuggestionViewController.swift */; };\n\t\t405B15631DEF3F2A0009871C /* TaskSuggestionPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 405B15621DEF3F2A0009871C /* TaskSuggestionPresenter.swift */; };\n\t\t405B15661DEF75660009871C /* AppViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 405B15651DEF75660009871C /* AppViewController.swift */; };\n\t\t406384891DE388C5004795A4 /* Tasks.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 406384881DE388C5004795A4 /* Tasks.storyboard */; };\n\t\t4065D39C1DD3B44200B73201 /* Day.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3181DD3B44200B73201 /* Day.swift */; };\n\t\t4065D39D1DD3B44200B73201 /* Report.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3191DD3B44200B73201 /* Report.swift */; };\n\t\t4065D39E1DD3B44200B73201 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D31A1DD3B44200B73201 /* Settings.swift */; };\n\t\t4065D39F1DD3B44200B73201 /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D31B1DD3B44200B73201 /* Task.swift */; };\n\t\t4065D3A11DD3B44200B73201 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D31D1DD3B44200B73201 /* User.swift */; };\n\t\t4065D3A21DD3B44200B73201 /* Week.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D31E1DD3B44200B73201 /* Week.swift */; };\n\t\t4065D3A31DD3B44200B73201 /* DateExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3201DD3B44200B73201 /* DateExtension.swift */; };\n\t\t4065D3A51DD3B44200B73201 /* StringIdGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3221DD3B44200B73201 /* StringIdGenerator.swift */; };\n\t\t4065D3A61DD3B44200B73201 /* ViewAutolayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3231DD3B44200B73201 /* ViewAutolayout.swift */; };\n\t\t4065D3A71DD3B44200B73201 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3241DD3B44200B73201 /* ViewController.swift */; };\n\t\t4065D3A81DD3B44200B73201 /* ViewControllerStoryboard.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3251DD3B44200B73201 /* ViewControllerStoryboard.swift */; };\n\t\t4065D3A91DD3B44200B73201 /* Conversions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3261DD3B44200B73201 /* Conversions.swift */; };\n\t\t4065D3AB1DD3B44200B73201 /* ComputerWakeUpInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3291DD3B44200B73201 /* ComputerWakeUpInteractor.swift */; };\n\t\t4065D3AC1DD3B44200B73201 /* CreateReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D32B1DD3B44200B73201 /* CreateReport.swift */; };\n\t\t4065D3AE1DD3B44200B73201 /* ReadDaysInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D32E1DD3B44200B73201 /* ReadDaysInteractor.swift */; };\n\t\t4065D3AF1DD3B44200B73201 /* ReadTasksInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D32F1DD3B44200B73201 /* ReadTasksInteractor.swift */; };\n\t\t4065D3B01DD3B44200B73201 /* TaskFinder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3301DD3B44200B73201 /* TaskFinder.swift */; };\n\t\t4065D3B21DD3B44200B73201 /* TaskInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3321DD3B44200B73201 /* TaskInteractor.swift */; };\n\t\t4065D3B41DD3B44200B73201 /* TaskTypeEstimator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3341DD3B44200B73201 /* TaskTypeEstimator.swift */; };\n\t\t4065D3B61DD3B44200B73201 /* TaskTypeSelection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3361DD3B44200B73201 /* TaskTypeSelection.swift */; };\n\t\t4065D3B81DD3B44200B73201 /* PredictiveTimeTyping.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3391DD3B44200B73201 /* PredictiveTimeTyping.swift */; };\n\t\t4065D3BA1DD3B44200B73201 /* RegisterUserInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D33C1DD3B44200B73201 /* RegisterUserInteractor.swift */; };\n\t\t4065D3BB1DD3B44200B73201 /* UserInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D33D1DD3B44200B73201 /* UserInteractor.swift */; };\n\t\t4065D3C81DD3B44200B73201 /* FlipAnimation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3521DD3B44200B73201 /* FlipAnimation.swift */; };\n\t\t4065D3C91DD3B44200B73201 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3541DD3B44200B73201 /* AppDelegate.swift */; };\n\t\t4065D3CA1DD3B44200B73201 /* AppWireframe.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3551DD3B44200B73201 /* AppWireframe.swift */; };\n\t\t4065D3CE1DD3B44200B73201 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4065D3591DD3B44200B73201 /* Main.storyboard */; };\n\t\t4065D3CF1DD3B44200B73201 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4065D35B1DD3B44200B73201 /* Images.xcassets */; };\n\t\t4065D3D31DD3B44200B73201 /* jirassic.sdef in Resources */ = {isa = PBXBuildFile; fileRef = 4065D3611DD3B44200B73201 /* jirassic.sdef */; };\n\t\t4065D3D61DD3B44200B73201 /* MenuBarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3651DD3B44200B73201 /* MenuBarController.swift */; };\n\t\t4065D3D71DD3B44200B73201 /* MenuBarIconView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3661DD3B44200B73201 /* MenuBarIconView.swift */; };\n\t\t4065D3D81DD3B44200B73201 /* InternalNotifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3681DD3B44200B73201 /* InternalNotifications.swift */; };\n\t\t4065D3D91DD3B44200B73201 /* UserNotifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3691DD3B44200B73201 /* UserNotifications.swift */; };\n\t\t4065D3DA1DD3B44200B73201 /* SleepNotifications.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D36A1DD3B44200B73201 /* SleepNotifications.swift */; };\n\t\t4065D3DE1DD3B44200B73201 /* NewTaskViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3711DD3B44200B73201 /* NewTaskViewController.swift */; };\n\t\t4065D3DF1DD3B44200B73201 /* SettingsInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3731DD3B44200B73201 /* SettingsInteractor.swift */; };\n\t\t4065D3E01DD3B44200B73201 /* SettingsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3741DD3B44200B73201 /* SettingsPresenter.swift */; };\n\t\t4065D3E11DD3B44200B73201 /* SettingsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3751DD3B44200B73201 /* SettingsViewController.swift */; };\n\t\t4065D3E21DD3B44200B73201 /* CalendarScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3771DD3B44200B73201 /* CalendarScrollView.swift */; };\n\t\t4065D3E31DD3B44200B73201 /* CellProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3781DD3B44200B73201 /* CellProtocol.swift */; };\n\t\t4065D3EE1DD3B44200B73201 /* TasksPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3831DD3B44200B73201 /* TasksPresenter.swift */; };\n\t\t4065D3EF1DD3B44200B73201 /* TasksScrollView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3841DD3B44200B73201 /* TasksScrollView.swift */; };\n\t\t4065D3F01DD3B44200B73201 /* TasksViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3851DD3B44200B73201 /* TasksViewController.swift */; };\n\t\t4065D3F21DD3B44200B73201 /* CloudKitRepository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D38A1DD3B44200B73201 /* CloudKitRepository.swift */; };\n\t\t4065D3F91DD3B44200B73201 /* Repository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3941DD3B44200B73201 /* Repository.swift */; };\n\t\t4065D3FA1DD3B44200B73201 /* RepositoryInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3951DD3B44200B73201 /* RepositoryInteractor.swift */; };\n\t\t4065D4171DD4536200B73201 /* main.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3871DD3B44200B73201 /* main.swift */; };\n\t\t4065D4181DD454C500B73201 /* Repository.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3941DD3B44200B73201 /* Repository.swift */; };\n\t\t4065D4191DD454CB00B73201 /* RepositoryInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3951DD3B44200B73201 /* RepositoryInteractor.swift */; };\n\t\t4065D4201DD4561D00B73201 /* UserInteractorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D33E1DD3B44200B73201 /* UserInteractorTests.swift */; };\n\t\t4065D4211DD4562100B73201 /* PredictiveTimeTypingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D33A1DD3B44200B73201 /* PredictiveTimeTypingTests.swift */; };\n\t\t4065D4231DD4562900B73201 /* DateExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3211DD3B44200B73201 /* DateExtensionTests.swift */; };\n\t\t4065D4241DD4562900B73201 /* CreateReportTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D32C1DD3B44200B73201 /* CreateReportTests.swift */; };\n\t\t4065D4251DD4562900B73201 /* TaskFinderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3311DD3B44200B73201 /* TaskFinderTests.swift */; };\n\t\t4065D4261DD4562900B73201 /* TaskInteractorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3331DD3B44200B73201 /* TaskInteractorTests.swift */; };\n\t\t4065D4271DD4562900B73201 /* TaskTypeEstimatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3351DD3B44200B73201 /* TaskTypeEstimatorTests.swift */; };\n\t\t4065D4281DD4574D00B73201 /* User.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D31D1DD3B44200B73201 /* User.swift */; };\n\t\t4065D4291DD4575B00B73201 /* Week.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D31E1DD3B44200B73201 /* Week.swift */; };\n\t\t4065D42A1DD4576000B73201 /* Task.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D31B1DD3B44200B73201 /* Task.swift */; };\n\t\t4065D42B1DD4576500B73201 /* Settings.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D31A1DD3B44200B73201 /* Settings.swift */; };\n\t\t4065D42C1DD4576800B73201 /* Report.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3191DD3B44200B73201 /* Report.swift */; };\n\t\t4065D42D1DD4576C00B73201 /* Day.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3181DD3B44200B73201 /* Day.swift */; };\n\t\t4065D42E1DD4577D00B73201 /* StringIdGenerator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3221DD3B44200B73201 /* StringIdGenerator.swift */; };\n\t\t4065D42F1DD4579400B73201 /* TaskInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3321DD3B44200B73201 /* TaskInteractor.swift */; };\n\t\t4065D4301DD4579F00B73201 /* ReadTasksInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D32F1DD3B44200B73201 /* ReadTasksInteractor.swift */; };\n\t\t4065D4311DD457B000B73201 /* DateExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3201DD3B44200B73201 /* DateExtension.swift */; };\n\t\t4065D4321DD457B500B73201 /* Conversions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4065D3261DD3B44200B73201 /* Conversions.swift */; };\n\t\t4073184F1DE9B1B40046F409 /* ComputerWakeUpInteractorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4073184E1DE9B1B40046F409 /* ComputerWakeUpInteractorTests.swift */; };\n\t\t40E092411DE385E4001EF5DA /* Settings.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 40E092401DE385E4001EF5DA /* Settings.storyboard */; };\n\t\t40FCE4251DF7646F00D4FD45 /* AppleScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40FCE4221DF7646F00D4FD45 /* AppleScript.swift */; };\n\t\t40FCE4261DF7646F00D4FD45 /* ExtensionsInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40FCE4231DF7646F00D4FD45 /* ExtensionsInteractor.swift */; };\n\t\t40FCE4271DF7646F00D4FD45 /* SandboxedAppleScript.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40FCE4241DF7646F00D4FD45 /* SandboxedAppleScript.swift */; };\n\t\t40FCE4291DFC1CB400D4FD45 /* TaskSuggestionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40FCE4281DFC1CB400D4FD45 /* TaskSuggestionTests.swift */; };\n\t\t40FCE42C1DFC3F8700D4FD45 /* WelcomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40FCE42B1DFC3F8700D4FD45 /* WelcomeViewController.swift */; };\n\t\t40FCE42E1DFC576C00D4FD45 /* Welcome.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 40FCE42D1DFC576C00D4FD45 /* Welcome.storyboard */; };\n\t\t40FCE4301DFD7C8D00D4FD45 /* Animatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 40FCE42F1DFD7C8D00D4FD45 /* Animatable.swift */; };\n\t\t564E55F3202883DB00CE4C76 /* WorklogsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 564E55F2202883DB00CE4C76 /* WorklogsViewController.swift */; };\n\t\t564E55F4202883DB00CE4C76 /* WorklogsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 564E55F2202883DB00CE4C76 /* WorklogsViewController.swift */; };\n\t\t564E55F6202884DE00CE4C76 /* WorklogsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 564E55F5202884DE00CE4C76 /* WorklogsPresenter.swift */; };\n\t\t564E55F7202884DE00CE4C76 /* WorklogsPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 564E55F5202884DE00CE4C76 /* WorklogsPresenter.swift */; };\n\t\t564E55F92028857300CE4C76 /* Worklogs.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 564E55F82028857300CE4C76 /* Worklogs.storyboard */; };\n\t\t564E55FA2028857300CE4C76 /* Worklogs.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 564E55F82028857300CE4C76 /* Worklogs.storyboard */; };\n\t\t565E19F020A5E336003A5E2A /* RCSync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 565E19EF20A5E336003A5E2A /* RCSync.swift */; };\n\t\t565E19F120A5E336003A5E2A /* RCSync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 565E19EF20A5E336003A5E2A /* RCSync.swift */; };\n\t\t565E19F220A5E336003A5E2A /* RCSync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 565E19EF20A5E336003A5E2A /* RCSync.swift */; };\n\t\t566B9FA7217DE67800EAF324 /* TasksInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 566B9FA6217DE67700EAF324 /* TasksInteractor.swift */; };\n\t\t566B9FA8217DE67800EAF324 /* TasksInteractor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 566B9FA6217DE67700EAF324 /* TasksInteractor.swift */; };\n\t\t5683DC3E20ECDED30000A138 /* ModuleCalendar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5683DC3D20ECDED30000A138 /* ModuleCalendar.swift */; };\n\t\t5683DC3F20ECDED30000A138 /* ModuleCalendar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5683DC3D20ECDED30000A138 /* ModuleCalendar.swift */; };\n\t\t5685C7671DE8721100CA545E /* CloudKitLoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5685C7631DE8721100CA545E /* CloudKitLoginViewController.swift */; };\n\t\t5685C7681DE8721100CA545E /* Login.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 5685C7641DE8721100CA545E /* Login.storyboard */; };\n\t\t5685C7691DE8721100CA545E /* LoginPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5685C7651DE8721100CA545E /* LoginPresenter.swift */; };\n\t\t5685C76A1DE8721100CA545E /* LoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5685C7661DE8721100CA545E /* LoginViewController.swift */; };\n\t\t5685C76C1DE8724400CA545E /* AccountViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5685C76B1DE8724400CA545E /* AccountViewController.swift */; };\n\t\t569C4C582023193B0049FBF1 /* ShellCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569C4C572023193B0049FBF1 /* ShellCell.swift */; };\n\t\t569C4C592023193B0049FBF1 /* ShellCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569C4C572023193B0049FBF1 /* ShellCell.swift */; };\n\t\t569C4C5E202319630049FBF1 /* JitCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569C4C5D202319630049FBF1 /* JitCell.swift */; };\n\t\t569C4C5F202319630049FBF1 /* JitCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569C4C5D202319630049FBF1 /* JitCell.swift */; };\n\t\t569C4C64202319870049FBF1 /* GitCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569C4C63202319870049FBF1 /* GitCell.swift */; };\n\t\t569C4C65202319870049FBF1 /* GitCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569C4C63202319870049FBF1 /* GitCell.swift */; };\n\t\t569C4C67202319930049FBF1 /* GitPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569C4C66202319930049FBF1 /* GitPresenter.swift */; };\n\t\t569C4C68202319930049FBF1 /* GitPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569C4C66202319930049FBF1 /* GitPresenter.swift */; };\n\t\t569C4C6A202319A20049FBF1 /* BrowserCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569C4C69202319A20049FBF1 /* BrowserCell.swift */; };\n\t\t569C4C6B202319A20049FBF1 /* BrowserCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569C4C69202319A20049FBF1 /* BrowserCell.swift */; };\n\t\t569C4C6D202319CA0049FBF1 /* BrowserPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569C4C6C202319CA0049FBF1 /* BrowserPresenter.swift */; };\n\t\t569C4C6E202319CA0049FBF1 /* BrowserPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 569C4C6C202319CA0049FBF1 /* BrowserPresenter.swift */; };\n\t\t569C4C70202319DE0049FBF1 /* ShellCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 569C4C6F202319DE0049FBF1 /* ShellCell.xib */; };\n\t\t569C4C71202319DE0049FBF1 /* ShellCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 569C4C6F202319DE0049FBF1 /* ShellCell.xib */; };\n\t\t569C4C73202319EE0049FBF1 /* JitCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 569C4C72202319EE0049FBF1 /* JitCell.xib */; };\n\t\t569C4C74202319EE0049FBF1 /* JitCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 569C4C72202319EE0049FBF1 /* JitCell.xib */; };\n\t\t569C4C76202319FC0049FBF1 /* GitCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 569C4C75202319FC0049FBF1 /* GitCell.xib */; };\n\t\t569C4C77202319FC0049FBF1 /* GitCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 569C4C75202319FC0049FBF1 /* GitCell.xib */; };\n\t\t569C4C7920231A0B0049FBF1 /* BrowserCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 569C4C7820231A0B0049FBF1 /* BrowserCell.xib */; };\n\t\t569C4C7A20231A0B0049FBF1 /* BrowserCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 569C4C7820231A0B0049FBF1 /* BrowserCell.xib */; };\n\t\t56ADBF6A21C3F625008350A6 /* GitUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56ADBF6921C3F625008350A6 /* GitUser.swift */; };\n\t\t56ADBF6B21C3F625008350A6 /* GitUser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56ADBF6921C3F625008350A6 /* GitUser.swift */; };\n\t\t56ADBF6D21C3F94D008350A6 /* GitUserParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56ADBF6C21C3F94D008350A6 /* GitUserParser.swift */; };\n\t\t56ADBF6E21C3F94D008350A6 /* GitUserParser.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56ADBF6C21C3F94D008350A6 /* GitUserParser.swift */; };\n\t\t56CD22BF1E72F89700F9CDB8 /* BuildScript.sh in Resources */ = {isa = PBXBuildFile; fileRef = 56CD22BE1E72F89700F9CDB8 /* BuildScript.sh */; };\n\t\t56D069E1216CABCB000D051D /* CreateMonthReportTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56D069E0216CABCB000D051D /* CreateMonthReportTests.swift */; };\n\t\t56D90CF820876F1100F24442 /* WizardJiraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56D90CF720876F1100F24442 /* WizardJiraView.swift */; };\n\t\t56D90CF920876F1100F24442 /* WizardJiraView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56D90CF720876F1100F24442 /* WizardJiraView.swift */; };\n\t\t56D90CFB20876F2B00F24442 /* WizardGitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56D90CFA20876F2B00F24442 /* WizardGitView.swift */; };\n\t\t56D90CFC20876F2B00F24442 /* WizardGitView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 56D90CFA20876F2B00F24442 /* WizardGitView.swift */; };\n\t\t56D90CFE20876F3C00F24442 /* WizardGitView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 56D90CFD20876F3C00F24442 /* WizardGitView.xib */; };\n\t\t56D90CFF20876F3C00F24442 /* WizardGitView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 56D90CFD20876F3C00F24442 /* WizardGitView.xib */; };\n\t\t56D90D0120876F4900F24442 /* WizardJiraView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 56D90D0020876F4900F24442 /* WizardJiraView.xib */; };\n\t\t56D90D0220876F4900F24442 /* WizardJiraView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 56D90D0020876F4900F24442 /* WizardJiraView.xib */; };\n\t\t6D3702602BA83E9A002260D0 /* SwiftKeychainWrapper in Frameworks */ = {isa = PBXBuildFile; productRef = 6D37025F2BA83E9A002260D0 /* SwiftKeychainWrapper */; };\n\t\t6D3702622BA83EB9002260D0 /* RCLog in Frameworks */ = {isa = PBXBuildFile; productRef = 6D3702612BA83EB9002260D0 /* RCLog */; };\n\t\t6D3702642BA83EBF002260D0 /* RCPreferences in Frameworks */ = {isa = PBXBuildFile; productRef = 6D3702632BA83EBF002260D0 /* RCPreferences */; };\n\t\t6D3702662BA83EC7002260D0 /* RCHttp in Frameworks */ = {isa = PBXBuildFile; productRef = 6D3702652BA83EC7002260D0 /* RCHttp */; };\n\t\t6D5BC4C82C1B5BE6002DA29B /* CreateDayReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D5BC4C62C1B5B70002DA29B /* CreateDayReport.swift */; };\n\t\t6D5BC4C92C1B5BE6002DA29B /* CreateDayReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D5BC4C62C1B5B70002DA29B /* CreateDayReport.swift */; };\n\t\t6D5BC4CB2C1B5BF7002DA29B /* CreateDayReport.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D5BC4C62C1B5B70002DA29B /* CreateDayReport.swift */; };\n/* End PBXBuildFile section */\n\n/* Begin PBXContainerItemProxy section */\n\t\t4065D4071DD4532100B73201 /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 4065D2FC1DD3A1AA00B73201 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 4065D3031DD3A1AA00B73201;\n\t\t\tremoteInfo = Jirassic;\n\t\t};\n\t\t566C09141F2B985C0058D90A /* PBXContainerItemProxy */ = {\n\t\t\tisa = PBXContainerItemProxy;\n\t\t\tcontainerPortal = 4065D2FC1DD3A1AA00B73201 /* Project object */;\n\t\t\tproxyType = 1;\n\t\t\tremoteGlobalIDString = 280D711C1ED5EE7F005D2689;\n\t\t\tremoteInfo = \"Jirassic macOS\";\n\t\t};\n/* End PBXContainerItemProxy section */\n\n/* Begin PBXCopyFilesBuildPhase section */\n\t\t28577E941E89972F002B07FD /* CopyFiles */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"\";\n\t\t\tdstSubfolderSpec = 10;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t28577E9B1E89A969002B07FD /* CopyFiles */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = \"\";\n\t\t\tdstSubfolderSpec = 10;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t4055B1351E0D81E600279430 /* CopyFiles */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = Contents/Library/LoginItems;\n\t\t\tdstSubfolderSpec = 1;\n\t\t\tfiles = (\n\t\t\t\t4055B1361E0D821500279430 /* JirassicLauncher.app in CopyFiles */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t4065D40E1DD4534C00B73201 /* CopyFiles */ = {\n\t\t\tisa = PBXCopyFilesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tdstPath = /usr/share/man/man1/;\n\t\t\tdstSubfolderSpec = 0;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 1;\n\t\t};\n/* End PBXCopyFilesBuildPhase section */\n\n/* Begin PBXFileReference section */\n\t\t2801388E205F86460051B532 /* TimeBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeBox.swift; sourceTree = \"<group>\"; };\n\t\t280300D51EDB5ECA000A763E /* StatisticsInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = StatisticsInteractor.swift; path = Statistics/StatisticsInteractor.swift; sourceTree = \"<group>\"; };\n\t\t2803A0C91EC184FF005F9389 /* BrowserNotification.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BrowserNotification.swift; sourceTree = \"<group>\"; };\n\t\t280C1D411ED74EF900C126A1 /* BrowserSupport.scpt */ = {isa = PBXFileReference; lastKnownFileType = file; path = BrowserSupport.scpt; sourceTree = \"<group>\"; };\n\t\t280C1D421ED74EF900C126A1 /* ShellSupport.scpt */ = {isa = PBXFileReference; lastKnownFileType = file; path = ShellSupport.scpt; sourceTree = \"<group>\"; };\n\t\t280D70B01ECC09D9005D2689 /* AppTheme.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppTheme.swift; sourceTree = \"<group>\"; };\n\t\t280D70B61ECFE06A005D2689 /* Jirassic iOS.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = \"Jirassic iOS.app\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t280D70F91ED0E7B0005D2689 /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS10.3.sdk/System/Library/Frameworks/CloudKit.framework; sourceTree = DEVELOPER_DIR; };\n\t\t280D70FD1ED20CBE005D2689 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t280D70FF1ED21989005D2689 /* Jirassic Scrum.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = \"Jirassic Scrum.entitlements\"; sourceTree = \"<group>\"; };\n\t\t280D71171ED4CFCB005D2689 /* ReadDaysInteractorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReadDaysInteractorTests.swift; sourceTree = \"<group>\"; };\n\t\t280D711D1ED5EE7F005D2689 /* Jirassic no cloud.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = \"Jirassic no cloud.app\"; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t280D71BA1ED60677005D2689 /* libsqlite3.0.tbd */ = {isa = PBXFileReference; lastKnownFileType = \"sourcecode.text-based-dylib-definition\"; name = libsqlite3.0.tbd; path = usr/lib/libsqlite3.0.tbd; sourceTree = SDKROOT; };\n\t\t280F507A1EC8541D007416AB /* ExtensionsInstallerInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExtensionsInstallerInteractor.swift; sourceTree = \"<group>\"; };\n\t\t280F507C1EC868B0007416AB /* StringArray.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringArray.swift; sourceTree = \"<group>\"; };\n\t\t2812F61C2145031A008EE81E /* IAPHelper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IAPHelper.swift; sourceTree = \"<group>\"; };\n\t\t2812F61D2145031A008EE81E /* Store.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Store.swift; sourceTree = \"<group>\"; };\n\t\t2818848021A4A2F800B33B9C /* Jirassic.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Jirassic.xcdatamodel; sourceTree = \"<group>\"; };\n\t\t2823C9341E4F69970055D036 /* Versioning.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Versioning.swift; sourceTree = \"<group>\"; };\n\t\t28279AD421C6245700376304 /* GitUsersViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitUsersViewController.swift; sourceTree = \"<group>\"; };\n\t\t28279E9B1E8300E200EAF9FC /* PlaceholderViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PlaceholderViewController.swift; sourceTree = \"<group>\"; };\n\t\t284192D62018841700E64A9A /* JProject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JProject.swift; sourceTree = \"<group>\"; };\n\t\t284192D92018855B00E64A9A /* JiraRepository+Projects.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"JiraRepository+Projects.swift\"; sourceTree = \"<group>\"; };\n\t\t284192DC2018A8B200E64A9A /* ModuleJiraTempo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModuleJiraTempo.swift; sourceTree = \"<group>\"; };\n\t\t2845B1342066C6E6006EFB3B /* AppleScriptProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppleScriptProtocol.swift; sourceTree = \"<group>\"; };\n\t\t2845B138206703C5006EFB3B /* Keychain.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Keychain.swift; sourceTree = \"<group>\"; };\n\t\t2845B13E2068351F006EFB3B /* TableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TableViewCell.swift; sourceTree = \"<group>\"; };\n\t\t2845B144206AE3A8006EFB3B /* ReportCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReportCell.swift; sourceTree = \"<group>\"; };\n\t\t2845B145206AE3A8006EFB3B /* ReportCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ReportCell.xib; sourceTree = \"<group>\"; };\n\t\t2845B146206AE3A8006EFB3B /* ReportCellPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReportCellPresenter.swift; sourceTree = \"<group>\"; };\n\t\t2845B147206AE3A8006EFB3B /* ReportsDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReportsDataSource.swift; sourceTree = \"<group>\"; };\n\t\t2845B148206AE3A8006EFB3B /* ReportsHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReportsHeaderView.swift; sourceTree = \"<group>\"; };\n\t\t2845B154206AE467006EFB3B /* TaskCellTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TaskCellTests.swift; sourceTree = \"<group>\"; };\n\t\t2845B155206AE467006EFB3B /* TaskCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TaskCell.swift; sourceTree = \"<group>\"; };\n\t\t2845B156206AE467006EFB3B /* TaskCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TaskCell.xib; sourceTree = \"<group>\"; };\n\t\t2845B157206AE467006EFB3B /* TaskCellPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TaskCellPresenter.swift; sourceTree = \"<group>\"; };\n\t\t2845B159206AE467006EFB3B /* TasksHeaderView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TasksHeaderView.swift; sourceTree = \"<group>\"; };\n\t\t2845B15A206AE467006EFB3B /* TasksHeaderView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = TasksHeaderView.xib; sourceTree = \"<group>\"; };\n\t\t2845B15C206AE467006EFB3B /* NonTaskCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NonTaskCell.swift; sourceTree = \"<group>\"; };\n\t\t2845B15D206AE467006EFB3B /* NonTaskCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = NonTaskCell.xib; sourceTree = \"<group>\"; };\n\t\t285465A1216C84E10052CB6A /* CreateMonthReport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateMonthReport.swift; sourceTree = \"<group>\"; };\n\t\t285465A6217858790052CB6A /* StoreView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreView.swift; sourceTree = \"<group>\"; };\n\t\t285465AC217858AF0052CB6A /* StoreView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = StoreView.xib; sourceTree = \"<group>\"; };\n\t\t28577EA71E8ADC53002B07FD /* SqliteRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SqliteRepository.swift; sourceTree = \"<group>\"; };\n\t\t28577EA81E8ADC53002B07FD /* SSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SSettings.swift; sourceTree = \"<group>\"; };\n\t\t28577EA91E8ADC53002B07FD /* STask.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = STask.swift; sourceTree = \"<group>\"; };\n\t\t28577EAA1E8ADC53002B07FD /* SUser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SUser.swift; sourceTree = \"<group>\"; };\n\t\t28577EB31E8AF08F002B07FD /* SQLiteDB.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SQLiteDB.swift; sourceTree = \"<group>\"; };\n\t\t28577EB41E8AF08F002B07FD /* SQLTable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SQLTable.swift; sourceTree = \"<group>\"; };\n\t\t28577EB91E8AF379002B07FD /* libsqlite3.tbd */ = {isa = PBXFileReference; lastKnownFileType = \"sourcecode.text-based-dylib-definition\"; name = libsqlite3.tbd; path = usr/lib/libsqlite3.tbd; sourceTree = SDKROOT; };\n\t\t28577EBB1E8AFB1B002B07FD /* Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = \"Bridging-Header.h\"; sourceTree = \"<group>\"; };\n\t\t28667B5C1FCB7017007B98E3 /* ModuleHookup.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModuleHookup.swift; sourceTree = \"<group>\"; };\n\t\t286BC00321909F85004D4CDD /* CloseDay.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CloseDay.swift; sourceTree = \"<group>\"; };\n\t\t287195142022E1E2001C237E /* HookupPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HookupPresenter.swift; sourceTree = \"<group>\"; };\n\t\t287195172022E8BC001C237E /* OutputTableViewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OutputTableViewDataSource.swift; sourceTree = \"<group>\"; };\n\t\t2871951A2022ECF7001C237E /* OutputsScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OutputsScrollView.swift; sourceTree = \"<group>\"; };\n\t\t2871951D2022FD14001C237E /* InputsScrollView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputsScrollView.swift; sourceTree = \"<group>\"; };\n\t\t287195202022FD87001C237E /* InputsTableViewDataSource.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InputsTableViewDataSource.swift; sourceTree = \"<group>\"; };\n\t\t2871952720241A6C001C237E /* TrackingView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = TrackingView.xib; sourceTree = \"<group>\"; };\n\t\t2871952A20241B25001C237E /* TrackingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrackingView.swift; sourceTree = \"<group>\"; };\n\t\t287195352027CAD9001C237E /* TimeInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeInteractor.swift; sourceTree = \"<group>\"; };\n\t\t287B358620FBAFC40022F43E /* WizardCalendarView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WizardCalendarView.swift; sourceTree = \"<group>\"; };\n\t\t287B358920FBAFD60022F43E /* WizardCalendarView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WizardCalendarView.xib; sourceTree = \"<group>\"; };\n\t\t288BB67D2085252900CF720A /* WizardViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WizardViewController.swift; sourceTree = \"<group>\"; };\n\t\t288BB6802087152B00CF720A /* WizardAppleScriptView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WizardAppleScriptView.xib; sourceTree = \"<group>\"; };\n\t\t288BB6832087157F00CF720A /* WizardAppleScriptView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WizardAppleScriptView.swift; sourceTree = \"<group>\"; };\n\t\t288BB6862087169F00CF720A /* ViewXib.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewXib.swift; sourceTree = \"<group>\"; };\n\t\t2892B2971F094A170085BAC2 /* JiraRepository.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JiraRepository.swift; sourceTree = \"<group>\"; };\n\t\t2892B29A1F094A760085BAC2 /* JiraRepository+Reports.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = \"JiraRepository+Reports.swift\"; sourceTree = \"<group>\"; };\n\t\t2892B29D1F094B0D0085BAC2 /* JReport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JReport.swift; sourceTree = \"<group>\"; };\n\t\t2892B2A61F094C800085BAC2 /* JWorkAttribute.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JWorkAttribute.swift; sourceTree = \"<group>\"; };\n\t\t2892E80A208D9B42004E5298 /* InputsScrollView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = InputsScrollView.xib; sourceTree = \"<group>\"; };\n\t\t2892E80D208D9DD0004E5298 /* OutputsScrollView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = OutputsScrollView.xib; sourceTree = \"<group>\"; };\n\t\t2892E810208E6275004E5298 /* LocalPreferences.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalPreferences.swift; sourceTree = \"<group>\"; };\n\t\t2898D3A72181907700CF5AD4 /* MonthReportsHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MonthReportsHeaderView.swift; sourceTree = \"<group>\"; };\n\t\t2898D3AA2184D1DB00CF5AD4 /* TimeBoxViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimeBoxViewController.swift; sourceTree = \"<group>\"; };\n\t\t2898D3AD2184ED3000CF5AD4 /* Components.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Components.storyboard; sourceTree = \"<group>\"; };\n\t\t2898D3B02185959300CF5AD4 /* EditableTimeBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EditableTimeBox.swift; sourceTree = \"<group>\"; };\n\t\t28A283932037874600DDCB63 /* ModuleGitLogs.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModuleGitLogs.swift; sourceTree = \"<group>\"; };\n\t\t28A283962037975600DDCB63 /* Saveable.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Saveable.swift; sourceTree = \"<group>\"; };\n\t\t28A2839920382BBB00DDCB63 /* GitCommit.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitCommit.swift; sourceTree = \"<group>\"; };\n\t\t28A2839E20385BE000DDCB63 /* GitCommitsParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitCommitsParser.swift; sourceTree = \"<group>\"; };\n\t\t28A283A120385F8C00DDCB63 /* GitCommitsParserTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitCommitsParserTests.swift; sourceTree = \"<group>\"; };\n\t\t28A283A42038AFB100DDCB63 /* JirassicCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JirassicCell.swift; sourceTree = \"<group>\"; };\n\t\t28A283A72038AFC500DDCB63 /* JirassicCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = JirassicCell.xib; sourceTree = \"<group>\"; };\n\t\t28A283AA203A93AB00DDCB63 /* GitBranchParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitBranchParser.swift; sourceTree = \"<group>\"; };\n\t\t28A283AD203C069F00DDCB63 /* GitBranchParserTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitBranchParserTests.swift; sourceTree = \"<group>\"; };\n\t\t28A283AF203CB1A100DDCB63 /* MergeTasksInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MergeTasksInteractor.swift; sourceTree = \"<group>\"; };\n\t\t28A283B2203CB1B900DDCB63 /* MergeTasksInteractorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MergeTasksInteractorTests.swift; sourceTree = \"<group>\"; };\n\t\t28A5F27D1E5789FC002BE564 /* TasksDataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TasksDataSource.swift; sourceTree = \"<group>\"; };\n\t\t28A5F2811E586426002BE564 /* DataSource.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataSource.swift; sourceTree = \"<group>\"; };\n\t\t28A928771E8F78580022AB55 /* SQLiteSchema.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SQLiteSchema.swift; sourceTree = \"<group>\"; };\n\t\t28A9287C1E9030BA0022AB55 /* CloudKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CloudKit.framework; path = System/Library/Frameworks/CloudKit.framework; sourceTree = SDKROOT; };\n\t\t28A928801E910DA40022AB55 /* SqliteRepository+Tasks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"SqliteRepository+Tasks.swift\"; sourceTree = \"<group>\"; };\n\t\t28A928831E910E5E0022AB55 /* SqliteRepository+User.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"SqliteRepository+User.swift\"; sourceTree = \"<group>\"; };\n\t\t28A928861E910EA70022AB55 /* SqliteRepository+Settings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"SqliteRepository+Settings.swift\"; sourceTree = \"<group>\"; };\n\t\t28A928891E910F4D0022AB55 /* CoreDataRepository+Tasks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"CoreDataRepository+Tasks.swift\"; sourceTree = \"<group>\"; };\n\t\t28A9288C1E910F970022AB55 /* CoreDataRepository+Settings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"CoreDataRepository+Settings.swift\"; sourceTree = \"<group>\"; };\n\t\t28A9288F1E910FF60022AB55 /* CoreDataRepository+User.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"CoreDataRepository+User.swift\"; sourceTree = \"<group>\"; };\n\t\t28A928921E91104B0022AB55 /* CloudKitRepository+Tasks.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"CloudKitRepository+Tasks.swift\"; sourceTree = \"<group>\"; };\n\t\t28A928941E9110980022AB55 /* CloudKitRepository+User.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"CloudKitRepository+User.swift\"; sourceTree = \"<group>\"; };\n\t\t28A928961E9110BF0022AB55 /* CloudKitRepository+Settings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"CloudKitRepository+Settings.swift\"; sourceTree = \"<group>\"; };\n\t\t28AFE7301E9A594500BAAD8C /* UserDefaults+token.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"UserDefaults+token.swift\"; sourceTree = \"<group>\"; };\n\t\t28B116B721AE5C45004ACE01 /* ReportsHeaderView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ReportsHeaderView.xib; sourceTree = \"<group>\"; };\n\t\t28B116BA21AE6179004ACE01 /* MonthReportsHeaderView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MonthReportsHeaderView.xib; sourceTree = \"<group>\"; };\n\t\t28C6A38321D359E60036DB29 /* RemoveDuplicate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoveDuplicate.swift; sourceTree = \"<group>\"; };\n\t\t28C9C6211EAD37D0007EB3E6 /* UserDefaults+uploadToken.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = \"UserDefaults+uploadToken.swift\"; sourceTree = \"<group>\"; };\n\t\t28CBB595204554A2006F9D3A /* ParseGitBranch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseGitBranch.swift; sourceTree = \"<group>\"; };\n\t\t28CBB59920474755006F9D3A /* ParseGitBranchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParseGitBranchTests.swift; sourceTree = \"<group>\"; };\n\t\t28DCA4542018B6E700DFAE29 /* JProjectIssue.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JProjectIssue.swift; sourceTree = \"<group>\"; };\n\t\t28E896621E830D6700722032 /* Placeholder.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Placeholder.storyboard; sourceTree = \"<group>\"; };\n\t\t28E8966E1E83732200722032 /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = \"macOS-launcher/AppDelegate.h\"; sourceTree = \"<group>\"; };\n\t\t28E8966F1E83732200722032 /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AppDelegate.m; path = \"macOS-launcher/AppDelegate.m\"; sourceTree = \"<group>\"; };\n\t\t28E896701E83732200722032 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = \"macOS-launcher/main.m\"; sourceTree = \"<group>\"; };\n\t\t28E896741E83770D00722032 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = \"macOS-launcher/Base.lproj/MainMenu.xib\"; sourceTree = \"<group>\"; };\n\t\t28EDE9381E59EC1500B360A4 /* TasksView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TasksView.swift; sourceTree = \"<group>\"; };\n\t\t28EE1F5D20EE8D1000C5C1D6 /* CalendarCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarCell.swift; sourceTree = \"<group>\"; };\n\t\t28EE1F6020EE8D6100C5C1D6 /* CalendarCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = CalendarCell.xib; sourceTree = \"<group>\"; };\n\t\t28EE1F6320EE92DA00C5C1D6 /* CalendarPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CalendarPresenter.swift; sourceTree = \"<group>\"; };\n\t\t28FB265020224E3A00AEA38D /* JiraTempoCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JiraTempoCell.swift; sourceTree = \"<group>\"; };\n\t\t28FB265320224E5B00AEA38D /* JiraTempoCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = JiraTempoCell.xib; sourceTree = \"<group>\"; };\n\t\t28FB265720224E9B00AEA38D /* HookupCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = HookupCell.xib; sourceTree = \"<group>\"; };\n\t\t28FB265A20224EA700AEA38D /* HookupCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HookupCell.swift; sourceTree = \"<group>\"; };\n\t\t28FB265D2022DC2B00AEA38D /* JiraTempoPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JiraTempoPresenter.swift; sourceTree = \"<group>\"; };\n\t\t28FE1886207A520B00DF796E /* NewTaskCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewTaskCommand.swift; sourceTree = \"<group>\"; };\n\t\t28FE18A4207B369800DF796E /* CocoaHookupCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CocoaHookupCell.swift; sourceTree = \"<group>\"; };\n\t\t28FE18A7207B36CB00DF796E /* CocoaHookupCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = CocoaHookupCell.xib; sourceTree = \"<group>\"; };\n\t\t28FE18AA207B375A00DF796E /* CocoaHookupPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CocoaHookupPresenter.swift; sourceTree = \"<group>\"; };\n\t\t4051D5EF1E0EA0EA002042BB /* JirassicLauncher.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; name = JirassicLauncher.entitlements; path = \"macOS-launcher/JirassicLauncher.entitlements\"; sourceTree = \"<group>\"; };\n\t\t4051D5F01E0EA0EA002042BB /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = \"macOS-launcher/Info.plist\"; sourceTree = \"<group>\"; };\n\t\t4051D5F71E0EA320002042BB /* Jirassic.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; path = Jirassic.entitlements; sourceTree = \"<group>\"; };\n\t\t4051D5F81E0EA48A002042BB /* AppLauncher.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppLauncher.swift; sourceTree = \"<group>\"; };\n\t\t4055B1231E0D802300279430 /* JirassicLauncher.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JirassicLauncher.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t4055B1381E0D82A900279430 /* ServiceManagement.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ServiceManagement.framework; path = System/Library/Frameworks/ServiceManagement.framework; sourceTree = SDKROOT; };\n\t\t405B15601DEF3D080009871C /* TaskSuggestionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TaskSuggestionViewController.swift; path = TaskSuggestion/TaskSuggestionViewController.swift; sourceTree = \"<group>\"; };\n\t\t405B15621DEF3F2A0009871C /* TaskSuggestionPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TaskSuggestionPresenter.swift; path = TaskSuggestion/TaskSuggestionPresenter.swift; sourceTree = \"<group>\"; };\n\t\t405B15651DEF75660009871C /* AppViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppViewController.swift; sourceTree = \"<group>\"; };\n\t\t406384881DE388C5004795A4 /* Tasks.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Tasks.storyboard; sourceTree = \"<group>\"; };\n\t\t4065D3041DD3A1AA00B73201 /* Jirassic.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Jirassic.app; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t4065D3181DD3B44200B73201 /* Day.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Day.swift; sourceTree = \"<group>\"; };\n\t\t4065D3191DD3B44200B73201 /* Report.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Report.swift; sourceTree = \"<group>\"; };\n\t\t4065D31A1DD3B44200B73201 /* Settings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Settings.swift; sourceTree = \"<group>\"; };\n\t\t4065D31B1DD3B44200B73201 /* Task.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Task.swift; sourceTree = \"<group>\"; };\n\t\t4065D31D1DD3B44200B73201 /* User.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = User.swift; sourceTree = \"<group>\"; };\n\t\t4065D31E1DD3B44200B73201 /* Week.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Week.swift; sourceTree = \"<group>\"; };\n\t\t4065D3201DD3B44200B73201 /* DateExtension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateExtension.swift; sourceTree = \"<group>\"; };\n\t\t4065D3211DD3B44200B73201 /* DateExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DateExtensionTests.swift; sourceTree = \"<group>\"; };\n\t\t4065D3221DD3B44200B73201 /* StringIdGenerator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringIdGenerator.swift; sourceTree = \"<group>\"; };\n\t\t4065D3231DD3B44200B73201 /* ViewAutolayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewAutolayout.swift; sourceTree = \"<group>\"; };\n\t\t4065D3241DD3B44200B73201 /* ViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = \"<group>\"; };\n\t\t4065D3251DD3B44200B73201 /* ViewControllerStoryboard.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ViewControllerStoryboard.swift; sourceTree = \"<group>\"; };\n\t\t4065D3261DD3B44200B73201 /* Conversions.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Conversions.swift; sourceTree = \"<group>\"; };\n\t\t4065D3291DD3B44200B73201 /* ComputerWakeUpInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ComputerWakeUpInteractor.swift; sourceTree = \"<group>\"; };\n\t\t4065D32B1DD3B44200B73201 /* CreateReport.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateReport.swift; sourceTree = \"<group>\"; };\n\t\t4065D32C1DD3B44200B73201 /* CreateReportTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CreateReportTests.swift; sourceTree = \"<group>\"; };\n\t\t4065D32E1DD3B44200B73201 /* ReadDaysInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReadDaysInteractor.swift; sourceTree = \"<group>\"; };\n\t\t4065D32F1DD3B44200B73201 /* ReadTasksInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReadTasksInteractor.swift; sourceTree = \"<group>\"; };\n\t\t4065D3301DD3B44200B73201 /* TaskFinder.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TaskFinder.swift; sourceTree = \"<group>\"; };\n\t\t4065D3311DD3B44200B73201 /* TaskFinderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TaskFinderTests.swift; sourceTree = \"<group>\"; };\n\t\t4065D3321DD3B44200B73201 /* TaskInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TaskInteractor.swift; sourceTree = \"<group>\"; };\n\t\t4065D3331DD3B44200B73201 /* TaskInteractorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TaskInteractorTests.swift; sourceTree = \"<group>\"; };\n\t\t4065D3341DD3B44200B73201 /* TaskTypeEstimator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TaskTypeEstimator.swift; sourceTree = \"<group>\"; };\n\t\t4065D3351DD3B44200B73201 /* TaskTypeEstimatorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TaskTypeEstimatorTests.swift; sourceTree = \"<group>\"; };\n\t\t4065D3361DD3B44200B73201 /* TaskTypeSelection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TaskTypeSelection.swift; sourceTree = \"<group>\"; };\n\t\t4065D3391DD3B44200B73201 /* PredictiveTimeTyping.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PredictiveTimeTyping.swift; sourceTree = \"<group>\"; };\n\t\t4065D33A1DD3B44200B73201 /* PredictiveTimeTypingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PredictiveTimeTypingTests.swift; sourceTree = \"<group>\"; };\n\t\t4065D33C1DD3B44200B73201 /* RegisterUserInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RegisterUserInteractor.swift; sourceTree = \"<group>\"; };\n\t\t4065D33D1DD3B44200B73201 /* UserInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserInteractor.swift; sourceTree = \"<group>\"; };\n\t\t4065D33E1DD3B44200B73201 /* UserInteractorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserInteractorTests.swift; sourceTree = \"<group>\"; };\n\t\t4065D3421DD3B44200B73201 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t4065D3441DD3B44200B73201 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = \"<group>\"; };\n\t\t4065D3461DD3B44200B73201 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\t4065D3471DD3B44200B73201 /* DaysViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DaysViewController.swift; sourceTree = \"<group>\"; };\n\t\t4065D3491DD3B44200B73201 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = \"<group>\"; };\n\t\t4065D34B1DD3B44200B73201 /* LoginViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginViewController.swift; sourceTree = \"<group>\"; };\n\t\t4065D34D1DD3B44200B73201 /* NonTaskCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NonTaskCell.swift; sourceTree = \"<group>\"; };\n\t\t4065D34E1DD3B44200B73201 /* TaskCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TaskCell.swift; sourceTree = \"<group>\"; };\n\t\t4065D34F1DD3B44200B73201 /* TasksViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TasksViewController.swift; sourceTree = \"<group>\"; };\n\t\t4065D3521DD3B44200B73201 /* FlipAnimation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FlipAnimation.swift; sourceTree = \"<group>\"; };\n\t\t4065D3541DD3B44200B73201 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = \"<group>\"; };\n\t\t4065D3551DD3B44200B73201 /* AppWireframe.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppWireframe.swift; sourceTree = \"<group>\"; };\n\t\t4065D35A1DD3B44200B73201 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = \"<group>\"; };\n\t\t4065D35B1DD3B44200B73201 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = \"<group>\"; };\n\t\t4065D35C1DD3B44200B73201 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t4065D3611DD3B44200B73201 /* jirassic.sdef */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xml; path = jirassic.sdef; sourceTree = \"<group>\"; };\n\t\t4065D3651DD3B44200B73201 /* MenuBarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MenuBarController.swift; sourceTree = \"<group>\"; };\n\t\t4065D3661DD3B44200B73201 /* MenuBarIconView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MenuBarIconView.swift; sourceTree = \"<group>\"; };\n\t\t4065D3681DD3B44200B73201 /* InternalNotifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InternalNotifications.swift; sourceTree = \"<group>\"; };\n\t\t4065D3691DD3B44200B73201 /* UserNotifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserNotifications.swift; sourceTree = \"<group>\"; };\n\t\t4065D36A1DD3B44200B73201 /* SleepNotifications.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SleepNotifications.swift; sourceTree = \"<group>\"; };\n\t\t4065D3711DD3B44200B73201 /* NewTaskViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NewTaskViewController.swift; sourceTree = \"<group>\"; };\n\t\t4065D3731DD3B44200B73201 /* SettingsInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsInteractor.swift; sourceTree = \"<group>\"; };\n\t\t4065D3741DD3B44200B73201 /* SettingsPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsPresenter.swift; sourceTree = \"<group>\"; };\n\t\t4065D3751DD3B44200B73201 /* SettingsViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SettingsViewController.swift; sourceTree = \"<group>\"; };\n\t\t4065D3771DD3B44200B73201 /* CalendarScrollView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CalendarScrollView.swift; sourceTree = \"<group>\"; };\n\t\t4065D3781DD3B44200B73201 /* CellProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CellProtocol.swift; sourceTree = \"<group>\"; };\n\t\t4065D3831DD3B44200B73201 /* TasksPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TasksPresenter.swift; sourceTree = \"<group>\"; };\n\t\t4065D3841DD3B44200B73201 /* TasksScrollView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TasksScrollView.swift; sourceTree = \"<group>\"; };\n\t\t4065D3851DD3B44200B73201 /* TasksViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TasksViewController.swift; sourceTree = \"<group>\"; };\n\t\t4065D3871DD3B44200B73201 /* main.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = main.swift; sourceTree = \"<group>\"; };\n\t\t4065D38A1DD3B44200B73201 /* CloudKitRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CloudKitRepository.swift; sourceTree = \"<group>\"; };\n\t\t4065D38C1DD3B44200B73201 /* CoreDataRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CoreDataRepository.swift; sourceTree = \"<group>\"; };\n\t\t4065D38D1DD3B44200B73201 /* CSettings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CSettings.swift; sourceTree = \"<group>\"; };\n\t\t4065D38E1DD3B44200B73201 /* CTask.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CTask.swift; sourceTree = \"<group>\"; };\n\t\t4065D38F1DD3B44200B73201 /* CUser.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CUser.swift; sourceTree = \"<group>\"; };\n\t\t4065D3931DD3B44200B73201 /* InMemoryCoreDataRepository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InMemoryCoreDataRepository.swift; sourceTree = \"<group>\"; };\n\t\t4065D3941DD3B44200B73201 /* Repository.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Repository.swift; sourceTree = \"<group>\"; };\n\t\t4065D3951DD3B44200B73201 /* RepositoryInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RepositoryInteractor.swift; sourceTree = \"<group>\"; };\n\t\t4065D4021DD4532100B73201 /* JirassicTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = JirassicTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t4065D4061DD4532100B73201 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = \"<group>\"; };\n\t\t4065D4101DD4534C00B73201 /* jirassic */ = {isa = PBXFileReference; explicitFileType = \"compiled.mach-o.executable\"; includeInIndex = 0; path = jirassic; sourceTree = BUILT_PRODUCTS_DIR; };\n\t\t4073184E1DE9B1B40046F409 /* ComputerWakeUpInteractorTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ComputerWakeUpInteractorTests.swift; sourceTree = \"<group>\"; };\n\t\t40E092401DE385E4001EF5DA /* Settings.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Settings.storyboard; sourceTree = \"<group>\"; };\n\t\t40FCE4221DF7646F00D4FD45 /* AppleScript.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppleScript.swift; sourceTree = \"<group>\"; };\n\t\t40FCE4231DF7646F00D4FD45 /* ExtensionsInteractor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ExtensionsInteractor.swift; sourceTree = \"<group>\"; };\n\t\t40FCE4241DF7646F00D4FD45 /* SandboxedAppleScript.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SandboxedAppleScript.swift; sourceTree = \"<group>\"; };\n\t\t40FCE4281DFC1CB400D4FD45 /* TaskSuggestionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = TaskSuggestionTests.swift; path = TaskSuggestion/TaskSuggestionTests.swift; sourceTree = \"<group>\"; };\n\t\t40FCE42B1DFC3F8700D4FD45 /* WelcomeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WelcomeViewController.swift; sourceTree = \"<group>\"; };\n\t\t40FCE42D1DFC576C00D4FD45 /* Welcome.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Welcome.storyboard; sourceTree = \"<group>\"; };\n\t\t40FCE42F1DFD7C8D00D4FD45 /* Animatable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Animatable.swift; sourceTree = \"<group>\"; };\n\t\t564E55F2202883DB00CE4C76 /* WorklogsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WorklogsViewController.swift; sourceTree = \"<group>\"; };\n\t\t564E55F5202884DE00CE4C76 /* WorklogsPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WorklogsPresenter.swift; sourceTree = \"<group>\"; };\n\t\t564E55F82028857300CE4C76 /* Worklogs.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Worklogs.storyboard; sourceTree = \"<group>\"; };\n\t\t565E19EF20A5E336003A5E2A /* RCSync.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RCSync.swift; sourceTree = \"<group>\"; };\n\t\t566B9FA6217DE67700EAF324 /* TasksInteractor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TasksInteractor.swift; sourceTree = \"<group>\"; };\n\t\t5683DC3D20ECDED30000A138 /* ModuleCalendar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModuleCalendar.swift; sourceTree = \"<group>\"; };\n\t\t5685C7631DE8721100CA545E /* CloudKitLoginViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CloudKitLoginViewController.swift; sourceTree = \"<group>\"; };\n\t\t5685C7641DE8721100CA545E /* Login.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Login.storyboard; sourceTree = \"<group>\"; };\n\t\t5685C7651DE8721100CA545E /* LoginPresenter.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginPresenter.swift; sourceTree = \"<group>\"; };\n\t\t5685C7661DE8721100CA545E /* LoginViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginViewController.swift; sourceTree = \"<group>\"; };\n\t\t5685C76B1DE8724400CA545E /* AccountViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AccountViewController.swift; sourceTree = \"<group>\"; };\n\t\t569C4C572023193B0049FBF1 /* ShellCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShellCell.swift; sourceTree = \"<group>\"; };\n\t\t569C4C5D202319630049FBF1 /* JitCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = JitCell.swift; sourceTree = \"<group>\"; };\n\t\t569C4C63202319870049FBF1 /* GitCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitCell.swift; sourceTree = \"<group>\"; };\n\t\t569C4C66202319930049FBF1 /* GitPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitPresenter.swift; sourceTree = \"<group>\"; };\n\t\t569C4C69202319A20049FBF1 /* BrowserCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserCell.swift; sourceTree = \"<group>\"; };\n\t\t569C4C6C202319CA0049FBF1 /* BrowserPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrowserPresenter.swift; sourceTree = \"<group>\"; };\n\t\t569C4C6F202319DE0049FBF1 /* ShellCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ShellCell.xib; sourceTree = \"<group>\"; };\n\t\t569C4C72202319EE0049FBF1 /* JitCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = JitCell.xib; sourceTree = \"<group>\"; };\n\t\t569C4C75202319FC0049FBF1 /* GitCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = GitCell.xib; sourceTree = \"<group>\"; };\n\t\t569C4C7820231A0B0049FBF1 /* BrowserCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = BrowserCell.xib; sourceTree = \"<group>\"; };\n\t\t56ADBF6921C3F625008350A6 /* GitUser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitUser.swift; sourceTree = \"<group>\"; };\n\t\t56ADBF6C21C3F94D008350A6 /* GitUserParser.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GitUserParser.swift; sourceTree = \"<group>\"; };\n\t\t56CD22BE1E72F89700F9CDB8 /* BuildScript.sh */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.script.sh; path = BuildScript.sh; sourceTree = \"<group>\"; };\n\t\t56D069E0216CABCB000D051D /* CreateMonthReportTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateMonthReportTests.swift; sourceTree = \"<group>\"; };\n\t\t56D90CF720876F1100F24442 /* WizardJiraView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WizardJiraView.swift; sourceTree = \"<group>\"; };\n\t\t56D90CFA20876F2B00F24442 /* WizardGitView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WizardGitView.swift; sourceTree = \"<group>\"; };\n\t\t56D90CFD20876F3C00F24442 /* WizardGitView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WizardGitView.xib; sourceTree = \"<group>\"; };\n\t\t56D90D0020876F4900F24442 /* WizardJiraView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = WizardJiraView.xib; sourceTree = \"<group>\"; };\n\t\t6D3702672BA84233002260D0 /* Jirassic macOS.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = \"Jirassic macOS.entitlements\"; sourceTree = \"<group>\"; };\n\t\t6D5BC4C62C1B5B70002DA29B /* CreateDayReport.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CreateDayReport.swift; sourceTree = \"<group>\"; };\n/* End PBXFileReference section */\n\n/* Begin PBXFrameworksBuildPhase section */\n\t\t280D70B31ECFE06A005D2689 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t280D70FA1ED0E7B0005D2689 /* CloudKit.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t280D711A1ED5EE7F005D2689 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t280D71BE1ED6069A005D2689 /* ServiceManagement.framework in Frameworks */,\n\t\t\t\t280D71BC1ED60683005D2689 /* libsqlite3.tbd in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t4055B1201E0D802300279430 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t4065D3011DD3A1AA00B73201 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t28A9287D1E9030BA0022AB55 /* CloudKit.framework in Frameworks */,\n\t\t\t\t6D3702622BA83EB9002260D0 /* RCLog in Frameworks */,\n\t\t\t\t28577EBA1E8AF379002B07FD /* libsqlite3.tbd in Frameworks */,\n\t\t\t\t6D3702602BA83E9A002260D0 /* SwiftKeychainWrapper in Frameworks */,\n\t\t\t\t6D3702662BA83EC7002260D0 /* RCHttp in Frameworks */,\n\t\t\t\t6D3702642BA83EBF002260D0 /* RCPreferences in Frameworks */,\n\t\t\t\t4055B1391E0D82A900279430 /* ServiceManagement.framework in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t4065D3FF1DD4532100B73201 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t4065D40D1DD4534C00B73201 /* Frameworks */ = {\n\t\t\tisa = PBXFrameworksBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t28A9287A1E8FA8E90022AB55 /* libsqlite3.tbd in Frameworks */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXFrameworksBuildPhase section */\n\n/* Begin PBXGroup section */\n\t\t2801388D205F86250051B532 /* Components */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2801388E205F86460051B532 /* TimeBox.swift */,\n\t\t\t\t2898D3B02185959300CF5AD4 /* EditableTimeBox.swift */,\n\t\t\t\t2898D3AA2184D1DB00CF5AD4 /* TimeBoxViewController.swift */,\n\t\t\t\t4065D3711DD3B44200B73201 /* NewTaskViewController.swift */,\n\t\t\t\t28279AD421C6245700376304 /* GitUsersViewController.swift */,\n\t\t\t\t2898D3AD2184ED3000CF5AD4 /* Components.storyboard */,\n\t\t\t);\n\t\t\tpath = Components;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t280300D41EDB5E6D000A763E /* Statistics */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t280300D51EDB5ECA000A763E /* StatisticsInteractor.swift */,\n\t\t\t);\n\t\t\tname = Statistics;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2812F61B2145031A008EE81E /* IAP */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2812F61C2145031A008EE81E /* IAPHelper.swift */,\n\t\t\t\t2812F61D2145031A008EE81E /* Store.swift */,\n\t\t\t);\n\t\t\tpath = IAP;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t28279E9A1E8300E200EAF9FC /* Placeholder */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t28279E9B1E8300E200EAF9FC /* PlaceholderViewController.swift */,\n\t\t\t\t28E896621E830D6700722032 /* Placeholder.storyboard */,\n\t\t\t);\n\t\t\tpath = Placeholder;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2845B137206703A8006EFB3B /* Keychain */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2845B138206703C5006EFB3B /* Keychain.swift */,\n\t\t\t);\n\t\t\tpath = Keychain;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2845B141206AE2A4006EFB3B /* Reports */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2845B147206AE3A8006EFB3B /* ReportsDataSource.swift */,\n\t\t\t\t287B943B21A690C100FFC4A5 /* HeaderView */,\n\t\t\t\t2845B143206AE3A8006EFB3B /* ReportCell */,\n\t\t\t);\n\t\t\tpath = Reports;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2845B142206AE342006EFB3B /* Calendar */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D3771DD3B44200B73201 /* CalendarScrollView.swift */,\n\t\t\t);\n\t\t\tpath = Calendar;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2845B143206AE3A8006EFB3B /* ReportCell */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2845B144206AE3A8006EFB3B /* ReportCell.swift */,\n\t\t\t\t2845B145206AE3A8006EFB3B /* ReportCell.xib */,\n\t\t\t\t2845B146206AE3A8006EFB3B /* ReportCellPresenter.swift */,\n\t\t\t);\n\t\t\tpath = ReportCell;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2845B153206AE467006EFB3B /* TaskCell */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2845B155206AE467006EFB3B /* TaskCell.swift */,\n\t\t\t\t2845B156206AE467006EFB3B /* TaskCell.xib */,\n\t\t\t\t2845B154206AE467006EFB3B /* TaskCellTests.swift */,\n\t\t\t\t2845B157206AE467006EFB3B /* TaskCellPresenter.swift */,\n\t\t\t);\n\t\t\tpath = TaskCell;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2845B158206AE467006EFB3B /* HeaderView */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2845B159206AE467006EFB3B /* TasksHeaderView.swift */,\n\t\t\t\t2845B15A206AE467006EFB3B /* TasksHeaderView.xib */,\n\t\t\t);\n\t\t\tpath = HeaderView;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2845B15B206AE467006EFB3B /* NonTaskCell */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2845B15C206AE467006EFB3B /* NonTaskCell.swift */,\n\t\t\t\t2845B15D206AE467006EFB3B /* NonTaskCell.xib */,\n\t\t\t);\n\t\t\tpath = NonTaskCell;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2845B16F206C2888006EFB3B /* AllTasks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t28A5F27D1E5789FC002BE564 /* TasksDataSource.swift */,\n\t\t\t\t4065D3781DD3B44200B73201 /* CellProtocol.swift */,\n\t\t\t\t2845B158206AE467006EFB3B /* HeaderView */,\n\t\t\t\t2845B15B206AE467006EFB3B /* NonTaskCell */,\n\t\t\t\t2845B153206AE467006EFB3B /* TaskCell */,\n\t\t\t);\n\t\t\tpath = AllTasks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t285465A5217858120052CB6A /* Store */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t285465A6217858790052CB6A /* StoreView.swift */,\n\t\t\t\t285465AC217858AF0052CB6A /* StoreView.xib */,\n\t\t\t);\n\t\t\tpath = Store;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t28577EA01E8ADBBD002B07FD /* sqlite */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t28577EA71E8ADC53002B07FD /* SqliteRepository.swift */,\n\t\t\t\t28A928801E910DA40022AB55 /* SqliteRepository+Tasks.swift */,\n\t\t\t\t28A928831E910E5E0022AB55 /* SqliteRepository+User.swift */,\n\t\t\t\t28A928861E910EA70022AB55 /* SqliteRepository+Settings.swift */,\n\t\t\t\t28577EA81E8ADC53002B07FD /* SSettings.swift */,\n\t\t\t\t28577EA91E8ADC53002B07FD /* STask.swift */,\n\t\t\t\t28577EAA1E8ADC53002B07FD /* SUser.swift */,\n\t\t\t\t28577EB31E8AF08F002B07FD /* SQLiteDB.swift */,\n\t\t\t\t28577EB41E8AF08F002B07FD /* SQLTable.swift */,\n\t\t\t\t28A928771E8F78580022AB55 /* SQLiteSchema.swift */,\n\t\t\t\t28C9C6211EAD37D0007EB3E6 /* UserDefaults+uploadToken.swift */,\n\t\t\t);\n\t\t\tpath = sqlite;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t28667B591FCADF4E007B98E3 /* Modules */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t5683DC3C20ECDEA30000A138 /* CalendarEvents */,\n\t\t\t\t28A28392203786F600DDCB63 /* GitLogs */,\n\t\t\t\t28667B5A1FCADF68007B98E3 /* JiraTempo */,\n\t\t\t\t28667B5B1FCADF73007B98E3 /* Hookup */,\n\t\t\t);\n\t\t\tpath = Modules;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t28667B5A1FCADF68007B98E3 /* JiraTempo */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t284192DC2018A8B200E64A9A /* ModuleJiraTempo.swift */,\n\t\t\t);\n\t\t\tpath = JiraTempo;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t28667B5B1FCADF73007B98E3 /* Hookup */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t28667B5C1FCB7017007B98E3 /* ModuleHookup.swift */,\n\t\t\t);\n\t\t\tpath = Hookup;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t287195232022FEA4001C237E /* Tracking */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2871952A20241B25001C237E /* TrackingView.swift */,\n\t\t\t\t2871952720241A6C001C237E /* TrackingView.xib */,\n\t\t\t);\n\t\t\tpath = Tracking;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t287B358520FBAD160022F43E /* Onboarding */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t40FCE42D1DFC576C00D4FD45 /* Welcome.storyboard */,\n\t\t\t\t40FCE42B1DFC3F8700D4FD45 /* WelcomeViewController.swift */,\n\t\t\t\t288BB67D2085252900CF720A /* WizardViewController.swift */,\n\t\t\t\t288BB6832087157F00CF720A /* WizardAppleScriptView.swift */,\n\t\t\t\t288BB6802087152B00CF720A /* WizardAppleScriptView.xib */,\n\t\t\t\t56D90CFA20876F2B00F24442 /* WizardGitView.swift */,\n\t\t\t\t56D90CFD20876F3C00F24442 /* WizardGitView.xib */,\n\t\t\t\t287B358620FBAFC40022F43E /* WizardCalendarView.swift */,\n\t\t\t\t287B358920FBAFD60022F43E /* WizardCalendarView.xib */,\n\t\t\t\t56D90CF720876F1100F24442 /* WizardJiraView.swift */,\n\t\t\t\t56D90D0020876F4900F24442 /* WizardJiraView.xib */,\n\t\t\t);\n\t\t\tpath = Onboarding;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t287B943B21A690C100FFC4A5 /* HeaderView */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2845B148206AE3A8006EFB3B /* ReportsHeaderView.swift */,\n\t\t\t\t28B116B721AE5C45004ACE01 /* ReportsHeaderView.xib */,\n\t\t\t);\n\t\t\tpath = HeaderView;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2892B2961F0949D70085BAC2 /* Jira */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2892B2971F094A170085BAC2 /* JiraRepository.swift */,\n\t\t\t\t2892B29A1F094A760085BAC2 /* JiraRepository+Reports.swift */,\n\t\t\t\t284192D92018855B00E64A9A /* JiraRepository+Projects.swift */,\n\t\t\t\t2892B29D1F094B0D0085BAC2 /* JReport.swift */,\n\t\t\t\t2892B2A61F094C800085BAC2 /* JWorkAttribute.swift */,\n\t\t\t\t284192D62018841700E64A9A /* JProject.swift */,\n\t\t\t\t28DCA4542018B6E700DFAE29 /* JProjectIssue.swift */,\n\t\t\t);\n\t\t\tpath = Jira;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t2898D3A62181905600CF5AD4 /* MonthReports */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2898D3A72181907700CF5AD4 /* MonthReportsHeaderView.swift */,\n\t\t\t\t28B116BA21AE6179004ACE01 /* MonthReportsHeaderView.xib */,\n\t\t\t);\n\t\t\tpath = MonthReports;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t28A28392203786F600DDCB63 /* GitLogs */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t28A283932037874600DDCB63 /* ModuleGitLogs.swift */,\n\t\t\t\t28A2839E20385BE000DDCB63 /* GitCommitsParser.swift */,\n\t\t\t\t28A283A120385F8C00DDCB63 /* GitCommitsParserTests.swift */,\n\t\t\t\t56ADBF6C21C3F94D008350A6 /* GitUserParser.swift */,\n\t\t\t\t28A283AA203A93AB00DDCB63 /* GitBranchParser.swift */,\n\t\t\t\t28A283AD203C069F00DDCB63 /* GitBranchParserTests.swift */,\n\t\t\t);\n\t\t\tpath = GitLogs;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t28A283A32038AF9600DDCB63 /* JirassicCmd */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t28A283A42038AFB100DDCB63 /* JirassicCell.swift */,\n\t\t\t\t28A283A72038AFC500DDCB63 /* JirassicCell.xib */,\n\t\t\t);\n\t\t\tpath = JirassicCmd;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t28CBB59420455467006F9D3A /* Parsing */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t28CBB595204554A2006F9D3A /* ParseGitBranch.swift */,\n\t\t\t\t28CBB59920474755006F9D3A /* ParseGitBranchTests.swift */,\n\t\t\t);\n\t\t\tpath = Parsing;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t28EE1F5C20EE8CE600C5C1D6 /* Calendar */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t28EE1F5D20EE8D1000C5C1D6 /* CalendarCell.swift */,\n\t\t\t\t28EE1F6320EE92DA00C5C1D6 /* CalendarPresenter.swift */,\n\t\t\t\t28EE1F6020EE8D6100C5C1D6 /* CalendarCell.xib */,\n\t\t\t);\n\t\t\tpath = Calendar;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t28FB264D20224DE200AEA38D /* Input */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2871951D2022FD14001C237E /* InputsScrollView.swift */,\n\t\t\t\t2892E80A208D9B42004E5298 /* InputsScrollView.xib */,\n\t\t\t\t287195202022FD87001C237E /* InputsTableViewDataSource.swift */,\n\t\t\t\t28EE1F5C20EE8CE600C5C1D6 /* Calendar */,\n\t\t\t\t28A283A32038AF9600DDCB63 /* JirassicCmd */,\n\t\t\t\t569C4C53202318F50049FBF1 /* Shell */,\n\t\t\t\t569C4C56202319120049FBF1 /* Jit */,\n\t\t\t\t569C4C552023190A0049FBF1 /* Git */,\n\t\t\t\t569C4C54202319010049FBF1 /* Browser */,\n\t\t\t);\n\t\t\tpath = Input;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t28FB264E20224DEB00AEA38D /* Output */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2871951A2022ECF7001C237E /* OutputsScrollView.swift */,\n\t\t\t\t2892E80D208D9DD0004E5298 /* OutputsScrollView.xib */,\n\t\t\t\t287195172022E8BC001C237E /* OutputTableViewDataSource.swift */,\n\t\t\t\t28FB264F20224E0A00AEA38D /* JiraTempo */,\n\t\t\t\t28FB265620224E8600AEA38D /* Hookup */,\n\t\t\t\t28FE18A3207B366A00DF796E /* CocoaHookup */,\n\t\t\t);\n\t\t\tpath = Output;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t28FB264F20224E0A00AEA38D /* JiraTempo */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t28FB265020224E3A00AEA38D /* JiraTempoCell.swift */,\n\t\t\t\t28FB265D2022DC2B00AEA38D /* JiraTempoPresenter.swift */,\n\t\t\t\t28FB265320224E5B00AEA38D /* JiraTempoCell.xib */,\n\t\t\t);\n\t\t\tpath = JiraTempo;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t28FB265620224E8600AEA38D /* Hookup */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t28FB265A20224EA700AEA38D /* HookupCell.swift */,\n\t\t\t\t287195142022E1E2001C237E /* HookupPresenter.swift */,\n\t\t\t\t28FB265720224E9B00AEA38D /* HookupCell.xib */,\n\t\t\t);\n\t\t\tpath = Hookup;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t28FE1885207A516300DF796E /* AppleScriptCommands */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t28FE1886207A520B00DF796E /* NewTaskCommand.swift */,\n\t\t\t);\n\t\t\tpath = AppleScriptCommands;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t28FE18A3207B366A00DF796E /* CocoaHookup */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t28FE18A4207B369800DF796E /* CocoaHookupCell.swift */,\n\t\t\t\t28FE18AA207B375A00DF796E /* CocoaHookupPresenter.swift */,\n\t\t\t\t28FE18A7207B36CB00DF796E /* CocoaHookupCell.xib */,\n\t\t\t);\n\t\t\tpath = CocoaHookup;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4055B1371E0D82A800279430 /* Frameworks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t280D71BA1ED60677005D2689 /* libsqlite3.0.tbd */,\n\t\t\t\t280D70F91ED0E7B0005D2689 /* CloudKit.framework */,\n\t\t\t\t28A9287C1E9030BA0022AB55 /* CloudKit.framework */,\n\t\t\t\t28577EB91E8AF379002B07FD /* libsqlite3.tbd */,\n\t\t\t\t4055B1381E0D82A900279430 /* ServiceManagement.framework */,\n\t\t\t);\n\t\t\tname = Frameworks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4055B13A1E0E663800279430 /* macOS-launcher */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t28E8966E1E83732200722032 /* AppDelegate.h */,\n\t\t\t\t28E8966F1E83732200722032 /* AppDelegate.m */,\n\t\t\t\t28E896701E83732200722032 /* main.m */,\n\t\t\t\t4051D5F01E0EA0EA002042BB /* Info.plist */,\n\t\t\t\t28E896731E83770D00722032 /* MainMenu.xib */,\n\t\t\t\t4051D5EF1E0EA0EA002042BB /* JirassicLauncher.entitlements */,\n\t\t\t);\n\t\t\tname = \"macOS-launcher\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t405B155F1DEF3CE20009871C /* TaskSuggestion */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t405B15601DEF3D080009871C /* TaskSuggestionViewController.swift */,\n\t\t\t\t405B15621DEF3F2A0009871C /* TaskSuggestionPresenter.swift */,\n\t\t\t\t40FCE4281DFC1CB400D4FD45 /* TaskSuggestionTests.swift */,\n\t\t\t);\n\t\t\tname = TaskSuggestion;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t405B15641DEF66EE0009871C /* Resources */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t56CD22BE1E72F89700F9CDB8 /* BuildScript.sh */,\n\t\t\t\t4065D35B1DD3B44200B73201 /* Images.xcassets */,\n\t\t\t\t4065D35C1DD3B44200B73201 /* Info.plist */,\n\t\t\t\t28577EBB1E8AFB1B002B07FD /* Bridging-Header.h */,\n\t\t\t\t4065D3611DD3B44200B73201 /* jirassic.sdef */,\n\t\t\t\t4051D5F71E0EA320002042BB /* Jirassic.entitlements */,\n\t\t\t\t280C1D411ED74EF900C126A1 /* BrowserSupport.scpt */,\n\t\t\t\t280C1D421ED74EF900C126A1 /* ShellSupport.scpt */,\n\t\t\t);\n\t\t\tname = Resources;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D2FB1DD3A1AA00B73201 = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t6D3702672BA84233002260D0 /* Jirassic macOS.entitlements */,\n\t\t\t\t4065D3161DD3B44200B73201 /* App */,\n\t\t\t\t4065D3401DD3B44200B73201 /* Delivery */,\n\t\t\t\t4065D3881DD3B44200B73201 /* External */,\n\t\t\t\t4065D3991DD3B44200B73201 /* Vendor */,\n\t\t\t\t4065D4031DD4532100B73201 /* JirassicTests */,\n\t\t\t\t4065D3051DD3A1AA00B73201 /* Products */,\n\t\t\t\t4055B1371E0D82A800279430 /* Frameworks */,\n\t\t\t);\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3051DD3A1AA00B73201 /* Products */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D3041DD3A1AA00B73201 /* Jirassic.app */,\n\t\t\t\t4065D4021DD4532100B73201 /* JirassicTests.xctest */,\n\t\t\t\t4065D4101DD4534C00B73201 /* jirassic */,\n\t\t\t\t4055B1231E0D802300279430 /* JirassicLauncher.app */,\n\t\t\t\t280D70B61ECFE06A005D2689 /* Jirassic iOS.app */,\n\t\t\t\t280D711D1ED5EE7F005D2689 /* Jirassic no cloud.app */,\n\t\t\t);\n\t\t\tname = Products;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3161DD3B44200B73201 /* App */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D3171DD3B44200B73201 /* Entities */,\n\t\t\t\t4065D31F1DD3B44200B73201 /* Extensions */,\n\t\t\t\t4065D3271DD3B44200B73201 /* Notifications */,\n\t\t\t\t4065D32A1DD3B44200B73201 /* Reports */,\n\t\t\t\t4065D32D1DD3B44200B73201 /* Tasks */,\n\t\t\t\t280300D41EDB5E6D000A763E /* Statistics */,\n\t\t\t\t4065D3371DD3B44200B73201 /* Time */,\n\t\t\t\t4065D33B1DD3B44200B73201 /* User */,\n\t\t\t\t28CBB59420455467006F9D3A /* Parsing */,\n\t\t\t);\n\t\t\tpath = App;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3171DD3B44200B73201 /* Entities */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D3181DD3B44200B73201 /* Day.swift */,\n\t\t\t\t4065D3191DD3B44200B73201 /* Report.swift */,\n\t\t\t\t4065D31A1DD3B44200B73201 /* Settings.swift */,\n\t\t\t\t4065D31B1DD3B44200B73201 /* Task.swift */,\n\t\t\t\t4065D31D1DD3B44200B73201 /* User.swift */,\n\t\t\t\t4065D31E1DD3B44200B73201 /* Week.swift */,\n\t\t\t\t28A2839920382BBB00DDCB63 /* GitCommit.swift */,\n\t\t\t\t56ADBF6921C3F625008350A6 /* GitUser.swift */,\n\t\t\t);\n\t\t\tpath = Entities;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D31F1DD3B44200B73201 /* Extensions */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D3201DD3B44200B73201 /* DateExtension.swift */,\n\t\t\t\t4065D3211DD3B44200B73201 /* DateExtensionTests.swift */,\n\t\t\t\t4065D3221DD3B44200B73201 /* StringIdGenerator.swift */,\n\t\t\t\t280F507C1EC868B0007416AB /* StringArray.swift */,\n\t\t\t\t4065D3231DD3B44200B73201 /* ViewAutolayout.swift */,\n\t\t\t\t4065D3241DD3B44200B73201 /* ViewController.swift */,\n\t\t\t\t4065D3251DD3B44200B73201 /* ViewControllerStoryboard.swift */,\n\t\t\t\t288BB6862087169F00CF720A /* ViewXib.swift */,\n\t\t\t\t2845B13E2068351F006EFB3B /* TableViewCell.swift */,\n\t\t\t\t4065D3261DD3B44200B73201 /* Conversions.swift */,\n\t\t\t);\n\t\t\tpath = Extensions;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3271DD3B44200B73201 /* Notifications */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D3291DD3B44200B73201 /* ComputerWakeUpInteractor.swift */,\n\t\t\t\t4073184E1DE9B1B40046F409 /* ComputerWakeUpInteractorTests.swift */,\n\t\t\t);\n\t\t\tpath = Notifications;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D32A1DD3B44200B73201 /* Reports */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D32B1DD3B44200B73201 /* CreateReport.swift */,\n\t\t\t\t4065D32C1DD3B44200B73201 /* CreateReportTests.swift */,\n\t\t\t\t6D5BC4C62C1B5B70002DA29B /* CreateDayReport.swift */,\n\t\t\t\t285465A1216C84E10052CB6A /* CreateMonthReport.swift */,\n\t\t\t\t56D069E0216CABCB000D051D /* CreateMonthReportTests.swift */,\n\t\t\t);\n\t\t\tpath = Reports;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D32D1DD3B44200B73201 /* Tasks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D32E1DD3B44200B73201 /* ReadDaysInteractor.swift */,\n\t\t\t\t280D71171ED4CFCB005D2689 /* ReadDaysInteractorTests.swift */,\n\t\t\t\t286BC00321909F85004D4CDD /* CloseDay.swift */,\n\t\t\t\t4065D32F1DD3B44200B73201 /* ReadTasksInteractor.swift */,\n\t\t\t\t4065D3301DD3B44200B73201 /* TaskFinder.swift */,\n\t\t\t\t4065D3311DD3B44200B73201 /* TaskFinderTests.swift */,\n\t\t\t\t4065D3321DD3B44200B73201 /* TaskInteractor.swift */,\n\t\t\t\t4065D3331DD3B44200B73201 /* TaskInteractorTests.swift */,\n\t\t\t\t4065D3341DD3B44200B73201 /* TaskTypeEstimator.swift */,\n\t\t\t\t4065D3351DD3B44200B73201 /* TaskTypeEstimatorTests.swift */,\n\t\t\t\t4065D3361DD3B44200B73201 /* TaskTypeSelection.swift */,\n\t\t\t\t28A283AF203CB1A100DDCB63 /* MergeTasksInteractor.swift */,\n\t\t\t\t28A283B2203CB1B900DDCB63 /* MergeTasksInteractorTests.swift */,\n\t\t\t\t28C6A38321D359E60036DB29 /* RemoveDuplicate.swift */,\n\t\t\t);\n\t\t\tpath = Tasks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3371DD3B44200B73201 /* Time */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D3391DD3B44200B73201 /* PredictiveTimeTyping.swift */,\n\t\t\t\t4065D33A1DD3B44200B73201 /* PredictiveTimeTypingTests.swift */,\n\t\t\t\t287195352027CAD9001C237E /* TimeInteractor.swift */,\n\t\t\t);\n\t\t\tpath = Time;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D33B1DD3B44200B73201 /* User */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D33C1DD3B44200B73201 /* RegisterUserInteractor.swift */,\n\t\t\t\t4065D33D1DD3B44200B73201 /* UserInteractor.swift */,\n\t\t\t\t4065D33E1DD3B44200B73201 /* UserInteractorTests.swift */,\n\t\t\t);\n\t\t\tpath = User;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3401DD3B44200B73201 /* Delivery */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D3411DD3B44200B73201 /* iOS */,\n\t\t\t\t4065D3501DD3B44200B73201 /* macOS */,\n\t\t\t\t4055B13A1E0E663800279430 /* macOS-launcher */,\n\t\t\t\t4065D3861DD3B44200B73201 /* macOS-cmd */,\n\t\t\t);\n\t\t\tpath = Delivery;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3411DD3B44200B73201 /* iOS */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D3421DD3B44200B73201 /* AppDelegate.swift */,\n\t\t\t\t4065D34B1DD3B44200B73201 /* LoginViewController.swift */,\n\t\t\t\t4065D3471DD3B44200B73201 /* DaysViewController.swift */,\n\t\t\t\t4065D34F1DD3B44200B73201 /* TasksViewController.swift */,\n\t\t\t\t4065D34E1DD3B44200B73201 /* TaskCell.swift */,\n\t\t\t\t4065D34D1DD3B44200B73201 /* NonTaskCell.swift */,\n\t\t\t\t4065D3491DD3B44200B73201 /* Images.xcassets */,\n\t\t\t\t280D70FD1ED20CBE005D2689 /* Info.plist */,\n\t\t\t\t280D70FF1ED21989005D2689 /* Jirassic Scrum.entitlements */,\n\t\t\t\t4065D3451DD3B44200B73201 /* Main.storyboard */,\n\t\t\t\t4065D3431DD3B44200B73201 /* LaunchScreen.xib */,\n\t\t\t);\n\t\t\tpath = iOS;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3501DD3B44200B73201 /* macOS */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t2812F61B2145031A008EE81E /* IAP */,\n\t\t\t\t4065D3531DD3B44200B73201 /* App */,\n\t\t\t\t4065D3641DD3B44200B73201 /* Menu */,\n\t\t\t\t4065D3511DD3B44200B73201 /* Animations */,\n\t\t\t\t4065D36B1DD3B44200B73201 /* Screens */,\n\t\t\t\t2801388D205F86250051B532 /* Components */,\n\t\t\t\t40FCE4211DF7646F00D4FD45 /* External */,\n\t\t\t\t28667B591FCADF4E007B98E3 /* Modules */,\n\t\t\t\t4065D3671DD3B44200B73201 /* Notifications */,\n\t\t\t\t405B15641DEF66EE0009871C /* Resources */,\n\t\t\t);\n\t\t\tpath = macOS;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3511DD3B44200B73201 /* Animations */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D3521DD3B44200B73201 /* FlipAnimation.swift */,\n\t\t\t\t40FCE42F1DFD7C8D00D4FD45 /* Animatable.swift */,\n\t\t\t);\n\t\t\tpath = Animations;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3531DD3B44200B73201 /* App */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D3591DD3B44200B73201 /* Main.storyboard */,\n\t\t\t\t4065D3541DD3B44200B73201 /* AppDelegate.swift */,\n\t\t\t\t4065D3551DD3B44200B73201 /* AppWireframe.swift */,\n\t\t\t\t405B15651DEF75660009871C /* AppViewController.swift */,\n\t\t\t\t4051D5F81E0EA48A002042BB /* AppLauncher.swift */,\n\t\t\t\t2823C9341E4F69970055D036 /* Versioning.swift */,\n\t\t\t\t280D70B01ECC09D9005D2689 /* AppTheme.swift */,\n\t\t\t\t2892E810208E6275004E5298 /* LocalPreferences.swift */,\n\t\t\t);\n\t\t\tpath = App;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3641DD3B44200B73201 /* Menu */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D3651DD3B44200B73201 /* MenuBarController.swift */,\n\t\t\t\t4065D3661DD3B44200B73201 /* MenuBarIconView.swift */,\n\t\t\t);\n\t\t\tpath = Menu;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3671DD3B44200B73201 /* Notifications */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D3681DD3B44200B73201 /* InternalNotifications.swift */,\n\t\t\t\t4065D3691DD3B44200B73201 /* UserNotifications.swift */,\n\t\t\t\t4065D36A1DD3B44200B73201 /* SleepNotifications.swift */,\n\t\t\t\t2803A0C91EC184FF005F9389 /* BrowserNotification.swift */,\n\t\t\t);\n\t\t\tpath = Notifications;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D36B1DD3B44200B73201 /* Screens */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t28279E9A1E8300E200EAF9FC /* Placeholder */,\n\t\t\t\t287B358520FBAD160022F43E /* Onboarding */,\n\t\t\t\t405B155F1DEF3CE20009871C /* TaskSuggestion */,\n\t\t\t\t5685C7621DE8721100CA545E /* Account */,\n\t\t\t\t4065D3721DD3B44200B73201 /* Settings */,\n\t\t\t\t564E55F12028839F00CE4C76 /* Worklogs */,\n\t\t\t\t2845B142206AE342006EFB3B /* Calendar */,\n\t\t\t\t4065D3761DD3B44200B73201 /* Tasks */,\n\t\t\t);\n\t\t\tpath = Screens;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3721DD3B44200B73201 /* Settings */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D3751DD3B44200B73201 /* SettingsViewController.swift */,\n\t\t\t\t4065D3741DD3B44200B73201 /* SettingsPresenter.swift */,\n\t\t\t\t4065D3731DD3B44200B73201 /* SettingsInteractor.swift */,\n\t\t\t\t28A283962037975600DDCB63 /* Saveable.swift */,\n\t\t\t\t40E092401DE385E4001EF5DA /* Settings.storyboard */,\n\t\t\t\t285465A5217858120052CB6A /* Store */,\n\t\t\t\t287195232022FEA4001C237E /* Tracking */,\n\t\t\t\t28FB264E20224DEB00AEA38D /* Output */,\n\t\t\t\t28FB264D20224DE200AEA38D /* Input */,\n\t\t\t);\n\t\t\tpath = Settings;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3761DD3B44200B73201 /* Tasks */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t406384881DE388C5004795A4 /* Tasks.storyboard */,\n\t\t\t\t4065D3851DD3B44200B73201 /* TasksViewController.swift */,\n\t\t\t\t4065D3831DD3B44200B73201 /* TasksPresenter.swift */,\n\t\t\t\t566B9FA6217DE67700EAF324 /* TasksInteractor.swift */,\n\t\t\t\t4065D3841DD3B44200B73201 /* TasksScrollView.swift */,\n\t\t\t\t28EDE9381E59EC1500B360A4 /* TasksView.swift */,\n\t\t\t\t28A5F2811E586426002BE564 /* DataSource.swift */,\n\t\t\t\t2845B16F206C2888006EFB3B /* AllTasks */,\n\t\t\t\t2845B141206AE2A4006EFB3B /* Reports */,\n\t\t\t\t2898D3A62181905600CF5AD4 /* MonthReports */,\n\t\t\t);\n\t\t\tpath = Tasks;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3861DD3B44200B73201 /* macOS-cmd */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D3871DD3B44200B73201 /* main.swift */,\n\t\t\t);\n\t\t\tpath = \"macOS-cmd\";\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3881DD3B44200B73201 /* External */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t28FE1885207A516300DF796E /* AppleScriptCommands */,\n\t\t\t\t2845B137206703A8006EFB3B /* Keychain */,\n\t\t\t\t2892B2961F0949D70085BAC2 /* Jira */,\n\t\t\t\t28577EA01E8ADBBD002B07FD /* sqlite */,\n\t\t\t\t4065D38B1DD3B44200B73201 /* CoreData */,\n\t\t\t\t4065D3921DD3B44200B73201 /* InMemoryStorage */,\n\t\t\t\t4065D3891DD3B44200B73201 /* CloudKit */,\n\t\t\t\t4065D3941DD3B44200B73201 /* Repository.swift */,\n\t\t\t\t4065D3951DD3B44200B73201 /* RepositoryInteractor.swift */,\n\t\t\t\t565E19EF20A5E336003A5E2A /* RCSync.swift */,\n\t\t\t);\n\t\t\tpath = External;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3891DD3B44200B73201 /* CloudKit */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D38A1DD3B44200B73201 /* CloudKitRepository.swift */,\n\t\t\t\t28A928921E91104B0022AB55 /* CloudKitRepository+Tasks.swift */,\n\t\t\t\t28A928961E9110BF0022AB55 /* CloudKitRepository+Settings.swift */,\n\t\t\t\t28A928941E9110980022AB55 /* CloudKitRepository+User.swift */,\n\t\t\t\t28AFE7301E9A594500BAAD8C /* UserDefaults+token.swift */,\n\t\t\t);\n\t\t\tpath = CloudKit;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D38B1DD3B44200B73201 /* CoreData */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D38C1DD3B44200B73201 /* CoreDataRepository.swift */,\n\t\t\t\t28A928891E910F4D0022AB55 /* CoreDataRepository+Tasks.swift */,\n\t\t\t\t28A9288C1E910F970022AB55 /* CoreDataRepository+Settings.swift */,\n\t\t\t\t28A9288F1E910FF60022AB55 /* CoreDataRepository+User.swift */,\n\t\t\t\t4065D38D1DD3B44200B73201 /* CSettings.swift */,\n\t\t\t\t4065D38E1DD3B44200B73201 /* CTask.swift */,\n\t\t\t\t4065D38F1DD3B44200B73201 /* CUser.swift */,\n\t\t\t\t2818847F21A4A2F800B33B9C /* Jirassic.xcdatamodeld */,\n\t\t\t);\n\t\t\tpath = CoreData;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3921DD3B44200B73201 /* InMemoryStorage */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D3931DD3B44200B73201 /* InMemoryCoreDataRepository.swift */,\n\t\t\t);\n\t\t\tpath = InMemoryStorage;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3991DD3B44200B73201 /* Vendor */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t);\n\t\t\tpath = Vendor;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D4031DD4532100B73201 /* JirassicTests */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D4061DD4532100B73201 /* Info.plist */,\n\t\t\t);\n\t\t\tpath = JirassicTests;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t40FCE4211DF7646F00D4FD45 /* External */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t40FCE4231DF7646F00D4FD45 /* ExtensionsInteractor.swift */,\n\t\t\t\t280F507A1EC8541D007416AB /* ExtensionsInstallerInteractor.swift */,\n\t\t\t\t2845B1342066C6E6006EFB3B /* AppleScriptProtocol.swift */,\n\t\t\t\t40FCE4221DF7646F00D4FD45 /* AppleScript.swift */,\n\t\t\t\t40FCE4241DF7646F00D4FD45 /* SandboxedAppleScript.swift */,\n\t\t\t);\n\t\t\tpath = External;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t564E55F12028839F00CE4C76 /* Worklogs */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t564E55F2202883DB00CE4C76 /* WorklogsViewController.swift */,\n\t\t\t\t564E55F5202884DE00CE4C76 /* WorklogsPresenter.swift */,\n\t\t\t\t564E55F82028857300CE4C76 /* Worklogs.storyboard */,\n\t\t\t);\n\t\t\tpath = Worklogs;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t5683DC3C20ECDEA30000A138 /* CalendarEvents */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t5683DC3D20ECDED30000A138 /* ModuleCalendar.swift */,\n\t\t\t);\n\t\t\tpath = CalendarEvents;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t5685C7621DE8721100CA545E /* Account */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t5685C76B1DE8724400CA545E /* AccountViewController.swift */,\n\t\t\t\t5685C7631DE8721100CA545E /* CloudKitLoginViewController.swift */,\n\t\t\t\t5685C7641DE8721100CA545E /* Login.storyboard */,\n\t\t\t\t5685C7651DE8721100CA545E /* LoginPresenter.swift */,\n\t\t\t\t5685C7661DE8721100CA545E /* LoginViewController.swift */,\n\t\t\t);\n\t\t\tpath = Account;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t569C4C53202318F50049FBF1 /* Shell */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t569C4C572023193B0049FBF1 /* ShellCell.swift */,\n\t\t\t\t569C4C6F202319DE0049FBF1 /* ShellCell.xib */,\n\t\t\t);\n\t\t\tpath = Shell;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t569C4C54202319010049FBF1 /* Browser */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t569C4C69202319A20049FBF1 /* BrowserCell.swift */,\n\t\t\t\t569C4C6C202319CA0049FBF1 /* BrowserPresenter.swift */,\n\t\t\t\t569C4C7820231A0B0049FBF1 /* BrowserCell.xib */,\n\t\t\t);\n\t\t\tpath = Browser;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t569C4C552023190A0049FBF1 /* Git */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t569C4C63202319870049FBF1 /* GitCell.swift */,\n\t\t\t\t569C4C66202319930049FBF1 /* GitPresenter.swift */,\n\t\t\t\t569C4C75202319FC0049FBF1 /* GitCell.xib */,\n\t\t\t);\n\t\t\tpath = Git;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t569C4C56202319120049FBF1 /* Jit */ = {\n\t\t\tisa = PBXGroup;\n\t\t\tchildren = (\n\t\t\t\t569C4C5D202319630049FBF1 /* JitCell.swift */,\n\t\t\t\t569C4C72202319EE0049FBF1 /* JitCell.xib */,\n\t\t\t);\n\t\t\tpath = Jit;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXGroup section */\n\n/* Begin PBXNativeTarget section */\n\t\t280D70B51ECFE06A005D2689 /* Jirassic iOS */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 280D70C51ECFE06A005D2689 /* Build configuration list for PBXNativeTarget \"Jirassic iOS\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t280D70B21ECFE06A005D2689 /* Sources */,\n\t\t\t\t280D70B31ECFE06A005D2689 /* Frameworks */,\n\t\t\t\t280D70B41ECFE06A005D2689 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"Jirassic iOS\";\n\t\t\tproductName = \"Jirassic iOS\";\n\t\t\tproductReference = 280D70B61ECFE06A005D2689 /* Jirassic iOS.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n\t\t280D711C1ED5EE7F005D2689 /* Jirassic macOS */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 280D71291ED5EE7F005D2689 /* Build configuration list for PBXNativeTarget \"Jirassic macOS\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t280D71191ED5EE7F005D2689 /* Sources */,\n\t\t\t\t280D711A1ED5EE7F005D2689 /* Frameworks */,\n\t\t\t\t280D711B1ED5EE7F005D2689 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"Jirassic macOS\";\n\t\t\tpackageProductDependencies = (\n\t\t\t);\n\t\t\tproductName = \"Jirassic no cloud\";\n\t\t\tproductReference = 280D711D1ED5EE7F005D2689 /* Jirassic no cloud.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n\t\t4055B1221E0D802300279430 /* JirassicLauncher */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 4055B1311E0D802300279430 /* Build configuration list for PBXNativeTarget \"JirassicLauncher\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t4055B11F1E0D802300279430 /* Sources */,\n\t\t\t\t4055B1201E0D802300279430 /* Frameworks */,\n\t\t\t\t4055B1211E0D802300279430 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = JirassicLauncher;\n\t\t\tproductName = JirassicLauncher;\n\t\t\tproductReference = 4055B1231E0D802300279430 /* JirassicLauncher.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n\t\t4065D3031DD3A1AA00B73201 /* Jirassic AppStore */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 4065D3131DD3A1AA00B73201 /* Build configuration list for PBXNativeTarget \"Jirassic AppStore\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t4065D3001DD3A1AA00B73201 /* Sources */,\n\t\t\t\t4065D3011DD3A1AA00B73201 /* Frameworks */,\n\t\t\t\t4065D3021DD3A1AA00B73201 /* Resources */,\n\t\t\t\t4055B1351E0D81E600279430 /* CopyFiles */,\n\t\t\t\t28577E941E89972F002B07FD /* CopyFiles */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"Jirassic AppStore\";\n\t\t\tpackageProductDependencies = (\n\t\t\t\t6D37025F2BA83E9A002260D0 /* SwiftKeychainWrapper */,\n\t\t\t\t6D3702612BA83EB9002260D0 /* RCLog */,\n\t\t\t\t6D3702632BA83EBF002260D0 /* RCPreferences */,\n\t\t\t\t6D3702652BA83EC7002260D0 /* RCHttp */,\n\t\t\t);\n\t\t\tproductName = Jirassic;\n\t\t\tproductReference = 4065D3041DD3A1AA00B73201 /* Jirassic.app */;\n\t\t\tproductType = \"com.apple.product-type.application\";\n\t\t};\n\t\t4065D4011DD4532100B73201 /* JirassicTests */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 4065D4091DD4532100B73201 /* Build configuration list for PBXNativeTarget \"JirassicTests\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t4065D3FE1DD4532100B73201 /* Sources */,\n\t\t\t\t4065D3FF1DD4532100B73201 /* Frameworks */,\n\t\t\t\t4065D4001DD4532100B73201 /* Resources */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t\t4065D4081DD4532100B73201 /* PBXTargetDependency */,\n\t\t\t\t566C09151F2B985C0058D90A /* PBXTargetDependency */,\n\t\t\t);\n\t\t\tname = JirassicTests;\n\t\t\tproductName = JirassicTests;\n\t\t\tproductReference = 4065D4021DD4532100B73201 /* JirassicTests.xctest */;\n\t\t\tproductType = \"com.apple.product-type.bundle.unit-test\";\n\t\t};\n\t\t4065D40F1DD4534C00B73201 /* jirassic-cmd */ = {\n\t\t\tisa = PBXNativeTarget;\n\t\t\tbuildConfigurationList = 4065D4141DD4534C00B73201 /* Build configuration list for PBXNativeTarget \"jirassic-cmd\" */;\n\t\t\tbuildPhases = (\n\t\t\t\t4065D40C1DD4534C00B73201 /* Sources */,\n\t\t\t\t4065D40D1DD4534C00B73201 /* Frameworks */,\n\t\t\t\t4065D40E1DD4534C00B73201 /* CopyFiles */,\n\t\t\t\t28577E9B1E89A969002B07FD /* CopyFiles */,\n\t\t\t);\n\t\t\tbuildRules = (\n\t\t\t);\n\t\t\tdependencies = (\n\t\t\t);\n\t\t\tname = \"jirassic-cmd\";\n\t\t\tproductName = \"jirassic-cmd\";\n\t\t\tproductReference = 4065D4101DD4534C00B73201 /* jirassic */;\n\t\t\tproductType = \"com.apple.product-type.tool\";\n\t\t};\n/* End PBXNativeTarget section */\n\n/* Begin PBXProject section */\n\t\t4065D2FC1DD3A1AA00B73201 /* Project object */ = {\n\t\t\tisa = PBXProject;\n\t\t\tattributes = {\n\t\t\t\tBuildIndependentTargetsInParallel = YES;\n\t\t\t\tLastSwiftUpdateCheck = 0830;\n\t\t\t\tLastUpgradeCheck = 1530;\n\t\t\t\tORGANIZATIONNAME = \"Imagin soft\";\n\t\t\t\tTargetAttributes = {\n\t\t\t\t\t280D70B51ECFE06A005D2689 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 8.3.2;\n\t\t\t\t\t\tDevelopmentTeam = 5NHDC5EV44;\n\t\t\t\t\t\tLastSwiftMigration = 0920;\n\t\t\t\t\t\tProvisioningStyle = Automatic;\n\t\t\t\t\t\tSystemCapabilities = {\n\t\t\t\t\t\t\tcom.apple.Push = {\n\t\t\t\t\t\t\t\tenabled = 0;\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tcom.apple.iCloud = {\n\t\t\t\t\t\t\t\tenabled = 1;\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t};\n\t\t\t\t\t};\n\t\t\t\t\t280D711C1ED5EE7F005D2689 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 8.3.2;\n\t\t\t\t\t\tDevelopmentTeam = 5NHDC5EV44;\n\t\t\t\t\t\tLastSwiftMigration = \"\";\n\t\t\t\t\t\tProvisioningStyle = Manual;\n\t\t\t\t\t\tSystemCapabilities = {\n\t\t\t\t\t\t\tcom.apple.Sandbox = {\n\t\t\t\t\t\t\t\tenabled = 0;\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t};\n\t\t\t\t\t};\n\t\t\t\t\t4055B1221E0D802300279430 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 8.2.1;\n\t\t\t\t\t\tLastSwiftMigration = 0820;\n\t\t\t\t\t\tSystemCapabilities = {\n\t\t\t\t\t\t\tcom.apple.Sandbox = {\n\t\t\t\t\t\t\t\tenabled = 1;\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t};\n\t\t\t\t\t};\n\t\t\t\t\t4065D3031DD3A1AA00B73201 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 8.1;\n\t\t\t\t\t\tLastSwiftMigration = \"\";\n\t\t\t\t\t\tSystemCapabilities = {\n\t\t\t\t\t\t\tcom.apple.Push = {\n\t\t\t\t\t\t\t\tenabled = 0;\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tcom.apple.Sandbox = {\n\t\t\t\t\t\t\t\tenabled = 1;\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\tcom.apple.iCloud = {\n\t\t\t\t\t\t\t\tenabled = 1;\n\t\t\t\t\t\t\t};\n\t\t\t\t\t\t};\n\t\t\t\t\t};\n\t\t\t\t\t4065D4011DD4532100B73201 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 8.1;\n\t\t\t\t\t\tDevelopmentTeam = 5NHDC5EV44;\n\t\t\t\t\t\tLastSwiftMigration = \"\";\n\t\t\t\t\t\tProvisioningStyle = Manual;\n\t\t\t\t\t\tTestTargetID = 280D711C1ED5EE7F005D2689;\n\t\t\t\t\t};\n\t\t\t\t\t4065D40F1DD4534C00B73201 = {\n\t\t\t\t\t\tCreatedOnToolsVersion = 8.1;\n\t\t\t\t\t\tDevelopmentTeam = 5NHDC5EV44;\n\t\t\t\t\t\tLastSwiftMigration = 1000;\n\t\t\t\t\t\tProvisioningStyle = Automatic;\n\t\t\t\t\t};\n\t\t\t\t};\n\t\t\t};\n\t\t\tbuildConfigurationList = 4065D2FF1DD3A1AA00B73201 /* Build configuration list for PBXProject \"Jirassic\" */;\n\t\t\tcompatibilityVersion = \"Xcode 3.2\";\n\t\t\tdevelopmentRegion = English;\n\t\t\thasScannedForEncodings = 0;\n\t\t\tknownRegions = (\n\t\t\t\tEnglish,\n\t\t\t\ten,\n\t\t\t\tBase,\n\t\t\t);\n\t\t\tmainGroup = 4065D2FB1DD3A1AA00B73201;\n\t\t\tpackageReferences = (\n\t\t\t\t6D37025B2BA83DB0002260D0 /* XCRemoteSwiftPackageReference \"RCLog\" */,\n\t\t\t\t6D37025C2BA83DDB002260D0 /* XCRemoteSwiftPackageReference \"RCpreferences\" */,\n\t\t\t\t6D37025D2BA83DFE002260D0 /* XCRemoteSwiftPackageReference \"RChttp\" */,\n\t\t\t\t6D37025E2BA83E9A002260D0 /* XCRemoteSwiftPackageReference \"SwiftKeychainWrapper\" */,\n\t\t\t);\n\t\t\tproductRefGroup = 4065D3051DD3A1AA00B73201 /* Products */;\n\t\t\tprojectDirPath = \"\";\n\t\t\tprojectRoot = \"\";\n\t\t\ttargets = (\n\t\t\t\t280D711C1ED5EE7F005D2689 /* Jirassic macOS */,\n\t\t\t\t4065D3031DD3A1AA00B73201 /* Jirassic AppStore */,\n\t\t\t\t4065D4011DD4532100B73201 /* JirassicTests */,\n\t\t\t\t4055B1221E0D802300279430 /* JirassicLauncher */,\n\t\t\t\t280D70B51ECFE06A005D2689 /* Jirassic iOS */,\n\t\t\t\t4065D40F1DD4534C00B73201 /* jirassic-cmd */,\n\t\t\t);\n\t\t};\n/* End PBXProject section */\n\n/* Begin PBXResourcesBuildPhase section */\n\t\t280D70B41ECFE06A005D2689 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t280D70C91ECFE5B1005D2689 /* LaunchScreen.xib in Resources */,\n\t\t\t\t280D70CD1ECFE5DC005D2689 /* Images.xcassets in Resources */,\n\t\t\t\t280D70CA1ECFE5BD005D2689 /* Main.storyboard in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t280D711B1ED5EE7F005D2689 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2892E80E208D9DD0004E5298 /* OutputsScrollView.xib in Resources */,\n\t\t\t\t569C4C7920231A0B0049FBF1 /* BrowserCell.xib in Resources */,\n\t\t\t\t569C4C70202319DE0049FBF1 /* ShellCell.xib in Resources */,\n\t\t\t\t28A283A82038AFC500DDCB63 /* JirassicCell.xib in Resources */,\n\t\t\t\t288BB6812087152B00CF720A /* WizardAppleScriptView.xib in Resources */,\n\t\t\t\t280D71C91ED60908005D2689 /* jirassic.sdef in Resources */,\n\t\t\t\t2892E80B208D9B42004E5298 /* InputsScrollView.xib in Resources */,\n\t\t\t\t28EE1F6120EE8D6100C5C1D6 /* CalendarCell.xib in Resources */,\n\t\t\t\t280D71BF1ED608D6005D2689 /* Main.storyboard in Resources */,\n\t\t\t\t2898D3AE2184ED3000CF5AD4 /* Components.storyboard in Resources */,\n\t\t\t\t280D71C01ED608D6005D2689 /* Placeholder.storyboard in Resources */,\n\t\t\t\t280C1D441ED74EF900C126A1 /* ShellSupport.scpt in Resources */,\n\t\t\t\t28FB265820224E9B00AEA38D /* HookupCell.xib in Resources */,\n\t\t\t\t28B116BB21AE6179004ACE01 /* MonthReportsHeaderView.xib in Resources */,\n\t\t\t\t287B358A20FBAFD60022F43E /* WizardCalendarView.xib in Resources */,\n\t\t\t\t280D71C11ED608D6005D2689 /* Welcome.storyboard in Resources */,\n\t\t\t\t280D71C21ED608D6005D2689 /* Login.storyboard in Resources */,\n\t\t\t\t56D90CFE20876F3C00F24442 /* WizardGitView.xib in Resources */,\n\t\t\t\t280D71C31ED608D6005D2689 /* Settings.storyboard in Resources */,\n\t\t\t\t280D71C41ED608D6005D2689 /* Tasks.storyboard in Resources */,\n\t\t\t\t564E55F92028857300CE4C76 /* Worklogs.storyboard in Resources */,\n\t\t\t\t2845B162206AE468006EFB3B /* TaskCell.xib in Resources */,\n\t\t\t\t56D90D0120876F4900F24442 /* WizardJiraView.xib in Resources */,\n\t\t\t\t280C1D431ED74EF900C126A1 /* BrowserSupport.scpt in Resources */,\n\t\t\t\t28B116B821AE5C45004ACE01 /* ReportsHeaderView.xib in Resources */,\n\t\t\t\t2871952820241A6C001C237E /* TrackingView.xib in Resources */,\n\t\t\t\t28FB265420224E5B00AEA38D /* JiraTempoCell.xib in Resources */,\n\t\t\t\t2845B14B206AE3A8006EFB3B /* ReportCell.xib in Resources */,\n\t\t\t\t28FE18A8207B36CB00DF796E /* CocoaHookupCell.xib in Resources */,\n\t\t\t\t569C4C76202319FC0049FBF1 /* GitCell.xib in Resources */,\n\t\t\t\t2845B168206AE468006EFB3B /* TasksHeaderView.xib in Resources */,\n\t\t\t\t280D71C81ED608D6005D2689 /* Images.xcassets in Resources */,\n\t\t\t\t285465AD217858AF0052CB6A /* StoreView.xib in Resources */,\n\t\t\t\t2845B16C206AE468006EFB3B /* NonTaskCell.xib in Resources */,\n\t\t\t\t569C4C73202319EE0049FBF1 /* JitCell.xib in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t4055B1211E0D802300279430 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t28E896751E83770D00722032 /* MainMenu.xib in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t4065D3021DD3A1AA00B73201 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2898D3AF2184ED3000CF5AD4 /* Components.storyboard in Resources */,\n\t\t\t\t569C4C7A20231A0B0049FBF1 /* BrowserCell.xib in Resources */,\n\t\t\t\t288BB6822087152B00CF720A /* WizardAppleScriptView.xib in Resources */,\n\t\t\t\t569C4C74202319EE0049FBF1 /* JitCell.xib in Resources */,\n\t\t\t\t2845B16D206AE468006EFB3B /* NonTaskCell.xib in Resources */,\n\t\t\t\t2871952920241A6C001C237E /* TrackingView.xib in Resources */,\n\t\t\t\t2892E80F208D9DD0004E5298 /* OutputsScrollView.xib in Resources */,\n\t\t\t\t285465AE217858AF0052CB6A /* StoreView.xib in Resources */,\n\t\t\t\t28FB265920224E9B00AEA38D /* HookupCell.xib in Resources */,\n\t\t\t\t40FCE42E1DFC576C00D4FD45 /* Welcome.storyboard in Resources */,\n\t\t\t\t5685C7681DE8721100CA545E /* Login.storyboard in Resources */,\n\t\t\t\t569C4C71202319DE0049FBF1 /* ShellCell.xib in Resources */,\n\t\t\t\t28B116B921AE5C45004ACE01 /* ReportsHeaderView.xib in Resources */,\n\t\t\t\t2892E80C208D9B42004E5298 /* InputsScrollView.xib in Resources */,\n\t\t\t\t287B358B20FBAFD60022F43E /* WizardCalendarView.xib in Resources */,\n\t\t\t\t4065D3CF1DD3B44200B73201 /* Images.xcassets in Resources */,\n\t\t\t\t56CD22BF1E72F89700F9CDB8 /* BuildScript.sh in Resources */,\n\t\t\t\t28FB265520224E5B00AEA38D /* JiraTempoCell.xib in Resources */,\n\t\t\t\t2845B14C206AE3A8006EFB3B /* ReportCell.xib in Resources */,\n\t\t\t\t406384891DE388C5004795A4 /* Tasks.storyboard in Resources */,\n\t\t\t\t28FE18A9207B36CB00DF796E /* CocoaHookupCell.xib in Resources */,\n\t\t\t\t569C4C77202319FC0049FBF1 /* GitCell.xib in Resources */,\n\t\t\t\t28E896631E830D6700722032 /* Placeholder.storyboard in Resources */,\n\t\t\t\t56D90D0220876F4900F24442 /* WizardJiraView.xib in Resources */,\n\t\t\t\t4065D3CE1DD3B44200B73201 /* Main.storyboard in Resources */,\n\t\t\t\t2845B163206AE468006EFB3B /* TaskCell.xib in Resources */,\n\t\t\t\t4065D3D31DD3B44200B73201 /* jirassic.sdef in Resources */,\n\t\t\t\t40E092411DE385E4001EF5DA /* Settings.storyboard in Resources */,\n\t\t\t\t28B116BC21AE6179004ACE01 /* MonthReportsHeaderView.xib in Resources */,\n\t\t\t\t56D90CFF20876F3C00F24442 /* WizardGitView.xib in Resources */,\n\t\t\t\t564E55FA2028857300CE4C76 /* Worklogs.storyboard in Resources */,\n\t\t\t\t2845B169206AE468006EFB3B /* TasksHeaderView.xib in Resources */,\n\t\t\t\t28A283A92038AFC500DDCB63 /* JirassicCell.xib in Resources */,\n\t\t\t\t28EE1F6220EE8D6100C5C1D6 /* CalendarCell.xib in Resources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t4065D4001DD4532100B73201 /* Resources */ = {\n\t\t\tisa = PBXResourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXResourcesBuildPhase section */\n\n/* Begin PBXSourcesBuildPhase section */\n\t\t280D70B21ECFE06A005D2689 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t280D70E51ECFE88F005D2689 /* CUser.swift in Sources */,\n\t\t\t\t280D70F51ECFE98C005D2689 /* UserDefaults+uploadToken.swift in Sources */,\n\t\t\t\t280D70E91ECFE8B9005D2689 /* CloudKitRepository+Settings.swift in Sources */,\n\t\t\t\t280D70D21ECFE7ED005D2689 /* Day.swift in Sources */,\n\t\t\t\t280D70DA1ECFE83F005D2689 /* CreateReport.swift in Sources */,\n\t\t\t\t280D70D71ECFE817005D2689 /* DateExtension.swift in Sources */,\n\t\t\t\t280D70F01ECFE8CC005D2689 /* Repository.swift in Sources */,\n\t\t\t\t280D70F61ECFE9B3005D2689 /* RegisterUserInteractor.swift in Sources */,\n\t\t\t\t280D70DE1ECFE870005D2689 /* UserInteractor.swift in Sources */,\n\t\t\t\t280D70E11ECFE88F005D2689 /* CoreDataRepository+Settings.swift in Sources */,\n\t\t\t\t280D70C81ECFE5AC005D2689 /* AppDelegate.swift in Sources */,\n\t\t\t\t280D70E21ECFE88F005D2689 /* CoreDataRepository+User.swift in Sources */,\n\t\t\t\t280D70EA1ECFE8B9005D2689 /* CloudKitRepository+User.swift in Sources */,\n\t\t\t\t280D70CB1ECFE5D0005D2689 /* DaysViewController.swift in Sources */,\n\t\t\t\t280D70D31ECFE7FB005D2689 /* Report.swift in Sources */,\n\t\t\t\t280D70CF1ECFE5E7005D2689 /* NonTaskCell.swift in Sources */,\n\t\t\t\t280D70CE1ECFE5E3005D2689 /* LoginViewController.swift in Sources */,\n\t\t\t\t2818848221A4A2F800B33B9C /* Jirassic.xcdatamodeld in Sources */,\n\t\t\t\t280D70DF1ECFE888005D2689 /* CoreDataRepository.swift in Sources */,\n\t\t\t\t280D70F41ECFE96F005D2689 /* Settings.swift in Sources */,\n\t\t\t\t280D70E81ECFE8B9005D2689 /* CloudKitRepository+Tasks.swift in Sources */,\n\t\t\t\t280D70E71ECFE8B9005D2689 /* CloudKitRepository.swift in Sources */,\n\t\t\t\t280D70E01ECFE88F005D2689 /* CoreDataRepository+Tasks.swift in Sources */,\n\t\t\t\t280D70E31ECFE88F005D2689 /* CSettings.swift in Sources */,\n\t\t\t\t280D70DC1ECFE84C005D2689 /* ReadTasksInteractor.swift in Sources */,\n\t\t\t\t280D70EB1ECFE8B9005D2689 /* UserDefaults+token.swift in Sources */,\n\t\t\t\t280D70F11ECFE8D0005D2689 /* RepositoryInteractor.swift in Sources */,\n\t\t\t\t280D70D01ECFE5EA005D2689 /* TaskCell.swift in Sources */,\n\t\t\t\t280D70D81ECFE82E005D2689 /* ViewAutolayout.swift in Sources */,\n\t\t\t\t280300D81EDB5ECA000A763E /* StatisticsInteractor.swift in Sources */,\n\t\t\t\t280D70D91ECFE835005D2689 /* Conversions.swift in Sources */,\n\t\t\t\t565E19F220A5E336003A5E2A /* RCSync.swift in Sources */,\n\t\t\t\t280D70DB1ECFE847005D2689 /* ReadDaysInteractor.swift in Sources */,\n\t\t\t\t28CBB598204554A2006F9D3A /* ParseGitBranch.swift in Sources */,\n\t\t\t\t280D70E41ECFE88F005D2689 /* CTask.swift in Sources */,\n\t\t\t\t280D70D41ECFE7FF005D2689 /* Task.swift in Sources */,\n\t\t\t\t280D70D51ECFE803005D2689 /* User.swift in Sources */,\n\t\t\t\t280D70D11ECFE5EE005D2689 /* TasksViewController.swift in Sources */,\n\t\t\t\t280D70F71ED0E6EC005D2689 /* StringIdGenerator.swift in Sources */,\n\t\t\t\t280D70D61ECFE807005D2689 /* Week.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t280D71191ED5EE7F005D2689 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t280D712C1ED6043D005D2689 /* Day.swift in Sources */,\n\t\t\t\t2892B29B1F094A760085BAC2 /* JiraRepository+Reports.swift in Sources */,\n\t\t\t\t280D712D1ED6043D005D2689 /* Report.swift in Sources */,\n\t\t\t\t28EE1F6420EE92DA00C5C1D6 /* CalendarPresenter.swift in Sources */,\n\t\t\t\t280D712E1ED6043D005D2689 /* Settings.swift in Sources */,\n\t\t\t\t2898D3AB2184D1DB00CF5AD4 /* TimeBoxViewController.swift in Sources */,\n\t\t\t\t280D712F1ED6043D005D2689 /* Task.swift in Sources */,\n\t\t\t\t287195312025C360001C237E /* CSettings.swift in Sources */,\n\t\t\t\t56ADBF6A21C3F625008350A6 /* GitUser.swift in Sources */,\n\t\t\t\t287195302025C35C001C237E /* CoreDataRepository+User.swift in Sources */,\n\t\t\t\t280D71311ED6043D005D2689 /* User.swift in Sources */,\n\t\t\t\t280D71321ED6043D005D2689 /* Week.swift in Sources */,\n\t\t\t\t566B9FA7217DE67800EAF324 /* TasksInteractor.swift in Sources */,\n\t\t\t\t288BB67E2085252900CF720A /* WizardViewController.swift in Sources */,\n\t\t\t\t28FB265E2022DC2B00AEA38D /* JiraTempoPresenter.swift in Sources */,\n\t\t\t\t280D71331ED6043D005D2689 /* DateExtension.swift in Sources */,\n\t\t\t\t56ADBF6D21C3F94D008350A6 /* GitUserParser.swift in Sources */,\n\t\t\t\t280D71351ED6043D005D2689 /* StringIdGenerator.swift in Sources */,\n\t\t\t\t280D71361ED6043D005D2689 /* StringArray.swift in Sources */,\n\t\t\t\t287195362027CAD9001C237E /* TimeInteractor.swift in Sources */,\n\t\t\t\t280D71371ED6043D005D2689 /* ViewAutolayout.swift in Sources */,\n\t\t\t\t285465A7217858790052CB6A /* StoreView.swift in Sources */,\n\t\t\t\t280D71381ED6043D005D2689 /* ViewController.swift in Sources */,\n\t\t\t\t2871951E2022FD14001C237E /* InputsScrollView.swift in Sources */,\n\t\t\t\t28FE18A5207B369800DF796E /* CocoaHookupCell.swift in Sources */,\n\t\t\t\t280D71391ED6043D005D2689 /* ViewControllerStoryboard.swift in Sources */,\n\t\t\t\t2871952B20241B25001C237E /* TrackingView.swift in Sources */,\n\t\t\t\t286BC00421909F85004D4CDD /* CloseDay.swift in Sources */,\n\t\t\t\t284192DD2018A8B200E64A9A /* ModuleJiraTempo.swift in Sources */,\n\t\t\t\t28667B5D1FCB7017007B98E3 /* ModuleHookup.swift in Sources */,\n\t\t\t\t2812F61E2145031B008EE81E /* IAPHelper.swift in Sources */,\n\t\t\t\t280D713A1ED6043D005D2689 /* Conversions.swift in Sources */,\n\t\t\t\t280D713B1ED6043D005D2689 /* ComputerWakeUpInteractor.swift in Sources */,\n\t\t\t\t280D713D1ED6043D005D2689 /* CreateReport.swift in Sources */,\n\t\t\t\t280D713F1ED6043D005D2689 /* ReadDaysInteractor.swift in Sources */,\n\t\t\t\t280D71411ED6043D005D2689 /* ReadTasksInteractor.swift in Sources */,\n\t\t\t\t280D71431ED6043D005D2689 /* TaskFinder.swift in Sources */,\n\t\t\t\t280D71451ED6043D005D2689 /* TaskInteractor.swift in Sources */,\n\t\t\t\t285465A2216C84E10052CB6A /* CreateMonthReport.swift in Sources */,\n\t\t\t\t56D90CF820876F1100F24442 /* WizardJiraView.swift in Sources */,\n\t\t\t\t2801388F205F86460051B532 /* TimeBox.swift in Sources */,\n\t\t\t\t280D71471ED6043D005D2689 /* TaskTypeEstimator.swift in Sources */,\n\t\t\t\t280D71491ED6043D005D2689 /* TaskTypeSelection.swift in Sources */,\n\t\t\t\t2845B160206AE468006EFB3B /* TaskCell.swift in Sources */,\n\t\t\t\t28FE18AB207B375A00DF796E /* CocoaHookupPresenter.swift in Sources */,\n\t\t\t\t280D714A1ED6043D005D2689 /* PredictiveTimeTyping.swift in Sources */,\n\t\t\t\t280D714C1ED6043D005D2689 /* RegisterUserInteractor.swift in Sources */,\n\t\t\t\t280D714D1ED6043D005D2689 /* UserInteractor.swift in Sources */,\n\t\t\t\t28FB265120224E3A00AEA38D /* JiraTempoCell.swift in Sources */,\n\t\t\t\t280D71591ED6043D005D2689 /* AppDelegate.swift in Sources */,\n\t\t\t\t280D715A1ED6043D005D2689 /* AppWireframe.swift in Sources */,\n\t\t\t\t280D715B1ED6043D005D2689 /* AppViewController.swift in Sources */,\n\t\t\t\t28279AD521C6245700376304 /* GitUsersViewController.swift in Sources */,\n\t\t\t\t287195322025C364001C237E /* CTask.swift in Sources */,\n\t\t\t\t5683DC3E20ECDED30000A138 /* ModuleCalendar.swift in Sources */,\n\t\t\t\t2892E811208E6275004E5298 /* LocalPreferences.swift in Sources */,\n\t\t\t\t280D715D1ED6043D005D2689 /* AppLauncher.swift in Sources */,\n\t\t\t\t280D715E1ED6043D005D2689 /* Versioning.swift in Sources */,\n\t\t\t\t2845B14D206AE3A8006EFB3B /* ReportCellPresenter.swift in Sources */,\n\t\t\t\t2845B164206AE468006EFB3B /* TaskCellPresenter.swift in Sources */,\n\t\t\t\t280D715F1ED6043D005D2689 /* AppTheme.swift in Sources */,\n\t\t\t\t28CBB596204554A2006F9D3A /* ParseGitBranch.swift in Sources */,\n\t\t\t\t280D71601ED6043D005D2689 /* MenuBarController.swift in Sources */,\n\t\t\t\t280D71611ED6043D005D2689 /* MenuBarIconView.swift in Sources */,\n\t\t\t\t569C4C67202319930049FBF1 /* GitPresenter.swift in Sources */,\n\t\t\t\t2871951B2022ECF7001C237E /* OutputsScrollView.swift in Sources */,\n\t\t\t\t280D71621ED6043D005D2689 /* FlipAnimation.swift in Sources */,\n\t\t\t\t280D71631ED6043D005D2689 /* Animatable.swift in Sources */,\n\t\t\t\t564E55F3202883DB00CE4C76 /* WorklogsViewController.swift in Sources */,\n\t\t\t\t280D71641ED6043D005D2689 /* PlaceholderViewController.swift in Sources */,\n\t\t\t\t28FE1887207A520B00DF796E /* NewTaskCommand.swift in Sources */,\n\t\t\t\t280D71661ED6043D005D2689 /* WelcomeViewController.swift in Sources */,\n\t\t\t\t280D71681ED6043D005D2689 /* TaskSuggestionViewController.swift in Sources */,\n\t\t\t\t280D71691ED6043D005D2689 /* TaskSuggestionPresenter.swift in Sources */,\n\t\t\t\t2871952E2025C356001C237E /* CoreDataRepository+Tasks.swift in Sources */,\n\t\t\t\t28A283B0203CB1A100DDCB63 /* MergeTasksInteractor.swift in Sources */,\n\t\t\t\t2812F6202145031B008EE81E /* Store.swift in Sources */,\n\t\t\t\t280D716B1ED6043D005D2689 /* AccountViewController.swift in Sources */,\n\t\t\t\t56D90CFB20876F2B00F24442 /* WizardGitView.swift in Sources */,\n\t\t\t\t280D716C1ED6043D005D2689 /* CloudKitLoginViewController.swift in Sources */,\n\t\t\t\t2871952D2025C353001C237E /* CoreDataRepository.swift in Sources */,\n\t\t\t\t280D716E1ED6043D005D2689 /* LoginPresenter.swift in Sources */,\n\t\t\t\t28FB265B20224EA700AEA38D /* HookupCell.swift in Sources */,\n\t\t\t\t287195332025C367001C237E /* CUser.swift in Sources */,\n\t\t\t\t280D716F1ED6043D005D2689 /* LoginViewController.swift in Sources */,\n\t\t\t\t2898D3B12185959300CF5AD4 /* EditableTimeBox.swift in Sources */,\n\t\t\t\t2845B149206AE3A8006EFB3B /* ReportCell.swift in Sources */,\n\t\t\t\t2892B29E1F094B0D0085BAC2 /* JReport.swift in Sources */,\n\t\t\t\t280D71701ED6043D005D2689 /* ExtensionsInteractor.swift in Sources */,\n\t\t\t\t2845B13F2068351F006EFB3B /* TableViewCell.swift in Sources */,\n\t\t\t\t288BB6872087169F00CF720A /* ViewXib.swift in Sources */,\n\t\t\t\t28A283972037975600DDCB63 /* Saveable.swift in Sources */,\n\t\t\t\t280D71711ED6043D005D2689 /* ExtensionsInstallerInteractor.swift in Sources */,\n\t\t\t\t280D71721ED6043D005D2689 /* AppleScript.swift in Sources */,\n\t\t\t\t28A283A52038AFB100DDCB63 /* JirassicCell.swift in Sources */,\n\t\t\t\t280D71731ED6043D005D2689 /* SandboxedAppleScript.swift in Sources */,\n\t\t\t\t280D71741ED6043D005D2689 /* SettingsViewController.swift in Sources */,\n\t\t\t\t280D71751ED6043D005D2689 /* SettingsPresenter.swift in Sources */,\n\t\t\t\t280D71761ED6043D005D2689 /* SettingsInteractor.swift in Sources */,\n\t\t\t\t280D71781ED6043D005D2689 /* NewTaskViewController.swift in Sources */,\n\t\t\t\t28A283942037874600DDCB63 /* ModuleGitLogs.swift in Sources */,\n\t\t\t\t280D717A1ED6043D005D2689 /* TasksViewController.swift in Sources */,\n\t\t\t\t288BB6842087157F00CF720A /* WizardAppleScriptView.swift in Sources */,\n\t\t\t\t2845B151206AE3A8006EFB3B /* ReportsHeaderView.swift in Sources */,\n\t\t\t\t28A283AB203A93AB00DDCB63 /* GitBranchParser.swift in Sources */,\n\t\t\t\t280D717B1ED6043D005D2689 /* TasksPresenter.swift in Sources */,\n\t\t\t\t2818848121A4A2F800B33B9C /* Jirassic.xcdatamodeld in Sources */,\n\t\t\t\t2845B14F206AE3A8006EFB3B /* ReportsDataSource.swift in Sources */,\n\t\t\t\t280D717C1ED6043D005D2689 /* CalendarScrollView.swift in Sources */,\n\t\t\t\t280D717D1ED6043D005D2689 /* TasksScrollView.swift in Sources */,\n\t\t\t\t280D717E1ED6043D005D2689 /* TasksDataSource.swift in Sources */,\n\t\t\t\t28A2839F20385BE000DDCB63 /* GitCommitsParser.swift in Sources */,\n\t\t\t\t287195152022E1E2001C237E /* HookupPresenter.swift in Sources */,\n\t\t\t\t280D71811ED6043D005D2689 /* DataSource.swift in Sources */,\n\t\t\t\t28C6A38421D359E60036DB29 /* RemoveDuplicate.swift in Sources */,\n\t\t\t\t280D71821ED6043D005D2689 /* CellProtocol.swift in Sources */,\n\t\t\t\t280D71831ED6043D005D2689 /* TasksView.swift in Sources */,\n\t\t\t\t2898D3A82181907700CF5AD4 /* MonthReportsHeaderView.swift in Sources */,\n\t\t\t\t2845B16A206AE468006EFB3B /* NonTaskCell.swift in Sources */,\n\t\t\t\t2845B1352066C6E6006EFB3B /* AppleScriptProtocol.swift in Sources */,\n\t\t\t\t569C4C582023193B0049FBF1 /* ShellCell.swift in Sources */,\n\t\t\t\t569C4C64202319870049FBF1 /* GitCell.swift in Sources */,\n\t\t\t\t569C4C6D202319CA0049FBF1 /* BrowserPresenter.swift in Sources */,\n\t\t\t\t280D718D1ED6043D005D2689 /* InternalNotifications.swift in Sources */,\n\t\t\t\t280D718E1ED6043D005D2689 /* UserNotifications.swift in Sources */,\n\t\t\t\t280D718F1ED6043D005D2689 /* SleepNotifications.swift in Sources */,\n\t\t\t\t2892B2981F094A170085BAC2 /* JiraRepository.swift in Sources */,\n\t\t\t\t280D71901ED6043D005D2689 /* BrowserNotification.swift in Sources */,\n\t\t\t\t280D719D1ED6043D005D2689 /* SqliteRepository.swift in Sources */,\n\t\t\t\t284192D72018841700E64A9A /* JProject.swift in Sources */,\n\t\t\t\t280D719E1ED6043D005D2689 /* SqliteRepository+Tasks.swift in Sources */,\n\t\t\t\t2892B2A71F094C800085BAC2 /* JWorkAttribute.swift in Sources */,\n\t\t\t\t2845B166206AE468006EFB3B /* TasksHeaderView.swift in Sources */,\n\t\t\t\t28DCA4552018B6E700DFAE29 /* JProjectIssue.swift in Sources */,\n\t\t\t\t280D719F1ED6043D005D2689 /* SqliteRepository+User.swift in Sources */,\n\t\t\t\t28EE1F5E20EE8D1000C5C1D6 /* CalendarCell.swift in Sources */,\n\t\t\t\t280D71A01ED6043D005D2689 /* SqliteRepository+Settings.swift in Sources */,\n\t\t\t\t280D71A11ED6043D005D2689 /* SSettings.swift in Sources */,\n\t\t\t\t280D71A21ED6043D005D2689 /* STask.swift in Sources */,\n\t\t\t\t569C4C6A202319A20049FBF1 /* BrowserCell.swift in Sources */,\n\t\t\t\t280D71A31ED6043D005D2689 /* SUser.swift in Sources */,\n\t\t\t\t280D71A41ED6043D005D2689 /* SQLiteDB.swift in Sources */,\n\t\t\t\t2871952F2025C359001C237E /* CoreDataRepository+Settings.swift in Sources */,\n\t\t\t\t280D71A51ED6043D005D2689 /* SQLTable.swift in Sources */,\n\t\t\t\t2845B139206703C5006EFB3B /* Keychain.swift in Sources */,\n\t\t\t\t280D71A61ED6043D005D2689 /* SQLiteSchema.swift in Sources */,\n\t\t\t\t280D71A71ED6043D005D2689 /* UserDefaults+uploadToken.swift in Sources */,\n\t\t\t\t28279AD121BBF08C00376304 /* InMemoryCoreDataRepository.swift in Sources */,\n\t\t\t\t287195182022E8BC001C237E /* OutputTableViewDataSource.swift in Sources */,\n\t\t\t\t569C4C5E202319630049FBF1 /* JitCell.swift in Sources */,\n\t\t\t\t28A2839A20382BBB00DDCB63 /* GitCommit.swift in Sources */,\n\t\t\t\t284192DA2018855B00E64A9A /* JiraRepository+Projects.swift in Sources */,\n\t\t\t\t565E19F020A5E336003A5E2A /* RCSync.swift in Sources */,\n\t\t\t\t280D71B61ED6043D005D2689 /* Repository.swift in Sources */,\n\t\t\t\t564E55F6202884DE00CE4C76 /* WorklogsPresenter.swift in Sources */,\n\t\t\t\t287195212022FD87001C237E /* InputsTableViewDataSource.swift in Sources */,\n\t\t\t\t287B358720FBAFC40022F43E /* WizardCalendarView.swift in Sources */,\n\t\t\t\t280D71B71ED6043D005D2689 /* RepositoryInteractor.swift in Sources */,\n\t\t\t\t6D5BC4C82C1B5BE6002DA29B /* CreateDayReport.swift in Sources */,\n\t\t\t\t280300D61EDB5ECA000A763E /* StatisticsInteractor.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t4055B11F1E0D802300279430 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t28E896721E83732200722032 /* main.m in Sources */,\n\t\t\t\t28E896711E83732200722032 /* AppDelegate.m in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t4065D3001DD3A1AA00B73201 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t2803A0CA1EC184FF005F9389 /* BrowserNotification.swift in Sources */,\n\t\t\t\t28279AD621C6245700376304 /* GitUsersViewController.swift in Sources */,\n\t\t\t\t4065D3EE1DD3B44200B73201 /* TasksPresenter.swift in Sources */,\n\t\t\t\t4065D3AB1DD3B44200B73201 /* ComputerWakeUpInteractor.swift in Sources */,\n\t\t\t\t2892B29F1F094B0D0085BAC2 /* JReport.swift in Sources */,\n\t\t\t\t28A928811E910DA40022AB55 /* SqliteRepository+Tasks.swift in Sources */,\n\t\t\t\t28279AD321BBF09900376304 /* Jirassic.xcdatamodeld in Sources */,\n\t\t\t\t56ADBF6E21C3F94D008350A6 /* GitUserParser.swift in Sources */,\n\t\t\t\t2898D3B22185959300CF5AD4 /* EditableTimeBox.swift in Sources */,\n\t\t\t\t4065D39F1DD3B44200B73201 /* Task.swift in Sources */,\n\t\t\t\t4065D3CA1DD3B44200B73201 /* AppWireframe.swift in Sources */,\n\t\t\t\t569C4C5F202319630049FBF1 /* JitCell.swift in Sources */,\n\t\t\t\t4065D3C91DD3B44200B73201 /* AppDelegate.swift in Sources */,\n\t\t\t\t405B15661DEF75660009871C /* AppViewController.swift in Sources */,\n\t\t\t\t6D5BC4C92C1B5BE6002DA29B /* CreateDayReport.swift in Sources */,\n\t\t\t\t569C4C65202319870049FBF1 /* GitCell.swift in Sources */,\n\t\t\t\t287195372027CAD9001C237E /* TimeInteractor.swift in Sources */,\n\t\t\t\t287195192022E8BC001C237E /* OutputTableViewDataSource.swift in Sources */,\n\t\t\t\t28577EAD1E8ADC53002B07FD /* SSettings.swift in Sources */,\n\t\t\t\t28577EB51E8AF08F002B07FD /* SQLiteDB.swift in Sources */,\n\t\t\t\t2898D3AC2184D1DB00CF5AD4 /* TimeBoxViewController.swift in Sources */,\n\t\t\t\t286BC00521909F85004D4CDD /* CloseDay.swift in Sources */,\n\t\t\t\t28A928951E9110980022AB55 /* CloudKitRepository+User.swift in Sources */,\n\t\t\t\t4065D3EF1DD3B44200B73201 /* TasksScrollView.swift in Sources */,\n\t\t\t\t4065D3E01DD3B44200B73201 /* SettingsPresenter.swift in Sources */,\n\t\t\t\t569C4C6B202319A20049FBF1 /* BrowserCell.swift in Sources */,\n\t\t\t\t4065D3A31DD3B44200B73201 /* DateExtension.swift in Sources */,\n\t\t\t\t28AA500B1EDCD51300AAF03D /* CoreDataRepository+User.swift in Sources */,\n\t\t\t\t4065D3D81DD3B44200B73201 /* InternalNotifications.swift in Sources */,\n\t\t\t\t4065D3FA1DD3B44200B73201 /* RepositoryInteractor.swift in Sources */,\n\t\t\t\t2898D3A92181907700CF5AD4 /* MonthReportsHeaderView.swift in Sources */,\n\t\t\t\t28DCA4562018B6E700DFAE29 /* JProjectIssue.swift in Sources */,\n\t\t\t\t28A928871E910EA70022AB55 /* SqliteRepository+Settings.swift in Sources */,\n\t\t\t\t28FE1888207A520B00DF796E /* NewTaskCommand.swift in Sources */,\n\t\t\t\t28013890205F86460051B532 /* TimeBox.swift in Sources */,\n\t\t\t\t2812F6212145031B008EE81E /* Store.swift in Sources */,\n\t\t\t\t4065D3F91DD3B44200B73201 /* Repository.swift in Sources */,\n\t\t\t\t4065D3B21DD3B44200B73201 /* TaskInteractor.swift in Sources */,\n\t\t\t\t4065D3A21DD3B44200B73201 /* Week.swift in Sources */,\n\t\t\t\t28AFE7311E9A594500BAAD8C /* UserDefaults+token.swift in Sources */,\n\t\t\t\t4065D3F01DD3B44200B73201 /* TasksViewController.swift in Sources */,\n\t\t\t\t5685C76A1DE8721100CA545E /* LoginViewController.swift in Sources */,\n\t\t\t\t569C4C592023193B0049FBF1 /* ShellCell.swift in Sources */,\n\t\t\t\t2845B14E206AE3A8006EFB3B /* ReportCellPresenter.swift in Sources */,\n\t\t\t\t2823C9351E4F69970055D036 /* Versioning.swift in Sources */,\n\t\t\t\t4065D3A11DD3B44200B73201 /* User.swift in Sources */,\n\t\t\t\t4065D3A71DD3B44200B73201 /* ViewController.swift in Sources */,\n\t\t\t\t4065D3BB1DD3B44200B73201 /* UserInteractor.swift in Sources */,\n\t\t\t\t4065D3E31DD3B44200B73201 /* CellProtocol.swift in Sources */,\n\t\t\t\t2812F61F2145031B008EE81E /* IAPHelper.swift in Sources */,\n\t\t\t\t4065D3A61DD3B44200B73201 /* ViewAutolayout.swift in Sources */,\n\t\t\t\t28CBB597204554A2006F9D3A /* ParseGitBranch.swift in Sources */,\n\t\t\t\t28667B5E1FCB7017007B98E3 /* ModuleHookup.swift in Sources */,\n\t\t\t\t40FCE4271DF7646F00D4FD45 /* SandboxedAppleScript.swift in Sources */,\n\t\t\t\t4065D3B81DD3B44200B73201 /* PredictiveTimeTyping.swift in Sources */,\n\t\t\t\t2845B14A206AE3A8006EFB3B /* ReportCell.swift in Sources */,\n\t\t\t\t288BB6882087169F00CF720A /* ViewXib.swift in Sources */,\n\t\t\t\t5683DC3F20ECDED30000A138 /* ModuleCalendar.swift in Sources */,\n\t\t\t\t28C6A38521D359E60036DB29 /* RemoveDuplicate.swift in Sources */,\n\t\t\t\t284192DB2018855B00E64A9A /* JiraRepository+Projects.swift in Sources */,\n\t\t\t\t28A928971E9110BF0022AB55 /* CloudKitRepository+Settings.swift in Sources */,\n\t\t\t\t564E55F4202883DB00CE4C76 /* WorklogsViewController.swift in Sources */,\n\t\t\t\t288BB6852087157F00CF720A /* WizardAppleScriptView.swift in Sources */,\n\t\t\t\t2871951F2022FD14001C237E /* InputsScrollView.swift in Sources */,\n\t\t\t\t4065D3E11DD3B44200B73201 /* SettingsViewController.swift in Sources */,\n\t\t\t\t4065D3C81DD3B44200B73201 /* FlipAnimation.swift in Sources */,\n\t\t\t\t4065D39E1DD3B44200B73201 /* Settings.swift in Sources */,\n\t\t\t\t28A283B1203CB1A100DDCB63 /* MergeTasksInteractor.swift in Sources */,\n\t\t\t\t2892B29C1F094A760085BAC2 /* JiraRepository+Reports.swift in Sources */,\n\t\t\t\t2845B1402068351F006EFB3B /* TableViewCell.swift in Sources */,\n\t\t\t\t28C9C6221EAD37D0007EB3E6 /* UserDefaults+uploadToken.swift in Sources */,\n\t\t\t\t284192DE2018A8B200E64A9A /* ModuleJiraTempo.swift in Sources */,\n\t\t\t\t4065D3BA1DD3B44200B73201 /* RegisterUserInteractor.swift in Sources */,\n\t\t\t\t28FE18A6207B369800DF796E /* CocoaHookupCell.swift in Sources */,\n\t\t\t\t4065D3B41DD3B44200B73201 /* TaskTypeEstimator.swift in Sources */,\n\t\t\t\t285465A8217858790052CB6A /* StoreView.swift in Sources */,\n\t\t\t\t4065D3D91DD3B44200B73201 /* UserNotifications.swift in Sources */,\n\t\t\t\t569C4C6E202319CA0049FBF1 /* BrowserPresenter.swift in Sources */,\n\t\t\t\t4065D3A51DD3B44200B73201 /* StringIdGenerator.swift in Sources */,\n\t\t\t\t2845B150206AE3A8006EFB3B /* ReportsDataSource.swift in Sources */,\n\t\t\t\t28577EAB1E8ADC53002B07FD /* SqliteRepository.swift in Sources */,\n\t\t\t\t28A283982037975600DDCB63 /* Saveable.swift in Sources */,\n\t\t\t\t28AA50081EDCD51300AAF03D /* CoreDataRepository.swift in Sources */,\n\t\t\t\t280300D71EDB5ECA000A763E /* StatisticsInteractor.swift in Sources */,\n\t\t\t\t28A283A62038AFB100DDCB63 /* JirassicCell.swift in Sources */,\n\t\t\t\t4065D3DF1DD3B44200B73201 /* SettingsInteractor.swift in Sources */,\n\t\t\t\t28577EAF1E8ADC53002B07FD /* STask.swift in Sources */,\n\t\t\t\t28A5F2821E586426002BE564 /* DataSource.swift in Sources */,\n\t\t\t\t28A928931E91104B0022AB55 /* CloudKitRepository+Tasks.swift in Sources */,\n\t\t\t\t566B9FA8217DE67800EAF324 /* TasksInteractor.swift in Sources */,\n\t\t\t\t4065D3B01DD3B44200B73201 /* TaskFinder.swift in Sources */,\n\t\t\t\t28A283952037874600DDCB63 /* ModuleGitLogs.swift in Sources */,\n\t\t\t\t284192D82018841700E64A9A /* JProject.swift in Sources */,\n\t\t\t\t56D90CF920876F1100F24442 /* WizardJiraView.swift in Sources */,\n\t\t\t\t28279AD221BBF08E00376304 /* InMemoryCoreDataRepository.swift in Sources */,\n\t\t\t\t28EDE9391E59EC1500B360A4 /* TasksView.swift in Sources */,\n\t\t\t\t28A283AC203A93AB00DDCB63 /* GitBranchParser.swift in Sources */,\n\t\t\t\t40FCE4301DFD7C8D00D4FD45 /* Animatable.swift in Sources */,\n\t\t\t\t4065D3F21DD3B44200B73201 /* CloudKitRepository.swift in Sources */,\n\t\t\t\t4065D3AE1DD3B44200B73201 /* ReadDaysInteractor.swift in Sources */,\n\t\t\t\t285465A3216C84E10052CB6A /* CreateMonthReport.swift in Sources */,\n\t\t\t\t4065D3D71DD3B44200B73201 /* MenuBarIconView.swift in Sources */,\n\t\t\t\t28A283A020385BE000DDCB63 /* GitCommitsParser.swift in Sources */,\n\t\t\t\t4065D3DA1DD3B44200B73201 /* SleepNotifications.swift in Sources */,\n\t\t\t\t280F507D1EC868B0007416AB /* StringArray.swift in Sources */,\n\t\t\t\t569C4C68202319930049FBF1 /* GitPresenter.swift in Sources */,\n\t\t\t\t28FB265C20224EA700AEA38D /* HookupCell.swift in Sources */,\n\t\t\t\t2845B13A206703C5006EFB3B /* Keychain.swift in Sources */,\n\t\t\t\t28AA500D1EDCD51300AAF03D /* CTask.swift in Sources */,\n\t\t\t\t4065D3A81DD3B44200B73201 /* ViewControllerStoryboard.swift in Sources */,\n\t\t\t\t28AA500C1EDCD51300AAF03D /* CSettings.swift in Sources */,\n\t\t\t\t5685C7691DE8721100CA545E /* LoginPresenter.swift in Sources */,\n\t\t\t\t2871952C20241B25001C237E /* TrackingView.swift in Sources */,\n\t\t\t\t40FCE4261DF7646F00D4FD45 /* ExtensionsInteractor.swift in Sources */,\n\t\t\t\t4051D5F91E0EA48A002042BB /* AppLauncher.swift in Sources */,\n\t\t\t\t28EE1F5F20EE8D1000C5C1D6 /* CalendarCell.swift in Sources */,\n\t\t\t\t56ADBF6B21C3F625008350A6 /* GitUser.swift in Sources */,\n\t\t\t\t2845B167206AE468006EFB3B /* TasksHeaderView.swift in Sources */,\n\t\t\t\t28AA500A1EDCD51300AAF03D /* CoreDataRepository+Settings.swift in Sources */,\n\t\t\t\t280D70B11ECC09D9005D2689 /* AppTheme.swift in Sources */,\n\t\t\t\t5685C7671DE8721100CA545E /* CloudKitLoginViewController.swift in Sources */,\n\t\t\t\t28AA500E1EDCD51300AAF03D /* CUser.swift in Sources */,\n\t\t\t\t2845B165206AE468006EFB3B /* TaskCellPresenter.swift in Sources */,\n\t\t\t\t2871951C2022ECF7001C237E /* OutputsScrollView.swift in Sources */,\n\t\t\t\t2845B1362066C6E6006EFB3B /* AppleScriptProtocol.swift in Sources */,\n\t\t\t\t28577EB11E8ADC53002B07FD /* SUser.swift in Sources */,\n\t\t\t\t4065D3DE1DD3B44200B73201 /* NewTaskViewController.swift in Sources */,\n\t\t\t\t4065D39C1DD3B44200B73201 /* Day.swift in Sources */,\n\t\t\t\t56D90CFC20876F2B00F24442 /* WizardGitView.swift in Sources */,\n\t\t\t\t40FCE42C1DFC3F8700D4FD45 /* WelcomeViewController.swift in Sources */,\n\t\t\t\t28EE1F6520EE92DA00C5C1D6 /* CalendarPresenter.swift in Sources */,\n\t\t\t\t2845B16B206AE468006EFB3B /* NonTaskCell.swift in Sources */,\n\t\t\t\t4065D39D1DD3B44200B73201 /* Report.swift in Sources */,\n\t\t\t\t40FCE4251DF7646F00D4FD45 /* AppleScript.swift in Sources */,\n\t\t\t\t28A928781E8F78580022AB55 /* SQLiteSchema.swift in Sources */,\n\t\t\t\t28FE18AC207B375A00DF796E /* CocoaHookupPresenter.swift in Sources */,\n\t\t\t\t4065D3AF1DD3B44200B73201 /* ReadTasksInteractor.swift in Sources */,\n\t\t\t\t565E19F120A5E336003A5E2A /* RCSync.swift in Sources */,\n\t\t\t\t28AA50091EDCD51300AAF03D /* CoreDataRepository+Tasks.swift in Sources */,\n\t\t\t\t287195162022E1E2001C237E /* HookupPresenter.swift in Sources */,\n\t\t\t\t2892E812208E6275004E5298 /* LocalPreferences.swift in Sources */,\n\t\t\t\t4065D3E21DD3B44200B73201 /* CalendarScrollView.swift in Sources */,\n\t\t\t\t4065D3AC1DD3B44200B73201 /* CreateReport.swift in Sources */,\n\t\t\t\t2845B161206AE468006EFB3B /* TaskCell.swift in Sources */,\n\t\t\t\t28FB265F2022DC2B00AEA38D /* JiraTempoPresenter.swift in Sources */,\n\t\t\t\t287195222022FD87001C237E /* InputsTableViewDataSource.swift in Sources */,\n\t\t\t\t28577EB71E8AF08F002B07FD /* SQLTable.swift in Sources */,\n\t\t\t\t28A928841E910E5E0022AB55 /* SqliteRepository+User.swift in Sources */,\n\t\t\t\t288BB67F2085252900CF720A /* WizardViewController.swift in Sources */,\n\t\t\t\t2892B2A81F094C800085BAC2 /* JWorkAttribute.swift in Sources */,\n\t\t\t\t5685C76C1DE8724400CA545E /* AccountViewController.swift in Sources */,\n\t\t\t\t2845B152206AE3A8006EFB3B /* ReportsHeaderView.swift in Sources */,\n\t\t\t\t2892B2991F094A170085BAC2 /* JiraRepository.swift in Sources */,\n\t\t\t\t28A2839B20382BBB00DDCB63 /* GitCommit.swift in Sources */,\n\t\t\t\t4065D3A91DD3B44200B73201 /* Conversions.swift in Sources */,\n\t\t\t\t405B15611DEF3D080009871C /* TaskSuggestionViewController.swift in Sources */,\n\t\t\t\t564E55F7202884DE00CE4C76 /* WorklogsPresenter.swift in Sources */,\n\t\t\t\t28279E9C1E8300E200EAF9FC /* PlaceholderViewController.swift in Sources */,\n\t\t\t\t28FB265220224E3A00AEA38D /* JiraTempoCell.swift in Sources */,\n\t\t\t\t287B358820FBAFC40022F43E /* WizardCalendarView.swift in Sources */,\n\t\t\t\t405B15631DEF3F2A0009871C /* TaskSuggestionPresenter.swift in Sources */,\n\t\t\t\t4065D3D61DD3B44200B73201 /* MenuBarController.swift in Sources */,\n\t\t\t\t28A5F27E1E5789FC002BE564 /* TasksDataSource.swift in Sources */,\n\t\t\t\t4065D3B61DD3B44200B73201 /* TaskTypeSelection.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t4065D3FE1DD4532100B73201 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t4065D4231DD4562900B73201 /* DateExtensionTests.swift in Sources */,\n\t\t\t\t56D069E1216CABCB000D051D /* CreateMonthReportTests.swift in Sources */,\n\t\t\t\t287558451EFE5969009A2503 /* ReadDaysInteractorTests.swift in Sources */,\n\t\t\t\t4065D4241DD4562900B73201 /* CreateReportTests.swift in Sources */,\n\t\t\t\t2845B16E206AE46F006EFB3B /* TaskCellTests.swift in Sources */,\n\t\t\t\t4073184F1DE9B1B40046F409 /* ComputerWakeUpInteractorTests.swift in Sources */,\n\t\t\t\t28A283AE203C069F00DDCB63 /* GitBranchParserTests.swift in Sources */,\n\t\t\t\t4065D4271DD4562900B73201 /* TaskTypeEstimatorTests.swift in Sources */,\n\t\t\t\t28CBB59A20474755006F9D3A /* ParseGitBranchTests.swift in Sources */,\n\t\t\t\t40FCE4291DFC1CB400D4FD45 /* TaskSuggestionTests.swift in Sources */,\n\t\t\t\t4065D4211DD4562100B73201 /* PredictiveTimeTypingTests.swift in Sources */,\n\t\t\t\t28A283A220385F8C00DDCB63 /* GitCommitsParserTests.swift in Sources */,\n\t\t\t\t4065D4251DD4562900B73201 /* TaskFinderTests.swift in Sources */,\n\t\t\t\t4065D4261DD4562900B73201 /* TaskInteractorTests.swift in Sources */,\n\t\t\t\t28A283B3203CB1B900DDCB63 /* MergeTasksInteractorTests.swift in Sources */,\n\t\t\t\t4065D4201DD4561D00B73201 /* UserInteractorTests.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n\t\t4065D40C1DD4534C00B73201 /* Sources */ = {\n\t\t\tisa = PBXSourcesBuildPhase;\n\t\t\tbuildActionMask = 2147483647;\n\t\t\tfiles = (\n\t\t\t\t28C9C6231EAD37D0007EB3E6 /* UserDefaults+uploadToken.swift in Sources */,\n\t\t\t\t28577EB81E8AF08F002B07FD /* SQLTable.swift in Sources */,\n\t\t\t\t4065D42D1DD4576C00B73201 /* Day.swift in Sources */,\n\t\t\t\t28577EAC1E8ADC53002B07FD /* SqliteRepository.swift in Sources */,\n\t\t\t\t28577EAE1E8ADC53002B07FD /* SSettings.swift in Sources */,\n\t\t\t\t28A9287B1E8FC9B90022AB55 /* CreateReport.swift in Sources */,\n\t\t\t\t285465A4216C84E10052CB6A /* CreateMonthReport.swift in Sources */,\n\t\t\t\t4065D42E1DD4577D00B73201 /* StringIdGenerator.swift in Sources */,\n\t\t\t\t28A928881E910EA70022AB55 /* SqliteRepository+Settings.swift in Sources */,\n\t\t\t\t4065D4321DD457B500B73201 /* Conversions.swift in Sources */,\n\t\t\t\t28A928821E910DA40022AB55 /* SqliteRepository+Tasks.swift in Sources */,\n\t\t\t\t4065D4191DD454CB00B73201 /* RepositoryInteractor.swift in Sources */,\n\t\t\t\t4065D42A1DD4576000B73201 /* Task.swift in Sources */,\n\t\t\t\t28A928851E910E5E0022AB55 /* SqliteRepository+User.swift in Sources */,\n\t\t\t\t4065D42C1DD4576800B73201 /* Report.swift in Sources */,\n\t\t\t\t280300D91EDB5ECA000A763E /* StatisticsInteractor.swift in Sources */,\n\t\t\t\t4065D4301DD4579F00B73201 /* ReadTasksInteractor.swift in Sources */,\n\t\t\t\t6D5BC4CB2C1B5BF7002DA29B /* CreateDayReport.swift in Sources */,\n\t\t\t\t4065D4171DD4536200B73201 /* main.swift in Sources */,\n\t\t\t\t4065D42B1DD4576500B73201 /* Settings.swift in Sources */,\n\t\t\t\t280D71021ED35A25005D2689 /* UserDefaults+token.swift in Sources */,\n\t\t\t\t4065D4281DD4574D00B73201 /* User.swift in Sources */,\n\t\t\t\t4065D4311DD457B000B73201 /* DateExtension.swift in Sources */,\n\t\t\t\t28577EB01E8ADC53002B07FD /* STask.swift in Sources */,\n\t\t\t\t4065D4291DD4575B00B73201 /* Week.swift in Sources */,\n\t\t\t\t280D71031ED35A3E005D2689 /* StringArray.swift in Sources */,\n\t\t\t\t28577EB21E8ADC53002B07FD /* SUser.swift in Sources */,\n\t\t\t\t4065D42F1DD4579400B73201 /* TaskInteractor.swift in Sources */,\n\t\t\t\t28577EB61E8AF08F002B07FD /* SQLiteDB.swift in Sources */,\n\t\t\t\t28A928791E8F78580022AB55 /* SQLiteSchema.swift in Sources */,\n\t\t\t\t4065D4181DD454C500B73201 /* Repository.swift in Sources */,\n\t\t\t);\n\t\t\trunOnlyForDeploymentPostprocessing = 0;\n\t\t};\n/* End PBXSourcesBuildPhase section */\n\n/* Begin PBXTargetDependency section */\n\t\t4065D4081DD4532100B73201 /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 4065D3031DD3A1AA00B73201 /* Jirassic AppStore */;\n\t\t\ttargetProxy = 4065D4071DD4532100B73201 /* PBXContainerItemProxy */;\n\t\t};\n\t\t566C09151F2B985C0058D90A /* PBXTargetDependency */ = {\n\t\t\tisa = PBXTargetDependency;\n\t\t\ttarget = 280D711C1ED5EE7F005D2689 /* Jirassic macOS */;\n\t\t\ttargetProxy = 566C09141F2B985C0058D90A /* PBXContainerItemProxy */;\n\t\t};\n/* End PBXTargetDependency section */\n\n/* Begin PBXVariantGroup section */\n\t\t28E896731E83770D00722032 /* MainMenu.xib */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t28E896741E83770D00722032 /* Base */,\n\t\t\t);\n\t\t\tname = MainMenu.xib;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3431DD3B44200B73201 /* LaunchScreen.xib */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D3441DD3B44200B73201 /* Base */,\n\t\t\t);\n\t\t\tname = LaunchScreen.xib;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3451DD3B44200B73201 /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D3461DD3B44200B73201 /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n\t\t4065D3591DD3B44200B73201 /* Main.storyboard */ = {\n\t\t\tisa = PBXVariantGroup;\n\t\t\tchildren = (\n\t\t\t\t4065D35A1DD3B44200B73201 /* Base */,\n\t\t\t);\n\t\t\tname = Main.storyboard;\n\t\t\tpath = ..;\n\t\t\tsourceTree = \"<group>\";\n\t\t};\n/* End PBXVariantGroup section */\n\n/* Begin XCBuildConfiguration section */\n\t\t280D70C61ECFE06A005D2689 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = \"$(SRCROOT)/Delivery/iOS/Jirassic Scrum.entitlements\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEVELOPMENT_TEAM = 5NHDC5EV44;\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/Delivery/iOS/Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = \"$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.jirassic.ios;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_SWIFT3_OBJC_INFERENCE = On;\n\t\t\t\tSWIFT_VERSION = 4.0;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t280D70C71ECFE06A005D2689 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = \"$(SRCROOT)/Delivery/iOS/Jirassic Scrum.entitlements\";\n\t\t\t\t\"CODE_SIGN_IDENTITY[sdk=iphoneos*]\" = \"iPhone Developer\";\n\t\t\t\tCURRENT_PROJECT_VERSION = 1;\n\t\t\t\tDEVELOPMENT_TEAM = 5NHDC5EV44;\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/Delivery/iOS/Info.plist\";\n\t\t\t\tIPHONEOS_DEPLOYMENT_TARGET = 12.0;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = \"$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.jirassic.ios;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tSDKROOT = iphoneos;\n\t\t\t\tSWIFT_SWIFT3_OBJC_INFERENCE = On;\n\t\t\t\tSWIFT_VERSION = 4.0;\n\t\t\t\tVALIDATE_PRODUCT = YES;\n\t\t\t\tVERSIONING_SYSTEM = \"apple-generic\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t280D712A1ED5EE7F005D2689 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = \"Jirassic macOS.entitlements\";\n\t\t\t\tCODE_SIGN_IDENTITY = \"Mac Developer\";\n\t\t\t\tCODE_SIGN_STYLE = Manual;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tDEVELOPMENT_TEAM = 5NHDC5EV44;\n\t\t\t\tENABLE_HARDENED_RUNTIME = YES;\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/Delivery/macOS/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = \"$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.jirassic.macos;\n\t\t\t\tPRODUCT_NAME = \"Jirassic no cloud\";\n\t\t\t\tPROVISIONING_PROFILE_SPECIFIER = \"jirassic dev\";\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"Delivery/macOS/Bridging-Header.h\";\n\t\t\t\tSWIFT_SWIFT3_OBJC_INFERENCE = Default;\n\t\t\t\tSWIFT_VERSION = 4.2;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t280D712B1ED5EE7F005D2689 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = \"Jirassic macOS.entitlements\";\n\t\t\t\tCODE_SIGN_IDENTITY = \"Apple Development\";\n\t\t\t\tCODE_SIGN_STYLE = Manual;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tDEVELOPMENT_TEAM = 5NHDC5EV44;\n\t\t\t\tENABLE_HARDENED_RUNTIME = YES;\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/Delivery/macOS/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = \"$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.jirassic.macos;\n\t\t\t\tPRODUCT_NAME = \"Jirassic no cloud\";\n\t\t\t\tPROVISIONING_PROFILE_SPECIFIER = \"jirassic distribution\";\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"Delivery/macOS/Bridging-Header.h\";\n\t\t\t\tSWIFT_SWIFT3_OBJC_INFERENCE = Default;\n\t\t\t\tSWIFT_VERSION = 4.2;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t4055B12F1E0D802300279430 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = \"$(SRCROOT)/Delivery/macOS-launcher/JirassicLauncher.entitlements\";\n\t\t\t\tCODE_SIGN_IDENTITY = \"Apple Development\";\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tDEVELOPMENT_TEAM = 5NHDC5EV44;\n\t\t\t\tENABLE_HARDENED_RUNTIME = YES;\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/Delivery/macOS-launcher/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = \"$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.jirassic.macos.launcher;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tPROVISIONING_PROFILE = \"3509678e-d1ba-4d07-bf3c-684b4c4fa932\";\n\t\t\t\tPROVISIONING_PROFILE_SPECIFIER = \"\";\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t\tSWIFT_VERSION = 3.0;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t4055B1301E0D802300279430 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = \"$(SRCROOT)/Delivery/macOS-launcher/JirassicLauncher.entitlements\";\n\t\t\t\tCODE_SIGN_IDENTITY = \"3rd Party Mac Developer Application\";\n\t\t\t\tCODE_SIGN_STYLE = Manual;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tDEVELOPMENT_TEAM = 5NHDC5EV44;\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/Delivery/macOS-launcher/Info.plist\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = \"$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.jirassic.macos.launcher;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tPROVISIONING_PROFILE = \"19d0790c-3a77-4e31-8bbc-4f0b931c9e98\";\n\t\t\t\tPROVISIONING_PROFILE_SPECIFIER = \"jirassic launcher appstore\";\n\t\t\t\tSKIP_INSTALL = YES;\n\t\t\t\tSWIFT_VERSION = 3.0;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t4065D3111DD3A1AA00B73201 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVES = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"-\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = dwarf;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_TESTABILITY = YES;\n\t\t\t\tENABLE_USER_SCRIPT_SANDBOXING = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_DYNAMIC_NO_PIC = NO;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_OPTIMIZATION_LEVEL = 0;\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t);\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.10;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = YES;\n\t\t\t\tONLY_ACTIVE_ARCH = YES;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t4065D3121DD3A1AA00B73201 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tALWAYS_SEARCH_USER_PATHS = NO;\n\t\t\t\tCLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES;\n\t\t\t\tCLANG_ANALYZER_NONNULL = YES;\n\t\t\t\tCLANG_CXX_LANGUAGE_STANDARD = \"gnu++0x\";\n\t\t\t\tCLANG_CXX_LIBRARY = \"libc++\";\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCLANG_ENABLE_OBJC_ARC = YES;\n\t\t\t\tCLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;\n\t\t\t\tCLANG_WARN_BOOL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_COMMA = YES;\n\t\t\t\tCLANG_WARN_CONSTANT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;\n\t\t\t\tCLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;\n\t\t\t\tCLANG_WARN_DOCUMENTATION_COMMENTS = YES;\n\t\t\t\tCLANG_WARN_EMPTY_BODY = YES;\n\t\t\t\tCLANG_WARN_ENUM_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_INFINITE_RECURSION = YES;\n\t\t\t\tCLANG_WARN_INT_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;\n\t\t\t\tCLANG_WARN_OBJC_LITERAL_CONVERSION = YES;\n\t\t\t\tCLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;\n\t\t\t\tCLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;\n\t\t\t\tCLANG_WARN_RANGE_LOOP_ANALYSIS = YES;\n\t\t\t\tCLANG_WARN_STRICT_PROTOTYPES = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVE = YES;\n\t\t\t\tCLANG_WARN_SUSPICIOUS_MOVES = YES;\n\t\t\t\tCLANG_WARN_UNREACHABLE_CODE = YES;\n\t\t\t\tCLANG_WARN__DUPLICATE_METHOD_MATCH = YES;\n\t\t\t\tCODE_SIGN_IDENTITY = \"-\";\n\t\t\t\tCOPY_PHASE_STRIP = NO;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tDEBUG_INFORMATION_FORMAT = \"dwarf-with-dsym\";\n\t\t\t\tENABLE_NS_ASSERTIONS = NO;\n\t\t\t\tENABLE_STRICT_OBJC_MSGSEND = YES;\n\t\t\t\tENABLE_USER_SCRIPT_SANDBOXING = YES;\n\t\t\t\tGCC_C_LANGUAGE_STANDARD = gnu99;\n\t\t\t\tGCC_NO_COMMON_BLOCKS = YES;\n\t\t\t\tGCC_WARN_64_TO_32_BIT_CONVERSION = YES;\n\t\t\t\tGCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;\n\t\t\t\tGCC_WARN_UNDECLARED_SELECTOR = YES;\n\t\t\t\tGCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;\n\t\t\t\tGCC_WARN_UNUSED_FUNCTION = YES;\n\t\t\t\tGCC_WARN_UNUSED_VARIABLE = YES;\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = 10.10;\n\t\t\t\tMTL_ENABLE_DEBUG_INFO = NO;\n\t\t\t\tSDKROOT = macosx;\n\t\t\t\tSWIFT_COMPILATION_MODE = wholemodule;\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-O\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t4065D3141DD3A1AA00B73201 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppStoreIcon;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = \"$(SRCROOT)/Delivery/macOS/Jirassic.entitlements\";\n\t\t\t\tCODE_SIGN_IDENTITY = \"Apple Development\";\n\t\t\t\tCODE_SIGN_STYLE = Automatic;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tDEVELOPMENT_TEAM = 5NHDC5EV44;\n\t\t\t\tENABLE_HARDENED_RUNTIME = YES;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = \"$(inherited)\";\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"APPSTORE=1\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/Delivery/macOS/Info.plist\";\n\t\t\t\tINFOPLIST_KEY_LSApplicationCategoryType = \"public.app-category.productivity\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = \"$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)\";\n\t\t\t\tOTHER_SWIFT_FLAGS = \"-D APPSTORE -D DEBUG\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.jirassic.macos;\n\t\t\t\tPRODUCT_NAME = Jirassic;\n\t\t\t\tPROVISIONING_PROFILE = \"f679af74-4f51-4414-a117-26fcd2203fad\";\n\t\t\t\tPROVISIONING_PROFILE_SPECIFIER = \"\";\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"Delivery/macOS/Bridging-Header.h\";\n\t\t\t\tSWIFT_OPTIMIZATION_LEVEL = \"-Onone\";\n\t\t\t\tSWIFT_SWIFT3_OBJC_INFERENCE = Default;\n\t\t\t\tSWIFT_VERSION = 4.2;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t4065D3151DD3A1AA00B73201 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tASSETCATALOG_COMPILER_APPICON_NAME = AppStoreIcon;\n\t\t\t\tCLANG_ENABLE_MODULES = YES;\n\t\t\t\tCODE_SIGN_ENTITLEMENTS = \"$(SRCROOT)/Delivery/macOS/Jirassic.entitlements\";\n\t\t\t\tCODE_SIGN_IDENTITY = \"3rd Party Mac Developer Application\";\n\t\t\t\tCODE_SIGN_STYLE = Manual;\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tDEVELOPMENT_TEAM = 5NHDC5EV44;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = \"$(inherited)\";\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = \"APPSTORE=1\";\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/Delivery/macOS/Info.plist\";\n\t\t\t\tINFOPLIST_KEY_LSApplicationCategoryType = \"public.app-category.productivity\";\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = \"$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)\";\n\t\t\t\tOTHER_SWIFT_FLAGS = \"-D APPSTORE\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.jirassic.macos;\n\t\t\t\tPRODUCT_NAME = Jirassic;\n\t\t\t\tPROVISIONING_PROFILE = \"ec430240-7fda-4d18-9ddb-146d41480c9b\";\n\t\t\t\tPROVISIONING_PROFILE_SPECIFIER = \"jirassic appstore\";\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"Delivery/macOS/Bridging-Header.h\";\n\t\t\t\tSWIFT_SWIFT3_OBJC_INFERENCE = Default;\n\t\t\t\tSWIFT_VERSION = 4.2;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t4065D40A1DD4532100B73201 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tCODE_SIGN_IDENTITY = \"Mac Developer\";\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tDEVELOPMENT_TEAM = 5NHDC5EV44;\n\t\t\t\tINFOPLIST_FILE = JirassicTests/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/../Frameworks\",\n\t\t\t\t\t\"@loader_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = \"$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.ralcr.JirassicTests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tPROVISIONING_PROFILE_SPECIFIER = \"\";\n\t\t\t\tSWIFT_SWIFT3_OBJC_INFERENCE = Default;\n\t\t\t\tSWIFT_VERSION = 4.2;\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/Jirassic no cloud.app/Contents/MacOS/Jirassic no cloud\";\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t4065D40B1DD4532100B73201 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tBUNDLE_LOADER = \"$(TEST_HOST)\";\n\t\t\t\tCODE_SIGN_IDENTITY = \"Mac Developer\";\n\t\t\t\tCOMBINE_HIDPI_IMAGES = YES;\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tDEVELOPMENT_TEAM = 5NHDC5EV44;\n\t\t\t\tINFOPLIST_FILE = JirassicTests/Info.plist;\n\t\t\t\tLD_RUNPATH_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"@executable_path/../Frameworks\",\n\t\t\t\t\t\"@loader_path/../Frameworks\",\n\t\t\t\t);\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = \"$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)\";\n\t\t\t\tPRODUCT_BUNDLE_IDENTIFIER = com.ralcr.JirassicTests;\n\t\t\t\tPRODUCT_NAME = \"$(TARGET_NAME)\";\n\t\t\t\tPROVISIONING_PROFILE_SPECIFIER = \"\";\n\t\t\t\tSWIFT_SWIFT3_OBJC_INFERENCE = Default;\n\t\t\t\tSWIFT_VERSION = 4.2;\n\t\t\t\tTEST_HOST = \"$(BUILT_PRODUCTS_DIR)/Jirassic no cloud.app/Contents/MacOS/Jirassic no cloud\";\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n\t\t4065D4151DD4534C00B73201 /* Debug */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tDEVELOPMENT_TEAM = 5NHDC5EV44;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PROJECT_DIR)/External/Realm\",\n\t\t\t\t);\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = (\n\t\t\t\t\t\"DEBUG=1\",\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"CMD=1\",\n\t\t\t\t);\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/Delivery/macOS-cmd/Info.plist\";\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = \"$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)\";\n\t\t\t\tOTHER_SWIFT_FLAGS = \"-D CMD\";\n\t\t\t\tPRODUCT_NAME = jirassic;\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"Delivery/macOS/Bridging-Header.h\";\n\t\t\t\tSWIFT_SWIFT3_OBJC_INFERENCE = On;\n\t\t\t\tSWIFT_VERSION = 4.2;\n\t\t\t};\n\t\t\tname = Debug;\n\t\t};\n\t\t4065D4161DD4534C00B73201 /* Release */ = {\n\t\t\tisa = XCBuildConfiguration;\n\t\t\tbuildSettings = {\n\t\t\t\tDEAD_CODE_STRIPPING = YES;\n\t\t\t\tDEVELOPMENT_TEAM = 5NHDC5EV44;\n\t\t\t\tFRAMEWORK_SEARCH_PATHS = (\n\t\t\t\t\t\"$(inherited)\",\n\t\t\t\t\t\"$(PROJECT_DIR)/External/Realm\",\n\t\t\t\t);\n\t\t\t\tGCC_PREPROCESSOR_DEFINITIONS = \"CMD=1\";\n\t\t\t\tINFOPLIST_FILE = \"$(SRCROOT)/Delivery/macOS-cmd/Info.plist\";\n\t\t\t\tMACOSX_DEPLOYMENT_TARGET = \"$(RECOMMENDED_MACOSX_DEPLOYMENT_TARGET)\";\n\t\t\t\tOTHER_SWIFT_FLAGS = \"-D CMD\";\n\t\t\t\tPRODUCT_NAME = jirassic;\n\t\t\t\tSWIFT_OBJC_BRIDGING_HEADER = \"Delivery/macOS/Bridging-Header.h\";\n\t\t\t\tSWIFT_SWIFT3_OBJC_INFERENCE = On;\n\t\t\t\tSWIFT_VERSION = 4.2;\n\t\t\t};\n\t\t\tname = Release;\n\t\t};\n/* End XCBuildConfiguration section */\n\n/* Begin XCConfigurationList section */\n\t\t280D70C51ECFE06A005D2689 /* Build configuration list for PBXNativeTarget \"Jirassic iOS\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t280D70C61ECFE06A005D2689 /* Debug */,\n\t\t\t\t280D70C71ECFE06A005D2689 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t280D71291ED5EE7F005D2689 /* Build configuration list for PBXNativeTarget \"Jirassic macOS\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t280D712A1ED5EE7F005D2689 /* Debug */,\n\t\t\t\t280D712B1ED5EE7F005D2689 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t4055B1311E0D802300279430 /* Build configuration list for PBXNativeTarget \"JirassicLauncher\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t4055B12F1E0D802300279430 /* Debug */,\n\t\t\t\t4055B1301E0D802300279430 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t4065D2FF1DD3A1AA00B73201 /* Build configuration list for PBXProject \"Jirassic\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t4065D3111DD3A1AA00B73201 /* Debug */,\n\t\t\t\t4065D3121DD3A1AA00B73201 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t4065D3131DD3A1AA00B73201 /* Build configuration list for PBXNativeTarget \"Jirassic AppStore\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t4065D3141DD3A1AA00B73201 /* Debug */,\n\t\t\t\t4065D3151DD3A1AA00B73201 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t4065D4091DD4532100B73201 /* Build configuration list for PBXNativeTarget \"JirassicTests\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t4065D40A1DD4532100B73201 /* Debug */,\n\t\t\t\t4065D40B1DD4532100B73201 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n\t\t4065D4141DD4534C00B73201 /* Build configuration list for PBXNativeTarget \"jirassic-cmd\" */ = {\n\t\t\tisa = XCConfigurationList;\n\t\t\tbuildConfigurations = (\n\t\t\t\t4065D4151DD4534C00B73201 /* Debug */,\n\t\t\t\t4065D4161DD4534C00B73201 /* Release */,\n\t\t\t);\n\t\t\tdefaultConfigurationIsVisible = 0;\n\t\t\tdefaultConfigurationName = Release;\n\t\t};\n/* End XCConfigurationList section */\n\n/* Begin XCRemoteSwiftPackageReference section */\n\t\t6D37025B2BA83DB0002260D0 /* XCRemoteSwiftPackageReference \"RCLog\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/cristibaluta/RCLog\";\n\t\t\trequirement = {\n\t\t\t\tbranch = master;\n\t\t\t\tkind = branch;\n\t\t\t};\n\t\t};\n\t\t6D37025C2BA83DDB002260D0 /* XCRemoteSwiftPackageReference \"RCpreferences\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/cristibaluta/RCpreferences\";\n\t\t\trequirement = {\n\t\t\t\tbranch = master;\n\t\t\t\tkind = branch;\n\t\t\t};\n\t\t};\n\t\t6D37025D2BA83DFE002260D0 /* XCRemoteSwiftPackageReference \"RChttp\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/cristibaluta/RChttp\";\n\t\t\trequirement = {\n\t\t\t\tbranch = master;\n\t\t\t\tkind = branch;\n\t\t\t};\n\t\t};\n\t\t6D37025E2BA83E9A002260D0 /* XCRemoteSwiftPackageReference \"SwiftKeychainWrapper\" */ = {\n\t\t\tisa = XCRemoteSwiftPackageReference;\n\t\t\trepositoryURL = \"https://github.com/jrendel/SwiftKeychainWrapper\";\n\t\t\trequirement = {\n\t\t\t\tkind = upToNextMajorVersion;\n\t\t\t\tminimumVersion = 4.0.1;\n\t\t\t};\n\t\t};\n/* End XCRemoteSwiftPackageReference section */\n\n/* Begin XCSwiftPackageProductDependency section */\n\t\t6D37025F2BA83E9A002260D0 /* SwiftKeychainWrapper */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = 6D37025E2BA83E9A002260D0 /* XCRemoteSwiftPackageReference \"SwiftKeychainWrapper\" */;\n\t\t\tproductName = SwiftKeychainWrapper;\n\t\t};\n\t\t6D3702612BA83EB9002260D0 /* RCLog */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = 6D37025B2BA83DB0002260D0 /* XCRemoteSwiftPackageReference \"RCLog\" */;\n\t\t\tproductName = RCLog;\n\t\t};\n\t\t6D3702632BA83EBF002260D0 /* RCPreferences */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = 6D37025C2BA83DDB002260D0 /* XCRemoteSwiftPackageReference \"RCpreferences\" */;\n\t\t\tproductName = RCPreferences;\n\t\t};\n\t\t6D3702652BA83EC7002260D0 /* RCHttp */ = {\n\t\t\tisa = XCSwiftPackageProductDependency;\n\t\t\tpackage = 6D37025D2BA83DFE002260D0 /* XCRemoteSwiftPackageReference \"RChttp\" */;\n\t\t\tproductName = RCHttp;\n\t\t};\n/* End XCSwiftPackageProductDependency section */\n\n/* Begin XCVersionGroup section */\n\t\t2818847F21A4A2F800B33B9C /* Jirassic.xcdatamodeld */ = {\n\t\t\tisa = XCVersionGroup;\n\t\t\tchildren = (\n\t\t\t\t2818848021A4A2F800B33B9C /* Jirassic.xcdatamodel */,\n\t\t\t);\n\t\t\tcurrentVersion = 2818848021A4A2F800B33B9C /* Jirassic.xcdatamodel */;\n\t\t\tpath = Jirassic.xcdatamodeld;\n\t\t\tsourceTree = \"<group>\";\n\t\t\tversionGroupType = wrapper.xcdatamodel;\n\t\t};\n/* End XCVersionGroup section */\n\t};\n\trootObject = 4065D2FC1DD3A1AA00B73201 /* Project object */;\n}\n"
  },
  {
    "path": "Jirassic.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>IDEDidComputeMac32BitWarning</key>\n\t<true/>\n</dict>\n</plist>\n"
  },
  {
    "path": "Jirassic.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict/>\n</plist>\n"
  },
  {
    "path": "Jirassic.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved",
    "content": "{\n  \"originHash\" : \"63bc3e1363d6b6d18dc356b60ac504be39a3587819f597ee22b44a717292b934\",\n  \"pins\" : [\n    {\n      \"identity\" : \"rchttp\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/cristibaluta/RChttp\",\n      \"state\" : {\n        \"branch\" : \"master\",\n        \"revision\" : \"eb5fbb823105f356eb38b10d70202b532831cd0e\"\n      }\n    },\n    {\n      \"identity\" : \"rclog\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/cristibaluta/RCLog\",\n      \"state\" : {\n        \"branch\" : \"master\",\n        \"revision\" : \"f3166aa52b66e2278523ce8eef40bf31a37ddaad\"\n      }\n    },\n    {\n      \"identity\" : \"rcpreferences\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/cristibaluta/RCpreferences\",\n      \"state\" : {\n        \"branch\" : \"master\",\n        \"revision\" : \"d8a2750659ebff18429489d43a933c5560e8367a\"\n      }\n    },\n    {\n      \"identity\" : \"swiftkeychainwrapper\",\n      \"kind\" : \"remoteSourceControl\",\n      \"location\" : \"https://github.com/jrendel/SwiftKeychainWrapper\",\n      \"state\" : {\n        \"revision\" : \"185a3165346a03767101c4f62e9a545a0fe0530f\",\n        \"version\" : \"4.0.1\"\n      }\n    }\n  ],\n  \"version\" : 3\n}\n"
  },
  {
    "path": "Jirassic.xcodeproj/xcshareddata/xcschemes/Jirassic AppStore.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1530\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"4065D3031DD3A1AA00B73201\"\n               BuildableName = \"Jirassic.app\"\n               BlueprintName = \"Jirassic AppStore\"\n               ReferencedContainer = \"container:Jirassic.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      codeCoverageEnabled = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"4065D3031DD3A1AA00B73201\"\n            BuildableName = \"Jirassic.app\"\n            BlueprintName = \"Jirassic AppStore\"\n            ReferencedContainer = \"container:Jirassic.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <Testables>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"4065D4011DD4532100B73201\"\n               BuildableName = \"JirassicTests.xctest\"\n               BlueprintName = \"JirassicTests\"\n               ReferencedContainer = \"container:Jirassic.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"4065D3031DD3A1AA00B73201\"\n            BuildableName = \"Jirassic.app\"\n            BlueprintName = \"Jirassic AppStore\"\n            ReferencedContainer = \"container:Jirassic.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"4065D3031DD3A1AA00B73201\"\n            BuildableName = \"Jirassic.app\"\n            BlueprintName = \"Jirassic AppStore\"\n            ReferencedContainer = \"container:Jirassic.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "Jirassic.xcodeproj/xcshareddata/xcschemes/Jirassic iOS.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1530\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"280D70B51ECFE06A005D2689\"\n               BuildableName = \"Jirassic iOS.app\"\n               BlueprintName = \"Jirassic iOS\"\n               ReferencedContainer = \"container:Jirassic.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"280D70B51ECFE06A005D2689\"\n            BuildableName = \"Jirassic iOS.app\"\n            BlueprintName = \"Jirassic iOS\"\n            ReferencedContainer = \"container:Jirassic.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"280D70B51ECFE06A005D2689\"\n            BuildableName = \"Jirassic iOS.app\"\n            BlueprintName = \"Jirassic iOS\"\n            ReferencedContainer = \"container:Jirassic.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"280D70B51ECFE06A005D2689\"\n            BuildableName = \"Jirassic iOS.app\"\n            BlueprintName = \"Jirassic iOS\"\n            ReferencedContainer = \"container:Jirassic.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "Jirassic.xcodeproj/xcshareddata/xcschemes/Jirassic macOS.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1530\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"280D711C1ED5EE7F005D2689\"\n               BuildableName = \"Jirassic no cloud.app\"\n               BlueprintName = \"Jirassic macOS\"\n               ReferencedContainer = \"container:Jirassic.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      codeCoverageEnabled = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"280D711C1ED5EE7F005D2689\"\n            BuildableName = \"Jirassic no cloud.app\"\n            BlueprintName = \"Jirassic macOS\"\n            ReferencedContainer = \"container:Jirassic.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <Testables>\n         <TestableReference\n            skipped = \"NO\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"4065D4011DD4532100B73201\"\n               BuildableName = \"JirassicTests.xctest\"\n               BlueprintName = \"JirassicTests\"\n               ReferencedContainer = \"container:Jirassic.xcodeproj\">\n            </BuildableReference>\n         </TestableReference>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"280D711C1ED5EE7F005D2689\"\n            BuildableName = \"Jirassic no cloud.app\"\n            BlueprintName = \"Jirassic macOS\"\n            ReferencedContainer = \"container:Jirassic.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"280D711C1ED5EE7F005D2689\"\n            BuildableName = \"Jirassic no cloud.app\"\n            BlueprintName = \"Jirassic macOS\"\n            ReferencedContainer = \"container:Jirassic.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "Jirassic.xcodeproj/xcshareddata/xcschemes/JirassicLauncher.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1530\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"4055B1221E0D802300279430\"\n               BuildableName = \"JirassicLauncher.app\"\n               BlueprintName = \"JirassicLauncher\"\n               ReferencedContainer = \"container:Jirassic.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"4055B1221E0D802300279430\"\n            BuildableName = \"JirassicLauncher.app\"\n            BlueprintName = \"JirassicLauncher\"\n            ReferencedContainer = \"container:Jirassic.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"4055B1221E0D802300279430\"\n            BuildableName = \"JirassicLauncher.app\"\n            BlueprintName = \"JirassicLauncher\"\n            ReferencedContainer = \"container:Jirassic.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"4055B1221E0D802300279430\"\n            BuildableName = \"JirassicLauncher.app\"\n            BlueprintName = \"JirassicLauncher\"\n            ReferencedContainer = \"container:Jirassic.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "Jirassic.xcodeproj/xcshareddata/xcschemes/jirassic-cmd.xcscheme",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Scheme\n   LastUpgradeVersion = \"1530\"\n   version = \"1.3\">\n   <BuildAction\n      parallelizeBuildables = \"YES\"\n      buildImplicitDependencies = \"YES\">\n      <BuildActionEntries>\n         <BuildActionEntry\n            buildForTesting = \"YES\"\n            buildForRunning = \"YES\"\n            buildForProfiling = \"YES\"\n            buildForArchiving = \"YES\"\n            buildForAnalyzing = \"YES\">\n            <BuildableReference\n               BuildableIdentifier = \"primary\"\n               BlueprintIdentifier = \"4065D40F1DD4534C00B73201\"\n               BuildableName = \"jirassic\"\n               BlueprintName = \"jirassic-cmd\"\n               ReferencedContainer = \"container:Jirassic.xcodeproj\">\n            </BuildableReference>\n         </BuildActionEntry>\n      </BuildActionEntries>\n   </BuildAction>\n   <TestAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\">\n      <MacroExpansion>\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"4065D40F1DD4534C00B73201\"\n            BuildableName = \"jirassic\"\n            BlueprintName = \"jirassic-cmd\"\n            ReferencedContainer = \"container:Jirassic.xcodeproj\">\n         </BuildableReference>\n      </MacroExpansion>\n      <Testables>\n      </Testables>\n   </TestAction>\n   <LaunchAction\n      buildConfiguration = \"Debug\"\n      selectedDebuggerIdentifier = \"Xcode.DebuggerFoundation.Debugger.LLDB\"\n      selectedLauncherIdentifier = \"Xcode.DebuggerFoundation.Launcher.LLDB\"\n      launchStyle = \"0\"\n      useCustomWorkingDirectory = \"NO\"\n      ignoresPersistentStateOnLaunch = \"NO\"\n      debugDocumentVersioning = \"YES\"\n      debugServiceExtension = \"internal\"\n      allowLocationSimulation = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"4065D40F1DD4534C00B73201\"\n            BuildableName = \"jirassic\"\n            BlueprintName = \"jirassic-cmd\"\n            ReferencedContainer = \"container:Jirassic.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </LaunchAction>\n   <ProfileAction\n      buildConfiguration = \"Release\"\n      shouldUseLaunchSchemeArgsEnv = \"YES\"\n      savedToolIdentifier = \"\"\n      useCustomWorkingDirectory = \"NO\"\n      debugDocumentVersioning = \"YES\">\n      <BuildableProductRunnable\n         runnableDebuggingMode = \"0\">\n         <BuildableReference\n            BuildableIdentifier = \"primary\"\n            BlueprintIdentifier = \"4065D40F1DD4534C00B73201\"\n            BuildableName = \"jirassic\"\n            BlueprintName = \"jirassic-cmd\"\n            ReferencedContainer = \"container:Jirassic.xcodeproj\">\n         </BuildableReference>\n      </BuildableProductRunnable>\n   </ProfileAction>\n   <AnalyzeAction\n      buildConfiguration = \"Debug\">\n   </AnalyzeAction>\n   <ArchiveAction\n      buildConfiguration = \"Release\"\n      revealArchiveInOrganizer = \"YES\">\n   </ArchiveAction>\n</Scheme>\n"
  },
  {
    "path": "JirassicTests/Info.plist",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n<dict>\n\t<key>CFBundleDevelopmentRegion</key>\n\t<string>en</string>\n\t<key>CFBundleExecutable</key>\n\t<string>$(EXECUTABLE_NAME)</string>\n\t<key>CFBundleIdentifier</key>\n\t<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>\n\t<key>CFBundleInfoDictionaryVersion</key>\n\t<string>6.0</string>\n\t<key>CFBundleName</key>\n\t<string>$(PRODUCT_NAME)</string>\n\t<key>CFBundlePackageType</key>\n\t<string>BNDL</string>\n\t<key>CFBundleShortVersionString</key>\n\t<string>1.0</string>\n\t<key>CFBundleVersion</key>\n\t<string>1</string>\n</dict>\n</plist>\n"
  },
  {
    "path": "MyPlayground.playground/Contents.swift",
    "content": "//: Playground - noun: a place where people can play\n\nimport Cocoa\n\nlet ymdhmsUnitFlags: Set<Calendar.Component> = [.year, .month, .weekday, .day, .hour, .minute, .second]\nlet gregorian = Calendar(identifier: Calendar.Identifier.gregorian)\n\nextension Date {\n    \n    init (year: Int, month: Int, day: Int, hour: Int, minute: Int, second: Int=0) {\n        \n        var comps = gregorian.dateComponents(ymdhmsUnitFlags, from: Date())\n        comps.year = year\n        comps.month = month\n        comps.day = day\n        comps.hour = hour\n        comps.minute = minute\n        comps.second = second\n        \n        self.init(timeInterval: 0, since: gregorian.date(from: comps)!)\n    }\n}\n\n\nprint(Date())\nDate(year: 2017, month: 5, day: 5, hour: 0, minute:0)\nNSCalendar.current.isDate(Date(year: 2017, month: 5, day: 5, hour: 0, minute:0), \n                          inSameDayAs: Date(year: 2017, month: 5, day: 5, hour: 23, minute:59))\nprint ( gregorian.startOfDay(for: Date()) )\n\nlet taskIdEreg = \"([A-Z]+-[0-9])\\\\w+\"\nlet title = \"Pull Request #2411: IOS-1690 Push Notifications Handle\"\nlet regex = try! NSRegularExpression(pattern: taskIdEreg, options: [])\nlet match = regex.firstMatch(in: title, options: [], range: NSRange(location: 0, length: title.characters.count))\n(title as NSString).substring(with: match!.range)"
  },
  {
    "path": "MyPlayground.playground/contents.xcplayground",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>\n<playground version='5.0' target-platform='macos'>\n    <timeline fileName='timeline.xctimeline'/>\n</playground>"
  },
  {
    "path": "README.md",
    "content": "# Jirassic - Jira Time Tracker for employees\n\nJirassic is a Mac app that runs in background and tracks automatically the work you do at your workplace. At the end of the day creates a worklog which you can save to Jira Tempo. Its purpose is to replace primitive tracking methods or relying on memory and do everything automatically.\n\n# Features\n- Track automatically the time you’ve spent on tasks based on git commits\n- Track lunch break\n- Track daily scrum meetings\n- Track code reviews\n- Track time on social media\n- Save worklogs to Jira Tempo\n\n![Screenshot](https://image.ibb.co/eAniz7/tasks.png)\n![Screenshot](https://image.ibb.co/bBhoXS/settings.png)\n\n# How it works\n- When you open your computer in the morning, Jirassic will ask you to start the day\n- Tasks are logged automatically or manually when you finish them, not when you start. The premise is that you're always doing something from start to finish, which you do, isn't?\n- At the end of the day/week/month you can save the worklogs to Jira Tempo or go to reports tab and see them in more detail.\n\n# Shell support\n- jit-CLI Is a wrapper over git which easies the work with jira and branches. Commits made with jit will log tasks to Jirassic Read more at https://github.com/ralcr/Jit\n- jirassic-CLI Use Jirassic from the command line, you can manipulate the Jirassic database directly from the command line and the app does not have to be open.\n\n### Install jirassic CLI\nYou can install it by running this commands in Terminal:\n\n    sudo curl -o /usr/local/bin/jirassic https://raw.githubusercontent.com/ralcr/Jirassic/master/build/jirassic\n    sudo chmod +x /usr/local/bin/jirassic\n\n(Note that this precompiled version works with the AppStore app, it won't see the database of the 'Jirassic macOS' target)\n![Screenshot](https://s1.postimg.org/tq0jtk65b/Screen_Shot_2017-04-01_at_17.45.21.png)\n\n# Compile\nXcode9 and swift4 is needed. Use the target 'Jirassic macOS' because it is configured to run without signing, that means backup to iCloud will not be available. If you need iCloud you can use the Jirassic AppStore target after you create your own iCloud container and provisioning.\n\n# Licence & contribution\nJirassic is free in the Appstore but with some IAP for some features, for this reason you are not allowed to resell or distribute this software. If you wish to contribute with code note that you will not be paid, we still hope you contribute with creating issues to make it a better software.\n"
  },
  {
    "path": "licence.txt",
    "content": "Copyright (C) 2017 jirassic.com\n\nPermission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to use or modify the app for personal purpose. Re-selling or distributing this app is not allowed.\n\nThe above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
  },
  {
    "path": "scripts/add-key.sh",
    "content": "#!/bin/sh\n# Create a custom keychain\nsecurity create-keychain -p travis macos-build.keychain\n\n# Make the custom keychain default, so xcodebuild will use it for signing\nsecurity default-keychain -s macos-build.keychain\n\n# Unlock the keychain\nsecurity unlock-keychain -p travis macos-build.keychain\n\n# Set keychain timeout to 1 hour for long builds\n# see http://www.egeek.me/2013/02/23/jenkins-and-xcode-user-interaction-is-not-allowed/\nsecurity set-keychain-settings -t 3600 -l ~/Library/Keychains/macos-build.keychain\n\n# Add certificates to keychain and allow codesign to access them\nsecurity import ./scripts/certs/MacDeveloper.p12 -k ~/Library/Keychains/macos-build.keychain -P $PASSWORD -T /usr/bin/codesign\n\n# Put the provisioning profile in place\nmkdir -p ~/Library/MobileDevice/Provisioning\\ Profiles\ncp \"./scripts/profile/jirassic_dev.provisionprofile\" ~/Library/MobileDevice/Provisioning\\ Profiles/\ncp \"./scripts/profile/jirassic_launcher_dev.provisionprofile\" ~/Library/MobileDevice/Provisioning\\ Profiles/"
  }
]